How To display 2 robots in the same RViz environment?

Published:

(20241122).

How To display 2 or more robots in the same RViz environment?

Steps-1

Make sure two publishers are in separate namespace: "/robot1/joint_states", "/robot2/joint_states". Importantly, when constructing the msg, the joint names should be exactly the same as the ones used in the corresponding URDF files, robot2 joint names could be "robot2/waist", "robot2/shoulder", "robot2/elbow", etc.

Steps-2

In the URDF file of robot2, add namespace for all links and joints, e.g., "robot2/waist", "robot2/shoulder", "robot2/elbow", etc. Note that, for robot1, you can add and use namespace as well like what we did for robot2, but for simplicity, the robot1 URDF and its joint state publisher can remain unchanged which means it is not necessary to add namespace for robot1 URDF and its joint state publisher.

Steps-3

To move the base location of robot2 in RViz environment, use <node pkg="tf2_ros" type="static_transform_publisher" name="robot2_base_transform" args="0.1 0 0 0 0 0 world robot2/base" /> in the lauch file, which will move the robot2 base to x=0.1m. Note that, (a) the "robot2/base" is according to the name you defined in the URDF file. (b) this static base transform requires to set the "Fixed Frame" in rviz file to be "world" instead of "base" ("base" in the base name used in URDF file).

Steps-4

In the *.rviz file, add or modify as the following,

Displays:
    - Alpha: 0.5
      Cell Size: 1
      Class: rviz/Grid
      Color: 160; 160; 164
      Enabled: true
      Line Style:
        Line Width: 0.03
        Value: Lines
      Name: Grid
      Normal Cell Count: 0
      Offset:
        X: 0
        Y: 0
        Z: 0
      Plane: XY
      Plane Cell Count: 10
      Reference Frame: <Fixed Frame>
      Value: true
    - Alpha: 1
      Class: rviz/RobotModel
      Collision Enabled: false
      Enabled: true
      Links:
        All Links Enabled: true
        Expand Joint Details: false
        Expand Link Details: false
        Expand Tree: false
        Link Tree Style: Links in Alphabetic Order
        base:   #(Note: make sure these link names are exactly same as you used in the URDF file.)
          Alpha: 1
          Show Axes: true   #(Note: you can set it true to show the base frame axis in rviz.)
          Show Trail: false
          Value: true
        lower_arm:
          Alpha: 1
          Show Axes: false
          Show Trail: false
          Value: true
        stylus:
          Alpha: 1
          Show Axes: true    #(Note: you can set it true to show the EE frame axis in rviz.)
          Show Trail: false
          Value: true
        tip:
          Alpha: 1
          Show Axes: false
          Show Trail: false
          Value: true
        torso:
          Alpha: 1
          Show Axes: false
          Show Trail: false
          Value: true
        upper_arm:
          Alpha: 1
          Show Axes: false
          Show Trail: false
          Value: true
        wrist:
          Alpha: 1
          Show Axes: false
          Show Trail: false
          Value: true
      Name: RobotModel1  #(Note: set a unique name for this robot.)
      Robot Description: /robot1/robot_description  #(Note: modify here.)
      TF Prefix: ""  #(Note: DO NOT modify here.)
      Update Interval: 0
      Value: true
      Visual Enabled: true
    - Alpha: 1
      Class: rviz/RobotModel
      Collision Enabled: false
      Enabled: true
      Links:
        All Links Enabled: true
        Expand Joint Details: false
        Expand Link Details: false
        Expand Tree: false
        Link Tree Style: Links in Alphabetic Order
        base:   #(Note: make sure these link names are exactly same as you used in the URDF file.)
          Alpha: 1
          Show Axes: true    #(Note: you can set it true to show the base frame axis in rviz.)
          Show Trail: false
          Value: true
        lower_arm:
          Alpha: 1
          Show Axes: false
          Show Trail: false
          Value: true
        stylus:
          Alpha: 1
          Show Axes: true    #(Note: you can set it true to show the EE frame axis in rviz.)
          Show Trail: false
          Value: true
        tip:
          Alpha: 1
          Show Axes: false
          Show Trail: false
          Value: true
        torso:
          Alpha: 1
          Show Axes: false
          Show Trail: false
          Value: true
        upper_arm:
          Alpha: 1
          Show Axes: false
          Show Trail: false
          Value: true
        wrist:
          Alpha: 1
          Show Axes: false
          Show Trail: false
          Value: true
      Name: RobotModel2  #(Note: set a unique name for this robot.)
      Robot Description: /robot2/robot_description  #(Note: modify here.)
      TF Prefix: "" #(Note: DO NOT modify here.)
      Update Interval: 0
      Value: true
      Visual Enabled: true
  Enabled: true
  Global Options:
    Background Color: 48; 48; 48
    Fixed Frame: world  #(Note: modify here.)
    Frame Rate: 30

Steps-5

Adjust the pose of the two robots in rviz using a mouse, and save the rviz file (This will auto correct some minor mistakes you may have made when editing the rviz file, e.g., the robot2 links should be "robot2/base:", "robot2/lower_arm:", etc.).

Steps-6

Finally, in the launch file, add the following code to launch the two robots with different namespaces.

<launch>
  <!-- Launch Robot 1 -->
  <group ns="robot1">
    <param name="robot_description" command="cat $(find robot_description)/urdf/robot1.urdf" />
    <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" />
    <node pkg="tf2_ros" type="static_transform_publisher" name="robot1_base_transform"
      args="-0.5 0 0 0 0 0 world base" /> 
      <!-- note, static base transform requires to set the "Fixed Frame" in rviz file to be "world" instead of "base". -->
  </group>

  <!-- Launch Robot 2 -->
  <group ns="robot2">
    <param name="robot_description" command="cat $(find robot_description)/urdf/robot2.urdf" />    
    <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" />
    <node pkg="tf2_ros" type="static_transform_publisher" name="robot2_base_transform"
      args="0.1 0 0 0 0 0 world robot2/base" />
      <!-- note, static base transform requires to set the "Fixed Frame" in rviz file to be "world" instead of "base". -->
  </group>
  <node name="rviz2" pkg="rviz" type="rviz" args="-d $(find robot_common)/launch/robotx2.rviz" required="true" />
</launch>

Steps-7

Now you can run the launch file, if it can correctly display two robots in the same RViz, then you can command "$ rosrun rqt_tf_tree rqt_tf_tree" to check the tf tree.

Notes

  • Note, it is better to NOT use <remap from="/tf" to="robot2/tf" /> and <remap from="/tf_static" to="robot2/tf_static" /> in the launch file. Because it will make the command "$ rosrun rqt_tf_tree rqt_tf_tree" be invalid when you want to check the tf tree. /tf itself can discriminate the joint states based on namespace, so no need to remap /tf.

Created on 2024-11-22.