Dev Notes
Architecture decisions
Section titled “Architecture decisions”Why pixi for the native workflow?
Section titled “Why pixi for the native workflow?”ROS 2 + Gazebo + their dependencies are notoriously painful to install natively, especially across different OS versions. pixi solves this by storing the entire environment (ROS 2 Jazzy, Gazebo Harmonic, all dependencies) inside the repo’s .pixi/ directory via conda. Deleting the repo also deletes the environment — your system stays completely clean. The same pixi install works on Linux, macOS, and WSL2 without any OS-level ROS installation.
Why a Dev Container (alternative)?
Section titled “Why a Dev Container (alternative)?”The Docker Dev Container is an alternative for users who prefer a containerized environment or already have Docker set up. It provides the same ROS 2 Jazzy + Gazebo Harmonic environment inside a container. The Dev Container is useful for Windows users (via Docker Desktop), CI systems, or anyone who wants strong isolation from their host system.
Why Gazebo Harmonic?
Section titled “Why Gazebo Harmonic?”Gazebo Harmonic (gz-sim 8.x) is the current LTS release of the new-generation Gazebo and pairs with ROS 2 Jazzy. It replaces the old Gazebo Fortress (ignition-fortress). The package prefix changed from ign to gz in this generation — use gz topic, gz service, etc.
Why two packages per robot?
Section titled “Why two packages per robot?”The _description / _bringup split is a ROS convention:
_descriptioncontains the robot model (URDF + meshes) — things that change when the CAD changes_bringupcontains runtime config (launch files, controller YAML, RViz config) — things you tweak during development
This separation means sim update can safely replace the description without touching your launch customizations.
Useful CLI commands
Section titled “Useful CLI commands”Gazebo camera position
Section titled “Gazebo camera position”To set the camera position in the Gazebo viewer:
gz service -s /gui/move_to/pose \ --reqtype gz.msgs.GUICamera \ --reptype gz.msgs.Boolean \ --timeout 2000 \ --req "pose: {position: {x: 0.0, y: -2.0, z: 2.0} orientation: {x: -0.2706, y: 0.2706, z: 0.6533, w: 0.6533}}"To read the current camera position:
gz topic -e -t /gui/camera/poseROS 2 inspection
Section titled “ROS 2 inspection”# List all topicsros2 topic list
# See joint states in real timeros2 topic echo /joint_states
# List active controllersros2 control list_controllers
# Check controller manager statusros2 control list_hardware_interfacesBuilding a single package
Section titled “Building a single package”cd robot-simcolcon build --packages-select arm_descriptionsource install/setup.bashCommunity apt repository (Dev Container)
Section titled “Community apt repository (Dev Container)”Some ROS packages live in the universe repository rather than main. If apt can’t find a package inside the container:
apt-get updateapt-get install -y software-properties-commonadd-apt-repository -y universeapt-get updateCommon pitfalls
Section titled “Common pitfalls”Forgetting to source after build: ROS 2 can’t find packages until you run source install/setup.bash. The launch script does this automatically, but if you’re running ROS commands manually, you need to source first.
Stale build artifacts: If something breaks for no obvious reason, run sim clean and rebuild. Colcon’s incremental builds can get confused after certain types of changes.
X server not running (Dev Container only): Gazebo and RViz will fail silently or crash if the X server isn’t started. The Dev Container starts it automatically, but if you need to restart it manually, run .devcontainer/x_server.sh.
Port conflicts (Dev Container only): If port 6080 or 5900 is already in use, the X server script will fail. Make sure no other VNC sessions or containers are using those ports.