Delivbot provides a complete ROS 2 workspace package for simulating and running the Delivbot mobile base. It bundles URDF, meshes, Gazebo simulation assets, and launch files for both simulation and real hardware bring-up.
- Unified
robot.launch.pyfor real-robot bring-up (robot_state_publisher, lidar, RealSense, ODrive, joystick teleop, twist_mux). - Modular launch files for each hardware subsystem: RealSense, Hesai lidar, and ODrive hoverboard driver.
- Gazebo simulation launch with twist mux, joystick teleop, ros2_control, and ROS ↔︎ Gazebo bridges.
- Ready-to-use URDF/Xacro, configuration, and RViz profiles for inspecting the robot.
| Path | Description |
|---|---|
config/ |
Controller, bridge, teleop, and RViz configuration YAML files. |
launch/ |
Gazebo, joystick, display, and hardware bring-up launch files (see below). |
meshes/ |
Robot visuals and collision geometry. |
resource/ |
Ament resource index markers. |
urdf/ |
Xacro description of the Delivbot robot. |
worlds/ |
Gazebo world files. |
# From the workspace root (e.g., ~/ros2_ws)
colcon build --packages-select delivbot --symlink-install
source install/setup.bashLaunch the full Gazebo simulation stack:
ros2 launch delivbot gazebo.launch.pyThis starts Gazebo, spawns Delivbot, loads ros2_control controllers, the joystick teleop pipeline, and bridges available sensors to ROS topics.
For a URDF-only visualization in RViz:
ros2 launch delivbot display.launch.py- Set joystick to D-Mode
- Enable/drive with left trigger (button 6) held.
- Turbo speed with right trigger (button 7).
The default SLAM stack now wraps lidarslam_ros2, which performs scan-matching SLAM with optional IMU fusion and a graph-based loop-closure back-end.
Prerequisites:
- Clone
lidarslam_ros2into your workspace so the packagesscanmatcher,graph_based_slam,lidarslam, andlidarslam_msgsbuild alongside this robot package. - Provide a point cloud on
/lidar/points(the Gazebo bridge already publishes this) and optionally an IMU on/imu(seeimu.launch.pyand the Gazebo IMU sensor).
Start SLAM:
ros2 launch delivbot slam.launch.pyKey launch arguments (override as needed):
pointcloud_topic(default/lidar/points)imu_topic(default/imu)use_imu(trueto fuse IMU,falseto ignore it)use_odom(set totrueto fuse wheel odometry when available; defaults tofalseso SLAM still works without odom)initial_pose_topic(defaultinitial_poseif you have a PoseStamped publisher)params_file(defaults toconfig/lidarslam_params.yaml)auto_initial_pose(truepublishes a PoseStamped automatically; disable if you want to set it manually)initial_pose_{x,y,z,qx,qy,qz,qw,delay}(override the auto-published pose)
RViz quickstart:
- Fixed frame:
map - Add
Posedisplay for/current_pose,Pathfor/path, andPointCloud2for/map(global accumulated cloud). - Loop-closed results appear on
/modified_pathand/modified_map.
To produce a 2D occupancy grid suitable for Nav2, run the projection pipeline:
ros2 launch delivbot grid_projection.launch.pyThis wraps octomap_server to consume the /map point cloud and publish /map (occupancy grid) plus /octomap_* topics. Adjust parameters in config/octomap_params.yaml if you need different z-bounds or resolution.
The core SLAM tuning lives in config/lidarslam_params.yaml. Modify voxel sizes, registration method (NDT/GICP), scan ranges, and loop-closure thresholds there as you iterate.
robot.launch.py runs the physical robot stack while keeping Gazebo assets untouched. It loads the URDF, publishes TFs, launches joystick teleop, and can selectively start the hardware drivers.
ros2 launch delivbot robot.launch.py \
launch_lidar:=true \
launch_realsense:=true \
launch_odrive:=true \
launch_joystick:=true \
cmd_vel_topic:=/cmd_velJoystick commands flow through twist_mux so /cmd_vel_joy and navigation topics are arbitrated automatically before reaching the ODrive driver (default /cmd_vel).
- Set joystick to X-Mode
- Enable/drive with left shoulder (button 4) held.
- Turbo speed with right shoulder (button 5).
| Argument | Default | Purpose |
|---|---|---|
robot_namespace |
`` (empty) | Apply a namespace to all nodes. |
model |
<pkg>/urdf/delivbot.xacro |
Path to the robot description Xacro. |
use_sim_time |
false |
Set to true only if you provide simulated time (e.g., from Gazebo). |
launch_lidar |
true |
Toggle Hesai lidar driver. |
launch_realsense |
true |
Toggle RealSense camera driver. |
launch_odrive |
true |
Toggle ODrive hoverboard driver. |
launch_joystick |
true |
Toggle joystick + teleop_twist pipeline. |
lidar_params_file |
`` (empty) | Optional YAML file for hesai_ros_driver. |
realsense_params_file |
`` (empty) | Optional YAML file for realsense2_camera. |
odrive_params_file |
`` (empty) | Optional YAML file for delivbot_odrive. |
cmd_vel_topic |
/cmd_vel |
Velocity command topic for the ODrive driver (also used by twist_mux output). |
| Launch file | Description | Notes |
|---|---|---|
launch/lidar.launch.py |
Starts hesai_ros_driver_node. |
Supports namespace, params, and use_sim_time. |
launch/realsense.launch.py |
Starts realsense2_camera_node. |
Provide a params YAML to customize camera streams. |
launch/odrive.launch.py |
Starts the delivbot_odrive driver executable. |
Exposes cmd_vel_topic and optional params YAML for tuning. |
launch/joystick.launch.py |
Starts joy_node and teleop_twist_joy. |
Publishes cmd_vel_joy, which feeds the twist mux. |
Each subsystem launch file mirrors the ros2 run commands you would call manually, adding ergonomic launch arguments for consistent configuration.
Ensure the following packages/drivers are available in your workspace or installed on the system:
ros_gz_sim,ros_gz_bridge,ros_gz_imagehesai_ros_driverrealsense2_cameraodrive_hoverboardjoy,teleop_twist_joytwist_muxscanmatcher,graph_based_slam,lidarslam,lidarslam_msgs(fromlidarslam_ros2)
Refer to each dependency’s documentation for hardware setup (e.g., USB permissions for RealSense cameras and ODrive).
- Simulation test: Verify navigation stack interaction and teleoperation via
gazebo.launch.py. - Hardware dry-run: Connect the robot and start
robot.launch.py, disabling specific drivers if they are not attached yet (e.g.,launch_realsense:=false). - Parameter tuning: Provide YAML configuration files through the launch arguments as you refine driver settings (e.g., wheel parameters for the ODrive driver).
- Monitoring: Use
rqt_graph,rqt_tf_tree, and RViz withconfig/display.rvizto visualize topics and transforms.
For adjustments or new integrations, update the relevant launch file or configuration under config/, add documentation here, and rebuild with colcon. Contributions should include testing steps and documentation updates.