← BlogAMR Navigation Basics· 11/12

How Nav2 Connects to Isaac Sim over ROS2 — TF, cmd_vel, and Namespace

Isaac Sim and Nav2 form a closed ROS2 loop: sensor data (scan/odom) flows from the simulator into Nav2, and commands (cmd_vel) flow back out to the simulated wheels via DriveAPI. Multi-robot isolation uses namespaces, and sim odom lag affects closed-loop controllers.

~4 min
Nav2Isaac-SimROS2TFnamespace

How Nav2 Connects to Isaac Sim over ROS2

The previous posts examined Nav2's internals. Nav2 can drive a simulated robot just as well as a physical one, because the simulator (Isaac Sim) and Nav2 are connected through ROS2 topics and TF. This post looks at that bridge.

▶ Simulation footage — Nova Carter AMR in Isaac Sim following Nav2 waypoints across terrain. The blue line is the global path, the top banner shows waypoint progress, and the bottom displays real-time speed, heading, and position telemetry.

One Full Loop of Data Flow

The connection is a closed loop: sensors flow from the simulator into Nav2; commands flow from Nav2 back into the simulator.

Rendering diagram…
  • Sim → Nav2: LiDAR publishes /{robot}/scan; wheel odometry publishes /odom (via the OmniGraph ROS2 bridge).
  • Nav2 → Sim: The controller's cmd_vel passes through velocity_smoother to /{robot}/cmd_vel; DriveAPI picks it up and spins the wheels.
  • The resulting motion is measured again as odom, feeding back into Nav2— a closed loop.

The Coordinate Skeleton — TF

Everything in this loop must happen in a shared coordinate frame. Following the ROS standard (REP 105), a TF tree connecting map → odom → base_link must exist before the costmap, planner, and controller can determine where the robot is. The simulator publishes the robot's base_link transform to complete this skeleton.

⚠️ TF lag halts everything — if the costmap activates before map → odom → base_link is available, it stalls indefinitely not knowing its own position. The startup sequence of sim boot, TF publication, and costmap activation must be synchronized.

Multi-Robot — Isolation by Namespace

With multiple robots, topics must not collide. Each robot is isolated by namespace, so topics become /{robot_id}/scan, /{robot_id}/cmd_vel, and so on.

💡 Namespace isolation — placing each robot's Nav2 stack under its own namespace means identical topic names like /carter_1/... and /carter_2/... never interfere. This is foundational practice for multi-robot simulation.

Sim-Specific Pitfall — odom Lag

There is one subtle difference that comes from being in simulation. PhysX physics can introduce a one-tick odom delay, which affects Nav2's closed-loop controller — the RPP rotation stuck at 0.05 rad/s bug was caused exactly by this odom lag. Understanding this lag is essential for interpreting the behavioral differences between simulation and a physical robot.

In a nutshell

📌 Nav2 and Isaac Sim are connected through a ROS2 closed loop: sensors (/scan, /odom) flow sim → Nav2; commands (/cmd_vel) flow Nav2 → sim, with the map → odom → base_link TF tree as the coordinate backbone. Multi-robot deployments isolate each robot by namespace. Sim odom lag can affect closed-loop controllers and must be accounted for.

See standard test results with videos and verdict evidence on the imSim Portal.

View public results →