前言:该篇是ROS学习记录的第二篇,如果还没关注过之前文章的读者,如有需要可以通过下方传送门去看之前的文章:
ROS学习记录(一) Plugin插件
这两天关注了古月老师的公众号,看到了其中一篇课程推荐:
好课推荐|《如何在Gazebo中实现阿克曼转向车的仿真》课程优惠中 (qq.com)
寻思着过段时间实验室买的新车是基于阿克曼转向的,而之前学的ROS小车导航定位等算法大多都是基于两轮差分的车辆模型。为了更贴近今后实验室的机器人平台及真实车辆的模型,又正好看到了古月老师推荐的课程,便咬咬牙和另外两位同僚花了点钱拼下了课程。古月老师的课程共五讲,那我这个系列接下来3篇左右的文章就记录一下我学习该课程的一些总结和思考。
今天这篇文章主要是阿克曼转向车辆运动学模型分析,及在gazebo中搭建阿克曼转向车辆的仿真环境。
一、阿克曼转向车辆运动学模型
1、车辆转向模型
通常来说,车辆转向模型大致可以分为四种:
① 差速转向模型; ② 麦克纳姆轮模型;
③ 履带模型; ④ 阿克曼转向模型。
图片来源:古月居课程及百度图片
不像其他三种转向模型可以实现原地旋转或通过轮胎、履带差速的方式控制车辆的转向和速度,阿克曼转向模型具有后轮驱动、前轮转向的特点,这可以很自然的让我们联想到日常乘坐的民用汽车,的确当今民用汽车所使用的都是阿克曼转向模型,因此了解阿克曼转向原理对后续不论是实验车或者真车的无人驾驶实验都是很重要的。
2、阿克曼转向运动学模型
由阿克曼转向的特点,可以将其转向模型表示成如下形式:
即要求车辆转向时,左右前轮的瞬时转向中心重合于后轮所在直线上的同一点,因此实际上车辆转弯时内侧轮的转向角度要略微大于外侧轮的转向角度,两个轮子呈一个梯形而非平行四边形:
图片来源:https://www.icauto.com.cn/baike/71/716170.html
为了便于分析,通常可以将模型进行简化,即在前轮中心和后轮中心各假想一个轮胎来代表前后轮的运动,即所谓的单车模型:
控制量通常选取后轮速度及前轮转角 ,状态量选取世界坐标系下的坐标,及航向角,则阿克曼转向的运动学模型可以表示为:
对应的里程计模型为:
二、在gazebo中搭建仿真环境
1、源码下载
在工作空间中下载课程源码:Zeende/racecar_sim (gitee.com),共包含三个文件夹:
将其中的smartcar_plane功能包复制到.gazebo/models文件夹下,该功能包包含了gazebo中的仿环境模型文件。
2、阿克曼转向模型
由于阿克曼转向前轮部分实际上是通过四连杆机构来进行控制,而urdf模型中无法直接添加四连杆机构,所以这里采用的方式是给车辆前轮设定一个旋转轴。除了轮胎本身可以绕水平轴旋转外,还可以绕着一根假象的与地面垂直的轴进行旋转,从而改变前轮转向角。
图片来源:古月居课程
在racecar.urdf.xacro车辆模型的描述文件中,可以找到对前轮部分垂直于地面旋转轴的描述的相关代码:
...
<joint name="${lr_prefix}_steering_joint" type="revolute">
<parent link="${lr_prefix}_steering_link"/>
<child link="${lr_prefix}_${fr_prefix}_axle_carrier"/>
<axis xyz="0 0 1"/>
<limit lower="${-degrees_45}" upper="${degrees_45}"
effort="${servo_stall_torque}" velocity="${servo_no_load_speed}"/>
</joint>
...
可以注意到这里添加的joint定义了一个<axis xyz=”0 0 1″/>,即允许前轮绕z轴旋转,旋转的角度为<limit lower=”${-degrees_45}” upper=”${degrees_45}”,即-45°到+45°,这里采用宏定义的方式将角度转化为了弧度:
...
<xacro:property name="degrees_45" value="0.785398163"/>
<xacro:property name="degrees_90" value="1.57079633"/>
...
其它部分对轮胎的定义与差速小车相同。在最后需要将定义好的车辆前后轮模型进行引用:
...
<xacro:front_wheel lr_prefix="left" fr_prefix="front"
lr_reflect="1" fr_reflect="1"/>
<xacro:front_wheel lr_prefix="right" fr_prefix="front"
lr_reflect="-1" fr_reflect="1"/>
<xacro:rear_wheel lr_prefix="left" fr_prefix="rear"
lr_reflect="1" fr_reflect="-1"/>
<xacro:rear_wheel lr_prefix="right" fr_prefix="rear"
lr_reflect="-1" fr_reflect="-1"/>
...
3、launch文件设置
① 在racecar_gazebo.launch文件中添加设置好的机器人模型:
...
<!-- 加载机器人模型描述参数 -->
<param name="robot_description" command="$(find xacro)/xacro --inorder '$(find racecar_description)/urdf/racecar.urdf.xacro'"/>
<!-- 在gazebo中加载机器人模型-->
<node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
args="-urdf -model racecar -param robot_description -x $(arg x_pos) -y $(arg y_pos) -z $(arg z_pos)"/>
...
需要注意的是,xacro文件无法直接加入到gazebo中,需要通过工具转化为参数放在robot_description中。
② 加载仿真环境模型
<!-- 设置launch文件的参数 -->
<arg name="paused" default="false"/>
<arg name="use_sim_time" default="true"/>
<arg name="gui" default="true"/>
<arg name="headless" default="false"/>
<arg name="debug" default="false"/>
...
<!--运行gazebo仿真环境-->
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="debug" value="$(arg debug)" />
<arg name="gui" value="$(arg gui)" />
<arg name="paused" value="$(arg paused)"/>
<arg name="use_sim_time" value="$(arg use_sim_time)"/>
<arg name="headless" value="$(arg headless)"/>
<arg name="world_name" value="$(find racecar_description)/worlds/racetrack.world"/>
</include>
③ 设置小车初始位置
...
<!--模型车的起点放置位置-->
<arg name="x_pos" default="-0.5"/>
<arg name="y_pos" default="0"/>
<arg name="z_pos" default="0.0"/>
...
4、加载模型
在终端中运行launch文件
roslaunch bringup racecar_gazebo.launch
最终效果如下:
结语
本篇主要介绍了阿克曼转向车辆的运动学模型,及在gazebo中加载仿真环境。
目前为止程序中还没添加控制器及发布里程计数据,所以在rviz中仅能看到车辆模型,但无法通过keyboard控制,小车原地不动。
下一篇中我会根据古月老师的课程讲解,说明一下给小车添加ros_control功能以实现对小车控制的过程,及自定义发布里程计数据的程序。
文章如有侵权的地方,请及时与我联系修改。
文章出处登录后可见!