1.ros_control
ros_control就是ROS为用户提供的应用与机器人之间的中间件,包含一系列控制器接口、传动装置接口、硬件接口、控制器工具箱等等,可以帮助机器人应用快速落地,提高开发效率。
上图是ros_control的总体框架,可以看到对于不同类型的控制器(底盘、机械臂等),ros_control可以提供多种类型的控制器,但是这些控制器的接口各不相同,为了提高代码的复用率,ros_control还提供一个硬件的抽象层。
硬件抽象层负责机器人硬件资源的管理,而controller从抽象层请求资源即可,并不直接接触硬件。
上图是ros_control的数据流图,可以更加清晰的看到每个层次包含的功能:
(1)Controller Manager:每个机器人可能有多个controller,所以这里有一个控制器管理器的概念,提供一种通用的接口来管理不同的controller。controller manager的输入就是ROS上层应用的输出。
(2)Controller:controller可以完成每个joint的控制,请求下层的硬件资源,并且提供了PID控制器,读取硬件资源接口中的状态,在发布控制命令。
(3)Hardware Rescource:为上下两层提供硬件资源的接口。
(4)RobotHW:硬件抽象层和硬件直接打交道,通过write和read方法来完成硬件的操作,这一层也包含关节限位、力矩转换、状态转换等功能。
(5)Real Robot:实际的机器人上也需要有自己的嵌入式控制器,接收到命令后需要反映到执行器上,比如接收到位置1的命令后,那就需要让执行器快速、稳定的到达位置1。
Controller Manager
controller manager提供了一种控制多个controller的机制,可以加载、开始运行、停止运行、卸载不同的controller,并且提供了多种工具来完成这些操作。
Controller
ros_controllers这个功能包提供了已有的一些controllers,比较常用的是如下几个:
(1)effort_controllers - 直接控制关节的力/扭矩
●joint_effort_controller
●joint_position_controller
●joint_velocity_controller
(2)position_controllers - 一次设置一个/多个关节位置
●joint_position_controller
(3)velocity_controllers - 一次设置一个/多个关节速度
●joint_velocity_controller
(4)joint_state_controller - 读取所有关节位置
●joint_state_controller
更多controller可参考:http://wiki.ros.org/ros_controllers
当然,我们也可以根据自己的需求,创建需要的controller,然后通过controller来管理自己创建的controller,可以参考https://github.com/ros-controls/ros_control/wiki/controller_interface
Hardware Interface
Hardware Interface是controller和RobotHw沟通的接口,基本上和controllers的种类是对应的。ROS提供了如下的hardwareInterface接口供选择:
(1)Joint Command Interfaces
●Effort Joint Interface
●Velocity Joint Interface
●Position Joint Interface
(2)Joint State Interfaces
(3)Actuator State Interfaces
(4)Actuator Command Interfaces
●Effort Actuator Interface
●Velocity Actuator Interface
●Position Actuator Interface
(5)Force-torque sensor Interface
(6)IMU sensor Interface
hardware_interface作为ros_control 组件最重要的一部分,做了以下抽象:
●将能动的部分(类似于机器人关节)抽象为joint,joint类型有旋转,平动,固定等等,详见urdf,joint有三个属性,pose,velocity,effort,位置和速度好理解,effort不同的joint类型有不同的含义,一般是力矩,力(语义比较混乱在各个不同派系的开源代码中)。执行器模型抽象为actuator,与joint不一样的部分是actuator的属性值需要一定变换才能对应到joint,可以理解为电机减速,或者机构传动。
●根据不同的控制方式或者不同的传感器暴露出相应的数据接口,一般移动机器人底盘是速度闭环,而机械臂上又是位置闭环,根据这些控制方式的不同分出了不同的控制接口,暴露给上层的controller。
●作为机器人的硬件资源与上层的直接接口,可以被运行时产生与删除,结合机器人本身的通讯组件这样实际上实现了一种对机器人硬件资源的低层次管理。
而hardware_interface具体实现方式是存储对应状态变量的指针,用字符串表示不同的joint与Actuator资源。robothw基类是硬件通讯库与hardware_interface交互的部分。硬件通讯库具体的读写过程都在read与 write两个虚方法中实现,更新的数据放在robothw类的成员变量中,这些存储着joint与actuator状态与命令的空间被hardware_interface索引,传给controller_manager,通过controller_manager的接口将数据接给controller,所以ros_control内部不存在进程间通讯。
同样的,hardware_interface也可以自己创建需要的接口,可以参考:https://github.com/ros-controls/ros_control/wiki/hardware_interface
Transmissions
Transmissions就是机器人的传动系统,机器人每个需要运动的关节都需要配置相应的Transmission,可以通过代码完成https://github.com/ros-controls/ros_control/wiki/transmission_interface,但大部分情况下,都会在URDF文件中直接添加(http://ros.org/wiki/urdf/XML/Transmission)1
2
3
4
5
6
7
8
9
10<transmission name="simple_trans">
<type>transmission_interface/SimpleTransmission</type>
<joint name="foo_joint">
<hardwareInterface>EffortJointInterface</hardwareInterface>
</joint>
<actuator name="foo_motor">
<mechanicalReduction>50</mechanicalReduction>
<hardwareInterface>EffortJointInterface</hardwareInterface>
</actuator>
</transmission>
Joint Limits
Joint Limits是硬件抽象层中的一块,维护一个关节限位的数据结构,这些限位数据可以从机器人的URDF文件中加载,也可以ROS的参数服务器上加载(先用YAML配置文件导入ROS parameter server),这些限位数据不仅包含关节速度、位置、加速度、加加速度、力矩等方面的限位,还包含安全作用的位置软限位、速度边界(k_v)和位置边界(k_p)等等。
我们来看一个URDF中设置Joint Limits的例子:1
2
3
4
5
6
7<joint name="$foo_joint" type="revolute">
<!-- other joint description elements -->
<!-- Joint limits -->
<limit lower="0.0" upper="1.0" effort="10.0" velocity="5.0" />
<!-- Soft limits -->
<safety_controller k_position="100" k_velocity="10" soft_lower_limit="0.1" soft_upper_limit="0.9" />
</joint>
还有一些参数需要通过YAML配置文件先加载到参数服务器中,YAML文件的格式如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 joint_limits:
foo_joint:
has_position_limits: true
min_position: 0.0
max_position: 1.0
has_velocity_limits: true
max_velocity: 2.0
has_acceleration_limits: true
max_acceleration: 5.0
has_jerk_limits: true
max_jerk: 100.0
has_effort_limits: true
max_effort: 5.0
bar_joint:
has_position_limits: false # Continuous joint
has_velocity_limits: true
max_velocity: 4.0
另外,我们还可以在代码中使用joint_limits_interface来加载和设置关节的限位参数,可以参考:https://github.com/ros-controls/ros_control/wiki/joint_limits_interface
2.arbotix_ros
arbotix控制器是一款比较受欢迎的舵机驱动器,用于驱动BIOLOID和DYNAMIXEL舵机。
arbotix_ros是arbotix控制器的ROS软件包。利用arbotix_ros可以很方便通过ROS来控制小车运动。
2.1arbotix在ROS中的使用
在launch文件中添加arbotix插件,加载arbotix节点以及控制器配置文件。1
2
3
4<node name="arbotix" pkg="arbotix_python" type="arbotix_driver" output="screen">
<rosparam file="$(find smartcar_description)/config/smartcar_arbotix.yaml" command="load" />
<param name="sim" value="true"/>
</node>
关于arbotix_python可参考:http://wiki.ros.org/arbotix_python
在config文件夹目录下创建一个.yaml文件,用于配置小车的控制器base_controller。1
2
3
4
5
6
7
8
9
10
11
12
13controllers: {
base_controller: {
type: diff_controller,
base_frame_id: base_footprint,
base_width: 0.16,
ticks_meter: 4100,
Kp: 12,
Kd: 12,
Ki: 0,
Ko: 50,
accel_limit: 1.0
}
}
说明:
●type表示控制器类型,diff_controller是两轮差速的控制器。
●base_frame_id表示参考的坐标系。
●base_width在这里表示左右两个轮子的间距,单位米。
●ticks_meter表示编码器精度,单位是tick/米。
●Kp、Kd和Ki分别表示PID的三个参数,即比例、微分和积分。
●Ko表示PID的缩放比例参数。
●accel_limit表示加速度的限位。
详情可参考:http://wiki.ros.org/arbotix_python/diff_controller