UCLA X1 Robotics 2025-26 B^3 Project
For the current split Jetson + Raspberry Pi headless startup procedure, use:
That guide includes copy-paste commands for:
- Jetson ZED/Nav2/web console startup.
- Raspberry Pi Sense HAT, RL balance controller, ROS listener, and CAN motor startup.
- Tailscale and hotspot DDS modes.
- Live checks for
/cmd_vel_manual,/cmd_vel_balanced,/jet_cmd, motor powers, and RL policy status.
-
Install ROS2 Humble https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debs.html
-
Install the ZED SDK: https://www.stereolabs.com/developers/release/5.0#82af3640d775
-
Install the ROS2 Wrapper for the ZED SDK https://www.stereolabs.com/docs/ros2
-
Enable positional tracking in the ZED wrapper configuration.
Relevant wrapper parameters:
pos_tracking.pos_tracking_enabled: truepos_tracking.publish_tf: truepos_tracking.publish_map_tf: falsewhileslam_toolboxmapping or localization ownsmap -> odompos_tracking.area_memory: truepos_tracking.two_d_mode: truefor a ground robot
- Run the ZED positional tracking bridge node after the wrapper is running:
ros2 run depth_processing zed_tracking
Useful options:
--ros-args -p input_pose_topic:=/zed/zed_node/pose--ros-args -p input_pose_cov_topic:=/zed/zed_node/pose_with_covariance--ros-args -p input_odom_topic:=/zed/zed_node/odom--ros-args -p input_image_topic:=/zed/zed_node/rgb/color/rect/image/compressed--ros-args -p input_image_is_compressed:=true--ros-args -p require_odom_for_localized:=true--ros-args -p show_visualization_window:=true
Notes:
zed_trackingdoes not estimate localization itself. The ZED ROS 2 wrapper does that work; this node republishes the wrapper outputs in simpler topics for the rest of the robot.- When you are running
slam_toolboxmapping or localization, do not let a second node publish a competingmap -> odomtransform at the same time. - The wrapper pose is the camera pose in the map frame. For your BB-8 style robot, that means this is the head-mounted camera pose unless you add a separate transform/fusion step to estimate the body center.
- The node now also subscribes to the ZED color stream so it can show a live camera view with localization status, pose text, and a top-down trajectory inset.
- It publishes the recent camera trajectory on
zed/path, which is useful in RViz. - It publishes an annotated image on
zed/localization_view/compressed, so you can inspect the localization overlay withrqt_image_viewif the OpenCV window is inconvenient.
- Navigation groundwork
To make the ZED localization usable for mapping and Nav2, there is now a base-frame adapter, a point-cloud-to-scan bringup launch, and a first end-to-end Nav2 stack.
Base-frame adapter:
ros2 run depth_processing zed_base_adapter- Converts camera-centric ZED topics into:
zed/base_pose
zed/base_pose_with_covariancezed/base_odomzed/base_path- Publishes
odom -> base_linkby default. - It can also publish
map -> odom, but that is off by default so it does not fight whichever node already owns the global map transform. - The default rigid transform now assumes the ZED is mounted
0.381 mabove the chassis origin.
Navigation groundwork launch:
ros2 launch depth_processing zed_nav_bringup.launch.py- Starts:
zed_base_adapterpointcloud_to_laserscanto generate a 2Dscanfrom/zed/zed_node/point_cloud/cloud_registered
Mapping pass launch:
ros2 launch depth_processing zed_mapping_pass.launch.py- Starts:
zed_base_adapterpointcloud_to_laserscanslam_toolboxin online async mapping mode
- This is the intended first mode for a new environment.
Localization-after-mapping launch:
ros2 launch depth_processing zed_localization_mode.launch.py map_file_name:=/absolute/path/to/posegraph_prefix- Starts:
zed_base_adapterpointcloud_to_laserscanslam_toolboxin localization mode using a saved pose graph
- This is the intended second mode after the robot finishes its mapping pass in that environment.
Nav2 bringup on top of an already-running SLAM or localization stack:
ros2 launch depth_processing zed_nav2_bringup.launch.py- Starts:
- Nav2 planner, controller, behavior server, and BT navigator
twist_safety_gate
- Expects:
map/scanmap -> odom -> base_linkzed/is_localized
One-command full SLAM + navigation launch:
ros2 launch depth_processing zed_slam_nav.launch.py slam_mode:=mappingros2 launch depth_processing zed_slam_nav.launch.py slam_mode:=localization map_file_name:=/absolute/path/to/posegraph_prefix- In
mappingmode, the occupancy map continues updating while Nav2 is running. - In
localizationmode, the saved environment is reused and Nav2 runs on top of that localization layer.
Safety gating:
- Nav2 publishes motion to
cmd_vel_nav. twist_safety_gateonly forwards that tocmd_velwhen localization and/scanare healthy.- Gate status is published on
nav/cmd_vel_gate_status.
Useful options:
base_to_camera_translation:=x,y,zbase_to_camera_rpy:=roll,pitch,yawbase_frame:=base_linkpublish_map_to_odom_tf:=trueonly for ZED-only debugging whenslam_toolboxis not owningmap -> odom
See these docs for more detail:
- [Navigation plan](/Users/sara/Documents/My-Documents/X1 Robotics/B_Cubed/docs/navigation_plan.md)
- [Mapping to navigation workflow](/Users/sara/Documents/My-Documents/X1 Robotics/B_Cubed/docs/README_mapping_to_navigation.md)
- [Full SLAM stack](/Users/sara/Documents/My-Documents/X1 Robotics/B_Cubed/docs/README_full_slam_stack.md)
- [Handheld mapping test](/Users/sara/Documents/My-Documents/X1 Robotics/B_Cubed/docs/README_handheld_mapping_test.md)
- [Using launch.sh](/Users/sara/Documents/My-Documents/X1 Robotics/B_Cubed/docs/README_launch_sh.md)
- [ZED adapter and launch files](/Users/sara/Documents/My-Documents/X1 Robotics/B_Cubed/docs/README_zed_navigation_components.md)
- One-stop Jetson launcher
ros2_ws/launch.sh now runs the handheld ZED mapping workflow:
- launches the ZED wrapper
- waits for the ZED pose, odom, and cloud topics
- optionally starts MediaPipe gesture recognition
- optionally starts TensorRT person tracking
- starts
zed_slam_nav.launch.pyin mapping mode - opens the web planning console and prints the save commands
The web planning console is now a standalone ROS package, separate from the
ZED/depth nodes:
ros2 launch nav_planning_console nav_planning_console.launch.py
Useful environment overrides before running launch.sh:
MAP_SESSION_NAME=my_envMAP_OUTPUT_DIR=/home/jetson-nano-x1/Documents/B_Cubed/mapsBASE_TO_CAMERA_TRANSLATION=x,y,zBASE_TO_CAMERA_RPY=roll,pitch,yawZED_PARAM_OVERRIDES='general.grab_resolution:=VGA;general.grab_frame_rate:=15;pos_tracking.pos_tracking_enabled:=true;pos_tracking.area_memory:=true;pos_tracking.two_d_mode:=true;debug.use_pub_timestamps:=true'START_GESTURE_RECOGNITION=trueSTART_PERSON_TRACKING=trueBUILD_PARALLEL_WORKERS=2LAUNCH_MAX_CORES=1LAUNCH_MEMORY_LIMIT_MB=3072