Issac Sim | Python API - Camera orientation ignored

Creating a Camera sensor using the Python API, sets a default orientation, that cannot be changed. Trying to set orientation, is just being ignored. Here is a reproduction:

from omni.isaac.sensor import  Camera

right_camera = Camera("/camera_right", name="camera_right", translation=np.array([0, 0, 0]), orientation=np.array([1, 0, 0, 0]))
right_camera.set_world_pose(orientation=np.array([1, 0, 0, 0]))
right_camera.set_default_state(orientation=np.array([1, 0, 0, 0]))

hello, have you solve it ,? I also found that the orientation can not set

Unfortunately not, I decided to return back to using Gazebo after fighting with Isaac Sim for too long

Hi omers,

What you are seeing is the expected behaviour using the Camera class api since the orientation is being set using the right-handed coordinate conventions (+Z UP and +X forward). However the usd camera properties shown in the property panel are shown with the coordinate convention of (+Y up and -Z Forward).

Setting the orientation as [1, 0, 0, 0] should point the camera forwards towards the +X. Are you expecting the USD camera to be set in the ROS convention? Or you are confused with the difference between the api and USD property panel values?

Let us know if you are encountering more problems.

Take a look here for an explanation of the conventions: Conventions Reference — Omniverse Robotics documentation

@oahmed Thanks for the reply. It has nothing to do with ROS. We set a value in the python api, and expect to see the same value in the properties panel. The python api convention is WXYZ, and even if it wasn’t [1,0,0,0], wouldn’t be converted to [-0.5, -0.5, 0.5, 0.5]. You can see in the image.

Camera prims in USD are Y up -Z forward

image

The Camera() class that wraps around the usd camera prim hides this difference and presents a Z up X forwards interface for consistency. This is why setting the orientation of the Camera() class does not match whats in the property window.

One solution is to place the camera prim as a child of an XformPrim, changing the orientation of the XformPrim would match as you would expect.

@Hammad_M I think the issue here might be misunderstood. The camera has a default orientation of [-0.5, -0.5, 0.5, 0.5], which is in euler is x: 90, y: -90. No matter what this value can’t be changed. We can work around it by having a prim that will rotate it back to 0, but this doesn’t solve the bug, it is just a workaround. There is a bug here that needs to be solved regardless of the parent prim workaround.

To clarify, do you mean that in the property window, when you change the euler x,y,z angles, the object doesn’t rotate?

That specific bug has been fixed and will be part of 2022.2.1 coming out soon.

I mean that is you change it in the Python API, it doesn’t change it in the property window, nor rotate the object. Might be that it is related to the fixed bug, but not sure.

import asyncio
from omni.isaac.sensor import  Camera
import numpy as np
from omni.isaac.core.utils.stage import update_stage_async

async def run():
	right_camera = Camera("/camera_right", name="camera_right", translation=np.array([0, 0, 0]), orientation=np.array([1, 0, 0, 0]))
	await update_stage_async()
	#comment the line below to see the difference
	right_camera.set_world_pose(orientation=np.array([0, 0, 0,  1]))
asyncio.ensure_future(run())

Can you run this in the script editor? This should work for changing the orientation of the camera. Make sure to enable camera visualisation to see the orientation more clearly.

image

Try also following the docs at Camera — Omniverse Robotics documentation for better understanding of cameras.

Ignore the USD euler orientation property shown in the USD property panel for now since it had a bug that will be fixed in the next release.

Let us know if you have more questions.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.

Hi @oahmed

I tried the script given by you, and it’s working perfectly fine. However, when I write the similar code in the following way, it doesn’t work. Could you please let me know the reason why the orientation doesn’t change with my code?

from omni.isaac.sensor import Camera
import numpy as np
world_camera = Camera(
    prim_path="/World/world_camera"
)
world_camera.initialize()
world_camera.set_focus_distance(40)
world_camera.set_world_pose(orientation=np.array([1, 0, 0, 0])) # default orientation is [-0.5, -0.5, 0.5, 0.5]

I used the script editor for this given snippet. Since the default camera object has a focus distance equal to zero, I set the focus distance to 40 so that I can see the camera’s field of view.

My actual requirement is:

I want to add the camera to the end-effector of the Franka Panda robot. To achieve this, I am creating a camera primitive object as a child of the “panda_hand” link, and later I will adjust the orientation of the camera.

Hi, I found the similar problem with you, and I wrote a pose of it, hope it can help you out.
You can check this post out.

Solution

According to the discussion in the form, I think its a designed mechanism to automatically keep the same camera coordinate system(+Y up) across different USD files.

And if you want to cancel this “auto-rotation” effect, you can use camera_axes="usd" args in set_world_pose().

from omni.isaac.sensor import Camera
camera = Camera(
    prim_path="/World/camera",
    position=np.array([0, 0, 0]),
    orientation=np.array([1, 0, 0, 0]),
)
camera.set_world_pose(np.array([0, 0, 0]), np.array([1, 0, 0, 0]), camera_axes="usd")
my_world.step(render=True)

This way, the default camera pose will aligned with the world frame.
Pasted image 20240501181344 Pasted image 20240501181355

You can find more detailed information about set_world_pose() in the API docs of it here.