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
.
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.
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
nodes with parameters;Xacro to get URDF files,
FindExecutable(name="xacro") or xacro;
Launch scripts with parameters,
leading to nested Launch hierarchy,
PythonLaunchDescriptionSource(foo) or bar.launch.py.
Xacro
Xacro could mean a Macro-enriched XML file. In such a file, besides typical XML components,
a user could
ros2_control tag;Xacro's,
leading to nested Xacro hierarchy,
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.
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
Xacro with <ros2_control> tag that
matches information provided by controller_definitions,controller_definitions
<ros2_control>
tag in robot_description;
controller_manager::spawner that spawns controllers, including
joint_trajectory_controller, or an effort_controller,--active or --inactive on program launch,robot_description and
controller_definitions,
joint_state_broadcaster
robot_state_publisher::robot_state_publisher that
robot_description, andtf transformations;rviz2::rviz2 that
tf, robot_description,
joint_states,
When interacting with ROS-2 components, one typically wants to know the name and data type of
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,
~/joint_trajectory, with data type
trajectory_msgs::msg::JointTrajectory,
{node_name}/follow_joint_trajectory, with data
type FollowJTrajAction,
{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.