Steve Brown
Steve Brown

Reputation: 449

Displaying two robots in the same RViz window

Could anyone please tell me, how to display two robots in one instance of RViz?

This question can be broken into two:

  1. How can I add a robot to RViz (using UI? Using command line? Using config? What if I have 100 robots, or variable number of robots: how to avoid adding different number of robots every time?)
  1. What does RViz expect? In other words, let's say I have robot1 and robot2 (meaning that all corresponding links, joints and so on in URDF have prefix). What topics should they publish to appear in RViz and to not interfere with each other.

Any help is greatly appreciated. Thank you.

Upvotes: 2

Views: 1914

Answers (4)

Steve Brown
Steve Brown

Reputation: 449

I have figured it out. Full code at robotics.snowcron.com, in a "multiple robots" section. The solution is rather lengthy, as it covers both RViz and Gazebo, and (especially) makes Nav2 work with those. Here is a brief description.

  1. We need to provide each robot with its own namespace.
  2. The way Nav2 works, at least in Galaxy, some its modules do not accept namespaces (surprise!). Again, a complete description and complete code is available by the link above.
  3. What I did was dynamically replacing (using ROS2 methods, not by file loading and editing in memory) parameters in nav2_params.yaml and robot description sdf files, so namespaces are used, even if it wasn't possible to do directly. So in addition to passing namespaces to nodes, I had to do replacements in these files.
  4. Each robot has its own Nav stack and its own set of maps and keepout maps. In theory (for example, for robots of different types that have different requirements to road quality) these files can be different.
  5. To display maps properly, as odom of each robot points to a different point (initial robot's coordinates), maps are shown with corresponding shift.

With these changes, Nav2 works with multiple robots, they "see" each other and even TRYING to avoid collisions. I also painted robots (dynamically) in different colors :)

Upvotes: 1

Bart B
Bart B

Reputation: 41

I managed this in rviz2 with the method described below. This worked well for me, but there may be more ways to go.

  1. Set up agents to broadcast robot description for your robots.

In my case the robots were not the identical so the urdfs were streamed on separate topics. To do this I gave each robot its own description topic. I used a robot_state_publisher from the tutorials for each unique robot (named RAS_TN_DB and RAS_TN_PU) to make the descriptions available for rviz.

$ ros2 topic list
/RAS_TN_DB/joint_states
/RAS_TN_DB/robot_description
/RAS_TN_PU/joint_states
/RAS_TN_PU/robot_description
/parameter_events
/rosout
/tf
/tf_static
  1. Stream transforms of all the links that are defined in the urdf on /tf

It does not matter who broadcasts this information, as long as its available for rviz to figure out through the tf tree where each link is with respect to the fixed frame.

Initially I used the joint-state-publisher and the robot-state-publisher from the tutorials to get a consistent stream of my robots links positions. Using 'ros2 topic echo /tf' I could observe all transforms streamed, where frame_id and 'child_frame_id' were matching the names of links described in the urdf, or the name of the fixed frame.

Using tf_tree viewer I could see a tree leading back to my system's origin, in my case 'world'. tf tree of 2 robots , each with 2 movable actuators

  1. Configure Rviz2 (in the UI or by importing a config file)
  • Set fixed frame to what you decided to name it under global options (e.g. 'base_link' or 'world').
  • Add robots from with 'Add'-> 'RobotModel'
  • Configure the added RobotModels 'Description Topic' to match the topic that you chose.

Resulting rviz2 view

I hope this helps.

Upvotes: 1

Muhammad Luqman
Muhammad Luqman

Reputation: 96

To spawn and visualize multiple robots of the same type, you can use robot_state_publisher and the tf2_ros to handle the TF frames appropriately. This can be done using different namespaces for each robot.

  • Launch file

from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='robot_state_publisher',
            executable='robot_state_publisher',
            namespace='robot1',
            output='screen',
            parameters=[{'robot_description': 'file://path_to_urdf/robot.urdf.xacro'}],
        ),
        Node(
            package='robot_state_publisher',
            executable='robot_state_publisher',
            namespace='robot2',
            output='screen',
            parameters=[{'robot_description': 'file://path_to_urdf/robot.urdf.xacro'}],
        ),
        Node(
            package='rviz2',
            executable='rviz2',
            name='rviz2'
        ),
    ])

Each instance of the robot is assigned its own namespace (robot1 and robot2), allowing each to have its own separate topics and parameters.

Upvotes: 2

Steve Brown
Steve Brown

Reputation: 449

I was able to do it by prefixing all frames with robot's names.

Upvotes: 1

Related Questions