0 写在前面
在本系列博客中将主要介绍:
- ROS中的控制器插件
- 让之前博客中设计的移动机器人跑起来
- 使用博客中设计的移动机器人对我们搭建的gazebo环境进行建图
- 在已知地图上使用
AMCL
实现机器人定位,为之后的自主导航做准备工作 - 在已知地图上使用
move_base
实现机器人自主导航 - 实现机器人自主建图
在本博客中将先介绍1-3
1 ROS中的控制器插件
为什么要用控制器插件
-
Reason 1(原理角度). 我们一定希望我们操纵的机构能够快速,稳定,无误差的到达我们期望的状态,以智能车为例,当给定智能车的期望角速度和线速度时,我们希望智能车能够又快又准确的到达我们的速度目标,这又强调我们需要给定真正驱动小车行走的机构(电机,舵机)合适的信号,如何根据输入量(期望的角速度和线速度)获得执行机构(电机,舵机)的控制量呢,这就需要控制器串联其中,值得一提的是,我们绝大多数使用PID控制器。
-
Reason 2(应用角度). ROS中的控制器插件不仅仅为了我们提供了单纯的控制器,在官方文档中有着这样的描述:
为了成功发送速度指令给到机器人底盘,需要以下几个部分:
- 直接控制电机的基本速度控制器(the base velocity controller that directly commands the motors)
- 基本里程计控制器(the base odometry controller)
- 发送速度命令的高级程序(a higher-level program to send the velocity commands)
让我们来逐一分析这三个部分,对于第一个速度控制器可以由PID控制器充当,第三个高级程序可以由键盘控制指令,rostopic pub指令等等充当,那么第二个由谁提供呢?答案是简单的,我们的差速控制器插件集成了里程计控制器,因此为了成功让我们的小车动起来必须包含一个控制器插件。
两个差速控制器插件
在之前的系列中,大家可以看到的是,我们的小车拥有两个主动轮,两个万向从动轮,因此,我们的小车应当使用差速驱动。同时,心细的小伙伴可以发现在之前博客的launch
文件(URDF与Rviz集成)中,我们包含了arbotix
节点,这正是我们介绍的第一种差速控制器;同样是这个博客中,在Xacro文件夹的move.xacro文件中,大家可以看到我们包含了differential_drive_controller插件,这也正是我们要介绍的第二种差速控制器
Rviz中的arbotix
它是在Rviz(机器人的感知世界)中进行使用,它跟Gazebo软件比较,它不能模拟物理现象和没有传感器反馈,对于本系列中的移动机器人,它使用的是差速控制模式,需要调整的参数包含在control.yaml
中,有如下:
controllers: {
# 单控制器设置
base_controller: {
#类型: 差速控制器
type: diff_controller,
#参考坐标
base_frame_id: base_footprint,
#两个轮子之间的间距
base_width: 0.2,
#控制频率
ticks_meter: 2000,
#PID控制参数,使机器人车轮快速达到预期速度
Kp: 12,
Kd: 12,
Ki: 0,
Ko: 50,
#加速限制
accel_limit: 1.0
}
}
- 通过查看yaml文件,我们可以从另外的一个角度验证设计base_footprint的重要性,而在本机器人中base_width的取值则是base_link(长方体)的长(0.2)
- 笔者的博客中并没有只针对arbotix控制器的实验,感兴趣的伙伴可以查看:
https://blog.csdn.net/qq_43481884/article/details/105433575 -
总的来说,arbotix订阅/cmd_vel,并会做出相应操作,驱动小车做运动,再根据 Tf 变换,将小车的运动姿态,实时在 rviz 中显示出来,其中值得一提的是,提供TF变换的功能主要由robot_state_publisher功能包提供,这里也简单的对robot_state_publisher的应用加以介绍一下:
- 在前面关于机器人建模的系列博客中,其实我们主要对两个系统进行了仿真,一是机器人感知世界Rviz,二是机器人仿真物理世界Gazebo,细心的伙伴在看我们编写的launch文件时不难发现,只跟gazebo有关的launch文件并不需要包含此功能包,然而包含Rviz的launch的文件则必须提供此功能包,这就是我们要介绍的第一个功能——提供机器人系统的各坐标系间状态(TF树),用于Rviz显示
- 在之后将要介绍关于机器人的一些上层应用层(AMCL,move_base,slam等)博客中,这些功能包的实现都要求获取传感器间坐标系关系,关节间坐标系关系,进而得以实现数据的坐标间转换等功能,robot_state_publish就负责提供机器人系统的各坐标系关系(TF树),作为这些应用的其中一个输入
- joint_state_publisher经常与robot_state_publisher一同出现,他的作用和与robot_state_publisher的关系大家可以查看这篇博客
-
更详细的内容可以查看官方文档:http://wiki.ros.org/arbotix
gazebo中的differential_drive_controller
gazebo本身就提供差动控制器插件,控制器作用同arbotix一样,订阅/cmd_vel,驱动小车做运动,区别在于在设计gazebo中差速控制器插件之前,需要实现指定哪些关节是驱动关节,以及是什么类型的驱动器,具体详情可以看下面提供的文档:
- 官方文档写的已经相当详尽,就不再造轮子了,官方的文档地址:
http://gazebosim.org/tutorials?tut=ros_gzplugins#PlanarMovePlugin
值得一提的是,此官方文档详细介绍了之前博客所说的各个传感器插件,感兴趣的伙伴可以再看一看 - 或者大家可以看这篇博客写的也很是详细
2 让机器人动起来
当搭载运动控制器之后,我们向/cmd_vel话题发布速度信息即可实现机器人电机驱动,即机器人移动,这里我们可以使用ROS提供的键盘控制节点rosrun teleop_twist_keyboard teleop_twist_keyboard.py
同样的,我们也可以使用rostopic
指令向/cmd_vel
发送速度信息致使机器人移动rostopic pub -r 10 /cmd_vel geometry_msgs/Twist '{linear: {x: 0.2, y: 0, z: 0}, angular: {x: 0, y: 0, z: 0.5}}'
3 建图(SLAM)
我们在此过程中选择的是官方提供的gmapping节点,同时微调一些参数。
- 第一步需要做的是使用在博客中xacro与gazebo与rviz的集成roslaunch指令
roslaunch hw_car_gazebo.launch所在绝对路径
-
第二步启动gmapping节点,这里采用我们自己编写的launch文件,取名叫
slam_my.launch
文件位置不重要,有如下:<launch> <param name="use_sim_time" value="true"/> <!--gmapping包--> <node pkg="gmapping" type="slam_gmapping" name="slam_gmapping" output="screen"> <!--设置雷达话题--> <remap from="scan" to="scan"/> <param name="base_frame" value="base_footprint"/><!--底盘坐标系--> <param name="odom_frame" value="odom"/> <!--里程计坐标系--> <param name="map_update_interval" value="5.0"/> <param name="maxUrange" value="16.0"/> <param name="sigma" value="0.05"/> <param name="kernelSize" value="1"/> <param name="lstep" value="0.05"/> <param name="astep" value="0.05"/> <param name="iterations" value="5"/> <param name="lsigma" value="0.075"/> <param name="ogain" value="3.0"/> <param name="lskip" value="0"/> <param name="srr" value="0.1"/> <param name="srt" value="0.2"/> <param name="str" value="0.1"/> <param name="stt" value="0.2"/> <param name="linearUpdate" value="1.0"/> <param name="angularUpdate" value="0.5"/> <param name="temporalUpdate" value="3.0"/> <param name="resampleThreshold" value="0.5"/> <param name="particles" value="30"/> <param name="xmin" value="-50.0"/> <param name="ymin" value="-50.0"/> <param name="xmax" value="50.0"/> <param name="ymax" value="50.0"/> <param name="delta" value="0.05"/> <param name="llsamplerange" value="0.01"/> <param name="llsamplestep" value="0.01"/> <param name="lasamplerange" value="0.005"/> <param name="lasamplestep" value="0.005"/> </node> <node pkg="joint_state_publisher" name="joint_state_publisher" type="joint_state_publisher" /> <node pkg="robot_state_publisher" name="robot_state_publisher" type="robot_state_publisher" /> <!-- <node pkg="rviz" type="rviz" name="rviz" /> --> <!-- 可以保存 rviz 配置并后期直接使用--> <!-- <node pkg="rviz" type="rviz" name="rviz" args="-d $(find my_nav_sum)/rviz/gmapping.rviz"/> --> </launch>
指令为:
roslaunch slam_my.launch所在绝对路径
- 第三步启动键盘控制节点指令:
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
- 第四步当建图完成后,调用map_save.launch:
roslaunch map_save.launch所在绝对路径
文件位置不重要,有如下:
其中filename参数对应建好地图的存放位置,地图读取需要输入此参数<launch> <arg name="filename" value="$(find myNav)/map/map03" /> <node name="map_save" pkg="map_server" type="map_saver" args="-f $(arg filename)" /> </launch>
- 可以利用指令
rosrun rqt_gragh rqt_gragh
观察slam过程节点状态
最后生成的地图如下:
4 写在最后
SLAM的全称是simultaneous localization and mapping,即同步定位与建图,可见其本身就带有定位里程计的功能,而在下一篇博客中,我将首先单独介绍AMCL这一定位节点,接着使用move_base节点订阅AMCL的tf消息进行机器人自主导航,最后将amcl、move_base节点和本博客介绍的gmapping节点进行串联,实现机器人的自主环境建图
评论(0)
您还未登录,请登录后发表或查看评论