Skip to main content
The Innex1 Rover simulation provides a high-fidelity lunar environment with realistic physics, sensor data, and terrain interactions.

Launch the simulation

The primary launch file starts Gazebo in headless mode, spawns the rover, and bridges ROS topics:
ros2 launch lunabot_simulation moon_yard.launch.py

What happens during launch

1

Gazebo server starts

The Gazebo Fortress server loads the moon yard world (moon_yard.sdf) in headless mode without a GUI.
2

Robot description publishes

The robot_state_publisher node processes the URDF from lunabot_description/urdf/lunabot.urdf.xacro and publishes the robot model.
3

Rover spawns

The rover spawns at coordinates (x=0.0, y=0.0, z=0.5) and settles to the surface under gravity.
4

Bridges activate

ROS-Gazebo bridges connect simulation topics to ROS 2:
  • /cmd_vel - Velocity commands
  • /odom - Odometry
  • /imu/data_raw - IMU data
  • /scan - LiDAR scans
  • /camera_front/image - RGB camera
  • /camera_front/depth_image - Depth camera
  • /joint_states - Wheel encoders
Headless mode conserves CPU and GPU resources. Use visualization tools below to observe the simulation.

Visualization tools

The rover supports three visualization methods, each serving different purposes.

RViz2 - ROS visualization

RViz2 displays ROS topics, transforms, and sensor data:
ros2 run rviz2 rviz2
Recommended displays:
  • RobotModel - 3D robot visualization
  • TF - Coordinate frame transforms
  • LaserScan - LiDAR point cloud on /scan
  • Image - Camera feed on /camera_front/image
  • DepthCloud - Depth visualization on /camera_front/points
  • Odometry - Position trail on /odom
Save your RViz configuration to avoid reconfiguring displays:
rviz2 -d config/rover.rviz

GZ Web - Gazebo visualization

View the 3D world, terrain, and physics interactions:
1

Start WebSocket server

gzweb
Or without the alias:
ign launch $(ros2 pkg prefix lunabot_simulation)/share/lunabot_simulation/config/websocket.ign
2

Connect via browser

Open https://app.gazebosim.org/visualization and connect to:
ws://localhost:9002
GZ Web shows:
  • Arena geometry and obstacles
  • Lunar terrain surface mesh
  • Rover model and wheel interactions
  • Collision geometries
GZ Web requires an active internet connection to load the web interface, but the WebSocket server runs locally.

Foxglove Studio - Advanced debugging

Foxglove provides professional-grade visualization with custom layouts:
1

Launch Foxglove Bridge

ros2 run foxglove_bridge foxglove_bridge
2

Connect Foxglove Studio

Download Foxglove Studio and connect to:
ws://localhost:8765
Key features:
  • Multi-panel layouts for simultaneous data streams
  • Topic message inspection and playback
  • Custom plots for sensor trends
  • 3D transforms and point cloud rendering
  • Image synchronization across cameras
Foxglove is especially useful for remote debugging when running simulations on OrbStack VMs or cloud instances.

Visualization comparison

ToolPurposeProsCons
RViz2ROS data visualizationNative ROS integration, TF displayLimited world visualization
GZ WebWorld and physicsShows terrain and obstaclesRequires browser connection
FoxgloveProfessional debuggingAdvanced features, remote accessAdditional dependency

Manual control

Drive the rover using keyboard teleoperation:
ros2 run teleop_twist_keyboard teleop_twist_keyboard

Controls

Movement:
  • i - Move forward
  • , - Move backward
  • j - Rotate left
  • l - Rotate right
  • k - Stop
  • u/o - Forward + rotate
  • m/. - Backward + rotate
Speed:
  • q - Increase linear and angular speed by 10%
  • z - Decrease linear and angular speed by 10%
  • w - Increase linear speed only
  • x - Decrease linear speed only
  • e - Increase angular speed only
  • c - Decrease angular speed only
The teleop terminal must have focus to receive keyboard input. Click the terminal window before sending commands.

Inspecting topics

View active ROS topics:
ros2 topic list
Monitor topic data:
ros2 topic echo /odom
Check message rates:
ros2 topic hz /camera_front/image
Inspect topic types:
ros2 topic info /cmd_vel

Key topics

Sensor data

TopicTypeRateDescription
/imu/data_rawsensor_msgs/msg/Imu100 HzAcceleration and angular velocity
/scansensor_msgs/msg/LaserScan10 Hz2D LiDAR obstacle detection
/camera_front/imagesensor_msgs/msg/Image30 HzRGB camera feed
/camera_front/depth_imagesensor_msgs/msg/Image30 HzDepth camera data
/camera_front/pointssensor_msgs/msg/PointCloud230 Hz3D point cloud
/camera_front/camera_infosensor_msgs/msg/CameraInfo30 HzCamera calibration

Odometry and control

TopicTypeRateDescription
/odomnav_msgs/msg/Odometry50 HzPosition and velocity estimates
/joint_statessensor_msgs/msg/JointState50 HzWheel encoder positions
/cmd_velgeometry_msgs/msg/TwistVariableVelocity commands to rover

Material handling actions

ActionTypeDescription
/mission/excavatelunabot_interfaces/action/ExcavateExcavation with fill monitoring
/mission/depositlunabot_interfaces/action/DepositMaterial deposition with door control
See the API Reference for detailed action definitions.

Platform-specific behavior

macOS (OrbStack)

The launch file automatically detects macOS and switches from Ogre2 to Ogre rendering engine:
if platform.system() == "Darwin":
    # Patch world file to use Ogre instead of Ogre2
    patched_content = content.replace(
        "<render_engine>ogre2</render_engine>",
        "<render_engine>ogre</render_engine>",
    )
This ensures compatibility with OrbStack’s graphics stack.

Custom model paths

The launch file sets GZ_SIM_RESOURCE_PATH to include custom models:
models_path = os.path.join(pkg_lunabot_simulation, "models")
os.environ["GZ_SIM_RESOURCE_PATH"] = models_path + ":" + gz_resource_path
This allows Gazebo to find arena obstacles, regolith piles, and custom meshes.

Troubleshooting

Simulation freezes or lags: Reduce sensor update rates by editing the world file:
src/lunabot_simulation/worlds/moon_yard.sdf
Lower camera frame rates from 30 Hz to 10 Hz, or disable depth processing temporarily. Topics not publishing: Verify bridges are running:
ros2 node list
Expected nodes:
  • /clock_bridge
  • /robot_bridge
  • /robot_state_publisher
Rover falls through terrain: The surface mesh is at z=0. Ensure the spawn position in moon_yard.launch.py is above ground:
spawn_z = "0.5"  # Start above surface
Multiple Gazebo instances conflict: Kill all Gazebo processes:
pkill -9 -f "gz sim"
Models fail to load: First launch requires internet to download Gazebo Fuel models. Models cache in ~/.gz/fuel/ for offline use. Manually download models:
ign fuel download -u https://fuel.gazebosim.org/1.0/OpenRobotics/models/[model_name]

Next steps

API Reference

Explore ROS topics, actions, and message formats

Navigation

Set up Nav2 for autonomous path planning

Perception

Configure hazard detection and AprilTag localization

Material Handling

Use excavation and deposition actions

Build docs developers (and LLMs) love