Engineering Notes

What we learned building robot simulation

Physics, RL, sensors, navigation, standards — engineering notes from the imSim team. 69 posts grounded in real runs, commits, and measured data.

AMR Navigation Basics

12

What Is an Occupancy Grid — Drawing the Sensed World as a Grid

The occupancy grid — how a mobile robot represents its world as a 2D probabilistic grid of 'wall / free / unknown': the resolution trade-off, why it must be a *probability*, the limits of 2D, and the difference between how a real robot (SLAM) and a simulator (ground truth) build it.

Nav2mappingoccupancy-gridAMR

From Static Map to Nav2 Costmap — A Map That Knows Walls vs. One That Doesn't

How an occupancy grid flows through Nav2's map_server into a static-layer costmap that the planner can actually use, and why substituting an all-free empty map makes the robot believe the world has no walls.

Nav2costmapstatic-mapmap-server

Costmap 2D Dissected — How the Static, Obstacle, and Inflation Layers Compose

Nav2's costmap is not a single map but a composite of static, obstacle, and inflation layers stacked together. This post covers what each layer contributes and the real bug where removing the obstacle layer caused robots to pass through each other.

Nav2costmaplayersobstacle-layer

What Inflation Does — Bloating Obstacles So the Planner Can Treat the Robot as a Point

Inflation wraps a cost gradient around obstacles to compensate for the robot's physical width, letting the path planner treat the robot as a dimensionless point. This post explains the principle and why a single inflation radius breaks down in heterogeneous fleets.

Nav2inflationcostmaprobot-radius

Global vs Local Costmap — Dividing the Work Between Long-Range Planning and Instant Avoidance

Nav2 splits costmaps into a global one for whole-map path planning and a local rolling-window one for real-time obstacle avoidance. This post covers their roles, dynamic sizing, and why multi-robot deployments must populate both.

Nav2costmapglobal-plannerlocal-planner

Nav2 Lifecycle and Behavior Trees — How the Navigation Stack Wakes Up

Nav2 servers activate in a strict lifecycle order, and bt_navigator orchestrates planning, tracking, and recovery through a Behavior Tree. This post explains both and covers the real failures that occur when activation order goes wrong.

Nav2lifecyclebehavior-treebt-navigator

Path Planners NavFn and Smac — Finding the Lowest-Cost Route Across the Costmap

The planner treats the global costmap as a graph and solves for the shortest path. NavFn uses Dijkstra/A*-style potential field propagation; Smac adds kinematic constraints. The most common planner failure is not algorithmic — it is the goal falling Off Grid.

Nav2plannerNavFnSmac

The RPP Controller — How Pure Pursuit Converts a Path to Wheel Velocities (and the 0.05 Rotation Bug)

Regulated Pure Pursuit tracks a lookahead point on the path to produce cmd_vel. This post covers the principle and a real debugging case where odom acceleration clamping permanently pinned angular velocity at 0.05 rad/s.

Nav2controllerRPPpure-pursuit

Recovery Behaviors — How the Robot Gets Itself Unstuck

When path following fails or the robot stalls, recovery behaviors like spin, backup, and wait change the situation and retry. This post covers how the Behavior Tree triggers them and how fleet-level stops must cancel Nav2 goals — not just halt the wheels.

Nav2recoverybehavior-treestuck

VFH+ Reactive Avoidance — Finding a Gap with a Polar Histogram, No Costmap Required

Vector Field Histogram reduces a dense occupancy grid to a polar density histogram and picks the most open steering direction. VFH+ adds robot-width compensation via angular enlargement — useful as a lightweight fallback when Nav2 is not running or dynamic obstacles dominate.

Nav2VFHreactiveobstacle-avoidance

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.

Nav2Isaac-SimROS2TF

AMR Safety Simulation — From Navigation Stack to ISO 3691-4 Reference KPIs

The navigation concepts covered in this series — occupancy grid, costmap, planner, controller, and avoidance — ultimately answer one question: is this AMR safe to operate alongside people? This post shows how those components map to ISO 3691-4 safety KPIs measured in simulation.

AMRsafetyISO-3691-4KPI

How Isaac Sim Works

10

Isaac Sim Boot Order — SimulationApp Must Come First

Isaac Sim's omni.* modules do not exist until the Kit runtime is running. SimulationApp must be instantiated before any omni.* import, and world.reset() is a second hard boundary where physics state is locked in. imSim always uses Fresh mode — one boot per run — for reproducibility.

Isaac-SimOmniverseUSDPhysX

Composing a Scene with USD — Stage, Prim, and Reference

An Isaac Sim scene is not a single monolithic 3D file. It is a tree of prims on a USD stage. Environments and robots are inserted as references; runtime obstacles are defined as primitive geometry. The prim path is the address used to control every object later.

Isaac-SimOpenUSDstageprim

PhysicsScene and the Solver — How Physics Attaches to a Scene

Gravity, collision, and solver iterations are stored in a single PhysicsScene prim that broadcasts its settings to every rigid body in the scene. PhysX is the default — kinematic mode is only a shortcut for quick tests, not a substitute for real physics.

Isaac-SimPhysXphysics-scenesolver

Why Physics Runs at 200 Hz and Rendering at 60 Hz — Substeps

Why a simulation loop steps physics multiple times per render frame (substeps) — decoupling timesteps to hit stability and performance at once. This is also why legged robots fall apart at 60 Hz.

Isaac-SimPhysXtimestepsubsteps

What It Means to Drive Wheels with DriveAPI — Torque, Not Teleportation

Wheels and joints are articulation joints; DriveAPI (target velocity + stiffness/damping) lets PhysX compute the torque that actually spins them. The fundamental difference from kinematic position assignment.

Isaac-SimPhysXDriveAPIarticulation

Bridging to ROS2 with OmniGraph — A Visual Graph That Publishes Sensor Topics

How sensor-to-topic publishing and /cmd_vel-to-actuation are wired up as OmniGraph (visual compute graph) node chains — and the common pitfall when receiving external ROS2 commands.

Isaac-SimOmniGraphROS2sensors

Attaching Sensors — PhysX LiDAR vs RTX LiDAR, Camera, IMU

Sensors are created as prims in the scene; RTX LiDAR extracts a point cloud from the render pipeline. The fundamental difference between PhysX LiDAR and RTX LiDAR.

Isaac-SimsensorsLiDARRTX

Why Is Rendering On If It's Headless? — headless ≠ no-render

Even without a display window (headless), HLS streaming, video recording, RTX sensors, and synthetic data generation all require rendering — the common misconception that 'headless means render off.'

Isaac-SimheadlessrenderingRTX

Fresh Mode vs Daemon Mode — The Temptation of Fast Reuse and the Problem of State Contamination

Fresh mode boots a new simulator process per run; Daemon mode reuses a running process. The latter looks faster, but cross-run state contamination destroys the reproducibility that validation depends on.

Isaac-Simprocess-isolationstatevalidation

The Life of a Simulation Run — From Submission to Video and KPIs

The complete lifecycle of a simulation run triggered by a single button press: queue, worker, runner, outputs. What each stage does and where artifacts come from.

Isaac-Simorchestrationpipelinelifecycle

Physical AI Basics

5

What Is Physical AI — Intelligence That Steps Out of the Digital World Into the Physical One

Physical AI — intelligence that perceives and acts in the physical world, beyond the digital AI of text and images: why it is emerging now, how it tackles its biggest wall (data), and why simulation is the core infrastructure.

physical-aiembodied-airoboticssimulation

OpenUSD Scene Composition — Assembling a World with Layers, References, and Payloads

USD is not a single 3D file format — it is a non-destructive layer-compositing system. How the same asset can be reused across many scenarios without conflicts, through layers, references, payloads, variants, and LIVRPS strength ordering.

OpenUSDcompositionlayersLIVRPS

Synthetic Light for Real Sensors — RTX-Based EO/IR/LiDAR/Radar/Sonar

How multi-domain sensors — EO, IR, LiDAR, Radar, Sonar — use physics-based rendering and ray or acoustic tracing to generate synthetic data, and what makes each modality different.

RTXsensorsLiDARradar

A Digital Twin Is Not a 3D Model — It's a Living, Synchronized Replica

A digital twin is not a pretty 3D visualization — it is a virtual counterpart that stays synchronized with the real system. Sensors update the twin; the twin predicts and feeds back control. The bidirectional loop is the definition.

digital-twinOpenUSDsimulationfacility

From Simulation-Trained Policy to a Chip on the Robot — The Reality of Edge AI Deployment

Getting a policy trained on massive GPU clusters onto a small edge chip for real-time inference. The constraints of quantization, inference optimization, latency, and power — and how simulation validates the bridge between them.

edge-aideploymentTensorRTquantization

Debugging War Stories

5

The One Line That Sank Seven Ships to the Mariana Trench — The Substring Matching Trap

A surface buoyancy setup used a single identifier check to decide whether buoyancy was needed. Because the submarine's identifier didn't contain 'UUV', the entire fleet's buoyancy was switched off and all seven vessels sank to -2989 m.

debuggingbuoyancymaritimewar-story

The Joint Was Running 40× Over the Speed Limit — What Peak KPI Hid: 12,078 dps

A peak KPI that only measured maximum lift height kept awarding PASS even when the arm dropped the object mid-transfer. Once trajectory KPIs were added, cells that had been marked PASS turned out to have joint velocities 40× over the recommended limit.

debuggingmanipulatorKPItrajectory

Static Analysis Said 'Impossible' — But the Actual Run Rendered It: Gaussian Splatting in Isaac Sim

Code analysis concluded that Gaussian Splatting was impossible in this build. Then we actually ran it and got a photorealistic interior. A textbook case of empirical measurement overturning static reasoning.

debugginggaussian-splattingNuRecinstrument-first

One Vehicle Rolled Over at -63° — A Physics Bug That Was Actually Environment Version Drift

A vehicle convoy scenario that had already passed validation suddenly flipped one vehicle to -63° roll. We spent a long time suspecting physics, but the real culprit was a batch job that had silently swapped the environment DB from the validated flat terrain to a steep version.

debuggingenvironmentconfigregression

Vehicles Are Passing Through Each Other — The Price of Confusing ORCA Avoidance with PhysX Collision

Vehicles drove straight through each other and through obstacles. A record of tracking down the bug — rooted in confusing two distinct collision concepts: ORCA proactive avoidance vs. PhysX rigid-body contact.

debuggingcollisionPhysXORCA

RL & World Models

5

The Sim-to-Real Gap — Why Policies That Work in Simulation Break on Real Robots, and How to Measure It Honestly

The root causes of the sim-to-real reality gap, domain randomization as the primary countermeasure, and why honest measurement — not just simulation KPIs — is the only way to close it.

sim2realdomain-randomizationRLvalidation

Generating Synthetic Data with a World Foundation Model — NVIDIA Cosmos and the Data Flywheel

Real robot data is scarce and expensive. World Foundation Models — video-generation models that understand physics — mass-produce synthetic data for training perception and policy networks, forming a data flywheel that compounds with each iteration.

Cosmosworld-modelsynthetic-dataphysical-ai

The End of Training a New Policy for Every Task — VLA Foundation Models and GR00T

From training separate policies for every task to a single model that sees, hears, and acts: the VLA foundation model paradigm. NVIDIA GR00T's dual-system architecture and the role simulation plays in it.

VLAGR00Tfoundation-modelhumanoid

Training Thousands of Robots Simultaneously on a GPU — Isaac Lab Parallel Reinforcement Learning

What reinforcement learning is and why it's slow, why you can run thousands of environments at once on a GPU (it's all tensors), and the truly hard part — reward design. The basics of parallel RL.

RLIsaac-LabGPUPPO

RL Policy or cuMotion — They All Plug Into the Same Socket

The 'brain' driving a robot arm can be an RL policy, a classical motion planner, or a foundation model. The PolicyAdapter Protocol defines a common interface so any brain plugs into the same socket — the runner never needs to know which one it is.

policyadapterprotocolarchitecture