控制器配置
MoveIt 通常将机械臂的运动指令发布到 JointTrajectoryController。本教程假设你使用 MoveGroup 来控制机器人,而不是 MoveItCpp 或 MoveIt Servo。一个最小的配置需要以下内容:
-
一个 YAML 配置文件。按照最佳实践,我们建议将其命名为
moveit_controllers.yaml。该文件告诉 MoveIt 有哪些控制器可用、每个控制器与哪些关节相关联,以及 MoveIt 控制器接口类型(FollowJointTrajectory或GripperCommand)。示例控制器配置文件。 -
一个 launch 文件。该 launch 文件必须加载
moveit_controllersyaml 文件,并指定moveit_simple_controller_manager/MoveItSimpleControllerManager。yaml 文件加载后会作为参数传递给 Move Group 节点。示例 Move Group launch 文件。 -
启动相应的
ros2_controlJointTrajectoryController。这部分独立于 MoveIt 2 生态。ros2_control 启动示例。每个 JointTrajectoryController 都提供一个 action 接口,MoveIt 会根据 yaml 配置自动连接到该接口。 -
需要注意的是,你的机器人不一定非要用
ros2_control,也可以编写自定义的 action 接口。不过,99% 的用户都会选择ros2_control。
MoveIt 控制器管理器
Section titled “MoveIt 控制器管理器”控制器管理器的基类称为 MoveItControllerManager(MICM)。MICM 的子类之一称为 Ros2ControlManager(R2CM),它是与 ros2_control 交互的最佳方式。R2CM 可以解析来自 MoveIt 的轨迹指令中的关节名称,并激活相应的控制器。例如,它可以在“同时控制一个规划组中的两个机械臂”和“控制单个机械臂”之间自动切换。要使用 R2CM,只需在 launch 文件中设置 moveit_manage_controllers = true。R2CM launch 文件示例。
MoveIt 控制器接口
Section titled “MoveIt 控制器接口”上文描述了如何启动关节轨迹控制器的 action 接口。此外,MoveIt 还通过 action 接口支持平行夹爪控制。本节介绍这两种选项的参数。
-
FollowJointTrajectory 控制器接口
参数如下:
name:控制器的名称。(重要说明见下面的调试信息)action_ns:控制器的 action 命名空间。(重要说明见下面的调试信息)type:所使用的 action 类型(此处为 FollowJointTrajectory)。default:是否为默认控制器。MoveIt 在与特定规划组通信时会优先选择默认控制器。joints:此接口所涉及的所有关节的名称。
-
GripperCommand 控制器接口
参数如下:
name:控制器的名称。(重要说明见下面的调试信息)action_ns:控制器的 action 命名空间。(重要说明见下面的调试信息)type:所使用的 action 类型(此处为 GripperCommand)。default:是否为默认控制器。MoveIt 在与特定规划组通信时会优先选择默认控制器。joints:此接口所涉及的所有关节的名称。command_joint:控制夹爪实际状态的单个关节。这是唯一发送给控制器的值。必须是上面 joints 中的关节之一。如果未指定,将使用 joints 中的第一项。parallel:设置此参数时,joints 应为包含 2 个关节的列表,下发的指令值为两个关节值之和。
可选的允许轨迹执行时长参数
Section titled “可选的允许轨迹执行时长参数”(TODO:更新为 ROS 2)
对于每个控制器,可以选择设置 allowed_execution_duration_scaling 和 allowed_goal_duration_margin 参数,它们是对全局值 trajectory_execution/allowed_execution_duration_scaling 和 trajectory_execution/allowed_goal_duration_margin 的控制器级覆盖。与全局值不同,控制器特有的值不能在运行时动态重新配置。这些参数用于计算允许的轨迹执行时长:先缩放预期的执行时长,再加上余量。如果超过该时长,轨迹将被取消。控制器特有的参数可以按如下方式设置:
controller_list: - name: arm_controller action_ns: follow_joint_trajectory type: FollowJointTrajectory allowed_execution_duration_scaling: 1.2 allowed_goal_duration_margin: 0.5ros_control 接口的可选参数
Section titled “ros_control 接口的可选参数”使用 MoveIt ROS Control 接口时,你可以配置几个参数来优化其行为:
controller_service_call_timeout(double,默认值:3.0 秒)
该参数控制 MoveIt 等待控制器管理器服务(如 list_controllers 和 switch_controller)响应的时长。在资源受限的系统或网络拥塞的情况下,控制器发现和切换操作可能超过默认超时时间。适当增大此参数可以避免超时问题。
ros_control_namespace(string,默认值:/)
ros_control 节点的命名空间。
# In your moveit_controllers.yaml configurationros_control_namespace: /my_robotcontroller_service_call_timeout: 5.0 # Increase timeout to 5 seconds(TODO:更新为 ROS 2)
你的机器人上的 FollowJointTrajectory 或 GripperCommand 接口必须在命名空间 /name/action_ns 中通信。在上面的示例中,你应该能在机器人上看到以下主题(使用 ros2 topic list):
- /panda_arm_controller/follow_joint_trajectory/goal
- /panda_arm_controller/follow_joint_trajectory/feedback
- /panda_arm_controller/follow_joint_trajectory/result
- /hand_controller/gripper_action/goal
- /hand_controller/gripper_action/feedback
- /hand_controller/gripper_action/result
你还应该能看到(使用 ros2 topic info topic_name)这些主题由你机器人上的控制器以及 move_group 节点发布/订阅。
重映射 /joint_states 主题
Section titled “重映射 /joint_states 主题”(TODO:更新为 ROS 2)
当你运行 move group 节点 时,你可能需要将 /joint_states 主题重映射到 /robot/joint_states,否则 MoveIt 将无法获得关节的反馈。要进行这种重映射,可以为你的节点创建一个简单的 launch 文件,如下所示:
<node pkg="moveit_ros_move_group" type="move_group" name="any_name" output="screen"> <remap from="joint_states" to="robot/joint_states"/> </node>或者,你也可以创建一个订阅正确主题的订阅者,通过回调确保 move group 的起始状态与实际关节角度一致。
轨迹执行管理器选项
Section titled “轨迹执行管理器选项”MoveIt 提供了几个选项来调整执行管线的行为和安全检查。在 moveit_config 包中编辑 trajectory_execution.launch.xml 文件即可修改以下参数:
execution_duration_monitoring:设为false时,如果轨迹在底层控制器一侧的执行时间超过预期,不会抛出错误。allowed_goal_duration_margin:在触发轨迹取消之前允许超出预期执行时间的余量(在缩放之后应用)。allowed_start_tolerance:用于验证轨迹第一个点与当前机器人状态是否一致的关节值容差。设为零时,将跳过执行后等待机器人停止的过程。
示例控制器管理器
Section titled “示例控制器管理器”MoveIt 控制器管理器(这个叫法多少有点名不副实)是连接自定义底层控制器的接口。把它理解为 控制器接口 更为恰当。对于大多数用例,如果你的机器人控制器已经为 FollowJointTrajectory 提供了 ROS action,那么自带的 MoveItSimpleControllerManager 就足够了。如果使用 ros_control,自带的 MoveItRosControlInterface 也是理想之选。
然而,对于某些应用,你可能需要一个更定制化的控制器管理器。这里提供了一个自定义控制器管理器的示例模板。
如果没有实体机器人,使用 ros2_control 可以非常轻松地进行仿真,无需 Ignition 或 Gazebo,只用 RViz 就够了。ros2_control_demos 仓库中的所有示例都是仿真的。
控制器切换与命名空间
Section titled “控制器切换与命名空间”所有控制器名称都会以其 ros_control 节点的命名空间作为前缀。因此,控制器名称不应包含斜杠,也不能命名为 /。对于特定节点,MoveIt 可以决定启动或停止哪些控制器。由于 MoveIt 只处理注册了分配器插件的控制器,如果某个待启动的控制器需要特定资源,MoveIt 会根据各控制器已声明的资源依赖关系来停止相应的控制器。
使用 ROS Control 接口管理器进行控制器切换时,你可以通过 controller_service_call_timeout 参数(默认值:3.0 秒)配置控制器管理器服务调用的超时时间。在控制器切换可能超过默认超时时间的复杂配置中,这一点尤其有用。
多节点的控制器
Section titled “多节点的控制器”Ros2ControlManager 有一个变体:Ros2ControlMultiManager。Ros2ControlMultiManager 可用于管理多个 ros_control 节点。它的工作方式是为每个节点创建一个 Ros2ControlManager 实例,以各自的命名空间进行实例化,并负责正确的任务委派。要使用它,必须在 launch 文件中添加:
<param name="moveit_controller_manager" value="moveit_ros_control_interface::Ros2ControlMultiManager" />controller_service_call_timeout 参数也可以通过 Ros2ControlMultiManager 设置,该值将被所有发现的控制器管理器使用。