ROS-2 · Tracing Information in Launch, Xacro, ROS2_Control

Mar 31, 2024 | Tech Software

Summary

Launch, Xacro, and ros2_control are used very often in large ROS-2 projects. They can serve as single points of entry that lead to the execution of many programs with dynamically generated URDF files. In particular, Launch and Xacro can be nested to invoke themselves or one another to form logically complex hierarchy. They are convenient to use; however, at times, it can also make it difficult for users to keep track of the logic and information from such hierarchy.

This post provides some brief notes on these tools, outlining their components, functionalities, and where information can be obtained; and is left as a memo for future reference. For more information, see ROS-2: The ros2_control Architecture, ROS-2: Using Xacro , and ROS-2: Launch. For a reasonably complicated real-world example, see ROS-2 Kortex by Kinova and PickNik Robotics .

Conclusion in Advance

If you are a professional controls engineer (instead of a system integrator who only needs to get the robot working through its control API), do NOT use ros2_control as much as possible. It's just an API wrapper, it's not where you write, test, and debug your controls code.

The Launch

It's a Python package. A Launch script, typically written in Python, launches a project with many programs. In a Launch script, a user could

  • define parameters;
  • find packages and files;
  • launch nodes with parameters;
  • run Xacro to get URDF files,
    • which can typically be found by searching FindExecutable(name="xacro") or xacro;
  • launch other Launch scripts with parameters, leading to nested Launch hierarchy,
    • which can typically be found by searching PythonLaunchDescriptionSource(foo) or bar.launch.py.

The Xacro

Xacro could mean a Macro-enriched XML file. In such a file, besides typical XML components, a user could

  • define Macro's;
  • define variables;
  • define ros2_control tag;
  • find packages and files;
  • passes variables and include other Xacro's, leading to nested Xacro hierarchy,
    • which can typically be found by searching xacro:include.

Xacro could also mean a program. Invoking the Xacro program with an Xacro-compatible XML file as the input typically generates a composed URDF file.

The ros2_control

ros2_control is a plug-in-based package that provides interfaces for controllers and hardwares, and manages the interaction between built-in and user-defined modules. Major components of ros2_control include:

  • controller_manager,
  • resource_manager,
  • hardware interfaces (state, command, gpio),
  • controller_interfaces,
  • controllers.

To employ ros2_control, one typically launches the following programs:

  • controller_manager::ros2_control_node that takes
    • robot_description
      • a robot URDF typically generated by Xacro with <ros2_control> tag that matches information provided by controller_definitions,
    • controller_definitions
      • a controller definitions file in YAML format that matches information in the <ros2_control> tag in robot_description;
  • controller_manager::spawner that spawns controllers, including
    • as many controllers as possible a user wants to use
      • for example a joint_trajectory_controller, or an effort_controller,
      • could be set to --active or --inactive on program launch,
      • their parameters and definitions have to match that provided in robot_description and controller_definitions,
    • joint_state_broadcaster
      • technically a controller, but only publishes states;
  • robot_state_publisher::robot_state_publisher that
    • takes and publishes robot_description, and
    • publishes tf transformations;
  • rviz2::rviz2 that
    • subscribes to various topics include tf, robot_description, joint_states,
    • visualizes robots.

Finding Topics, Services, Actions used in ROS-2 Components

When interacting with ROS-2 components, one typically wants to know the name and data type of

  • what topics they publish to or subscribe from,
  • what services they offer,
  • what action servers they present.

One effective way is to go to their source code, and search for the following keywords, for below are the functions that rclcpp offers to create publication, subscription, service, and action servers,

  • create_publisher,
  • create_subscription,
  • create_service,
  • create_server.

These functions take in name and data type to create the corresponding communication objects. For example, in joint_trajectory_controller.cpp,

  • from line 831 , one finds that it subscribes to topic ~/joint_trajectory, with data type trajectory_msgs::msg::JointTrajectory,
  • from line 921 , one finds that it offers an action server named {node_name}/follow_joint_trajectory, with data type FollowJTrajAction,
  • from line 935 , one finds that it provides a service named {node_name}/query_state, with data type control_msgs::srv::QueryTrajectoryState,

In some source code, a module may invoke objects and functions from other modules, which could make it a little more challenging to find their communication name and type, but still doable using the above tricks. The other way is to search for their online documentation, which is faster but sometimes does not provide sufficient information.