Isaac Sim ROS2 Odometry/EKF: Robot Moves Backwards in Y When Facing +Y

Summary

When using Isaac Sim with ROS2 and robot_localization’s dual EKF, my robot’s odometry and IMU data appear correct when moving along the +X axis, but when the robot is rotated to face +Y and commanded to move forward, the /odometry/local (EKF output) shows the robot moving backwards in Y (i.e., in the -Y direction). The same command works as expected in +X.

System Details

  • Isaac Sim Version: 4.5.0-rc.36+release.19112

  • ROS2 Version: (please specify, e.g., Humble/Foxy)

  • OS: Ubuntu 22.04 (Linux 6.8.0-60-generic)

  • Robot URDF: Custom (four_wheel_robot.urdf, X+ forward, Y left, Z up)

  • Simulation Script: Custom Python (four_wheel_robot.py), publishes /odometry/wheel, /imu/data, /fix_sim (GPS), and TF

Topic Description

Detailed Description

I am using NVIDIA Isaac Sim with ROS2 and the robot_localization dual EKF to fuse wheel odometry, IMU, and GPS data. My robot’s odometry and IMU data appear correct when moving along the +X axis, but when I rotate the robot to face +Y and command it to move forward, the /odometry/local (EKF output) shows the robot moving backwards in Y (i.e., in the -Y direction). The same command works as expected in +X.

I expect that when the robot is facing +Y and I send a forward command, /odometry/local should increase in +Y, matching /odometry/wheel and the robot’s actual movement in Isaac Sim and RViz. Instead, it decreases in Y.

Steps to Reproduce

  1. Launch Isaac Sim and load my robot (URDF: X+ forward, Y left, Z up).

  2. Start my custom Python script (four_wheel_robot.py) that publishes /odometry/wheel, /imu/data, /fix_sim (GPS), and TF.

  3. Start the robot_localization dual EKF node, fusing /odometry/wheel, /imu/data, and /fix_sim.

  4. In RViz, face the robot in the +X direction and send a forward command—robot moves forward in +X as expected.

  5. Rotate the robot to face +Y in RViz and send a forward command—robot moves in -Y (backwards) in /odometry/local, even though /odometry/wheel and /imu/data look correct.

Error Messages

N/A (no explicit error messages; the issue is with the direction of motion in the EKF output)


Additional Information

What I’ve Tried

  • Ensured all topics (odometry, IMU, GPS) use the same frame: X forward, Y right, Z up (matching Isaac Sim).

  • Removed all Y-axis flips and yaw inversions from the code so that ROS and Isaac Sim use the same convention.

  • Odometry publisher: msg.pose.pose.position and msg.twist.twist.linear are both published in the robot’s local frame; orientation quaternion is published as received from Isaac Sim (no correction).

  • IMU publisher: orientation and linear acceleration are published as received from Isaac Sim (no correction).

  • TF tree: all frames are consistent and match the odometry/IMU conventions.

  • EKF configuration: dual EKF is configured to fuse /odometry/wheel, /imu/data, and /fix_sim.

Additional Context

  • When facing +X and moving forward, everything works as expected.

  • When facing +Y and moving forward, /odometry/local goes negative in Y (backwards), even though /odometry/wheel and /imu/data look correct.

  • The robot’s orientation in RViz matches the simulation, but the fused EKF output is wrong in Y.

  • I am unsure if the velocity in odometry should be published in the world frame or the robot’s local frame for the EKF to work correctly.

  • I would appreciate any advice or examples from others who have solved this, or clarification on the correct conventions for Isaac Sim + ROS2 EKF integration.


Hi @ravi.parmar May I know why you want the robot to face +Y direction? By default, the robot should face +X direction.

Yes, by default the robot faces the +X direction. But when I rotate the robot to face +Y in Isaac Sim, I can see in both Isaac Sim and RViz that the robot is oriented correctly along +Y.

When I send a forward command, the robot moves in the +Y direction in simulation, and /odometry/wheel also shows increasing Y values — which is expected.

However, in /odometry/local (from the dual EKF in robot_localization), the Y value decreases (i.e., moves in the -Y direction). Since RViz uses odom as the fixed frame, this makes the robot appear to move backward even though it’s commanded forward. The same reversed behavior happens when the robot is facing -Y.

I suspect the issue may be with the orientation quaternion being published from Isaac Sim — possibly not following the ROS REP-103 convention. Could you confirm if Isaac Sim uses a left-handed coordinate system for Y, and whether we need to apply a yaw correction to the quaternions published to /imu/data and /odometry/wheel?

Let me reach out to the internal team

@ravi.parmar could you please share your USD files/scripts for us to reproduce the issue? If you cannot share your robot, can you reproduce this using Isaac Sim robot and share with us? Thanks!

@zhengwang Thanks for your time and reply.
I have Resolved this Issue.

The issue was caused by a coordinate frame mismatch between Isaac Sim and ROS. When the robot was rotated to face +Y and moved forward in Isaac Sim, the /odometry/local output from the EKF incorrectly showed motion in the -Y direction.

To fix this I created a reflection matrix in my Isaac sim standalone python file to flip the Y-axis of the world frame (from +Y to -Y) before sending the data to ROS. This cancels out a hidden axis inversion happening somewhere in the pipeline either in Isaac Sim, the ROS bridge or RViz.

I applied the following transformation:

reflection_matrix = np.diag([1, -1, 1, 1]) # Flip Y-axis
corrected_transform = np.matmul(world_transform, reflection_matrix)

After applying this correction to the transform before publishing topics like /odometry/wheel, /imu/data etc, the EKF output and RViz visualization now perfectly match the robot’s actual movement in Isaac Sim.

2 Likes

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