ROS Moveit The most detailed tutorial on the entire network

Preface

moveit_configThere is a lot of content related to the use, configuration and principles of Moveit, especially the package generated by assistant , which contains a lot of content. It is easy for users to confused the relationship during configuration, making the configuration process difficult and long.

At the same time, the Moveit documentation on the Internet is relatively messy, and the configuration methods are also different. Therefore, during the learning process, the author sorted out the tutorials on the use, configuration and principles of Moveit, hoping to be helpful to future generations.

Tip: This article has about 94,000 words, and the reading time is over 2 hours. It is recommended to save it as a moveit reference book for reference.

Author: Herman Ye @Auromix Auromix is ​​an organization of robotics enthusiasts, welcome to participate in our open source project
on Github

Table of contents

Installation of Moveit

The author created a one-click configuration and installation of Moveit to facilitate use. This one-click configuration and installation script will also determine whether to download additional basic tutorial examples of Moveit according to user needs to assist users in learning.

Copy the following instructions to the command line, and configure and install with one click

wget -O $HOME/moveit1_install.sh https://raw.githubusercontent.com/auromix/ros-install-one-click/main/moveit1_install.sh && sudo chmod +x $HOME/moveit1_install.sh && sudo bash $HOME/moveit1_install.sh && rm $HOME/moveit1_install.sh

How to use Moveit

According to the Panda robotic arm as a basic tutorial example for Moveit's one-click configuration and installation, there are the following usage methods for simple use in RViz.

roslaunch panda_moveit_config demo.launch
roslaunch panda_moveit_config demo_gazebo.launch

For the specific usage method, there will be a prompt when using the Moveit one-key configuration installation script.

File analysis of config configuration package

robotname_moveit_configThere are too many files in it, which usually gives users a headache. The following is a detailed analysis of each content in these configuration packages, which can be consulted according to needs.
If you want to know more about the classic demo in config, it is recommended to read demo.launchand demo_gazebo.launchfile slice analysis

Insert image description here

Slice analysis 1: demo.launch

Insert image description here

The file name is Moveit's classic demo, which displays the robot model in RViz and controls Moveit robot_moveit_config/launch/demo.launchthrough RViz plug-ins to complete motion planning and trajectory control. The following is the complete code of Moveit’s official case :MotionPlanning
panda_moveit_config/launch/demo.launch

<launch>
  <arg name="arm_id" default="panda" />
  <!-- specify the planning pipeline -->
  <arg name="pipeline" default="ompl" />

  <!-- By default, we do not start a database (it can be large) -->
  <arg name="db" default="false" />
  <!-- Allow user to specify database location -->
  <arg name="db_path" default="$(find panda_moveit_config)/default_warehouse_mongo_db" />

  <!-- By default, we are not in debug mode -->
  <arg name="debug" default="false" />

  <!-- By default we will load the gripper -->
  <arg name="load_gripper" default="true" />

  <!-- By default, we will load or override the robot_description -->
  <arg name="load_robot_description" default="true"/>

  <!-- Choose controller manager: fake, simple, or ros_control -->
  <arg name="moveit_controller_manager" default="fake" />
  <!-- Set execution mode for fake execution controllers -->
  <arg name="fake_execution_type" default="interpolate" />
  <!-- Transmission used for joint control: position, velocity, or effort -->
  <arg name="transmission" />                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                

  <!-- By default, hide joint_state_publisher's GUI in 'fake' controller_manager mode -->
  <arg name="use_gui" default="false" />
  <arg name="use_rviz" default="true" />
  <!-- Use rviz config for MoveIt tutorial -->
  <arg name="rviz_tutorial" default="false" />

  <!-- If needed, broadcast static tf for robot root -->
  <node pkg="tf2_ros" type="static_transform_publisher" name="virtual_joint_broadcaster_0" args="0 0 0 0 0 0 world $(arg arm_id)_link0" />



  <group if="$(eval arg('moveit_controller_manager') == 'fake')">
    <!-- We do not have a real robot connected, so publish fake joint states via a joint_state_publisher
         MoveIt's fake controller's joint states are considered via the 'source_list' parameter -->
    <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" unless="$(arg use_gui)">
      <rosparam param="source_list">[move_group/fake_controller_joint_states]</rosparam>
    </node>
    <!-- If desired, a GUI version is available allowing to move the simulated robot around manually
         This corresponds to moving around the real robot without the use of MoveIt. -->
    <node name="joint_state_publisher" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" if="$(arg use_gui)">
      <rosparam param="source_list">[move_group/fake_controller_joint_states]</rosparam>
    </node>

    <!-- Given the published joint states, publish tf for the robot links -->
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" respawn="true" output="screen" />
  </group>

  <!-- Run the main MoveIt executable without trajectory execution (we do not have controllers configured by default) -->
  <include file="$(dirname)/move_group.launch" pass_all_args="true">
    <arg name="allow_trajectory_execution" value="true" />
    <arg name="info" value="true" />
  </include>

  <!-- Run Rviz and load the default config to see the state of the move_group node -->
  <include file="$(dirname)/moveit_rviz.launch" if="$(arg use_rviz)">
    <arg name="rviz_tutorial" value="$(arg rviz_tutorial)"/>
    <arg name="rviz_config" value="$(dirname)/moveit.rviz"/>
    <arg name="debug" value="$(arg debug)"/>
  </include>

  <!-- If database loading was enabled, start mongodb as well -->
  <include file="$(dirname)/default_warehouse_db.launch" if="$(arg db)">
    <arg name="moveit_warehouse_database_path" value="$(arg db_path)"/>
  </include>

</launch>

For each part of the code, there is the following analysis:

arm_id

  <arg name="arm_id" default="panda" />
  # 机器人的标识符。这个参数指定在机器人有多个实现时使用哪一个。
  # 当多机器人协同时,标识符可以用来区分它们。默认值设置为“panda”

pipeline

  <arg name="pipeline" default="ompl" />
  # 机器人运动规划的管道。
  # MoveIt提供了几种规划算法,例如OMPL、SBPL等。此参数允许用户选择使用哪种算法进行运动规划。默认值为“ompl”。

Regarding OMPL(Open Motion Planning Library)the algorithm, please refer to OMPL official documentation and OMPL Primer

db&db_path

  <!-- By default, we do not start a database (it can be large) -->
  <arg name="db" default="false" />
  <!-- Allow user to specify database location -->
  <arg name="db_path" default="$(find panda_moveit_config)/default_warehouse_mongo_db" />
  # db:指定是否启动运动规划数据库。
  # 如果设为true,MoveIt会启动MongoDB数据库来存储或检索运动规划数据。默认值为false。
  # db_path:指定运动规划数据库的路径。
  # 这个参数允许用户指定MongoDB数据库的位置。默认值设置为“$(find panda_moveit_config)/default_warehouse_mongo_db”。

Motion planning data usually refers to data used for robots or mobile devices to plan motion paths, such as target position, current position of the robot, obstacle avoidance information, etc.
In MoveIt, Warehouseits function is to provide a persistent storage method to save the complete planning scene and robot state. By using appropriate storage plugins such as Python warehouse_ros_mongoor warehouse_ros_sqlitePython, users can save scenes and states to different backend databases such as Python MongoDBor Python. SQLiteThis allows users to reload and use saved scenes and states at different times and locations.

In addition to providing persistent storage functions, Warehouse can also be used for data query, filtering and sorting. By using the interface provided by MoveIt, users can easily retrieve and obtain the scenes and states they need from the Warehouse. This is useful for real-time planning and decision-making in robotic operations, as it can quickly retrieve specific scenarios and states without having to recalculate or regenerate them each time.

MongoDBis a popular document-based (NoSQL) database that JSONstores data in binary format. Unlike traditional relational databases, MongoDB has a flexible structure and is suitable for storing semi-structured data or documents of any type.

For information on using a database to store and call motion planning data in Moveit, please refer to Moveit1 Warehouse MangoDB

debug

  <!-- By default, we are not in debug mode -->
  <arg name="debug" default="false" />
  # debug:指定是否启用RViz调试模式。如果设为true,则启用RViz中的调试模式。默认为false。
  # 该参数也会被传递给move_group.launch,用于开启move_group的GDB调试。

RViz debug modeCan help developers diagnose and solve problems. In debug mode, Rviz can display more debugging information, such as the content and reception frequency of ROS messages, frame rate information, and resource and memory usage used in RViz visualizations, etc.

This information can help developers quickly locate and solve problems, such as debugging communication problems between nodes, visualizing resource usage, etc. At the same time, the debug mode can also explicitly display the names, labels and coordinate information of various visual elements in Rviz to better understand and adjust the position dynamics of elements.

load_gripper

  <!-- By default we will load the gripper -->
  <arg name="load_gripper" default="true" />
  # load_gripper:指定是否加载机器人夹爪的控制器。此参数用于加载和配置夹爪的运动控制器。默认值为true。
  # 该参数将通过 pass_all_args="true" 属性被传递给move_group.launch

load_robot_description

  <!-- By default, we will load or override the robot_description -->
  <arg name="load_robot_description" default="true"/>
  # 指定是否加载或覆盖机器人描述。MoveIt需要知道机器人的描述才能进行规划和控制。
  # 这个参数用于加载机器人的URDF文件或覆盖已有的机器人描述。默认值为true。
  # 该参数将通过 pass_all_args="true" 属性被传递给move_group.launch

load_robot_descriptionLoad the robot's description file (usually in urdfor sdf format) into the ROS parameter server. If the load_robot_description parameter is true, the previously set robot description file will be loaded or overwritten. If false, the previously loaded robot description file is used.

robot_descriptionThe publishing is robot_state_publisherrealized through nodes. This node obtains the description information of the robot from the parameter server, calculates the transformation of each linkage component of the robot, and publishes the robot's tf tree and joint status information. The move_group node receives tf and joint status information for motion planning and execution.

moveit_controller_manager

  <!-- Choose controller manager: fake, simple, or ros_control -->
  <arg name="moveit_controller_manager" default="fake" />
  # moveit_controller_manager:选择控制器管理器的类型。
  # 控制器管理器用于加载和配置机器人的控制器。
  # MoveIt提供了几种类型的控制器管理器,包括“fake”,“simple”和“ros_control”。默认值为“fake”。

The controller managers provided by MoveIt include the following three types:

  1. fake: This type of controller only simulates movement and does not communicate with the real robot. It is often used for quick testing and demonstrations, and for simulation, fake controllers are often used to simulate motion.

  2. simple: This type of controller communicates with the robot but only provides basic control such as linear/arc interpolation, etc. It works well for some simpler robots.

  3. ros_control: This is a more flexible controller type that supports a variety of robot and controller hardware. It provides higher-level control interfaces, such as motor controller interfaces and sensor reading interfaces.
    Different types of controller managers are used depending on the application scenario and the requirements of the robot.
    ros_control is a powerful controller for robots. Please refer to the ros_control WIKI document and ros_control source code.

Insert image description here
Image source: ROS WIKI ros_control

fake_execution_type

  <!-- Set execution mode for fake execution controllers -->
<arg name="fake_execution_type" default="interpolate" />
  # fake_execution_type:设置虚拟控制器的执行模式。
  # 如果选择“fake”控制器管理器,则使用虚拟控制器进行模拟运动。
  # 此参数指定用于虚拟运动的执行模式,包括“interpolate”,“last point。默认值为“interpolate”。

interpolate: This option indicates that MoveIt assumes that the controller will interpolate between each target point of the trajectory. This method can simulate the continuous trajectory execution process.

last point: This option indicates that MoveIt assumes the controller will jump directly to the last target point of the trajectory. This method can simulate robots performing tasks quickly. Two descriptions were found in the document, and it is uncertain whether there is a third one
that matches the description in the official documentation . However, there is a detailed description in the Moveit official document . Please refer to the Moveit1 Noetic official document.launch/fake_moveit_controller_manager.launch.xmlvia pointsfake controller
fake controller

MoveIt provides a range of virtual track controllers that can be used in simulations. Among them, the configuration file of the virtual controller is located config/fake_controllers.yaml.

The following controller types can be adjusted as needed:

  • interpolate: Performs smooth interpolation across key points, default for visualization.
  • via points: Traverse key points without interpolating points between them, used for visual debugging.
  • last point: Jump directly to the last point of the trajectory for offline benchmarking.

Virtual controller type information is fake_controllers.yamlconfigurable in the file. For each controller, you need to specify the name, type, and involved joints. where the frequency is rate: 10, which can be used in the interpolation controller. But when controlling the gripper, the joints are an empty list [].

Example:

rate: 10
controller_list:
  - name: fake_arm_controller
    type: interpolate
    joints:
      - joint_1
      - joint_2
      - joint_3
      - joint_4
      - joint_5
      - joint_6
  - name: fake_gripper_controller
    joints:
      []

transmission

  <!-- Transmission used for joint control: position, velocity, or effort -->
  <arg name="transmission" /> 
  # 设置用于关节控制的传输类型。这个参数用来选择传输类型,例如position、velocity或effort。
  # 默认情况下,这个参数未设置,不用理会。    

use_gui

  <!-- By default, hide joint_state_publisher's GUI in 'fake' controller_manager mode -->
  <arg name="use_gui" default="false" />

  # use_gui:指定是否显示joint_state_publisher的GUI界面。
  # 如果设为true,则会在启动期间打开一个窗口,显示机器人的关节姿态。默认值为false。

In MoveIt demo.launch, a default fake controller manager mode is set, which means there is no actual controller connected to the robot arm.

In this mode, joint_state_publisherthe published joint status information is fake_controller_joint_statesobtained through topics, and hiding its graphical user interface (GUI) can avoid user misoperation. Therefore, a GUI hidden by default joint_state_publishercan increase the reliability of the system.

use_rviz

  <arg name="use_rviz" default="true" />
  # use_rviz:指定是否启用RViz。如果此参数设为true,则MoveIt将启动RViz进行可视化。默认值为true。
  <!-- Use rviz config for MoveIt tutorial -->
  <arg name="rviz_tutorial" default="false" />
  # rviz_tutorial:指定是否使用RViz配置进行MoveIt教程演示。
  # 如果设为true,则MoveIt将加载RViz演示配置。默认值为false。

Virtual joint static TF node

  <!-- If needed, broadcast static tf for robot root -->
  <node pkg="tf2_ros" type="static_transform_publisher" name="virtual_joint_broadcaster_0" args="0 0 0 0 0 0 world $(arg arm_id)_link0" />
  # 广播虚拟关节的静态变换
  # 将world坐标系映射到机器人的物理坐标系中的起点$(arg arm_id)_link0

By using virtual joints and introducing a virtual "datum" point to describe the robot 's position in its environment , the robot's joint states can be mapped to positions and postures in the physical world for inverse kinematics calculations, and the planner can Use this information to plan motion trajectories or generate robot poses.

Joint status and overall robot status

  <group if="$(eval arg('moveit_controller_manager') == 'fake')">
    <!-- We do not have a real robot connected, so publish fake joint states via a joint_state_publisher
         MoveIt's fake controller's joint states are considered via the 'source_list' parameter -->
    <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" unless="$(arg use_gui)">
      <rosparam param="source_list">[move_group/fake_controller_joint_states]</rosparam>
    </node>
    <!-- If desired, a GUI version is available allowing to move the simulated robot around manually
         This corresponds to moving around the real robot without the use of MoveIt. -->
    <node name="joint_state_publisher" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" if="$(arg use_gui)">
      <rosparam param="source_list">[move_group/fake_controller_joint_states]</rosparam>
    </node>

    <!-- Given the published joint states, publish tf for the robot links -->
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" respawn="true" output="screen" />
  </group>
 # 如果moveit_controller_manager的类型是fake
 # 则启动joint_state_publisher和robot_state_publisher
 # 默认不启用joint_state_publisher_gui,以防用户在图形化窗口不小心调节了关节状态值

roslaunch xml

If you are not familiar with the language used in this code snippet ROS1 launch XML, please refer to the ROS1 Launch documentation

The role of group

The function of this node group groupis that when Moveit's controller manager is set to faketype, the node group will publish the joint status of the virtual robot /joint_states, and then publish the topic of the virtual robot through the robot status publisher /tfin order to subscribe to the /tftopic in RViz And display the status of the virtual robot in RViz.

In this group, along with robot_state_publisherthe joint_state_publishernode, it is used to simulate publishing joint status information. Types of topics joint_state_publisherwill be published regularly , which contain status information of each joint of the robot. It will subscribe to these messages, calculate the pose information of each component of the robot based on the robot's URDF model, and publish topics, and finally complete the update and release of the robot's status.sensor_msgs/JointState/joint_statesrobot_state_publisher/tf

Diagram of the relationship between nodes

It can be seen from rqt_graphthe relationship between each node and topic in this demo:

  1. /move_groupNode publishing /move_group/fake_controller_joint_statestopic
  2. /joint_state_publisherNode /move_group/fake_controller_joint_statessubscription topic
  3. /joint_state_publisherNode publishing /joint_statetopic
  4. /robot_state_publisherNode /joint_statesubscription topic
  5. /robot_state_publisherNode publishing /tftopic
  6. Virtual joint static TF node publishing /tftopic
  7. /move_groupSubscribe to /tftopics of type
  8. RViz subscription /tftopics

Insert image description here

joint_state_publisher

Joint State Publisher is a ROS package used to publish the joint status of non-fixed joints of robots /joint_states. The topic type is sensor_msgs/JointState.
After reading the robot's URDF description robot_descriptionparameters, it identifies all non-fixed joints and creates JointStatemessages with these non-fixed joints to set and publish robot joint status values joint state values.
It can robot_state_publisherbe used with , to publish transformations of all joint states.

Input to joint_state_publisher

joint_state_publisherSubscribe from the parameter server , find all non-fixed jointsrobot_description in the robot description , and publish type messages with the status values ​​of these joints.sensor_msgs/JointState

joint_state_publisherIt can be source_listused as an input, which is a string list with multiple topic names, which is empty by default, and fill in the topic names that need to be subscribed to. These topics to be subscribed are about the joint status value, and the topic type is alsosensor_msgs/JointState

In GUI mode, joint_state_publisher_guiit can receive joint_state_publisher_guidirect joint state values ​​(such as angles) from the graphical window tool, and this state value is given by the user by dragging the angle bar.

In this case of Moveit, /joint_state_publisherthe node subscribes to the topic from /move_group, /move_group/fake_controller_joint_statesand source_listthe content of the parameter is[move_group/fake_controller_joint_states]

Output of joint_state_publisher

joint_state_publisherThe node publishes topics including robot joints name, positions position, speeds velocity, and strength levels . The topic type is sensor_msgs/JointState.effort/joint_states

robot_state_publisher

Robot State Publisher is a ROS package responsible for publishing the status information of the overall kinematics chain of the robot, including joint and link names, parent-child relationships, and the position and direction of each link. This package is essential for visualizing robot poses in RViz or other visualization tools.

robot_descriptionIt uses the Universal Robot Description Format (URDF) specified by the parameters in the parameter server and the joint state value group /joint_statesfrom the topic, topic type sensor_msgs/msg/JointState, to calculate the forward kinematics of the robot and publish /tfthe topic.

Input to robot_state_publisher

robot_state_publisherrobot_descriptionAt startup , the robot's kinematics tree model URDF will be loaded from the parameter server . robot_descriptionParameters can be passed through the startup file, and their values ​​are the robot's URDF description strings.

At the same time, robot_state_publisheryou need to subscribe to joint_statesthe topic and obtain the status value information of each joint.
These joint status information joint statesare used to update the kinematics tree model , and then calculate Linkthe 3D pose information of each member of the robot.Pose

output of robot_state_publisher

For fixed joints, the topic robot_state_publisherwill be published /tf_staticof type tf2_msgs/msg/TFMessage
For movable joints, the topic of type robot_state_publisherwill be published . The pose information of fixed joints will be published to the topic when the node starts , and this information will be saved in the history record. The pose information of the movable joints will be released to the topic in time when the topic receives the update of the state of the corresponding joints./tftf2_msgs/msg/TFMessage
/tf_static/joint_states/tf

For specific usage examples, you can view Gihub robot_state_publisher

Insert image description here
Image source: ROS WIKI robot_state_publisher

Load move_group

  <!-- Run the main MoveIt executable without trajectory execution (we do not have controllers configured by default) -->
  <include file="$(dirname)/move_group.launch" pass_all_args="true">
    <arg name="allow_trajectory_execution" value="true" />
    <arg name="info" value="true" />
  </include>
  # 启动move_group.launch来加载move_group相关内容
  # 通过pass_all_args="true" 将demo.launch文件的所有arg参数传递给move_group.launch作为参数
  # 设置 allow_trajectory_execution 为 true,
  # 可以让 move_group 在运行过程中尝试让机器人执行这些预定义的轨迹
  # 但如果该参数设置为 false,则只会规划但不会执行规划的轨迹,机器人将保持静止
  # 此功能对于测试和调试非常有用,因为它允许操纵轨迹,而无需在机器人上实际执行它们
  # 它在关注安全的情况下也很有用,因为它提供了一种防止意外执行危险轨迹的方法
  # 如果将 info 设置为 true,则 move_group 会在控制台输出调试信息

pass_all_args="true"It is an attribute to which all Father Launchincoming parameters are passed Child Launch.

In the MoveIt demo.launchfile, all arg parameters pass_all_args="true"are passed to , which means that all parameters from can be obtained and inherited from them.Father LaunchChild LaunchChild LaunchFather Launch

In this case, that is to demo.launchpass all arg internal parameters to move_group.launch.
Note that if not set pass_all_args="true", Child Launchonly includeparameters explicitly listed in the markup will be accepted. Passing only includethe parameters explicitly listed in the markup helps to control the parameter confusion when Launch is nested.

Load RViz

  <!-- Run Rviz and load the default config to see the state of the move_group node -->
  <include file="$(dirname)/moveit_rviz.launch" if="$(arg use_rviz)">
    <arg name="rviz_tutorial" value="$(arg rviz_tutorial)"/>
    <arg name="rviz_config" value="$(dirname)/moveit.rviz"/>
    <arg name="debug" value="$(arg debug)"/>
  </include>
  # 当use_rviz=true时运行moveit_rviz.launch文件
  # 并传递参数rviz_tutorial用于选择是否使用Moveit RViz教学模式
  # rviz_config的值用于打开同目录下的/moveit.rviz配置文件
  # debug的值用来设置是否开启RViz的debug模式

Load database

  <!-- If database loading was enabled, start mongodb as well -->
  <include file="$(dirname)/default_warehouse_db.launch" if="$(arg db)">
    <arg name="moveit_warehouse_database_path" value="$(arg db_path)"/>
  </include>
  # 当参数db=true时,运行default_warehouse_db.launch
  # 向default_warehouse_db.launch传入参数moveit_warehouse_database_path,参数值为该数据库的路径

Slice parsing 2: move_group.launch

The file name robot_moveit_config/launch/move_group.launchis used to start the move_group node and related functions. The move_group node is a key component in the MoveIt software package. It provides an interface for performing various functions of MoveIt, such as planning, execution, and kinematics calculations. wait.
It implements the planning and execution of robot motion by interacting with motion control hardware and planners.
move_group.launchThe file panda_moveit_config/launch/demo.launchis launched as a Child Launch file in .

The following is the complete code of Moveit’s official case panda_moveit_config/launch/move_group.launch:

<launch>

  <!-- GDB Debug Option -->
  <arg name="debug" default="false" />
  <arg unless="$(arg debug)" name="launch_prefix" value="" />
  <arg     if="$(arg debug)" name="launch_prefix"
           value="gdb -x $(dirname)/gdb_settings.gdb --ex run --args" />

  <!-- Verbose Mode Option -->
  <arg name="info" default="$(arg debug)" />
  <arg unless="$(arg info)" name="command_args" value="" />
  <arg     if="$(arg info)" name="command_args" value="--debug" />

  <!-- move_group settings -->
  <arg name="pipeline" default="ompl" />
  <arg name="allow_trajectory_execution" default="true"/>
  <arg name="moveit_controller_manager" default="simple" />
  <arg name="fake_execution_type" default="interpolate"/>
  <arg name="max_safe_path_cost" default="1"/>
  <arg name="publish_monitored_planning_scene" default="true"/>

  <arg name="capabilities" default=""/>
  <arg name="disable_capabilities" default=""/>

  <!--Other settings-->
  <arg name="load_gripper" default="true" />
  <arg name="transmission" default="effort" />
  <arg name="arm_id" default="panda" />

  <arg name="load_robot_description" default="true" />
  <!-- load URDF, SRDF and joint_limits configuration -->
  <include file="$(dirname)/planning_context.launch">
    <arg name="load_robot_description" value="$(arg load_robot_description)" />
    <arg name="load_gripper" value="$(arg load_gripper)" />
    <arg name="arm_id" value="$(arg arm_id)" />
  </include>

  <!-- Planning Pipelines -->
  <group ns="move_group/planning_pipelines">

    <!-- OMPL -->
    <include file="$(dirname)/planning_pipeline.launch.xml">
      <arg name="pipeline" value="ompl" />
      <arg name="arm_id" value="$(arg arm_id)" />
    </include>

    <!-- CHOMP -->
    <include file="$(dirname)/planning_pipeline.launch.xml">
      <arg name="pipeline" value="chomp" />
      <arg name="arm_id" value="$(arg arm_id)" />
    </include>

    <!-- Pilz Industrial Motion -->
    <include file="$(dirname)/planning_pipeline.launch.xml">
      <arg name="pipeline" value="pilz_industrial_motion_planner" />
      <arg name="arm_id" value="$(arg arm_id)" />
    </include>

    <!-- Support custom planning pipeline -->
    <include if="$(eval arg('pipeline') not in ['ompl', 'chomp', 'pilz_industrial_motion_planner'])"
             file="$(dirname)/planning_pipeline.launch.xml">
      <arg name="pipeline" value="$(arg pipeline)" />
      <arg name="arm_id" value="$(arg arm_id)" />
    </include>
  </group>

  <!-- Trajectory Execution Functionality -->
  <include ns="move_group" file="$(dirname)/trajectory_execution.launch.xml" pass_all_args="true" if="$(arg allow_trajectory_execution)">
    <arg name="moveit_manage_controllers" value="true" />
  </include>

  <!-- Sensors Functionality -->
  <include ns="move_group" file="$(dirname)/sensor_manager.launch.xml" if="$(arg allow_trajectory_execution)">
    <arg name="moveit_sensor_manager" value="panda" />
  </include>

  <!-- Start the actual move_group node/action server -->
  <node name="move_group" launch-prefix="$(arg launch_prefix)" pkg="moveit_ros_move_group" type="move_group" respawn="false" output="screen" args="$(arg command_args)">
    <!-- Set the display variable, in case OpenGL code is used internally -->
    <env name="DISPLAY" value="$(optenv DISPLAY :0)" />

    <param name="allow_trajectory_execution" value="$(arg allow_trajectory_execution)"/>
    <param name="sense_for_plan/max_safe_path_cost" value="$(arg max_safe_path_cost)"/>
    <param name="default_planning_pipeline" value="$(arg pipeline)" />
    <param name="capabilities" value="$(arg capabilities)" />
    <param name="disable_capabilities" value="$(arg disable_capabilities)" />

    <!-- Publish the planning scene of the physical robot so that rviz plugin can know actual robot -->
    <param name="planning_scene_monitor/publish_planning_scene" value="$(arg publish_monitored_planning_scene)" />
    <param name="planning_scene_monitor/publish_geometry_updates" value="$(arg publish_monitored_planning_scene)" />
    <param name="planning_scene_monitor/publish_state_updates" value="$(arg publish_monitored_planning_scene)" />
    <param name="planning_scene_monitor/publish_transforms_updates" value="$(arg publish_monitored_planning_scene)" />
  </node>

</launch>

GDB

  <!-- GDB Debug Option -->
  <arg name="debug" default="false" />
  <arg unless="$(arg debug)" name="launch_prefix" value="" />
  <arg     if="$(arg debug)" name="launch_prefix"
           value="gdb -x $(dirname)/gdb_settings.gdb --ex run --args" />
  # GDB Debug Option:用于设置是否启用GDB调试。
  # 当 GDB debug模式关闭时,launch_prefix值为空
  # 当 GDB debug模式开启时,launch_launch_prefix为GDB相关命令

GNU symbolic debugger (GDB) is the most commonly used program debugger on the Linux platform. The GDB compiler is usually used in the terminal (shell) as the gdb command.

Debugging tools can make the debugged program pause at the specified code and view the running status of the current program (such as the value of the current variable, the execution result of the function, etc.), which is breakpoint debugging .
Debugging can help you understand the logic errors that occur in your program.
Ubuntu comes with its own GDB debugging tool:

test@ubuntu:~$ gdb -v  # Check the version of GDB
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

In this code snippet
gdb: is the command for the GNU Debugger (GDB), which is used to debug a program and trace its execution.

gdb_settings.gdbContains a series of GDB commands and debugging settings for automatically performing some operations during debugging.
These command script files can contain initialization commands to be executed when starting a GDB session, setting breakpoints, specifying watchpoints, configuring debugging options, performing a series of debugging operations, and other customized GDB commands. By writing debugging scripts, you can automatically perform a series of debugging operations to save the time and energy of manually entering commands.
The file was not found in panda_moveit_config/launch/the folder. It may be automatically generated or the developer of Moveit does not want users to use it.

gdb -x $(dirname)/gdb_settings.gdbin -xcauses gdb_settings.gdbthe script file to be loaded into GDB, which will cause GDB to execute gdb_settings.gdbthe commands and operations defined in the script file.
--ex runThe option tells GDB to execute the run command immediately after starting the debugger, so that the program that needs to be debugged starts running.
--argsThe options can be followed by the program to be debugged and its parameters.

In this case, by enabling debug mode, the launch_prefix is ​​GDB related content. This prefix will be <node name="move_group" launch-prefix="$(arg launch_prefix)" pkg="moveit_ros_move_group" type="move_group" respawn="false" output="screen" args="$(arg command_args)">used in, that is, move_groupit will be passed in when starting the node launch-prefix.

info mode

  <!-- Verbose Mode Option -->
  <arg name="info" default="$(arg debug)" />
  <arg unless="$(arg info)" name="command_args" value="" />
  <arg     if="$(arg info)" name="command_args" value="--debug" />
  # Verbose Mode Option:用于设置是否启用详细模式。
  # 当开启详细模式时,move_group会在console输出更多信息,帮助用户了解move_group中发生的事情
  # info:用于指示是否启用详细模式的参数,默认与debug参数相同。
  # 当开启debug时,verbose详细模式也将被默认开启
  # 如果详细模式开启,则command_args参数值为--debug

In this case, move_groupthe node will be started with command_argsthe parameter passed to the node as an argument move_group:
<node name="move_group" launch-prefix="$(arg launch_prefix)" pkg="moveit_ros_move_group" type="move_group" respawn="false" output="screen" args="$(arg command_args)">.

infoParameters are passed into demo.launchas parameters in as parameters.pass_all_args="true"move_group.launch

pipeline

  <!-- move_group settings -->
  <arg name="pipeline" default="ompl" />
  # 机器人运动规划的管道。
  # MoveIt提供了几种规划算法,例如OMPL、SBPL等。此参数允许用户选择使用哪种算法进行运动规划。默认值为“ompl”。

Regarding OMPL(Open Motion Planning Library)the algorithm, please refer to the OMPL official documentation and OMPL Primer
. In this case, pipelinethe parameters are passed into demo.launchas parameters in as parameters.pass_all_args="true"move_group.launch

allow_trajectory_execution

  <arg name="allow_trajectory_execution" default="true"/>
  # 设置 allow_trajectory_execution 为 true,
  # 可以让 move_group 在运行过程中尝试让机器人执行这些预定义的轨迹
  # 但如果该参数设置为 false,则只会规划但不会执行规划的轨迹,机器人将保持静止
  # 此功能对于测试和调试非常有用,因为它允许操纵轨迹,而无需在机器人上实际执行它们
  # 它在关注安全的情况下也很有用,因为它提供了一种防止意外执行危险轨迹的方法

In this case, allow_trajectory_executionthe parameters in demo.launchas include file="$(dirname)/move_group.launch"parameters argare passed into move_group.launchas parameters.

moveit_controller_manager

  <arg name="moveit_controller_manager" default="simple" />
  # moveit_controller_manager:选择控制器管理器的类型,在move_group中默认值为“simple”。
  # 控制器管理器用于加载和配置机器人的控制器。
  # MoveIt提供了几种类型的控制器管理器,包括“fake”,“simple”和“ros_control”。

The controller managers provided by MoveIt include the following three types:

  1. fake: This type of controller only simulates movement and does not communicate with the real robot. It is often used for quick testing and demonstrations, and for simulation, fake controllers are often used to simulate motion.

  2. simple: This type of controller communicates with the robot but only provides basic control such as linear/arc interpolation, etc. It works well for some simpler robots.

  3. ros_control: This is a more flexible controller type that supports a variety of robot and controller hardware. It provides higher-level control interfaces, such as motor controller interfaces and sensor reading interfaces.
    Different types of controller managers are used depending on the application scenario and the requirements of the robot.

In this case, moveit_controller_managerthe parameters in demo.launchare pass_all_args="true"passed into move_group.launchas parameters.

move_group.launchThis parameter defaults to simple, while in , this is because it is purely used to test plug-ins in RViz. When demo.launchstarted by , the controller type is .fakedemo.launchMotionPlanningdemo.launchmove_group.launchfake

fake_execution_type

<arg name="fake_execution_type" default="interpolate" />
  # fake_execution_type:设置虚拟控制器的执行模式。
  # 如果选择“fake”控制器管理器,则使用虚拟控制器进行模拟运动。
  # 此参数指定用于虚拟运动的执行模式,包括“interpolate”,“last point。默认值为“interpolate”。

interpolate: This option indicates that MoveIt assumes that the controller will interpolate between each target point of the trajectory. This method can simulate the continuous trajectory execution process.

last point: This option indicates that MoveIt assumes the controller will jump directly to the last target point of the trajectory. This method can simulate robots performing tasks quickly. Two descriptions were found in the document, and it is uncertain whether there is a third one
that matches the description in the official documentation . However, there is a detailed description in the Moveit official document . Please refer to the Moveit1 Noetic official document.launch/fake_moveit_controller_manager.launch.xmlvia pointsfake controller
fake controller

MoveIt provides a range of virtual track controllers that can be used in simulations. Among them, the configuration file of the virtual controller is located config/fake_controllers.yaml.

The following controller types can be adjusted as needed:

  • interpolate: Performs smooth interpolation across key points, default for visualization.
  • via points: Traverse key points without interpolating points between them, used for visual debugging.
  • last point: Jump directly to the last point of the trajectory for offline benchmarking.

Virtual controller type information is fake_controllers.yamlconfigurable in the file. For each controller, you need to specify the name, type, and involved joints. where the frequency is rate: 10, which can be used in the interpolation controller. But when controlling the gripper, the joints are an empty list [].

Example:

rate: 10
controller_list:
  - name: fake_arm_controller
    type: interpolate
    joints:
      - joint_1
      - joint_2
      - joint_3
      - joint_4
      - joint_5
      - joint_6
  - name: fake_gripper_controller
    joints:
      []

max_safe_path_cost

  <arg name="max_safe_path_cost" default="1"/>
  # max_safe_path_cost:最大安全路径成本,默认为1。
  # 作为参数sense_for_plan/max_safe_path_cost的值被传入move_group节点
  # 这个参数值将影响move_group路径规划的行为。
  # 目前没有发现该值的使用标准和方式,可以不理会。

max_safe_path_costThe parameter is used to set the maximum safe path cost parameter in the move group (MoveGroup) sense_for_plan/max_safe_path_cost. This parameter defines the maximum path cost that the mobile group can accept when planning the robot path. The path cost is calculated based on factors such as obstacles on the path and the risk of collision.

When performing path planning, MoveIt will try to find a path that meets safety requirements based on the given goal settings and constraints. If the total cost (price) of the generated path exceeds max_safe_path_costthe threshold specified by the parameter, then MoveIt will consider the path to be unsafe and will stop searching for more paths. This helps avoid planning unsafe or costly paths.

A lower maximum safe path cost threshold will cause the planner to be more cautious and consider avoiding collisions and obstacles more, as it is easy to reach the maximum safe cost threshold and become unsafe.

A higher maximum safe path cost can help increase the planner's ability to generate effective paths because there is a more tolerant safe path cost range for the planner to generate paths.

By setting max_safe_path_costparameters, you can constrain the planner to choose the safest path for the path generated by the robot.

publish_monitored_planning_scene

  <arg name="publish_monitored_planning_scene" default="true"/>
  # 是否发布监视的规划场景,默认为true。

In MoveIt move_group.launch, <arg name="publish_monitored_planning_scene" default="true"/>it is used to set whether to release monitoring planning scenarios.

If this parameter is set to true, publishing the monitored planning scenario is enabled, it will publish the current planning scenario to a specific topic. Other nodes or tools can obtain the latest planning scenario information by subscribing to the topic. The monitored planning scenario contains Real-time data about robots, obstacles, planning requests and other related information.
When turned on, the user or system can monitor, analyze and respond to changes in the planning scene in real time to process accordingly, which is very useful for visualization, debugging and other purposes. it works.

MoveIt move_groupnodes will release monitored planning scenarios during the planning process, including planning_scene_monitor/publish_planning_scene, planning_scene_monitor/publish_geometry_updates, planning_scene_monitor/publish_state_updates, planning_scene_monitor/publish_transforms_updates.

capabilities

  <arg name="capabilities" default=""/>
  <arg name="disable_capabilities" default=""/>
  # 用于设置运动规划组(move_group)的功能和禁用功能的选项
  # 无需理会

<arg name="capabilities">Used to specify the features enabled in the motion planning group. These functions include, for example, allowing planning of motion trajectories, execution of motion trajectories, execution of single motion targets, etc. Specific functionality can <arg name="capabilities">be enabled by setting the corresponding value in .

<arg name="disable_capabilities">Used to disable certain functions in the motion planning group. <arg name="disable_capabilities">You can disable features that are not required in a planning group by setting the feature's value in . This is useful for limiting or simplifying the functionality of a motion planning group.

These options allow the flexibility to configure and customize the functionality of MoveIt's motion planning group based on the needs of the application.

load_gripper

  <!--Other settings-->
  <arg name="load_gripper" default="true" />
  # 指定是否加载机器人夹爪的控制器。此参数用于加载和配置夹爪的运动控制器。默认值为true。

In this case, load_gripperby demo.launchpassing pass_all_args="true"inmove_group.launch

transmission

  <arg name="transmission" default="effort" />
  # 设置用于关节控制的传输类型。这个参数用来选择传输类型,例如position、velocity或effort。
  # 默认情况下,这个参数在move_group中被设置为"effort"

In MoveGroup, <arg name="transmission" default="effort" />it is a parameter used to specify the transmission type of the robot arm. This parameter specifies the type of transmission system used by the robot arm controller (controller). The default is "effort" (force/torque transmission).

The choice of transmission type will affect how the robotic arm is controlled in MoveGroup. Specific drive types include:

  • Effort Transmission (force/torque transmission): This transmission type assumes that the control input of the manipulator is force/torque and is used to control the torque or force of the joint. Ideal for applications that require specific force or torque on a joint for precise control and force sensing.
  • Velocity is used to control the actuator to move at a specific speed. It can be used for tasks that require smooth, continuous motion.
  • Position is useful for controlling an actuator to move to a specific position or joint angle. It can be used for tasks that require precise position control.

If the task requires the application of a specific force or torque, the effort control method can be selected.
If the task requires smooth and continuous motion, you can choose the velocity control mode.
If the task requires precise position control, you can choose the position control method.
Choosing the appropriate transmission type depends on the specific configuration and requirements of the robotic arm. When configuring MoveGroup, you can set the corresponding parameters according to the transmission system of the robotic arm to ensure that the correct control signal is transmitted to the robotic arm.

In this case, transmissionpassed in demo.launchby , the value in is empty, that is, the default value is usedpass_all_args="true"move_group.launchdemo.launcheffort

arm_id

  <arg name="arm_id" default="panda" />
  # 机器人的标识符。这个参数指定在机器人有多个实现时使用哪一个。
  # 当多机器人协同时,标识符可以用来区分它们。默认值设置为“panda”

load_robot_description

  <arg name="load_robot_description" default="true" />
  # 指定是否加载或覆盖机器人描述及joint_limits文件。MoveIt需要知道机器人的描述才能进行规划和控制。
  # 这个参数用于加载机器人的URDF文件或覆盖已有的机器人描述。默认值为true。

load_robot_descriptionLoad the robot's description file (usually in urdfor sdf format) into the ROS parameter server. If the load_robot_description parameter is true, the previously set robot description file will be loaded or overwritten. If false, the previously loaded robot description file is used.
robot_descriptionThe publishing is robot_state_publisherrealized through nodes. This node obtains the description information of the robot from the parameter server, calculates the transformation of each linkage component of the robot, and publishes the robot's tf tree and joint status information. The move_group node receives tf and joint status information for motion planning and execution.

In this case, load_robot_descriptionby demo.launchpassing pass_all_args="true"inmove_group.launch

URDF/SRDF/joint_limits configuration

  <!-- load URDF, SRDF and joint_limits configuration -->
  <include file="$(dirname)/planning_context.launch">
    <arg name="load_robot_description" value="$(arg load_robot_description)" />
    <arg name="load_gripper" value="$(arg load_gripper)" />
    <arg name="arm_id" value="$(arg arm_id)" />
  </include>

A nested include directive calls planning_context.launchthe file, passing it load_robot_descriptionthe , , load_gripperand arm_idparameters.

planning_context.launchThe role of the file is to load URDF(Unified Robot Description Format), SRDF(Semantic Robot Description Format)and joint limit configuration joint_limits configurationand other related files planning contextto create the required configuration and environment for the robot's motion planning context.

motion planning pipeline

 <!-- Planning Pipelines -->
  <group ns="move_group/planning_pipelines">

    <!-- OMPL -->
    <include file="$(dirname)/planning_pipeline.launch.xml">
      <arg name="pipeline" value="ompl" />
      <arg name="arm_id" value="$(arg arm_id)" />
    </include>

    <!-- CHOMP -->
    <include file="$(dirname)/planning_pipeline.launch.xml">
      <arg name="pipeline" value="chomp" />
      <arg name="arm_id" value="$(arg arm_id)" />
    </include>

    <!-- Pilz Industrial Motion -->
    <include file="$(dirname)/planning_pipeline.launch.xml">
      <arg name="pipeline" value="pilz_industrial_motion_planner" />
      <arg name="arm_id" value="$(arg arm_id)" />
    </include>

    <!-- Support custom planning pipeline -->
    <include if="$(eval arg('pipeline') not in ['ompl', 'chomp', 'pilz_industrial_motion_planner'])"
             file="$(dirname)/planning_pipeline.launch.xml">
      <arg name="pipeline" value="$(arg pipeline)" />
      <arg name="arm_id" value="$(arg arm_id)" />
    </include>
  </group>
  # 启动OMPL规划器
  # 启动CHOMP规划器
  # 启动Pilz Industrial Motion规划器
  # 当还有其他自定义的pipeline时,再启动自定义规划器
  # 自定义规划器的文件为 planning_pipeline.launch.xml
  # 启动的规划器包括预定义的规划器(OMPL、CHOMP和Pilz Industrial Motion)以及自定义规划器

Reasons to load multiple planners at the same time

The purpose of starting all three planners at the same time is to provide multiple options and flexibility to suit different motion planning needs and algorithm preferences. Each planner has its own unique algorithm and characteristics, which can produce better planning results in different scenarios.

Although all three planners are loaded, only one of them is usually selected for planning tasks during actual use .

This is because move_groupwhen the node starts, the default planner will be selected. This default planner is the pipelineparameter passed in by the user. Only the planner that matches its value will actually perform the planning task.

 <param name="default_planning_pipeline" value="$(arg pipeline)" />

Therefore, only one of the planners will be activated and no conflicts will occur. By selecting the appropriate planner in the configuration file and setting the corresponding pipelineparameters to the corresponding values, you can ensure that only the required planners are started and used.
This design gives users the flexibility to select and switch planners to suit their specific needs and circumstances.

At the same time, for GUI control, the layout can be switched through the section in the plug- RVizin .MotionPlanningContext

trajectory actuator

  <!-- Trajectory Execution Functionality -->
  <include ns="move_group" file="$(dirname)/trajectory_execution.launch.xml" pass_all_args="true" if="$(arg allow_trajectory_execution)">
    <arg name="moveit_manage_controllers" value="true" />
  </include>
  # 当allow_trajectory_execution=true时,也就是允许轨迹执行时
  # 启动trajectory_execution.launch.xml文件
  # 这个文件负责运行MoveIt的轨迹执行功能
  # 将moveit_manage_controllers参数设置为`true`表示由MoveIt来管理控制器

File trajectory_execution.launch.xmlused to configure MoveIt's trajectory executor trajectory_execution. The parameters moveit_manage_controllersare used to control how MoveIt manages the underlying robot controller.

Specifically,
it moveit_manage_controllers="true"means that MoveIt will manage the entire robot control system (including the underlying controller) and be responsible for ensuring that the controller is started when needed and shut down when not. This is the most common setup, especially if using a single robot controller.

When moveit_manage_controllers="false"it means that MoveIt is not responsible for the startup management of the underlying robot controller. This means that users need to handle the management of the underlying controller themselves. This setup is suitable for those users who already have a separate controller management system, or in complex robotic systems using multiple independent controllers.

By configuring moveit_manage_controllersparameters, you can choose to let MoveIt manage the robot controller or let the user manage it themselves according to the actual situation.

sensor manager

  <!-- Sensors Functionality -->
  <include ns="move_group" file="$(dirname)/sensor_manager.launch.xml" if="$(arg allow_trajectory_execution)">
    <arg name="moveit_sensor_manager" value="panda" />
  </include>
  # 用于管理各个传感器
  # 当允许轨迹控制时才启动传感器管理器
  # 参数moveit_sensor_manager的作用是指定要使用的传感器管理器的名称或标识符
  # 该参数的值用于告知MoveIt系统应该使用哪个传感器管理器来处理与传感器设备的交互

moveit_sensor_manager

The sensor manager moveit_sensor_manageris a component in Moveit that is responsible for communication and data processing with sensor devices. Different sensor devices may require different sensor managers to handle their specific requirements such as data formats, communication interfaces, etc. Through moveit_sensor_manager, the sensor manager can be flexibly configured and switched to suit different sensor devices or needs.

allow_trajectory_execution

allow_trajectory_executionIf true, the sensor manager needs to be loaded.
This is because the trajectory execution phase requires the use of sensor data to monitor and adjust the actual motion execution process.
If trajectories are not being executed, or real-time monitoring and adjustments based on sensor data are not required, then loading the sensor manager may not be necessary, so using as a allow_trajectory_executionlaunch condition allows you to selectively load and use the sensor manager as needed.

sensor_manager.launch.xml

sensor_manager.launch.xmlThe function is to manage the sensors in MoveIt. It is used to configure and start sensor devices related to MoveIt. This could include devices like depth cameras, laser scanners, or other sensors. This file defines the parameters of the sensor device, such as the type of sensor, the topic of publication, and related parameter settings.

move_group.launchThe purpose of the call in is sensor_manager.launch.xmlto allow the MoveIt system to interact with sensor devices to obtain sensory data during motion planning and execution. By including sensor startup files move_group.launch, MoveGroup nodes can communicate with sensor nodes and use sensor data to enhance or adjust motion planning and execution.

move_group node

  <!-- Start the actual move_group node/action server -->
  <node name="move_group" launch-prefix="$(arg launch_prefix)" pkg="moveit_ros_move_group" type="move_group" respawn="false" output="screen" args="$(arg command_args)">
    # 根据GDB调试器开关的参数作为launch-prefix
    # launch-prefix用于指定在启动节点时添加的前缀命令。这通常用于设置环境变量或传递特定的命令行参数
    # 运行moveit_ros_move_group包中的move_group文件
    # respawn指定节点是否在结束后重新启动。在这里设置为"false",意味着节点在结束后不会重新启动。
    # output指定输出打印到屏幕上,也就是终端窗口里
    # args="$(arg command_args)"用于传递额外的命令行参数给节点。
    # 此处的command_args参数值是--debug
    # 意味着当debug模式开启时会提供详细信息输出模式

X server

X server ( X Server) is a software service for graphics display. It is one of the basic components for implementing graphical user interface (GUI) in Linuxand systems. UnixThe X server manages graphics display devices (such as monitors, keyboards, mice, etc.), receives user input and renders the graphical interface to the monitor.
In modern Linuxsystems, the commonly used X server implementations are X.Org Server,

UbuntuThe system usesXserver - X Window System display server

X Window SystemIt consists of a client and a server. The server X Serveris responsible for graphic display, and the client library sends graphic display requests to the corresponding X Clientsystem according to the environment variables set by the system . You only need to open an X Server remotely and set the DISPLAY variable accordingly on the target machine to complete the remote display of graphics.DISPLAYX Server

Common application scenarios are:

ssh -X username@ubuntu-server-ip

When in use ssh -X, by Secure Shell(SSH)performing X11 forwarding, users can run the graphical interface program on the remote server and display it on the local computer without installing the graphical interface software locally.

This means that users can connect to the robot through SSH for remote server management, and at the same time view and operate the remote graphical interface program on the local computer . The graphical interface will be displayed on the main computer through SSH tunnel and X11 forwarding.

Display

    <!-- Set the display variable, in case OpenGL code is used internally -->
    <env name="DISPLAY" value="$(optenv DISPLAY :0)" />

In ROS, the software used to control the robot usually runs on the high-end computer, not the edge, and usually the images are not displayed on the edge.
When it comes to displaying or manipulating on a graphical interface (such as visualizing robot models, visualizing results of motion planning, etc.), OpenGLlibraries are usually used for drawing operations.

The purpose of setting DISPLAYenvironment variables is to ensure that the code move_groupinside the node OpenGLcan display the graphical interface correctly . DISPLAYThe address specified by the environment variable X Servertells the program where to display the graphical interface.
<env>is the label used to set environment variables in the ROS Launch file.
optenvis a function in the ROS Launch file that takes values ​​from system environment variables and provides default values .

In Linuxa system (for example Ubuntu), DISPLAYthe environment variable indicates X Serverthe location, and its format is usually hostname:display_number.screen_number. For local X Server, it is generally used :0to represent the default first display.

$(optenv DISPLAY :0)Represents the value obtained from the system environment variable DISPLAY, or uses the default value if not found :0.
In this code, DISPLAYthe environment variable is set via the label $(optenv DISPLAY :0).

In this way, when the move_group node needs to display the results on the graphical interface, it will use the set DISPLAY environment variable to communicate with the X server to ensure that the OpenGL code can correctly render and display the graphical interface. In this way, users can view and operate the robot's motion planning results through a graphical interface.

Other parameters of move_group

    <param name="allow_trajectory_execution" value="$(arg allow_trajectory_execution)"/>
    <param name="sense_for_plan/max_safe_path_cost" value="$(arg max_safe_path_cost)"/>
    <param name="default_planning_pipeline" value="$(arg pipeline)" />
    <param name="capabilities" value="$(arg capabilities)" />
    <param name="disable_capabilities" value="$(arg disable_capabilities)" />
    # 以下为传入move_group节点的参数,他们在此前被介绍过
    # allow_trajectory_execution 允许轨迹执行
    # sense_for_plan/max_safe_path_cost 最大安全路径代价值
    # default_planning_pipeline 默认的规划流水线
    # capabilities 功能 无需理会
    # disable_capabilities 禁止功能 无需理会

move_group publishes the parameters of the actual robot's planning scenario

    <!-- Publish the planning scene of the physical robot so that rviz plugin can know actual robot -->
    <param name="planning_scene_monitor/publish_planning_scene" value="$(arg publish_monitored_planning_scene)" />
    <param name="planning_scene_monitor/publish_geometry_updates" value="$(arg publish_monitored_planning_scene)" />
    <param name="planning_scene_monitor/publish_state_updates" value="$(arg publish_monitored_planning_scene)" />
    <param name="planning_scene_monitor/publish_transforms_updates" value="$(arg publish_monitored_planning_scene)" />
  </node>

move_groupThe node enables RViz to understand the planning scenario of the actual robot by publishing the planning scenario of the actual robot. The move_groupparameters that need to be passed into the node include the following. These parameters will control the publication of the corresponding topic:
planning_scene_monitor/publish_planning_sceneParameters are used to publish information about the current planning scenario. It publishes the current planning scenario in the form of a message, allowing other nodes (such as visualization tools or motion planners) to subscribe and obtain the current planning scenario information. This can pass the latest scene information to other nodes in real time so that they can make appropriate decisions.

planning_scene_monitor/publish_geometry_updatesParameters used to publish updates to object geometry information . When the geometry of an object changes (for example, an object is added, removed, or its shape changes) , this topic publishes the updated geometric information. This way other nodes can adjust the planning scene based on geometry updates to keep it up to date.

planning_scene_monitor/publish_state_updatesParameters used to publish updates to motion status . When the robot's status changes (such as joint position modification, linkage status update) , this topic publishes the robot's status information . Other nodes can subscribe to this topic to obtain the latest robot status information to make appropriate decisions.

planning_scene_monitor/publish_transforms_updatesParameter used to publish updates to coordinate transformations . When the coordinate transformation related to the robot changes, this topic publishes the updated information of the transformation. Other nodes can subscribe to this topic to obtain the latest coordinate transformation information so that the correct coordinate transformation can be used during planning and execution.

The use of these parameters corresponding to open and closed topics can achieve real-time scene updates and status feedback, allowing different nodes to share and coordinate planning scene information, providing more effective motion planning and execution capabilities.

Slice parsing 4: planning_context.launch

planning_context.launchThe function of the file is to load robot description URDF(Unified Robot Description Format), semantic description SRDF(Semantic Robot Description Format), joint limit configuration joint_limits, Cartesian limit cartesian_limits, kinematic settings and other related files, and arrange the required configuration and environment for the robot's motion planning.

planning_context.launchThe file move_group.launchis called as a nested launch file in, and parameters are taken move_group.launchfrom it load_robot_description, load_gripperand arm_id.
The complete code is as follows:

<launch>
  <!-- By default we do not overwrite the URDF. Change the following to true to change the default behavior -->
  <arg name="load_gripper" default="true" />
  <arg name="load_robot_description" default="false"/>
  <arg name="arm_id" default="panda" />

  <!-- The name of the parameter under which the URDF is loaded -->
  <arg name="robot_description" default="robot_description"/>

  <!-- Load universal robot description format (URDF) -->
  <param name="$(arg robot_description)" command="xacro '$(find franka_description)/robots/panda/panda.urdf.xacro' hand:=$(arg load_gripper) arm_id:=$(arg arm_id)" if="$(arg load_robot_description)" />

  <!-- The semantic description that corresponds to the URDF -->
  <param name="$(arg robot_description)_semantic" command="xacro '$(find panda_moveit_config)/config/panda.srdf.xacro' hand:=$(arg load_gripper) arm_id:=$(arg arm_id)" />

  <!-- Load updated joint limits (override information from URDF) -->
  <group ns="$(arg robot_description)_planning">
    <rosparam command="load" file="$(find panda_moveit_config)/config/joint_limits.yaml" subst_value="true" />
    <rosparam command="load" file="$(find panda_moveit_config)/config/cartesian_limits.yaml" subst_value="true"/>
  </group>

  <!-- Load default settings for kinematics; these settings are overridden by settings in a node's namespace -->
  <group ns="$(arg robot_description)_kinematics">
    <rosparam command="load" file="$(find panda_moveit_config)/config/kinematics.yaml" subst_value="true"/>
  </group>

</launch>

Pass in parameters

  <!-- By default we do not overwrite the URDF. Change the following to true to change the default behavior -->
  <arg name="load_gripper" default="true" />
  <arg name="load_robot_description" default="false"/>
  <arg name="arm_id" default="panda" />
  # 是否加载夹爪
  # 是否加载URDF模型
  # 机械臂的id,用作识别机器人的标识

Load model

    <!-- The name of the parameter under which the URDF is loaded -->
    <arg name="robot_description" default="robot_description"/>
    # robot_description参数用于存储加载的机器人的URDF描述对应的参数名,无需理会
  <!-- Load universal robot description format (URDF) -->
    <param name="$(arg robot_description)" command="xacro '$(find franka_description)/robots/panda/panda.urdf.xacro' hand:=$(arg load_gripper) arm_id:=$(arg arm_id)" if="$(arg load_robot_description)" />
# 将URDF文件加载为ROS参数
# 这个URDF文件是由xacro命令从panda.urdf.xacro文件来生成的
# 之前引入的hand和arm_id被传给xacro命令作为参数

If installed using the one-click installation configuration script franka_description, it can /opt/ros/noetic/share/franka_description/robots/pandabe found in the directorypanda.urdf.xacro

xacro is an XML macro language. In this case, xacro is used to process URDF (Unified Robot Description Format) files, making URDF files more modular and easier to manage.

hand:=$(arg load_gripper)and arm_id:=$(arg arm_id)will be passed into the specified xacro file. These parameters are used in the xacro file to generate specific URDF configurations according to requirements.

panda.urdf.xacro

<?xml version='1.0' encoding='utf-8'?>
# XML的版本和编码声明。所有的XML文件都会以这个声明开始
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="panda">
# 定义一个名为“panda”的机器人。xmlns:xacro指定了xacro命名空间的URL
  <xacro:include filename="$(find franka_description)/robots/common/franka_robot.xacro"/>
# 引入另一个xacro文件,路径是通过find指令找到的
# 这是一种模块化设计,允许将机器人模型分割为更小、更易于管理的部分
  <xacro:arg name="arm_id" default="panda" />
# 定义参数名为"arm_id",并设置其默认值为"panda",如果有外部值传入,则为外部传入的值

  <xacro:franka_robot arm_id="$(arg arm_id)"
                 joint_limits="${xacro.load_yaml('$(find franka_description)/robots/panda/joint_limits.yaml')}">
# 调用franka_robot.xacro宏,并将参数arm_id和joint_limits传入
  </xacro:franka_robot>

</robot>

franka_robot.xacro

Among panda.urdf.xacrothe included franka_robot.xacro, the judgment for the call of hand is as follows:

    <xacro:if value="$(arg hand)">
      <xacro:include filename="$(find franka_description)/robots/common/franka_hand.xacro"/>
      <xacro:franka_hand
          arm_id="$(arg arm_id)"
          rpy="0 0 ${-pi/4}"
          tcp_xyz="$(arg tcp_xyz)"
          tcp_rpy="$(arg tcp_rpy)"
          connected_to="$(arg arm_id)_link8"
          safety_distance="0.03"
          gazebo="$(arg gazebo)"
       />
    </xacro:if>

Therefore, hand:=$(arg load_gripper)and arm_id:=$(arg arm_id)will be passed into the specified xacro file to determine whether the gripper needs to be loaded and arm_id set.

Load SRDF

    <!-- The semantic description that corresponds to the URDF -->
    <param name="$(arg robot_description)_semantic" command="xacro '$(find panda_moveit_config)/config/panda.srdf.xacro' hand:=$(arg load_gripper) arm_id:=$(arg arm_id)" />
# 加载SRDF (Semantic Robot Description Format) 文件到ROS参数服务器

The SRDF file usually contains high-level information about the robot. In Moveit's case, it is generated by SetupAssistant and contains things such as groups, chains, etc. SRDF files are also converted from xacro macros by the xacro command.

Joint limits and Cartesian limits

Used to overwrite the relevant limit information in URDF

    <!-- Load updated joint limits (override information from URDF) -->
    <group ns="$(arg robot_description)_planning">
      <rosparam command="load" file="$(find panda_moveit_config)/config/joint_limits.yaml" subst_value="true" />
      <rosparam command="load" file="$(find panda_moveit_config)/config/cartesian_limits.yaml" subst_value="true"/>
    </group>
# 加载限位数据到ROS参数服务器的robot_description_planning参数

Kinematics related settings

    <!-- Load default settings for kinematics; these settings are overridden by settings in a node's namespace -->
    <group ns="$(arg robot_description)_kinematics">
      <rosparam command="load" file="$(find panda_moveit_config)/config/kinematics.yaml" subst_value="true"/>
    </group>
# 加载运动学相关参数到ROS参数服务器的robot_description_kinematics参数    

Slice analysis 5: planning_pipeline.launch.xml

This file move_group.launchis called in the section about pipeline, which is used to call the corresponding <pipeline_name>_pipeline.launch.xml, for example ompl_planning_pipeline.launch.xml.
Now move_group.launch, it calls four pipelines, including ompl, chomp, pilz_industrial_motion_planner, 自定义pipeline. It can be regarded as a unified interface for various pipeline calls. The following is the content of this file:

<launch>

  <!-- This file makes it easy to include different planning pipelines;
       It is assumed that all planning pipelines are named XXX_planning_pipeline.launch  -->

  <arg name="pipeline" default="ompl" />
  <arg name="arm_id" default="panda" />

  <include ns="$(arg pipeline)" file="$(dirname)/$(arg pipeline)_planning_pipeline.launch.xml" pass_all_args="true"/>

</launch>

pipelineFor example, when the omplparameter passed in is , start the corresponding file, which makes it easy to manage ompl_planning_pipeline.launch.xmldifferent planning libraries , and call them exclusively through .planning_pipeline.launch.xmlplanning_pipeline.launch.xml
Insert image description here

Slice parsing 6: ompl_planning_pipeline.launch.xml

<launch>

    <!-- The request adapters (plugins) used when planning with OMPL. ORDER MATTERS! -->
    <arg name="planning_adapters"
         default="default_planner_request_adapters/AddTimeParameterization
                  default_planner_request_adapters/ResolveConstraintFrames
                  default_planner_request_adapters/FixWorkspaceBounds
                  default_planner_request_adapters/FixStartStateBounds
                  default_planner_request_adapters/FixStartStateCollision
                  default_planner_request_adapters/FixStartStatePathConstraints"
                  />
  
    <arg name="start_state_max_bounds_error" default="0.1" />
    <arg name="jiggle_fraction" default="0.05" />
    <arg name="arm_id" default="panda" />
  
    <param name="planning_plugin" value="ompl_interface/OMPLPlanner" />
    <param name="request_adapters" value="$(arg planning_adapters)" />
    <param name="start_state_max_bounds_error" value="$(arg start_state_max_bounds_error)" />
    <param name="jiggle_fraction" value="$(arg jiggle_fraction)" />
  
    <!-- Add MoveGroup capabilities specific to this pipeline -->
    <!-- <param name="capabilities" value="" /> -->
  
    <rosparam command="load" file="$(find panda_moveit_config)/config/ompl_planning.yaml" subst_value="true"/>
  
  </launch>

Planning adapter plug-in

    <!-- The request adapters (plugins) used when planning with OMPL. ORDER MATTERS! -->
    <arg name="planning_adapters"
         default="default_planner_request_adapters/AddTimeParameterization
                  default_planner_request_adapters/ResolveConstraintFrames
                  default_planner_request_adapters/FixWorkspaceBounds
                  default_planner_request_adapters/FixStartStateBounds
                  default_planner_request_adapters/FixStartStateCollision
                  default_planner_request_adapters/FixStartStatePathConstraints"
                  />

A parameter called planning_adapters is defined and a default value is set for it. This default value is a list.

In MoveIt, planning adapters refer to specific plug-ins that modify planning requests and planning responses before the planning request is sent to the planner and after the planner generates the path .

In the above code, planning_adaptersthe parameters include six default adapters, which are responsible for handling different types of problems. For example, AddTimeParameterizationit is used to add a time parameter to the planned trajectory, because most planners only care about space and not time.
Other adapters such as FixWorkspaceBounds, FixStartStateBounds, FixStartStateCollision, FixStartStatePathConstraintsand ResolveConstraintFramesetc. are respectively used to correct the workspace boundary, correct the start state boundary, correct the start state collision, correct the start state path constraints and solve the constraint frame problem.

Other parameters

<arg name="start_state_max_bounds_error" default="0.1" />
# 机器人开始状态的最大边界错误
# 默认值被设置为0.1

During the motion planning process, the current state of the robot is its starting state.
Due to sensor errors and other uncertainties, there may be some gaps between this starting state and the actual state of the robot. This parameter is used to limit this gap. If it exceeds this value, MoveIt will try to repair the starting state so that it meets this boundary error requirement.

<arg name="jiggle_fraction" default="0.05" />
# 开始状态调整时所允许的最大变化幅度
# 默认值被设置为0.05

This parameter is very important when repairing the starting state.
If for some reason, the robot's starting state does not meet the motion planning requirements (for example, the robot's starting state is in a collision state), MoveIt will try to fine-tune ("jiggle") the robot's joints so that the robot's starting state meets the planned motion requirements. Require.
This parameter indicates the maximum change allowed for each joint during this fine-tuning process, expressed as a percentage of the joint's range of motion.
For example, if set to 0.01, then during fine-tuning, the angle of each joint can only change within 1% of its range of motion.

<arg name="arm_id" default="panda" />
# 机械臂id,用于指定运动规划所涉及的机器臂

Parameters loaded into the ROS parameter server

<param name="planning_plugin" value="ompl_interface/OMPLPlanner" />
# 设置ROS参数planning_plugin的值为ompl_interface/OMPLPlanner
# 这表示运动规划将使用OMPL库进行
<param name="request_adapters" value="$(arg planning_adapters)" />
<param name="start_state_max_bounds_error" value="$(arg start_state_max_bounds_error)" />
<param name="jiggle_fraction" value="$(arg jiggle_fraction)" />
# 将之前设置的arg参数值作为值填入这几个ROS参数服务器的参数
<rosparam command="load" file="$(find panda_moveit_config)/config/ompl_planning.yaml" subst_value="true"/>
# 加载ompl_planning.yaml文件
# 该文件包含了用于OMPL运动规划库的具体参数配置

Slice analysis 7: trajectory_execution.launch.xml

trajectory_execution.launch.xmlConfigure some parameters of motion trajectory execution

<launch>
    <!-- This file summarizes all settings required for trajectory execution  -->
  
    <!-- Define moveit controller manager plugin: fake, simple, or ros_control -->
    <arg name="moveit_controller_manager" />
    <arg name="fake_execution_type" default="interpolate" />
  
    <!-- Flag indicating whether MoveIt is allowed to load/unload  or switch controllers -->
    <arg name="moveit_manage_controllers" default="true"/>
    <param name="moveit_manage_controllers" value="$(arg moveit_manage_controllers)"/>
  
    <!-- When determining the expected duration of a trajectory, this multiplicative factor is applied to get the allowed duration of execution -->
    <param name="trajectory_execution/allowed_execution_duration_scaling" value="1.2"/> <!-- default 1.2 -->
    <!-- Allow more than the expected execution time before triggering a trajectory cancel (applied after scaling) -->
    <param name="trajectory_execution/allowed_goal_duration_margin" value="0.5"/> <!-- default 0.5 -->
    <!-- Allowed joint-value tolerance for validation that trajectory's first point matches current robot state -->
    <param name="trajectory_execution/allowed_start_tolerance" value="0.01"/> <!-- default 0.01 -->
  
    <!-- We use pass_all_args=true here to pass fake_execution_type, which is required by fake controllers, but not by real-robot controllers.
         As real-robot controller_manager.launch files shouldn't be required to define this argument, we use the trick of passing all args. -->
    <include file="$(dirname)/$(arg moveit_controller_manager)_moveit_controller_manager.launch.xml" pass_all_args="true" />
  
  </launch>

controller manager

    <!-- Define moveit controller manager plugin: fake, simple, or ros_control -->
<arg name="moveit_controller_manager" />
# moveit_controller_manager参数用于指定MoveIt!控制器管理器插件的名称
# 可选的值为:fake, simple, or ros_control

The controller managers provided by MoveIt include the following three types:

  1. fake: This type of controller only simulates movement and does not communicate with the real robot. It is often used for quick testing and demonstrations, and for simulation, fake controllers are often used to simulate motion.

  2. simple: This type of controller communicates with the robot but only provides basic control such as linear/arc interpolation, etc. It works well for some simpler robots.

  3. ros_control: This is a more flexible controller type that supports a variety of robot and controller hardware. It provides higher-level control interfaces, such as motor controller interfaces and sensor reading interfaces.
    Different types of controller managers are used depending on the application scenario and the requirements of the robot.
    ros_control is a powerful controller for robots. Please refer to the ros_control WIKI document and ros_control source code.

Virtual Controller Execution Mode

<arg name="fake_execution_type" default="interpolate" />
  # fake_execution_type:设置虚拟控制器的执行模式。
  # 如果选择“fake”控制器管理器,则使用虚拟控制器进行模拟运动。
  # 此参数指定用于虚拟运动的执行模式,包括“interpolate”,“last point。默认值为“interpolate”。

interpolate: This option indicates that MoveIt assumes that the controller will interpolate between each target point of the trajectory. This method can simulate the continuous trajectory execution process.

last point: This option indicates that MoveIt assumes the controller will jump directly to the last target point of the trajectory. This method can simulate robots performing tasks quickly. Two descriptions were found in the document, and it is uncertain whether there is a third one
that matches the description in the official documentation . However, there is a detailed description in the Moveit official document . Please refer to the Moveit1 Noetic official document.launch/fake_moveit_controller_manager.launch.xmlvia pointsfake controller
fake controller

MoveIt provides a range of virtual track controllers that can be used in simulations. Among them, the configuration file of the virtual controller is located config/fake_controllers.yaml.

The following controller types can be adjusted as needed:

  • interpolate: Performs smooth interpolation across key points, default for visualization.
  • via points: Traverse key points without interpolating points between them, used for visual debugging.
  • last point: Jump directly to the last point of the trajectory for offline benchmarking.

Virtual controller type information is fake_controllers.yamlconfigurable in the file. For each controller, you need to specify the name, type, and involved joints. where the frequency is rate: 10, which can be used in the interpolation controller. But when controlling the gripper, the joints are an empty list [].

Example:

rate: 10
controller_list:
  - name: fake_arm_controller
    type: interpolate
    joints:
      - joint_1
      - joint_2
      - joint_3
      - joint_4
      - joint_5
      - joint_6
  - name: fake_gripper_controller
    joints:
      []

Administrative rights of controllers

    <!-- Flag indicating whether MoveIt is allowed to load/unload  or switch controllers -->
    <arg name="moveit_manage_controllers" default="true"/>
    <param name="moveit_manage_controllers" value="$(arg moveit_manage_controllers)"/>

move_gruop.launchThe parameter in is moveit_manage_controllersset to true, indicating that MoveIt manages the controller.
This parameter is then passed to trajectory_execution.launch.xml, where a parameter is defined and set as a ROS parameter named moveit_manage_controllers with a default value of "true".
When this parameter is "true", MoveIt will have permission to load/unload or switch controllers .
Different tasks or different stages of a task may require the use of different controllers. For example, one controller might be used for precise position control while another might be used for force control. By dynamically switching controllers, MoveIt! can better adapt to different task requirements.
Therefore, this option is usually required when running on a real robot or an emulator using ros_control.

Limiting parameters for trajectory execution

<!-- When determining the expected duration of a trajectory, this multiplicative factor is applied to get the allowed duration of execution -->
<param name="trajectory_execution/allowed_execution_duration_scaling" value="1.2"/> <!-- default 1.2 -->

allowed_execution_duration_scalingThe parameter is the scaling factor of the allowed motion trajectory execution time, and the default value is 1.2. This parameter is used to multiply the scaling factor when calculating the expected time of the motion trajectory to obtain the allowed execution time.

<!-- Allow more than the expected execution time before triggering a trajectory cancel (applied after scaling) -->
<param name="trajectory_execution/allowed_goal_duration_margin" value="0.5"/> <!-- default 0.5 -->

allowed_goal_duration_marginThe parameter is the tolerance range of the allowed motion trajectory execution time, and the default value is 0.5 seconds. If the trajectory execution time exceeds the expected time plus this tolerance range, then the trajectory cancellation operation will be triggered.

<!-- Allowed joint-value tolerance for validation that trajectory's first point matches current robot state -->
<param name="trajectory_execution/allowed_start_tolerance" value="0.01"/> <!-- default 0.01 -->

allowed_start_toleranceThe parameter is the tolerance range of joint values ​​allowed for the starting point of the motion trajectory. The default value is 0.1. MoveIt! will check whether the starting point of the trajectory matches the current status of the robot. If the difference exceeds this tolerance range, the trajectory will be considered illegal.

Controller manager startup file call

    <!-- We use pass_all_args=true here to pass fake_execution_type, which is required by fake controllers, but not by real-robot controllers.
         As real-robot controller_manager.launch files shouldn't be required to define this argument, we use the trick of passing all args. -->
    <include file="$(dirname)/$(arg moveit_controller_manager)_moveit_controller_manager.launch.xml" pass_all_args="true" />

moveit_controller_managerdemo.launchSpecified in , fakepassed pass_all_args="true"to move_group.launch, overrides the move_group.launchdefault moveit_controller_managerparameter value in simple, and then move_group.launchpassed pass_all_args="true"to trajectory_execution.launch.xml, trajectory_execution.launch.xmlused to select the controller type specified by the parameter.

For example, if moveit_controller_managerthe parameter is fake, the file will be called fake_moveit_controller_manager.launch.xml.
Insert image description here

Slice analysis 8: fake_moveit_controller_manager.launch.xml

fake_moveit_controller_manager.launch.xmlIt is called in trajectory_execution.launch.xmlbecause moveit_controller_managerthe parameter is fake, so fake_moveit_controller_manager.launch.xmlit is selected among the three controller managers (fake, simple, ros_control).

It is used to start an emulated controller.

<launch>

    <!-- execute the trajectory in 'interpolate' mode or jump to goal position in 'last point' mode -->
    <arg name="fake_execution_type" default="interpolate" />
  
    <!-- Set the param that trajectory_execution_manager needs to find the controller plugin -->
    <param name="moveit_controller_manager" value="moveit_fake_controller_manager/MoveItFakeControllerManager"/>
  
    <!-- The rest of the params are specific to this plugin -->
    <rosparam subst_value="true" file="$(find panda_moveit_config)/config/fake_controllers.yaml"/>
  
  </launch>

subst_value="true"The function is to replace the path in the launch file. When subst_valueis set to , the launch file will replace truein its path with the actual ROS package path before loading the parameter file . By default, if the attribute is not provided, the rosparam element will perform the action of$(find panda_moveit_config)
commandcommand="load"

Virtual Controller Execution Mode

    <!-- execute the trajectory in 'interpolate' mode or jump to goal position in 'last point' mode -->
    <arg name="fake_execution_type" default="interpolate" />
# fake_execution_type参数的值决定了执行轨迹的方式
# "interpolate"表示在模拟环境中,机器人会执行完整的轨迹
# 如果值设置为"last point",那么机器人将直接跳到目标位置。

Controller manager parameters for ROS parameter server

    <!-- Set the param that trajectory_execution_manager needs to find the controller plugin -->
    <param name="moveit_controller_manager" value="moveit_fake_controller_manager/MoveItFakeControllerManager"/>
# 设置ROS参数moveit_controller_manager
# 值为moveit_fake_controller_manager/MoveItFakeControllerManager
# 这个参数是用于指定控制器管理器的插件名称,这里使用的是MoveIt提供的虚拟控制器

Load fake_controllers.yaml to parameter server

    <!-- The rest of the params are specific to this plugin -->
    <rosparam subst_value="true" file="$(find panda_moveit_config)/config/fake_controllers.yaml"/>
# 加载了/config/fake_controllers.yaml配置文件
# 这个YAML文件包含了模拟控制器的配置信息

subst_value="true"The function is to replace the path in the launch file. When subst_valueis set to , the launch file will replace truein its path with the actual ROS package path before loading the parameter file . By default, if the attribute is not provided, the rosparam element will perform the action of$(find panda_moveit_config)
commandcommand="load"

config/fake_controllers.yaml

controller_list:
  - name: fake_$(arg arm_id)_arm_controller
    type: $(arg fake_execution_type)
    joints:
      - $(arg arm_id)_joint1
      - $(arg arm_id)_joint2
      - $(arg arm_id)_joint3
      - $(arg arm_id)_joint4
      - $(arg arm_id)_joint5
      - $(arg arm_id)_joint6
      - $(arg arm_id)_joint7

  - name: fake_$(arg arm_id)_hand_controller
    type: $(arg fake_execution_type)
    joints:
      - $(arg arm_id)_finger_joint1

initial:  # Define initial robot poses per group
  - group: $(arg arm_id)_arm
    pose: ready
  - group: $(arg arm_id)_hand
    pose: open

fake_controllers.yamlThe file defines some virtual controllers and initial robot poses for motion planning and control in ROS MoveIt.

  1. controller_list: This is a controller list with two virtual controllers defined, namely fake_$(arg arm_id)_arm_controllerand fake_$(arg arm_id)_hand_controller. These controllers are used to simulate motion control of robots.

    • name: The name of the controller, which contains $(arg arm_id)parameter replacement, that is, different controller names are dynamically generated according to the actual parameter values.
    • type: The type of controller, which contains $(arg fake_execution_type)the parameter replacement, that is, dynamically sets different controller types according to the actual parameter value.
    • joints: The list of joints controlled by the controller, which contains $(arg arm_id)parameter replacement, that is, different joint names are dynamically generated according to the actual parameter values.
  2. initial: This is a list of initial robot poses, defining the starting state of the robot. In this example, two initial poses are defined, namely $(arg arm_id)_armand $(arg arm_id)_hand.

    • group: The robot group to which the posture belongs, which contains $(arg arm_id)parameter replacement, that is, different robot group names are dynamically generated based on the actual parameter values.
    • pose: The name of the posture, indicating the status of the robot. In this example, are readyand , respectively open.

The specific content of this file is dynamically generated according to the actual parameter value, and the value of the parameter depends on the configuration at runtime. By using these virtual controllers and initial poses, robots with different joints and groups can be simulated and controlled in ROS MoveIt.

Slice analysis 9: sensor_manager.launch.xml

This startup file is responsible for initializing the sensor manager, including loading sensor types, setting Octomap parameters, setting the maximum detection distance of the sensor, and contains the startup file of the sensor manager for a specific robot (Panda)

<launch>

    <!-- This file makes it easy to include the settings for sensor managers -->
  
    <!-- Params for 3D sensors config: '' | pointcloud | depthmap -->
    <arg name="sensor_type" default="" />
    <rosparam if="$(eval arg('sensor_type')  != '')" command="load" file="$(find panda_moveit_config)/config/sensors_kinect_$(arg sensor_type).yaml" />
  
    <!-- Params for the octomap monitor -->
    <!--  <param name="octomap_frame" type="string" value="some frame in which the robot moves" /> -->
    <param name="octomap_frame" type="string" value="camera_rgb_optical_frame" />
    <param name="octomap_resolution" type="double" value="0.025" />
    <param name="max_range" type="double" value="5.0" />
  
    <!-- Load the robot specific sensor manager; this sets the moveit_sensor_manager ROS parameter -->
    <arg name="moveit_sensor_manager" default="panda" />
    <include file="$(dirname)/$(arg moveit_sensor_manager)_moveit_sensor_manager.launch.xml" />
  
  </launch>

Load sensors to ROS parameter server

    <!-- Params for 3D sensors config: '' | pointcloud | depthmap -->
    <arg name="sensor_type" default="" />
    <rosparam if="$(eval arg('sensor_type')  != '')" command="load" file="$(find panda_moveit_config)/config/sensors_kinect_$(arg sensor_type).yaml" />
# 通过设置"sensor_type"的参数来设定使用的传感器类型
# 支持的传感器类型为depthmap、空和pointcloud
# 其默认值为空
# 如果默认值不为空将载入对应的sensors_kinect_$(arg sensor_type).yaml到ROS参数服务器

Insert image description here

config/sensors_kinect_depthmap.yaml

Take calling sensors_kinect_depthmap.yamlas an example

sensors:
  - sensor_plugin: occupancy_map_monitor/DepthImageOctomapUpdater
    image_topic: /camera/depth_registered/image_raw
    queue_size: 5
    near_clipping_plane_distance: 0.3
    far_clipping_plane_distance: 5.0
    shadow_threshold: 0.2
    padding_scale: 4.0
    padding_offset: 0.03
    max_update_rate: 1.0
    filtered_cloud_topic: filtered_cloud
    ns: kinect

YAMLIt is a data serialization format that is highly readable and suitable for scenarios such as configuration files, exchanging data, defining languages, or serializing objects. Its syntax is designed to be easy to read and write.
In YAML, spaces must be used for indentation, not tabs. Elements at the same level must have the same indentation.

  • -Symbol: Indicates the beginning of a list item. In this file, - sensor_plugin: occupancy_map_monitor/DepthImageOctomapUpdaterthe value corresponding to the key "sensors" is a list starting with one element of the list. The content after -represents the content of this list element.

This YAML file is used to configure the Kinect, the depth image sensor used by the Panda robotic arm in ROS MoveIt.

  1. sensor_plugin: occupancy_map_monitor/DepthImageOctomapUpdater

    This line specifies the plugin that handles sensor data. Use the plugin here occupancy_map_monitor/DepthImageOctomapUpdaterto update Octomap. Octomap is a 3D grid map consisting of occupied, free and unknown cells, used for robot environment perception and navigation.

  2. image_topic: /camera/depth_registered/image_raw

    This line defines the topic name of the depth image. Topics are the way messaging is implemented in ROS, subscribe to /camera/depth_registered/image_rawtopics to receive depth images.

  3. queue_size: 5

    This line sets the size of the message queue. Here, if there are 5 messages waiting to be processed, /camera/depth_registered/image_rawthe new messages coming from will be discarded.

  4. near_clipping_plane_distance: 0.3

    This line sets the near clipping plane distance, which is the closest boundary of the valid area of ​​the depth image. Data smaller than this distance will be ignored.

  5. far_clipping_plane_distance: 5.0

    This line sets the far clipping plane distance, which is the furthest boundary of the valid area of ​​the depth image. Data larger than this distance will be ignored.

  6. shadow_threshold: 0.2

    This line sets the shadow threshold. This value is used to determine whether a pixel is in the shadow of another pixel. The smaller the threshold, the more shadows are detected.

  7. padding_scale: 4.0 and padding_offset: 0.03

    These two lines set the padding for the depth image. Padding is a processing method used to increase the space around an object to avoid collisions between the robot and the object.

  8. max_update_rate: 1.0

    This line sets the maximum update rate. Here, the processing speed of depth images is limited to at most once per second.

  9. filtered_cloud_topic: filtered_cloud

    This line defines the topic name of the filtered point cloud data. The processed depth images are converted into point clouds and published to this topic.

  10. ns: kinect

    This line sets the namespace (Namespace), in this case kinect. Namespaces are used to organize ROS topics, services, etc., making them easier to manage and locate in complex systems.

Overall, this YAML file defines some key configurations of the depth image sensor so that MoveIt can correctly process and use depth image data.

config/sensors_kinect_pointcloud.yaml

sensors:
  - sensor_plugin: occupancy_map_monitor/PointCloudOctomapUpdater
    point_cloud_topic: /camera/depth_registered/points
    max_range: 5.0
    point_subsample: 1
    padding_offset: 0.1
    padding_scale: 1.0
    max_update_rate: 1.0
    filtered_cloud_topic: filtered_cloud
    ns: kinect

This YAML file is used to configure the point cloud sensor of ROS MoveIt, specifically the configuration of the Kinect device. Below is a detailed explanation of these parameters:

  1. sensor_plugin: occupancy_map_monitor/PointCloudOctomapUpdater

    This line specifies plugins that process sensor data. Plugins are used here occupancy_map_monitor/PointCloudOctomapUpdaterto update Octomap based on point cloud data. Octomap is a 3D grid map for environmental perception and navigation of robots.

  2. point_cloud_topic: /camera/depth_registered/points

    This line defines the topic name of the point cloud data. Topics are the way to implement message passing in ROS. Here you subscribe to /camera/depth_registered/pointstopics to receive point cloud data.

  3. max_range: 5.0

    This line sets the maximum detection distance of the sensor, the value is 5.0, and the unit is usually meters. Objects beyond this distance will not be detected by the sensor.

  4. point_subsample: 1

    This line sets the sampling rate of the point cloud. Here it is set to 1, which means that every point will be sampled. If set to a value greater than 1, such as 10, then only one point in every 10 points will be sampled.

  5. padding_offset: 0.1 and padding_scale: 1.0

    These two lines set the filling of the point cloud. Padding is a processing method used to increase the space around an object to avoid collisions between the robot and the object.

  6. max_update_rate: 1.0

    This line sets the maximum update rate. Here, point cloud processing speed is limited to at most once per second.

  7. filtered_cloud_topic: filtered_cloud

    This line defines the topic name of the filtered point cloud data. The processed point cloud data will be published to this topic.

The difference between point cloud and depth map

Depth images and point clouds are both data structures that describe objects in three-dimensional space. Depth cameras can generate both depth images and point clouds. However, the processing methods and uses of depth images and point clouds are different. Which data structure to choose? Depends on your specific needs.

The depth image is a two-dimensional array, and the value of each element represents the distance from the pixel to the camera. Depth images are generated by depth cameras, such as devices such as Kinect or Intel RealSense, by measuring the depth information of each pixel. It provides a single depth value for each pixel, which together form a depth map. The advantage of the depth map is that the data structure is simple and easy to process and store, but it may not be accurate enough for some complex 3D spatial expressions.

Insert image description here
Picture from microsoft kinect

A point cloud is a collection of points distributed in three-dimensional space, and each point contains its spatial coordinates (X, Y, Z). Point clouds are usually generated by LiDAR or depth cameras. Compared with depth images, point clouds more directly represent the structure of three-dimensional space and can better handle complex three-dimensional geometric problems. However, the amount of data is large and the processing complexity is high.
Insert image description here

Picture from researchgate

Depending on the hardware configuration and task requirements of the robot system, you may choose to use depth images or point clouds. If you have a depth camera in your system and the task requires fast processing and small data volumes, then using depth images may be more appropriate. config/sensors_kinect_depthmap.yamlConfiguration files should be used .

If you have lidar in your system or require an accurate representation of three-dimensional space, point clouds may be a better choice. config/sensors_kinect_pointcloud.yamlConfiguration files should be used .

    <!-- Params for the octomap monitor -->
    <!--  <param name="octomap_frame" type="string" value="some frame in which the robot moves" /> -->
    <param name="octomap_frame" type="string" value="camera_rgb_optical_frame" />
# 定义了Octomap的参考坐标系。Octomap是一种用于机器人3D感知的数据结构
# 这里将它的参考坐标系设为了"camera_rgb_optical_frame"
# 这个参考坐标系通常是由RGB相机提供的

Every sensor reading or robot movement must be related to a specific reference frame.

These Frames are connected together to form a Frames tree, which is the basis for the robot to perceive its own position and external environment in the real world.

Here, octomap_frame is the reference coordinate system used by Octomap.
The value of this parameter camera_rgb_optical_framemay be the coordinate system of the Kinect camera sensor, which defines the position and orientation of the camera.

OctomapOctreeIt is a data structure used for 3D environment modeling and an application of octree . Octomap can create and update models of 3D environments through sensor data (such as depth cameras, lidar, etc.).
In Octomap, the environment is divided into cubic cells, and each cell can store information about the space, such as whether it is occupied (i.e., there is an object present).
OctomapIt is a sparse data structure. Cells are only created in areas where objects exist or are detected by sensors. This means that it only stores data where objects exist, making memory usage more efficient and efficient. Large scale environment.
Octree is often compared Octreewith other space division structures such as kd树binary space division tree ( BSP tree), quadtree ( , two-dimensional version), etc. QuadtreeThe following are some advantages and disadvantages of octrees compared to other spatial data structures:
Advantages:

  1. Space efficiency : Octrees help reduce memory usage. It achieves spatial efficiency by creating finer divisions in areas of space that require detailed description (for example, where objects are) and using coarser divisions in open or uniform areas.

  2. Query efficiency : When processing spatial queries (such as range search, nearest neighbor search, etc.), octree can provide higher efficiency. This is because it can quickly exclude large areas that are unlikely to contain query results.

  3. Layered and multi-resolution representation : The hierarchical characteristics of the octree enable it to support layered and multi-resolution spatial representation, which is very useful in many applications, such as LOD (Level of Detail) rendering and collision detection. , path planning, etc.

shortcoming:

  1. Build and update overhead : Building and updating octrees can incur some computational overhead, especially in dynamic environments. Because every time an object moves or the scene changes, the octree may need to be rebuilt or updated.

  2. Not suitable for processing specific patterns of data : For some specific patterns of data, such as highly flattened data or linearly distributed data, octrees may not be as efficient as other structures such as kd trees or BSP trees.

  3. Unbalanced partitioning : Since the octree is divided evenly, when processing some data with extremely uneven spatial distribution, the structure of the tree may be very unbalanced, which may affect query efficiency.

    <param name="octomap_resolution" type="double" value="0.025" />
# 设定了Octomap的分辨率,值为0.025,一般单位是米。
# 这个值决定了Octomap中每个voxel体素的大小

Voxel ( Volume Pixel) A voxel is a unit that represents data in three-dimensional space, similar to a pixel ( ) in a two-dimensional image Pixel. A Voxel represents a small cubic area in 3D space. In Octomap, each Voxel is a cell, which can store information about this small area, such as whether this area is occupied. The size of the Voxel (that is, the side length of the cube) determines the resolution of the 3D model: the smaller the Voxel, the richer the details it can represent, but it also requires more computing resources and storage space.

<param name="max_range" type="double" value="5.0" />
# 设定了传感器的最大探测距离,值为5.0,单位也通常是米
# 超过这个距离的物体将被屏蔽

Launch robotname_moveit_sensor_manager.launch.xml

The sensor-related startup files for the specific robot <arg name="moveit_sensor_manager" default="panda" />determined by the parameters will be called.

    <!-- Load the robot specific sensor manager; this sets the moveit_sensor_manager ROS parameter -->
    <arg name="moveit_sensor_manager" default="panda" />
    <include file="$(dirname)/$(arg moveit_sensor_manager)_moveit_sensor_manager.launch.xml" />

panda_moveit_sensor_manager.launch.xml

There is no content, this is sensor_manager.launch.xmlfor the specific bot called inpanda_moveit_sensor_manager.launch.xml

<launch>
</launch>

Slice parsing 10: moveit_rviz.launch

This particular launch file is used to start RViz.

<launch>

  <arg name="debug" default="false" />
  <arg unless="$(arg debug)" name="launch_prefix" value="" />
  <arg     if="$(arg debug)" name="launch_prefix" value="gdb --ex run --args" />

  <!--Retrieve the right rviz config file-->
  <arg name="rviz_tutorial" default="false" />
  <arg name="rviz_config" default="$(dirname)/moveit.rviz" />

  <arg if="$(eval rviz_config=='')" name="command_args" value="" />
  <arg if="$(eval rviz_config!='' and not rviz_tutorial)" name="command_args" value="-d $(arg rviz_config)" />
  <arg if="$(eval rviz_tutorial)" name="command_args" value="-d $(dirname)/moveit_empty.rviz" />

  <node name="$(anon rviz)" launch-prefix="$(arg launch_prefix)" pkg="rviz" type="rviz" respawn="false"
        args="$(arg command_args)" output="screen">
  </node>

</launch>

debug settings

  <arg name="debug" default="false" />
  <arg unless="$(arg debug)" name="launch_prefix" value="" />
  <arg     if="$(arg debug)" name="launch_prefix" value="gdb --ex run --args" />
# 定义了一个参数debug,默认值为false
# 该值从demo.launch中通过pass_all_args="true"继承给moveit_rviz.launch
# 如果不debug就正常启动,launch_prefix=""
# 如果要debug就将launch_prefix设置为gdb --ex run --args

If debugit is true, launch_prefixthe value will be gdb --ex run --args, which will cause the launch file to run in the GDB (GNU debugger) environment for easy debugging. Otherwise, launch_prefixempty.

RViz configuration

  <!--Retrieve the right rviz config file-->
  <arg name="rviz_tutorial" default="false" />
  <arg name="rviz_config" default="$(dirname)/moveit.rviz" />

rviz_tutorialThe default value of the parameter is false, which is used to turn on the RViz teaching mode (load an empty RViz configuration file).
This parameter is inherited demo.launchinpass_all_args="true"moveit_rviz.launch

rviz_configmoveit.rvizThe default value is the file in the current directory . .rvizThe file ending with is the RViz configuration file, which is used to set the display parameters of RViz. It can also be in.

Panels:
  - Class: rviz/Displays
    Help Height: 84
    Name: Displays
    Property Tree Widget:
      Expanded:
        - /MotionPlanning1
      Splitter Ratio: 0.5
    Tree Height: 226
  - Class: rviz/Help
    Name: Help
  - Class: rviz/Views
    Expanded:
      - /Current View1
    Name: Views
    Splitter Ratio: 0.5
Visualization Manager:
  Class: ""
  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
    - Class: moveit_rviz_plugin/MotionPlanning
      Enabled: true
      Name: MotionPlanning
      Planned Path:
        Links: ~
        Loop Animation: true
        Robot Alpha: 0.5
        Show Robot Collision: false
        Show Robot Visual: true
        Show Trail: false
        State Display Time: 0.05 s
        Trajectory Topic: move_group/display_planned_path
      Planning Metrics:
        Payload: 1
        Show Joint Torques: false
        Show Manipulability: false
        Show Manipulability Index: false
        Show Weight Limit: false
      Planning Request:
        Colliding Link Color: 255; 0; 0
        Goal State Alpha: 1
        Goal State Color: 250; 128; 0
        Interactive Marker Size: 0
        Joint Violation Color: 255; 0; 255
        Query Goal State: true
        Query Start State: false
        Show Workspace: false
        Start State Alpha: 1
        Start State Color: 0; 255; 0
      Planning Scene Topic: move_group/monitored_planning_scene
      Robot Description: robot_description
      Scene Geometry:
        Scene Alpha: 1
        Show Scene Geometry: true
        Voxel Coloring: Z-Axis
        Voxel Rendering: Occupied Voxels
      Scene Robot:
        Attached Body Color: 150; 50; 150
        Links: ~
        Robot Alpha: 0.5
        Show Scene Robot: true
      Value: true
  Enabled: true
  Global Options:
    Background Color: 48; 48; 48
    Fixed Frame: panda_link0
  Name: root
  Tools:
    - Class: rviz/Interact
      Hide Inactive Objects: true
    - Class: rviz/MoveCamera
    - Class: rviz/Select
  Value: true
  Views:
    Current:
      Class: rviz/Orbit
      Distance: 2.0
      Enable Stereo Rendering:
        Stereo Eye Separation: 0.06
        Stereo Focal Distance: 1
        Swap Stereo Eyes: false
        Value: false
      Field of View: 0.75
      Focal Point:
        X: -0.1
        Y: 0.25
        Z: 0.30
      Focal Shape Fixed Size: true
      Focal Shape Size: 0.05
      Invert Z Axis: false
      Name: Current View
      Near Clip Distance: 0.01
      Pitch: 0.5
      Target Frame: panda_link0
      Yaw: -0.6232355833053589
    Saved: ~
Window Geometry:
  Displays:
    collapsed: false
  Height: 848
  Help:
    collapsed: false
  Hide Left Dock: false
  Hide Right Dock: false
  MotionPlanning:
    collapsed: false
  MotionPlanning - Trajectory Slider:
    collapsed: false
  QMainWindow State: 000000ff00000000fd0000000100000000000001f0000002f6fc0200000007fb000000100044006900730070006c006100790073010000003d00000173000000c900fffffffb0000000800480065006c00700000000342000000bb0000006e00fffffffb0000000a00560069006500770073000000010c000000a4000000a400fffffffb0000000c00430061006d00650072006100000002ff000001610000000000000000fb0000001e004d006f00740069006f006e00200050006c0061006e006e0069006e00670100000374000001890000000000000000fb00000044004d006f00740069006f006e0050006c0061006e006e0069006e00670020002d0020005400720061006a006500630074006f0072007900200053006c00690064006500720000000000ffffffff0000001600000016fb0000001c004d006f00740069006f006e0050006c0061006e006e0069006e006701000001b60000017d0000017d00ffffff00000315000002f600000001000000020000000100000002fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000
  Views:
    collapsed: false
  Width: 1291
  X: 454
  Y: 25

moveit.rvizThe file contains a series of panels, displays and views. The panel is the interface element of RViz, the display is the element used to display data in the 3D environment, and the view is the parameter that controls the observation point of the 3D environment.

Selection of RViz configuration files

 <arg if="$(eval rviz_config=='')" name="command_args" value="" />
  <arg if="$(eval rviz_config!='' and not rviz_tutorial)" name="command_args" value="-d $(arg rviz_config)" />
  <arg if="$(eval rviz_tutorial)" name="command_args" value="-d $(dirname)/moveit_empty.rviz" />

parameters command_args. Its value depends on rviz_configthe value of and rviz_tutorialthe value of the parameter. If rviz_configit is empty, that is, the configuration file does not exist, command_argsit will be empty.
If rviz_configit is not empty and rviz_tutorialis false, that is, the configuration file exists, but the enlightenment mode is not turned on, then command_argsthe value is -d $(arg rviz_config), which will rvizload the specified rviz configuration file.
If the value rviz_tutorialis true, an empty rviz configuration file is loaded.command_args-d $(dirname)/moveit_empty.rviz

Start RViz

  <node name="$(anon rviz)" launch-prefix="$(arg launch_prefix)" pkg="rviz" type="rviz" respawn="false"
        args="$(arg command_args)" output="screen">

Node names are $(anon rviz)generated by , which generates a unique, anonymous node name. launch-prefixIt is the parameter defined before launch_prefixthat determines whether to start this node with GDB debugging.

anonIt is a special command of ROS that is used to ensure that each node started has a unique name, so that multiple such nodes can be started simultaneously in the same ROS system without errors caused by conflicting node names.

Regarding , this part is just a prefix, and ROS will append a unique string after the character to generate the node name $(anon rviz). This was chosen as a prefix to make the generated name more readable and to make it clear that the node is related to.rvizrvizrvizrviz

For example, use $(anon rviz)may generate the following node names: rviz_25742_1546445566103. In this name, rvizit is the specified prefix, and the following number is automatically generated by ROS to ensure the uniqueness of the name.

pkgand typerepresent the ROS package name and type name respectively, here are rviz.
respawnThe parameter is set to false, which means that if the rviz node stops, it will not restart automatically.
argsIt is a previously defined command_argsparameter, which specifies that the command line parameter when rviz starts is empty or moveit.rvizor moveit_empty.rviz.
outputThe parameter is set to screen, indicating that the output of rviz will be sent to the console.

Slice parsing 11: demo_gazebo.launch

Insert image description here
The file name robot_moveit_config/launch/demo_gazebo.launchis Moveit's classic demo. The robot model is displayed in RViz and MotionPlanningMoveit is controlled through the RViz plug-in to complete motion planning and trajectory control. At the same time, joint simulation is performed in Gazebo to simulate the control of a real robotic arm.
Insert image description here

The following is the complete code of Moveit’s official case panda_moveit_config/launch/demo_gazebo.launch:

<launch>
  <!-- specify the planning pipeline -->
  <arg name="pipeline" default="ompl" />

  <!-- Panda specific options -->
  <arg name="load_gripper" default="true" />
  <arg name="transmission" default="effort" />

  <!-- Gazebo specific options -->
  <arg name="gazebo_gui" default="true" />
  <arg name="paused" default="false" />

  <!-- Launch the gazebo simulator and spawn the robot -->
  <include file="$(find franka_gazebo)/launch/panda.launch" pass_all_args="true">
    <arg name="headless" value="$(eval not arg('gazebo_gui'))" />
    <arg name="use_gripper" default="$(arg load_gripper)" />
    <arg name="controller" default="$(arg transmission)_joint_trajectory_controller" />
  </include>

  <include file="$(dirname)/demo.launch" pass_all_args="true">
    <!-- robot description is loaded by gazebo.launch, to enable Gazebo features -->
    <arg name="load_robot_description" value="false" />
    <!-- MoveItSimpleControllerManager provides ros_control's JointTrajectory controllers
         as well as GripperCommand actions -->
    <arg name="moveit_controller_manager" value="simple" />
  </include>
</launch>

Slice analysis is as follows:

Motion planning pipeline

  <!-- specify the planning pipeline -->
  <arg name="pipeline" default="ompl" />
# 设定运动规划流水线为ompl运动规划库

Basic parameter settings related to the robot arm

  <!-- Panda specific options -->
  <arg name="load_gripper" default="true" />
# 加载夹爪,该参数被传递给franka_gazebo/launch/panda.launch
  <arg name="transmission" default="effort" />
# 将传动方式设置为effort力控

Gazebo settings

  <!-- Gazebo specific options -->
  <arg name="gazebo_gui" default="true" />
# 设置gazebo_gui参数为true
# gazebo默认将显示图形化界面
  <arg name="paused" default="false" />
# 在启动时,默认不暂停仿真模拟器的时间在0s
# 这个参数其实可能在后续会被覆盖掉
# 不确定在传入文件时是否只给第一次赋值还是会将传入文件的所有该参数均赋值
# 如果只给第一次赋值,那么这个参数是无效的
# 如果给所有都赋值,那么这个参数是有效的

Start Gazebo

  <!-- Launch the gazebo simulator and spawn the robot -->
  <include file="$(find franka_gazebo)/launch/panda.launch" pass_all_args="true">
    <arg name="headless" value="$(eval not arg('gazebo_gui'))" />
    <arg name="use_gripper" default="$(arg load_gripper)" />
    <arg name="controller" default="$(arg transmission)_joint_trajectory_controller" />
  </include>

Imported franka_gazebo/launch/panda.launcha file that loads the Panda robot in the Gazebo simulator and configures it with a series of parameters and controllers. Pass all parameters set above
to the file. Set parameters according to the value of Set parameters according to the value of Set parameters according to the transmission mode , for example, here is set tofranka_gazebo/launch/panda.launch
gazebo_guiheadless
load_gripperuse_gripper
transmissioncontrollereffortcontrollereffort_joint_trajectory_controller

franka_gazebo/launch/panda.launch

This file is franka_gazebothe content of the package. To run successfully, demo_gazebo.launchyou need to download and install this package first.

sudo apt install ros-noetic-franka-gazebo

The path to this file after installation is:/opt/ros/noetic/share/franka_gazebo/launch/panda.launch

The main function of this file is to load and configure the Panda robot in the Gazebo simulator, start the controller, and start RViz and interactive markers when needed. By the way, the detailed content of this file is shown, which has official detailed comments and is written. Very beautiful, I suggest you refer to:

<?xml version="1.0"?>
<launch>

  <!-- Gazebo & GUI Configuration -->
  <arg name="gazebo"      default="true"  doc="Should the gazebo simulation be launched? Use false in case if you want to include this file and launch gazebo yourself" />
  <arg name="headless"    default="false" doc="Should the gazebo GUI be launched?" />
  <arg name="paused"      default="false" doc="Should the simulation directly be stopped at 0s?" />
  <arg name="world"       default="worlds/empty.world" doc="Filename to a SDF World for gazebo to use" />
  <arg name="rviz"        default="false" doc="Should RVIz be launched?" />

  <!-- Robot Customization -->
  <arg name="arm_id"      default="panda" doc="Name of the panda robot to spawn" />
  <arg name="use_gripper" default="true"  doc="Should a franka hand be mounted on the flange?" />
  <arg name="controller"  default=" "     doc="Which example controller should be started? (One of {cartesian_impedance,model,force,joint_position,joint_velocity}_example_controller)" />
  <arg name="x"           default="0"     doc="How far forward to place the base of the robot in [m]?" />
  <arg name="y"           default="0"     doc="How far leftwards to place the base of the robot in [m]?" />
  <arg name="z"           default="0"     doc="How far upwards to place the base of the robot in [m]?" />
  <arg name="roll"        default="0"     doc="How much to rotate the base of the robot around its X-axis in [rad]?" />
  <arg name="pitch"       default="0"     doc="How much to rotate the base of the robot around its Y-axis in [rad]?" />
  <arg name="yaw"         default="0"     doc="How much to rotate the base of the robot around its Z-axis in [rad]?" />
  <arg name="xacro_args"  default=""      doc="Additional arguments to pass to panda.urdf.xacro" />
  <arg name="initial_joint_positions"
       doc="Initial joint configuration of the panda. Specify as a list of name/value pairs in form of '-J [name-of-joint] [value-in-rad]'. Default is a 90 degree bend in the elbow"
       default="-J $(arg arm_id)_joint1 0
                -J $(arg arm_id)_joint2 -0.785398163
                -J $(arg arm_id)_joint3 0
                -J $(arg arm_id)_joint4 -2.35619449
                -J $(arg arm_id)_joint5 0
                -J $(arg arm_id)_joint6 1.57079632679
                -J $(arg arm_id)_joint7 0.785398163397
                -J $(arg arm_id)_finger_joint1 0.001
                -J $(arg arm_id)_finger_joint2 0.001"
       />
  <arg name="interactive_marker" default="$(eval arg('controller') == 'cartesian_impedance_example_controller')" doc="Should the interactive marker node be started?" />

  <include file="$(find gazebo_ros)/launch/empty_world.launch" if="$(arg gazebo)">
    <arg name="world_name" value="$(arg world)"/>
    <!-- Always start in paused mode, and only unpause when spawning the model -->
    <arg name="paused" value="true"/>
    <arg name="gui" value="$(eval not arg('headless'))"/>
    <arg name="use_sim_time" value="true"/>
  </include>

  <param name="robot_description"
         command="xacro $(find franka_description)/robots/panda/panda.urdf.xacro
                  gazebo:=true
                  hand:=$(arg use_gripper)
                  arm_id:=$(arg arm_id)
                  xyz:='$(arg x) $(arg y) $(arg z)'
                  rpy:='$(arg roll) $(arg pitch) $(arg yaw)'
                  $(arg xacro_args)">
  </param>

  <rosparam file="$(find franka_gazebo)/config/franka_hw_sim.yaml" subst_value="true" />
  <rosparam file="$(find franka_gazebo)/config/sim_controllers.yaml" subst_value="true" />

  <param name="m_ee" value="0.76" if="$(arg use_gripper)" />

  <arg name="unpause" value="$(eval '' if arg('paused') else '-unpause')" />
  <node name="$(arg arm_id)_model_spawner"
        pkg="gazebo_ros"
        type="spawn_model"
        args="-param robot_description -urdf -model $(arg arm_id) $(arg unpause)
              $(arg initial_joint_positions)
              "/>

  <!-- Spawn required ROS controllers -->
  <node pkg="controller_manager"
        type="spawner"
        name="$(arg arm_id)_gripper_spawner"
        if="$(arg use_gripper)"
        args="franka_gripper"
        respawn="false"
  />

  <!-- spawns the controller after the robot was put into its initial joint pose -->
  <node pkg="controller_manager"
        type="spawner"
        name="$(arg arm_id)_controller_spawner"
        respawn="false" output="screen"
        args="--wait-for initialized franka_state_controller $(arg controller)"
  />

  <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
  <node name="joint_state_publisher" type="joint_state_publisher" pkg="joint_state_publisher">
    <rosparam param="source_list">[franka_state_controller/joint_states, franka_gripper/joint_states] </rosparam>
    <param name="rate" value="30"/>
  </node>

  <!-- Start only if cartesian_impedance_example_controller -->
  <node name="interactive_marker"
        pkg="franka_example_controllers"
        type="interactive_marker.py"
        if="$(arg interactive_marker)">
    <param name="link_name" value="$(arg arm_id)_link0" />
    <remap to="cartesian_impedance_example_controller/equilibrium_pose" from="equilibrium_pose" />
  </node>

  <node  pkg="rviz" type="rviz" output="screen" name="rviz" args="-d $(find franka_example_controllers)/launch/rviz/franka_description_with_marker.rviz" if="$(arg rviz)"/>

</launch>

  <include file="$(dirname)/demo.launch" pass_all_args="true">
    <!-- robot description is loaded by gazebo.launch, to enable Gazebo features -->
    <arg name="load_robot_description" value="false" />
    <!-- MoveItSimpleControllerManager provides ros_control's JointTrajectory controllers
         as well as GripperCommand actions -->
    <arg name="moveit_controller_manager" value="simple" />
  </include>
# 启动moveit_config/launch/demo.launch
# 在demo.launch中不加载robot_description因为在之前的 panda.launch 文件中已经加载过了
# 设置moveit_controller_manager为simple因为仿真可以视作简单的现实,因此不使用fake
# 使用simple类型的控制器管理器来管理和交互机器人的各个关节控制器

Slice analysis 12: gazebo.launch

demo_gazebo.launchWhat is started in the file is because /opt/ros/noetic/share/franka_gazebo/launch/panda.launchgazebo-related startup files are usually placed in the robot's robotname_gazebofolder, and franka officials also deleted the files panda_moveit_config/launchin the folder gazebo.launch.
In fact, there is also a gazebo related startup file moveit_config/launchbelow : , which will be created gazebo.launchin the stage.setupAssistant

Insert image description here
Re-establish a simple robot, the generated gazebo.launchcode is as follows:

<?xml version="1.0"?>
<launch>
  <!-- Gazebo options -->
  <arg name="gazebo_gui" default="true" doc="Start Gazebo GUI"/>
  <arg name="paused" default="false" doc="Start Gazebo paused"/>
  <arg name="world_name" default="worlds/empty.world" doc="Gazebo world file"/>
  <arg name="world_pose" default="-x 0 -y 0 -z 0 -R 0 -P 0 -Y 0" doc="Pose to spawn the robot at"/>
  <arg name="initial_joint_positions" default=" -J panda_joint1 0 -J panda_joint2 0 -J panda_joint3 0 -J panda_joint4 -1.5708 -J panda_joint5 0 -J panda_joint6 0 -J panda_joint7 0" doc="Initial joint configuration of the robot"/>

  <!-- Start Gazebo paused to allow the controllers to pickup the initial pose -->
  <include file="$(find gazebo_ros)/launch/empty_world.launch" pass_all_args="true">
    <arg name="paused" value="true"/>
  </include>

  <!-- Set the robot urdf on the parameter server -->
  <param name="robot_description" textfile="$(find test_arm_moveit_config)/config/gazebo_panda.urdf" />

  <!-- Unpause the simulation after loading the robot model -->
  <arg name="unpause" value="$(eval '' if arg('paused') else '-unpause')" />

  <!-- Spawn the robot in Gazebo -->
  <node name="spawn_gazebo_model" pkg="gazebo_ros" type="spawn_model" args="-urdf -param robot_description -model robot $(arg unpause) $(arg world_pose) $(arg initial_joint_positions)"
    respawn="false" output="screen" />

  <!-- Load the controller parameters onto the parameter server -->
  <rosparam file="$(find test_arm_moveit_config)/config/gazebo_controllers.yaml" />
  <include file="$(dirname)/ros_controllers.launch"/>

  <!-- Spawn the Gazebo ROS controllers -->
  <node name="gazebo_controller_spawner" pkg="controller_manager" type="spawner" respawn="false" output="screen" args="joint_state_controller" />

  <!-- Given the published joint states, publish tf for the robot links -->
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" respawn="true" output="screen" />
</launch>

gazebo startup parameters

  <!-- Gazebo options -->
  <arg name="gazebo_gui" default="true" doc="Start Gazebo GUI"/>
  <arg name="paused" default="false" doc="Start Gazebo paused"/>
  <arg name="world_name" default="worlds/empty.world" doc="Gazebo world file"/>
  <arg name="world_pose" default="-x 0 -y 0 -z 0 -R 0 -P 0 -Y 0" doc="Pose to spawn the robot at"/>
  <arg name="initial_joint_positions" default=" -J panda_joint1 0 -J panda_joint2 0 -J panda_joint3 0 -J panda_joint4 -1.5708 -J panda_joint5 0 -J panda_joint6 0 -J panda_joint7 0" doc="Initial joint configuration of the robot"/>
# 设置一些Gazebo需要的参数
# 设置初始的Gazebo中机械臂各关节的姿态

Start gazebo in pause mode

  <!-- Start Gazebo paused to allow the controllers to pickup the initial pose -->
  <include file="$(find gazebo_ros)/launch/empty_world.launch" pass_all_args="true">
    <arg name="paused" value="true"/>
  </include>
# 加载gazebo的空世界,同时暂停在0s来方便控制器获取到初始位的姿态值

The emulator is paused after Gazebo is initially loaded.
This is to allow the controller enough time to acquire the initial pose of the robot.
Without pausing the simulator first, a robot model in a running simulator may start moving before the controller has a chance to receive the initial pose, which may result in incorrect behavior or simulator errors.

Load the robot description file to the parameter server

 <!-- Set the robot urdf on the parameter server -->
  <param name="robot_description" textfile="$(find test_arm_moveit_config)/config/gazebo_panda.urdf" />
# 加载机器人描述文件到参数服务器

This file describes the robot's model, including links, joints, and other features. is a parameter required by robot_descriptionmany ROS nodes (including robot_state_publisherand ).move_group

Setting of unpause parameter

  <!-- Unpause the simulation after loading the robot model -->
  <arg name="unpause" value="$(eval '' if arg('paused') else '-unpause')" />

Set a parameter unpause. If pausedit is true (that is, Gazebo is paused after starting), then unpauseit is an empty string, otherwise it is -unpause.
This is because after loading the robot model, if the simulator was not initially paused, it needs to be unpaused to start the simulation. This line of setup is used to perform this operation when appropriate. This means that the parameter will contain the string
only if the simulator is paused , so that the simulator will be resumed from the paused state in the node. On the contrary, if the simulator has not been paused at the beginning, then the parameter will be an empty string, which will not affect the state of the simulator.unpause-unpausespawn_gazebo_modelunpause

Birth robot model

  <!-- Spawn the robot in Gazebo -->
  <node name="spawn_gazebo_model" pkg="gazebo_ros" type="spawn_model" args="-urdf -param robot_description -model robot $(arg unpause) $(arg world_pose) $(arg initial_joint_positions)"
    respawn="false" output="screen" />
  • args="-urdf -param robot_description -model robot $(arg unpause) $(arg world_pose) $(arg initial_joint_positions)"is spawn_modelthe parameter passed to the node.

    • -urdf: Indicates that the next parameter robot_descriptionis in URDF (Unified Robot Description Format, Unified Robot Description Format) format. This file has usually been .xacroconverted to .urdfthe parameter server.
    • -param robot_description: Parameters in the ROS parameter server, which contain the contents of the URDF file describing the robot model.
    • -model robot: A name is set in Gazebo for the robot model, here the name is robot.
    • $(arg unpause): This is a parameter defined previously. It may be an empty string (no pause occurred when the simulation started, that is, it has no impact), or (it was -unpausepaused when the simulation started. At this time, the model needs to be released after loading. pause).
    • $(arg world_pose): This is the initial posture of the robot model in the Gazebo world.
    • $(arg initial_joint_positions): This is the initial joint position of the robot model.
  • respawn="false": This option indicates that if the node stops running for any reason, ROS should not attempt to restart it.

  • output="screen": This indicates that the node's output should be printed to the screen. This is useful for debugging and monitoring the operation of the node.

This code snippet loads the robot model in URDF format into the Gazebo simulator. The initial position and joint status of the model are defined by the corresponding parameters. Moreover, according to unpausethe value of the parameter, the 0s pause state of the Gazebo simulator will be released after the model is loaded.

Load controller parameters to parameter server

 <!-- Load the controller parameters onto the parameter server -->
  <rosparam file="$(find test_arm_moveit_config)/config/gazebo_controllers.yaml" />
# 将config/gazebo_controllers.yaml文件加载到参数服务器

gazebo_controllers.yaml

# Publish joint_states
joint_state_controller:
  type: joint_state_controller/JointStateController
  publish_rate: 50

gazebo_controllers.yamlThe configuration file defines the controller to be managed and its related parameters for the controller manager (controller_manager) in ROS.

There is a controller named here defined joint_state_controller.

  • joint_state_controller:Is the name of the controller that will be used by the controller manager to refer to this controller.

  • type: joint_state_controller/JointStateControllerDefines the type of controller. In this example, the type of controller is JointStateControllerthat its task is to read the state (position, velocity, and torque) of each joint and publish it to joint_statesthe topic. This topic is typically robot_state_publishersubscribed to by nodes, which use this information to update the state of the robot model and publish that state to the tf (transform) topic.

  • publish_rate: 50Is JointStateControllera parameter of the controller, which defines that the controller should publish joint status information 50 times per second.

launch ros_controllers.launch

<include file="$(dirname)/ros_controllers.launch"/>
# 引用了ros_controllers.launch在此处启动

This is useless, because the content of the incoming controller is empty, so the corresponding controller is not started. It may be that the author of Moveit wants to distinguish between the ordinary controller under ros and the gazebo controller, or it may be a real robot arm and Gazebo's simulation requires digital twins to be synchronized, which is why there is such a difference. It is for reference only.

ros_controllers.launch

<?xml version="1.0"?>
<launch>

  <!-- Load joint controller configurations from YAML file to parameter server -->
  <rosparam file="$(find panda_moveit_config)/config/ros_controllers.yaml" command="load"  subst_value="true"/>

  <!-- Load and start the controllers -->
  <node name="controller_spawner" pkg="controller_manager" type="spawner" respawn="false" output="screen"
        args="$(arg transmission)_joint_trajectory_controller" />
</launch>

ros_controllers.launchLoad ros_controllers.yamlthe configuration of the controller into the parameter server

Then start controller_managerthe package spawnerto generate the controller.
The parameters of this node $(arg transmission)_joint_trajectory_controllerspecify the type of controller that needs to be started. If here effort, it is effort__joint_trajectory_controllera controller of type .

The value is passed in demo_gazebo.launchthe file, then passed gazebo.launch, then passed again ros_controllers.launchand applied here as effort, making the transmission mode force control

The parameter of the spawner node is $(arg transmission)_joint_trajectory_controller. In this case, that means it attempts to start effort_joint_trajectory_controllerthe controller named.

ros_controllers.yaml

The file is empty with no content

Start the controller in gazebo_controllers.yaml

  <!-- Spawn the Gazebo ROS controllers -->
  <node name="gazebo_controller_spawner" pkg="controller_manager" type="spawner" respawn="false" output="screen" args="joint_state_controller" />

The previous gazebo_controllers.yamlcontroller has been loaded into the parameter server and subsequently started there.
controller_managerThe node in the controller manager package spawnerwill joint_state_controllerstart the controller named (joint_state_controller exists in gazebo_controllers.yaml)

Post bot status

  <!-- Given the published joint states, publish tf for the robot links -->
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" respawn="true" output="screen" />
</launch>

robot_state_publisherThe node will publish the joint status of the robot and generate tf (transform) messages, which are used to track the pose of each link of the robot.

Slice analysis 13: joystick_control.launch

Use the handle to control the whole process. You can refer to the handle tutorial of moveit_ros , which will not be extended here.

<launch>
  <!-- See moveit_ros/visualization/doc/joystick.rst for documentation -->

  <arg name="dev" default="/dev/input/js0" />

  <!-- Launch joy node -->
  <node pkg="joy" type="joy_node" name="joy">
    <param name="dev" value="$(arg dev)" /> <!-- Customize this to match the location your joystick is plugged in on-->
    <param name="deadzone" value="0.2" />
    <param name="autorepeat_rate" value="40" />
    <param name="coalesce_interval" value="0.025" />
  </node>

  <!-- Launch python interface -->
  <node pkg="moveit_ros_visualization" type="moveit_joy.py" output="screen" name="moveit_joy"/>

</launch>

This launch file is used in the ROS system to set up a robot that uses a joystick to control movement.

Start joy_nodea node to handle gamepad input

  1. dev- This is the path to the gamepad device, defaults to /dev/input/js0. This path may need to be changed depending on your specific system.

  2. deadzone- Dead zone threshold, if the displacement of the handle is less than this value, it will be ignored to avoid misoperation due to small movements of the handle. This value defaults to 0.2.

  3. autorepeat_rate- This is the frequency of automatic repetition, the unit is Hz, the default is 40. This means that if a button of the controller is pressed and held, this node will generate 40 identical messages per second.

  4. coalesce_interval- This is the merge time interval in seconds, default is 0.025. If multiple input events arrive within this time interval, this node will merge them into a single event.

This launch file then launches another node moveit_joy.py, which is a Python interface for converting input from the gamepad into control signals that MoveIt! can understand.

Slice analysis 14: run_benchmark_ompl.launch

Performance evaluation tasks for the ompl library

<launch>

  <!-- This argument must specify the list of .cfg files to process for benchmarking -->
  <arg name="cfg" />

  <!-- Load URDF -->
  <include file="$(dirname)/planning_context.launch">
    <arg name="load_robot_description" value="true"/>
  </include>

  <!-- Start the database -->
  <include file="$(dirname)/warehouse.launch">
    <arg name="moveit_warehouse_database_path" value="moveit_ompl_benchmark_warehouse"/>
  </include>

  <!-- Start Benchmark Executable -->
  <node name="$(anon moveit_benchmark)" pkg="moveit_ros_benchmarks" type="moveit_run_benchmark" args="$(arg cfg) --benchmark-planners" respawn="false" output="screen">
    <rosparam command="load" file="$(find panda_moveit_config)/config/ompl_planning.yaml"/>
  </node>

</launch>

cfg

  <!-- This argument must specify the list of .cfg files to process for benchmarking -->
  <arg name="cfg" />

A command line parameter is defined that specifies a list of .cfg files to benchmark.

Launch planning_context.launch

  <!-- Load URDF -->
  <include file="$(dirname)/planning_context.launch">
    <arg name="load_robot_description" value="true"/>
  </include>
# 加载机器人描述文件,启动启动planning_context.launch

Start database

  <!-- Start the database -->
  <include file="$(dirname)/warehouse.launch">
    <arg name="moveit_warehouse_database_path" value="moveit_ompl_benchmark_warehouse"/>
  </include>

warehouse.launchFile used to start MoveIt!'s database service. This service is mainly used to store and retrieve motion planning problems, solutions, status, etc.
moveit_warehouse_database_pathis the path to the database.

  <!-- Start Benchmark Executable -->
  <node name="$(anon moveit_benchmark)" pkg="moveit_ros_benchmarks" type="moveit_run_benchmark" args="$(arg cfg) --benchmark-planners" respawn="false" output="screen">
    <rosparam command="load" file="$(find panda_moveit_config)/config/ompl_planning.yaml"/>
  </node>

anon moveit_benchmarkanonA unique suffix will be given to facilitate the execution of multiple tasks moveit_benchmarkwithout duplicate names. The node and flag moveit_ros_benchmarksof the startup package indicate that a benchmark planner is required. The parameter was previously defined but not assigned a value in the file, so the value of this parameter must be specified from the external command line, for example:moveit_run_benchmark--benchmark-planners
cfg

roslaunch package_name run_benchmark_ompl.launch cfg:=/path/to/your/config/file.cfg

In this way, cfgthe parameter is assigned a value of /path/to/your/config/file.cfg, and this path will be passed to the node as a parameter moveit_run_benchmark.

At the same time, when starting this node, the parameters are loaded ompl_planning.yamlto the ROS parameter server, which is used to read the settings of ompl to facilitate task evaluation.

Slice parsing 15: franka_control.launch

<?xml version="1.0"?>
<launch>
  <arg name="robot_ip" />
  <arg name="load_gripper" />

  <!-- Launch real-robot control -->
  <include file="$(find franka_control)/launch/franka_control.launch" pass_all_args="true" />

  <!-- By default use joint position controllers -->
  <arg name="transmission" default="position" />
  <!-- Start ROS controllers -->
  <include file="$(dirname)/ros_controllers.launch" pass_all_args="true" />

  <!-- as well as MoveIt demo -->
  <include file="$(dirname)/demo.launch" pass_all_args="true">
    <!-- robot description is loaded by franka_control.launch -->
    <arg name="load_robot_description" value="false" />
    <!-- MoveItSimpleControllerManager provides ros_control's JointTrajectory controllers
         as well as GripperCommand actions -->
    <arg name="moveit_controller_manager" value="simple" />
  </include>
</launch>

Load real robot arm control

  <!-- Launch real-robot control -->
  <include file="$(find franka_control)/launch/franka_control.launch" pass_all_args="true" />

Franka Emika Panda is a seven-degree-of-freedom robot arm commonly used for research and teaching, which is the demo robot arm used in this article Panda.
Start franka_controlthe package franka_control.launchand pass all parameters (such as the IP of the robot arm and whether to load the gripper). franka_control.launchThe file is used to start and control the Franka Emika Panda physical robot.

Real robotic arm franka_control.launch

If you have configured it with the one-click configuration installation script, you can /opt/ros/noetic/share/franka_control/launchfind it under the path franka_control.launch, the content is as follows:

<?xml version="1.0" ?>
<launch>
  <arg name="robot_ip" />
  <arg name="robot" default="panda" doc="choose your robot. Possible values: [panda, fr3]"/>
  <arg name="arm_id" default="$(arg robot)" />
  <arg name="load_gripper" default="true" />
  <arg name="xacro_args" default="" />

  <param name="robot_description" command="$(find xacro)/xacro $(find franka_description)/robots/$(arg robot)/$(arg robot).urdf.xacro hand:=$(arg load_gripper) arm_id:=$(arg arm_id) $(arg xacro_args)"/>

  <include file="$(find franka_gripper)/launch/franka_gripper.launch" if="$(arg load_gripper)">
    <arg name="robot_ip" value="$(arg robot_ip)" />
    <arg name="arm_id"   value="$(arg arm_id)" />
  </include>

  <node name="franka_control" pkg="franka_control" type="franka_control_node" output="screen" required="true">
    <rosparam command="load" file="$(find franka_control)/config/franka_control_node.yaml" subst_value="true" />
    <param name="robot_ip" value="$(arg robot_ip)" />
  </node>

  <rosparam command="load" file="$(find franka_control)/config/default_controllers.yaml" subst_value="true" />
  <node name="state_controller_spawner" pkg="controller_manager" type="spawner" respawn="false" output="screen" args="franka_state_controller"/>
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" output="screen"/>
  <node name="joint_state_publisher" type="joint_state_publisher" pkg="joint_state_publisher" output="screen">
    <rosparam if="$(arg load_gripper)" param="source_list">[franka_state_controller/joint_states, franka_gripper/joint_states] </rosparam>
    <rosparam unless="$(arg load_gripper)" param="source_list">[franka_state_controller/joint_states] </rosparam>
    <param name="rate" value="30"/>
  </node>
</launch>

To briefly explain some of this:

  <param name="robot_description" command="$(find xacro)/xacro $(find franka_description)/robots/$(arg robot)/$(arg robot).urdf.xacro hand:=$(arg load_gripper) arm_id:=$(arg arm_id) $(arg xacro_args)"/>
# 加载了robot_description到ROS参数服务器
# 具体的模型内容通过参数hand:=$(arg load_gripper) arm_id:=$(arg arm_id) $(arg xacro_args)在xacro宏里进行选择
# 比如是否加载夹爪和其他的xacro_args需求
  <include file="$(find franka_gripper)/launch/franka_gripper.launch" if="$(arg load_gripper)">
    <arg name="robot_ip" value="$(arg robot_ip)" />
    <arg name="arm_id"   value="$(arg arm_id)" />
  </include>
# 加载夹爪节点
# 不再拓展讲,有兴趣的自己看
  <node name="franka_control" pkg="franka_control" type="franka_control_node" output="screen" required="true">
    <rosparam command="load" file="$(find franka_control)/config/franka_control_node.yaml" subst_value="true" />
    <param name="robot_ip" value="$(arg robot_ip)" />
  </node>
# 启动franka_control_node控制节点
# 载入相关配置参数franka_control_node.yaml
 <rosparam command="load" file="$(find franka_control)/config/default_controllers.yaml" subst_value="true" />
  <node name="state_controller_spawner" pkg="controller_manager" type="spawner" respawn="false" output="screen" args="franka_state_controller"/>
# 载入控制器参数default_controllers.yaml到ROS参数服务器
# 使用控制器管理者的spawner来启动franka_state_controller
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" output="screen"/>
  <node name="joint_state_publisher" type="joint_state_publisher" pkg="joint_state_publisher" output="screen">
    <rosparam if="$(arg load_gripper)" param="source_list">[franka_state_controller/joint_states, franka_gripper/joint_states] </rosparam>
    <rosparam unless="$(arg load_gripper)" param="source_list">[franka_state_controller/joint_states] </rosparam>
    <param name="rate" value="30"/>
  </node>
# 加载机器人状态发布器robot_state_publisher节点
# 加载机器人关节状态发布器joint_state_publisher节点

Enable location control type controllers

 <!-- By default use joint position controllers -->
  <arg name="transmission" default="position" />
  <!-- Start ROS controllers -->
  <include file="$(dirname)/ros_controllers.launch" pass_all_args="true" />

Enable controllers of the position control type, that is, position_joint_trajectory_controllera controller named: It is not currently known which controller is loaded into the ROS parameter server, but it simple_moveit_controllers.yamlcan be found in If you use simplea controller manager of type, the $(arg transmission)_joint_trajectory_controllercontroller parameter named will be loaded into the ROS parameter server, which means that simplethe controller will be loaded correctly when available .

simple_moveit_controllers.yaml

controller_list:
  - name: $(arg transmission)_joint_trajectory_controller
    action_ns: follow_joint_trajectory
    type: FollowJointTrajectory
    default: True
    joints:
      - $(arg arm_id)_joint1
      - $(arg arm_id)_joint2
      - $(arg arm_id)_joint3
      - $(arg arm_id)_joint4
      - $(arg arm_id)_joint5
      - $(arg arm_id)_joint6
      - $(arg arm_id)_joint7
  - name: franka_gripper
    action_ns: gripper_action
    type: GripperCommand
    default: True
    joints:
      - $(arg arm_id)_finger_joint1

Launch RViz window

  <!-- as well as MoveIt demo -->
  <include file="$(dirname)/demo.launch" pass_all_args="true">
    <!-- robot description is loaded by franka_control.launch -->
    <arg name="load_robot_description" value="false" />
    <!-- MoveItSimpleControllerManager provides ros_control's JointTrajectory controllers
         as well as GripperCommand actions -->
    <arg name="moveit_controller_manager" value="simple" />
  </include>

Start the classic one demo.launch, the guess is that it is used to drag and drop the Motion_planning plug-in in RViz to control the physical mechanical arm.

Slice analysis 16: setup_assistant.launch

<!-- Re-launch the MoveIt Setup Assistant with this configuration package already loaded -->
<launch>

  <!-- Debug Info -->
  <arg name="debug" default="false" />
  <arg unless="$(arg debug)" name="launch_prefix" value="" />
  <arg     if="$(arg debug)" name="launch_prefix" value="gdb --ex run --args" />

  <!-- Run -->
  <node pkg="moveit_setup_assistant" type="moveit_setup_assistant" name="moveit_setup_assistant"
        args="--config_pkg=panda_moveit_config"
        launch-prefix="$(arg launch_prefix)"
        required="true"
        output="screen" />

</launch>

Passing in --config_pkg=panda_moveit_configparameters enables the content of Moveit SetupAssistantthis package to be loaded directly moveit_config, usually used to reconfigure the package. Of course, the same is true for
directly opening manual loading, whichever is more convenient.Moveit SetupAssistant

Other slices

pandu_moveit_configThere are also some other unique files in the package, which are not found in ordinary moveit_configpackages, but are more useful.
For example, CHOMP, LERP and STOMP are different algorithms used for robot path planning. In this case, demo_chomp.launchthe , demo_lerp.launchand demo_stomp.launchfiles are used to start and demonstrate these different path planning algorithms.

  1. demo_chomp.launch : CHOMP (Collision-Heuristic Optimization for Motion Planning) is a robot path planning algorithm that plans paths based on heuristic optimization to avoid collisions with objects in the environment. This demo file will start an example of path planning using the CHOMP algorithm.

  2. demo_lerp.launch : LERP (Linear Interpolation) is one of the simplest path planning algorithms, it simply generates a straight line between the robot's current position and the target position. However, it does not take into account obstacles in the environment, so this algorithm may not be suitable for all situations. This demo file will start an example of path planning using the LERP algorithm.

  3. demo_stomp.launch : STOMP (Stochastic Trajectory Optimization for Motion Planning) is another robot path planning algorithm that uses stochastic optimization methods to plan paths. Unlike CHOMP, STOMP takes into account the dynamic nature of the robot, as well as the noise and uncertainty in path planning. This demo file will start an example of path planning using the STOMP algorithm.

These three .launch files are used to demonstrate how to use MoveIt and ROS to use different path planning algorithms. Which algorithm you choose depends on your specific needs and the characteristics of your robot.

Moveit source code analysis

In the file analysis of the config configuration package, many parameters are imported into the ROS parameter server, but the specific implementation and calling process are opaque to users. If you need to understand, you need to go deep into the source code of moveit. In view of this article The length of the article is too long, so the moveit source code analysis will be placed in another article, and a link
TODO: moveit source code analysis link will be attached here.

Guess you like

Origin blog.csdn.net/m0_56661101/article/details/131415296