第七章建模与仿真分为上、中、下三节。
一、ROS_Control
针对不同机器人,ros_control提供多种类型控制器。控制器接口不相同,所以ros_control提供一个硬件抽象层,专门管理机器人硬件资源。control从抽象层请求资源,并不直接与硬件打交道。
1. 概念
Controller Manager
提供通用接口来管理不同的控制器。
Controller
使用控制器(比如PID)完成对每个关节的控制。他读取硬件资源接口中的真实状态,再发布控制命令。形成闭环控制。
RobotHW
机器人硬件抽象,通过读写方法直接与机器人硬件打交道。
Real robot
真实机器人上的嵌入式控制器,将接受到的命令传递到执行器。同时机器人身体上的传感器(编码器)将机器人当前状态传递回RobotHW
2. 控制器
目前功能包提供的控制器包括:
-
effort_controllers: 控制关节的力或者力矩
- joint_effort_controller:输入为力,输出为力
- joint_position_controller:输入为位置,输出为力(PID)
- joint_velocity_controller:输入为速度,输出为力(PID)
-
joint_state_controller: 发布所有注册在RobotHW上的硬件关节状态. 数据格式如下图
-
position_controllers: 一次性设置一到多个关节位置
- joint_position_controller
- joint_group_position_controller
-
velocity_controllers: 一次性设置一到多个关节的速度
- joint_velocity_controller
- joint_group_velocity_controller
-
joint_trajectory_controllers:控制整条轨迹
- position_controller
- velocity_controller
- effort_controller
- position_velocity_controller
- position_velocity_acceleration_controller
上述官方提供的控制器不合你意的话,可以自己通过Control manager实现自己的控制器。
3. 硬件接口
以上说的控制器,在收发命令的时候,需要用到与之对应的硬件接口。通过硬件接口来与RobotHW打交道。官方提供的接口有如下几种,具体就不再细说,🔗。
4. 传动装置
将对关节的指令转换为控制信号,实现具体的控制。
我们在撰写urdf的时候,每个不是fixed
的关节,都需要指定对应的传动系统。
<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>
5. 关节限制
对各个关节进行各种限制:位置速度,力,加速度,jerk等等
不止有硬约束,还有各种软约束:比如位置范围,速度范围。
加载的时候有两种途径:
第一:通过urdf文件的<limit>
标签
第二:写成yaml文件,直接用参数服务器load进来
6. controller manager
可以实现控制器的加载,运行,卸载等操作。就是用来管理上面提到的一大堆控制器。
我们在实现的时候,不需要跟每个控制器打交道。直接在manager上指定load对象即可。这大大方便我们的使用。
最常见的启动方法,就是集成在launch文件中,作为node节点来启动,指定arg参数即可将想要传入的控制器load进来。
举例:
<launch>
<node pkg="controller_manager"
type="spawner"
args="controller_name1 controller_name2" />
</launch>
在第七章下篇中,我们还有更多丰富的案例。
二、ArbotiX差分控制器
在一些简单场景,我们通常使用rviz + ArbotiX构建运动仿真器,使用rviz作为仿真场景就够用了。
本小节我们来实现依赖ArbotiX的机器人仿真。
注意
这个仿真只是模拟了机器人的base_link 相对于odom的tf变换,并没有实际控制轮子转动。
1. 安装
sudo apt-get install ros-melodic-arbotix
笔者的ros系统为melodic,各位看官根据自己环境安装对应功能包。
安装成功后如上图所示,五个相关功能包会被安装。
2. 关键功能包
arbotix_python
是关键功能包,提供与ros相关的接口。功能包中的节点arbotix_driver
做详细解释。(笔者的ros系统为melodic)
对diff_controller
控制器类型:
节点订阅:
/cmd_vel (geometry_msgs/Twist)
move_base发布的速度指令
节点发布:
/odom (nav_msgs/Odometry)
navigation stack 需要的TF坐标变换:odom → base_link
,可以用来说明当前坐标位置。
节点参数配置:
参数比较多,通常使用yaml文件直接对节点进行配置,然后用launch文件批量load。
常见的配置参数如下
port: /dev/ttyUSB0
baud: 115200
rate: 20
sync_write: True
sync_read: True
read_rate: 20
write_rate: 20
controllers: {
# Pololu motors: 1856 cpr = 0.3888105m travel = 4773 ticks per meter (empirical: 4100)
base_controller: {type: diff_controller, base_frame_id: base_footprint, base_width: 0.26, ticks_meter: 4100, Kp: 12, Kd: 12, Ki: 0, Ko: 50, accel_limit: 1.0 }
}
前面端口收发等参数是面对真实控制器而言,如果是仿真环境,直接配置参数 sim
= true 即可
关键参数controllers解释:
- 控制器名称:
base_constoller
- 控制类型:
diff_controller
差速控制器,对应差速运动的双轮机器人 - 参考坐标系:
base_footprint
(根据自己情况更改) - 编码器编码次数/m:
ticks_meter
- 机器人底盘宽度:
base_width
- pid 以及加速度限制
节点launch文件:
<launch>
<node name="arbotix" pkg="arbotix_python" type="arbotix_driver" output="screen">
<rosparam file="$(find your_package)/default.yaml" command="load" />
<param name="sim" value="true"/>
</node>
</launch>
3. 实例
根据我的实验观察,/arbotix
节点完全不发布/joint_states,仅仅是根据cmd_vel指令推算出来odom和tf
所以这个控制器的仿真,意义不大,根本不是在控制轮子转动,有点被骗了。除非你自己按照他的这套逻辑,重写/arbotix
节点