Welcome to Muto RS Robot repository
2)Multi-vehicle navigation
2.Multi-vehicle navigation(MutoRS)
2.Multi-vehicle navigation(MutoRS)1.1 Environment Preparation1.2 Startup Command2. Core Principles2.2 TF Transform Tree2.3 Navigation Parameter Rewriting (RewrittenYaml)3. Code Explanation3.1 Core Entry Point:robot_bringup_launch.py3.2 Hardware Driver:robot_driver_launch.py3.3 Navigation Logic:robot_nav_launch.py3.4 configuration file:multi_nav_params.yaml3.5 Model Files:Muto_multi.urdf.xacro
This feature pack supports multiple MutoRS vehicles navigating simultaneously on the same map, with each vehicle having its own independent namespace (robot1, robot2) and not interfering with each other.
1.1 Environment Preparation
First, configure the radar type in the terminal of each vehicle (select a1 or 4ROS according to the actual hardware):
export RPLIDAR_TYPE=4ROS # or a1# It's recommended to directly modify the RPLIDAR_TYPE section in the ~/.bashrc file.cd ~/yahboomcar_ros2_ws/yahboomcar_wssource install/setup.bash
In addition, we need to prepare a map file in advance. Under the default startup parameters, this map file will be launched. (Note: Please prepare the same map file in this directory of Robot1 and Robot2.)
/root/yahboomcar_ros2_ws/yahboomcar_ws/src/yahboomcar_nav/maps/yahboomcar.yaml

1.2 Startup Command
Method 1: One-click Startup Simultaneously starts the hardware drivers (radar, odometer, chassis) and navigation software (Nav2, AMCL, MapServer).
Robot 1
Start Docker
xxxxxxxxxxstart_muto_dockerxxxxxxxxxxros2 launch yahboomcar_multi robot_bringup_launch.py robot_name:=robot1
Robot 2
Start Docker
xxxxxxxxxxstart_muto_dockerxxxxxxxxxxros2 launch yahboomcar_multi robot_bringup_launch.py robot_name:=robot2Start RVIZ
This can be started from either robot 1 or robot 2.
xxxxxxxxxxros2 launch yahboomcar_rviz display_multi_nav_launch.py

Set the initial positions for robot1 and robot2 respectively, and then you can use the "2D Goal Pose" tool to control the navigation of robot1 and robot2 separately.

Method 2: Step-by-step startup (for debugging) If you need to view the underlying hardware logs or navigation logs separately, you can start the system in stages.
Terminal 1: Start the hardware driver
xxxxxxxxxxros2 launch yahboomcar_multi robot_driver_launch.py robot_name:=robot1Terminal 2: Start Navigation
xxxxxxxxxxros2 launch yahboomcar_multi robot_nav_launch.py robot_name:=robot1
2. Core Principles
The core of multi-machine navigation lies in namespace isolation and resource sharing.
2.1 Namespace
To prevent topic conflicts between multiple robots, we use ROS 2's
PushRosNamespacemechanism.- Robot 1: All topics are prefixed with
/robot1/(e.g.,/robot1/scan,/robot1/cmd_vel) - Robot 2: All topics are prefixed with
/robot2/
- Robot 1: All topics are prefixed with
2.2 TF Transform Tree
This is the most critical part of the system. Although topics are isolated, TF transforms must be globally visible, otherwise RViz cannot display two cars simultaneously.
- Global Frame:
/map((Shared by all robots)) - Robot 1 Branch:
/map->/robot1/odom->/robot1/base_link->/robot1/laser - Robot 2 Branch:
/map->/robot2/odom->/robot2/base_link->/robot2/laser
Key Point: The Launch file must force a remap of all nodes'
/tfand/tf_statictopics back to the global/tf. Without this step, each bot will publish TF to/robot1/tf, causing a break in the TF tree.
2.3 Navigation Parameter Rewriting (RewrittenYaml)
Nav2's parameter files typically hardcode base_link or odom. In multi-machine mode, we need to dynamically modify these parameters to /robot1/base_link, etc. We used the RewrittenYaml tool provided by Nav2 to dynamically replace these values at startup.
3. Code Explanation
3.1 Core Entry Point:robot_bringup_launch.py
This is the commander-in-chief, responsible for coordinating the hardware and software startup.
x# Core Logic:# 1. Receive the robot_name parameter (e.g., "robot1")# 2. Include robot_driver_launch.py ••(hardware)# 3. Include robot_nav_launch.py ••(software)# 4. Pass the map path3.2 Hardware Driver:robot_driver_launch.py
Responsible for launching the chassis, radar, odometer, and URDF.
Key Point 1: Namespace Isolation
xxxxxxxxxxPushRosNamespace(robot_name) # Place all nodes into the /robotX namespaceKey Point 2: TF Global Remapping This is the key to resolving the "TF tree break" issue. We force the TF topic to be "ejected" from the namespace.
xxxxxxxxxxSetRemap(src='/tf', dst='/tf'),SetRemap(src='/tf_static', dst='/tf_static'),Key Point 3: URDF Parameterization When calling
xacro, passrobot_nameto automatically add a prefix (e.g.,robot1/base_link) to the Frame ID in the robot model.xxxxxxxxxxCommand(['xacro ', urdf_path, ' robot_name:=', robot_name])
3.3 Navigation Logic:robot_nav_launch.py
Responsible for starting the Nav2 protocol stack (AMCL, Planner, Controller).
Key point: Dynamic parameter replacement Use
RewrittenYamlto convert a generic parameter file into a configuration specific to the robot.xxxxxxxxxxparam_substitutions = {'base_frame_id': [robot_name, '/base_link'], # Replace with robot1/base_link'scan_topic': 'scan', # Maintain relative path, automatically becomes /robot1/scan'global_frame': 'map', # Keep map frames global... }
3.4 configuration file:multi_nav_params.yaml
The specific parameters of Nav2.
- We changed
scan_topicfrom the absolute path/scanto the relative pathscan. Now, Nav2, under therobot1namespace, will automatically subscribe to/robot1/scan, and the data flow will be enabled.
3.5 Model Files:Muto_multi.urdf.xacro
This is an adaptive Xacro file that defines the robot's physical structure. We've prefixed all link and joint names with ${robot_name}/ to ensure that two (or even more) robots won't conflict in the TF tree due to identical names.