机器人究竟怎么动起来的呢?

0 前言

在本专栏的第二篇博客中,我们从文件组成的角度分析了七自由度机器人运行的规律,但在第2.3.2.2节,我们看到了seven_dof_arm_gazebo_control.launch文件中加载了seven_dof_arm_gazebo_control.yaml 文件,并在node中加载了controller,这些东西怎么来的,当时没有回答,现在就来回答这个问题。

1 控制机器人运动

在本专栏的第一篇博客中,采用ROS中已经做好的相关库,使机器人运动的流程可以归纳如下:
01

首先是在URDF文件的transmission属性指定了hardware_interface的类型是PositionJointInterface;其次在控制器配置文件 seven_dof_arm_gazebo_control.yaml 中指定了 namespaceseven_dof_arm,并且指定了控制器的名字joint_state_controllerjointx_state_controller(x表示1,2,3,…,7)。seven_dof_arm_gazebo_control.yaml中控制器的类型和URDF文件中hardware_interface的类型是匹配的。seven_dof_arm_gazebo_control.yaml中控制器的名字和seven_dof_arm_gazebo_launch中控制器节点的参数是一致的。

关于控制器的类型和hardware_interface之间的匹配关系,见ROS wiki ros_control.从官方链接点进去之后可以看到github上相应的.h源文件,打开可以看到它们之间的联系。以position_controllers为例,从官网的链接打开后,可以看到joint_position_controller.h文件:
02

从.h文件中可以看到namespace是 position_controllers,hardware_interface是PositionJointInterface,类型是JointPositionController

还有一点,需要注意的是,.h文件中说明了该控制器会提交一个std_msgs/Float64位的消息,该数据会作用在关节上。因此,在本专栏第一篇文章中,我们可以通过rostopic pub /seven_dof_arm/joint4_position_controller/command std_msgs/Float64 "data: 0.5"来控制机器人运动。

运行rostopic list,可以看到所有的topic:
04

如果你不知道具体怎么写,可以尝试Tab键自动补全。

如果是想控制多个关节,还有joint_group_position_controller.h:
03

2 seven_dof_arm_gazebo_control.yaml

.yaml文件是控制器的配置文件。我们一般在利用ROS已有的控制器时,会将控制器的参数写在该文件中。seven_dof_arm_gazebo_control.yaml 的源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
seven_dof_arm:
# Publish all joint states -----------------------------------
joint_state_controller:
type: joint_state_controller/JointStateController
publish_rate: 50

# Position Controllers ---------------------------------------
joint1_position_controller:
type: position_controllers/JointPositionController
joint: shoulder_pan_joint
pid: {p: 100.0, i: 0.01, d: 10.0}
joint2_position_controller:
type: position_controllers/JointPositionController
joint: shoulder_pitch_joint
pid: {p: 100.0, i: 0.01, d: 10.0}
joint3_position_controller:
type: position_controllers/JointPositionController
joint: elbow_roll_joint
pid: {p: 100.0, i: 0.01, d: 10.0}
joint4_position_controller:
type: position_controllers/JointPositionController
joint: elbow_pitch_joint
pid: {p: 100.0, i: 0.01, d: 10.0}
joint5_position_controller:
type: position_controllers/JointPositionController
joint: wrist_roll_joint
pid: {p: 100.0, i: 0.01, d: 10.0}
joint6_position_controller:
type: position_controllers/JointPositionController
joint: wrist_pitch_joint
pid: {p: 100.0, i: 0.01, d: 10.0}
joint7_position_controller:
type: position_controllers/JointPositionController
joint: gripper_roll_joint
pid: {p: 100.0, i: 0.01, d: 10.0}

从源码中可以看出,JointStateController可以控制publish state,JointPositionController可以控制单独一个关节,并可以调节pid参数。