深蓝学院ros学习总结
对于深蓝学院课程来说,最最基础的部分在于模型的建立,因为所有的运行都是基于仿真环境,无论是rviz还是gazebo环境。
模型的建立分为两种:urdf模型文件、xacro模型文件
两者的区别:
一、建立机器人模型
1.在模型建立上
urdf文件需要给每个连接link与关节joint设置他们的形状、颜色、坐标,即使只是位置不同的两个link和joint都要重新进行书写,所以整个文件显得非常庞大冗余。程序类似于:
<joint name="back_caster_joint" type="continuous">
<origin xyz="-0.18 0 -0.095" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="back_caster_wheel"/>
<axis xyz="0 1 0"/>
</joint>
<link name="back_caster_wheel">
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<sphere radius="0.015"/>
</geometry>
<material name="black">
<color rgba="0 0 0 1"/>
</material>
</visual>
</link>
xacro文件就是针对这个问题去解决的,xacro使用相当于类一样的文件描述,将特征相似的link和关节直接进行宏定义,相当于编程中的class类,调用时只需要给他们传入不同的参数就可以实现功能。因为减少了urdf重复性的工作,所以整个程序显得非常简短。而且,xacro文件可以进行宏定义与常数定义,宏定义就相当与之前所说的类,而常数定义就是相当于设置一个变量名,在宏定义中可以被引用,这样参数修改起来会比较方便,同时也可以进行数学计算,方便了参数设置。
常量设置:
<xacro:property name="M_PI" value="3.1415926"/>
<xacro:property name="base_radius" value="0.20"/>
<xacro:property name="base_length" value="0.16"/>
常量调用:
<child link="${prefix}_wheel_link"/>
宏定义:
<xacro:macro name="wheel" params="prefix reflect">
<joint name="${prefix}_wheel_joint" type="continuous">
<origin xyz="0 ${reflect*wheel_joint_y} ${-wheel_joint_z}" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="${prefix}_wheel_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="${prefix}_wheel_link">
<visual>
<origin xyz="0 0 0" rpy="${M_PI/2} 0 0"/>
<geometry>
<cylinder radius="${wheel_radius}" length="${wheel_length}"/>
</geometry>
<material name="gray"/>
</visual>
</link>
</xacro:macro>
宏定义调用:
<wheel prefix="left" reflect="-1"/>
<wheel prefix="right" reflect="1"/>
2. 在xml文件书写上
urdf文件开头直接是xml文件声明<?xml version="1.0"?>,这个与xacro文件相同,不同点在于书写标签时,urdf文件直接是开头并以结尾,在其中间部分书写模型描述程序。
xacro文件则不然,需要有一个xacro文件的声明:
<robot name="mbot" xmlns:xacro="http://www.ros.org/wiki/xacro">结尾也是以</robot>结尾
3. 在launch文件调用上
urdf文件的调用显示在rviz上直接使用命令:
<param name="robot_description" textfile="$(find robot_description)/urdf/robot_base.urdf"/>
来调用,调用的文件是直接的urdf文件。
xacro文件由于其是以宏定义的类型完成的,所以不能够直接进行调用,需要在launch文件中加入:
<arg name="model" default="(find xacro)/xacro --inorder '(find robot_description)/xacro/xacro/robot.xacro'"/>
<param name="robot_description" command="$(arg model)"/>
来完成对于xacro文件的转化调用,直接就可以通过launch文件运行。
还有一种方法就是先将xacro文件转化为urdf文件,再通过urdf的launch文件配置进行调用。转化命令如下:
rosrun xacro xacro.py robot_base.xacro > robot.urdf
注:
由于直接写好的xacro文件实际上只是一个模型的描述的类文件,没有运行的函数,所以还要有一个xacro文件作为总文件将其统一起来,同时也是方便以后再添加其他的模型结构。类似于搭积木,模块化。整体文件调用:<mbot_base/>
二、Abortix控制器的在模型中的运用
建立好一个模型之后,我们通过运行launch文件就能够在rviz中看到模型的显示,但是这只是简单的显示,肯定不是我们想要的,我们肯定想让小车能够动起来。这里就要用到Abortix控制器了。
操作步骤:
1.先下载好abortix_ros功能包,这是ros提供的。下载命令如下:
git clone https://github.com/vanadiumlabs/arbotix_ros.git
然后对该功能包进行编译。(python文件需要添加可执行权限)
2.配置launch文件
在显示模型的launch文件中只需要添加:下面这两句命令就可以啦!!
<node name="arbotix" pkg="arbotix_python" type="arbotix_driver" output="screen">
<rosparam file="$(find robot_description)/config/fake_mbot_arbotix.yaml"
command="load"/>
<param name="sim" value="true"/>
</node>
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find
robot_description)/config/mbot_arbotix.rviz" required="true"/>
要注意的是这个 fake_mbot_arbotix.yaml文件,因为Abortix是一个控制器,对于控制来说肯定是要一个控制参数的,yaml文件就是Abrotix的参数配置,里面是控制器文件,如下:
controllers: {
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
}
}
其中运用了pid控制,可以自己修改参数。同时里面还有机器人的控制方式、控制的坐标系、以及车身宽度和发布速率。
打开rviz界面之后,可以通过运行roslaunch mbot_teleop mbot_teleop.launch
用键盘控制模型进行运动,这是深蓝学院提供的键盘控制包。
小车模型
三、建立gazebo模型
前面几个步骤所建立的模型文件只是单纯的一个模型,只是可见而已,说白了就是空有其表,与真实的机器人还有很大的差别,因为真实的机器人是有物理属性的,而且所处的环境都是一个物理环境。rviz只是一个可视化平台,可以进行算法方面的验证,要实现机器人与真实环境一样的运行就需要gazebo环境,而涉及到gazebo环境就需要配置能在gazebo环境下运行的模型文件。
1. 模型参数配置
gazebo环境下的模型是基于之前所建立的xacro模型或者是urdf模型,但是从简化来说,还是运用xacro模型比较好。将一个xacro模型转换为gazebo_xacro模型,需要经过以下几个步骤:
1)给link设置物理属性,包括碰撞属性、惯性矩阵
2)给link设置标签,主要是配置模型在gazebo中的颜色,因为rviz模型颜色与gazebo环境颜色不兼容。
3)给joint添加传动装置
4)添加控制器插件
gazebo模型配置完成之后,调用文件与xacro文件的总文件内容是一致的。
下面举例说明:
1)给link设置物理属性,包括碰撞属性、惯性矩阵、质量
质量定义:
<xacro:property name="base_mass" value="20"/>
<xacro:property name="wheel_mass" value="2"/>
<xacro:property name="caster_mass" value="0.5"/>
设置碰撞属性:
<collision>
<origin xyz="0 0 0" rpy="${M_PI/2} 0 0"/>
<geometry>
<cylinder radius="${wheel_radius}" length="${wheel_length}"/>
</geometry>
</collision>
设置惯性矩阵:
<xacro:macro name="cylinder_inertial_matrix" params="m r h">
<inertial>
<mass value="${m}"/>
<inertia ixx="${m*(3*r*r+h*h)/12}" ixy="0" ixz="0"
iyy="${m*(3*r*r+h*h)/12}" iyz="0"
izz="${m*r*r/2}"/>
</inertial>
</xacro:macro>
<cylinder_inertial_matrix m="${wheel_mass}" r="${wheel_radius}" h="${wheel_length}"/>
这里,惯性矩阵的设置是通过一个宏定义的方式完成的,主要原因是每种形状的物体都有它特定的惯性矩阵的计算方法,设置为宏定义更加方便后面调用。
2)给link设置标签
<gazebo reference="${prefix}_wheel_link">
<material>Gazebo/Gray</material>
</gazebo>
3)给joint添加传动装置
<transmission name="${prefix}_wheel_joint_trans">
<type>transmission_interface/SimpleTransmission</type>
<joint name="${prefix}_wheel_joint"> <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
</joint>
<actuator name="${prefix}_wheel_joint_motor"> <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
4)添加控制器插件
<gazebo>
<plugin name="differential_drive_controller"
filename="libgazebo_ros_diff_drive.so">
<rosDebugLevel>Debug</rosDebugLevel>
<publishWheelTF>true</publishWheelTF>
<robotNamespace>/</robotNamespace>
<publishTf>1</publishTf>
<publishWheelJointState>true</publishWheelJointState>
<alwaysOn>true</alwaysOn>
<updateRate>100.0</updateRate>
<legacyMode>true</legacyMode>
<leftJoint>left_wheel_joint</leftJoint>
<rightJoint>right_wheel_joint</rightJoint>
<wheelSeparation>${wheel_joint_y*2}</wheelSeparation>
<wheelDiameter>${2*wheel_radius}</wheelDiameter>
<broadcastTF>1</broadcastTF>
<wheelTorque>30</wheelTorque>
<wheelAcceleration>1.8</wheelAcceleration>
<commandTopic>cmd_vel</commandTopic>
<odometryFrame>odom</odometryFrame>
<odometryTopic>odom</odometryTopic>
<robotBaseFrame>base_footprint</robotBaseFrame>
</plugin>
</gazebo>
**launch文件配置**
gazebo模型的launch文件与之前的文件有不同也有相似的地方。相同的地方在于都需要把所要使用的模型给加载进来,并需要运行joint_state_publisher节点和robot_state_publisher节点。不同的地方这里由于环境已经变为了gazebo环境,所以需要配置gazebo环境参数,然后再打开gazebo环境。
gazebo环境配置:
<!-- 设置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">%运行一个空的gazebo环境
<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)"/>
</include>
<node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false"
output="screen" args="-urdf -model mrobot -param robot_description"/>
**给模型添加传感器**
由于传感器需要被添加到模型上面,同时也需要配置物理参数以及传感器特有属性,所以一般将传感器单独建立一个xacro模型同时配置好gazebo环境参数,以及传感器特有的一些参数(这些参数都可以在ros_wiki上面找到其代表的含义的),最后将其以一个模块的形式添加到建立好的机器人模型和上面,就好象是一个在已经搭建好的积木上再添加一个模块。
由于之前的模型搭建上面都是一样的,这里只是列出rplidar的控制器插件和组合的情况:
控制器插件:
<gazebo reference="${prefix}_link">
<sensor type="ray" name="rplidar">
<pose>0 0 0 0 0 0</pose>
<visualize>false</visualize>
<update_rate>5.5</update_rate>
<ray>
<scan>
<horizontal>
<samples>360</samples>
<resolution>1</resolution>
<min_angle>-3</min_angle>
<max_angle>3</max_angle>
</horizontal>
</scan>
<range>
<min>0.10</min>
<max>6.0</max>
<resolution>0.01</resolution>
</range>
<noise>
<type>gaussian</type>
<mean>0.0</mean>
<stddev>0.01</stddev>
</noise>
</ray>
<plugin name="gazebo_rplidar" filename="libgazebo_ros_laser.so">
<topicName>/scan</topicName>
<frameName>laser_link</frameName>
</plugin>
</sensor>
</gazebo>
与机器人组装到一起:
在原gazebo模型的总xacro文件中添加如下代码,就可以实现将一个激光雷达添加到机器人上,并且实现其雷达功能。(雷达功能的实现主要是通过上面的控制器插件来实现)
<xacro:include filename="$(find robot_description)/xacro/gazebo/lidar_gazebo.xacro"/>
<xacro:property name="lidar_offset_x" value="0" />
<xacro:property name="lidar_offset_y" value="0" />
<xacro:property name="lidar_offset_z" value="0.105" />
<!-- lidar -->
<joint name="lidar_joint" type="fixed">
<origin xyz="${lidar_offset_x} ${lidar_offset_y} ${lidar_offset_z}" rpy="0 0 0" />
<parent link="base_link"/>
<child link="laser_link"/>
</joint>
<xacro:rplidar prefix="laser"/>
Gazebo仿真环境
注:到这里,一个gazebo环境下的模型就已经搭建完毕,同时提供其运行的launch文件也已经配置完毕,运行launch文件就可以打开gazebo环境同时小车也会出现在环境中。
在这里也可以调用roslaunch mbot_teleop mbot_teleop.launch
文件来通过键盘来控制模型在gazebo环境中运动。
4. gazebo中添加与保存地图以及调用地图。
由于gazebo环境是一个仿真实的物理环境,所以提供了很多场景来添加到空环境中。同时也可以自己创建一个环境。点击工具栏editor选项来创建自己的gazebo环境,创建完成之后点击保存。保存完毕之后就可以点击退出编辑环境进入gazebo环境,再次进行保存,,保存的文件格式是.world的格式。之后就可以通过launch文件直接将该环境直接打开了。
在原来的launch文件中添加:
<arg name="world_name" value="$(find robot_description)/world/room.world"/>
<arg name="world_name" value="$(arg world_name)"/>
就可以实现将保存好的世界在运行gazebo环境时就添加进来了。
好啦,上面都是建立模型的过程,也就是地基部分,为自己创建一个虚拟机器人的过程,下面就可以通过建立好的gazebo模型进行slam建图定位导航的功能了。这里理解建立一个虚拟模型的意义在于可以不受硬件条件的限制,只需要一台电脑就可以呈现机器人运动建图等功能的效果。同时,一个机器人模型建立之后除非你要改变机器人或者添加新的传感器,否则建立好的模型是不必要再调整变化的,只需要专注于算法的研究就可以啦!
slam是即时定位与地图构建,这就涉及到两个方面,一个就是把地图建立出来(分为三种方法,手动操作机器人进行的建图、在空间内选择目标点建图、自主探索空间建图),另一个方面就是在建立好的地图上面找到自己的位置(定位),最后定位好之后进行路径规划和导航。
四, 使用ros提供的功能包进行地图构建
1. gmapping实现的地图构建
1)首先安装gmapping功能包。
sudo apt-get install ros-kinetic-gmapping
- 安装好功能包之后就可以进行配置使用,功能包的使用比较简单,主要是进行launch文件的参数配置和包的调用。gmapping包要运用需要提供的参数是激光雷达和里程计的信息,所以需要进行参数配置,这个配置的参数比较多,具体每个参数名称代表什么意思可以直接在百度上找gmapping,进入roswiki里面有详细的解释。网址:http://wiki.ros.org/gmapping/
参数配置完成之后可以通过另外一个launch文件调用参数launch文件并启动rviz界面进行建图效果显示。
参数设置launch文件:
<launch>
<arg name="scan_topic" default="scan" />
<node pkg="gmapping" type="slam_gmapping" name="slam_gmapping" output="screen"
clear_params="true">
<param name="odom_frame" value="odom"/>
<param name="map_update_interval" value="5.0"/>
<!-- Set maxUrange < actual maximum range of the Laser -->
<param name="maxRange" value="5.0"/>
<param name="maxUrange" value="4.5"/>
<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.01"/>
<param name="srt" value="0.02"/>
<param name="str" value="0.01"/>
<param name="stt" value="0.02"/>
<param name="linearUpdate" value="0.5"/>
<param name="angularUpdate" value="0.436"/>
<param name="temporalUpdate" value="-1.0"/>
<param name="resampleThreshold" value="0.5"/>
<param name="particles" value="80"/>
<param name="xmin" value="-1.0"/>
<param name="ymin" value="-1.0"/>
<param name="xmax" value="1.0"/>
<param name="ymax" value="1.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"/>
<remap from="scan" to="$(arg scan_topic)"/>
</node>
</launch>
参数配置以及启动rviz的launch文件:
<launch>
<include file="$(find
slam_beginner)/launch/gmapping_slam/gmapping_base_params.launch"/>
<!--启动rviz-->
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find
slam_beginner)/rviz/gmapping.rviz"/>
</launch>
3)运行,进行建图以及地图保存
打开带有环境的gazebo模型文件,然后运行参数配置以及启动rviz的launch文件。这两步完成后就可以打开gazebo环境和rviz可视化环境,并且可以在rviz界面中看到激光点。
运行:
roslaunch mbot_teleop mbot_teleop.launch
打开键盘控制节点进行建图。当机器人已经建立完成所有的地图后,可以运行
rosrun map_server map_saver -f
地图名 保存已经建立好的地图。
2. hector包进行地图构建
1)首先下载安装hector包
sudo apt-get install ros-kinetic-hector-slam
2)hector包的使用与gmapping包的使用一致,涉及到很多参数配置。具体可以通过roswiki查看。hector包与gmapping包的差别在于,hector只需要激光雷达的信息而不需要里程计信息,它通过激光雷达数据来估算机器人的位姿。
参数launch文件配置:
<launch>
<node pkg = "hector_mapping" type="hector_mapping" name="hector_mapping"
output="screen">
<!-- Frame names -->
<param name="pub_map_odom_transform" value="true"/>
<param name="map_frame" value="map" />
<param name="base_frame" value="base_footprint" />
<param name="odom_frame" value="odom" />
<!-- Tf use -->
<param name="use_tf_scan_transformation" value="true"/>
<param name="use_tf_pose_start_estimate" value="false"/>
<!-- Map size / start point -->
<param name="map_resolution" value="0.05"/>
<param name="map_size" value="2048"/>
<param name="map_start_x" value="0.5"/>
<param name="map_start_y" value="0.5" />
<param name="laser_z_min_value" value = "-1.0" />
<param name="laser_z_max_value" value = "1.0" />
<param name="map_multi_res_levels" value="2" />
<param name="map_pub_period" value="2" />
<param name="laser_min_dist" value="0.4" />
<param name="laser_max_dist" value="5.5" />
<param name="output_timing" value="false" />
<param name="pub_map_scanmatch_transform" value="true" />
<!-- Map update parameters -->
<param name="update_factor_free" value="0.4"/>
<param name="update_factor_occupied" value="0.7" />
<param name="map_update_distance_thresh" value="0.2"/>
<param name="map_update_angle_thresh" value="0.06" />
<!-- Advertising config -->
<param name="advertise_map_service" value="true"/>
<param name="scan_subscriber_queue_size" value="5"/>
<param name="scan_topic" value="scan"/>
</node>
</launch>
参数配置以及启动rviz的launch文件:
<launch>
<include file="$(find slam_beginner)/launch/hector_slam/hector_base_params.launch"/>
<!-- 启动rviz-->
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find
slam_beginner)/rviz/gmapping.rviz"/>
</launch>
3)运行gazebo模型并运行参数配置以及启动rviz的launch文件。
3.cartographer包的地图构建
该包由于没有集成到ros的资源中所以不能通过前文的下载安装命令进行安装编译,只能通过下载源文件进行编译的方式进行。这是一个谷歌的开源包,基于图网络优化方法,设计目的在于计算机计算资源有限的情况下实施获取相对精度较高的2D地图。主要基于激光雷达。
1)cartographer包的下载与安装
安装工具:
sudo apt-get update
sudo apt-get install -y python-wstool python-rosdep ninja-build
初始化工作空间:
cd catkin_google_ws
wstool init src
设置下载地址:
wstool merge -t src
http:/raw.githubusercontent.com/googlecartographer/cartographer_ros/master/cartographer_ros.rosinstall
wstool update -t src
下载功能包:
rosdep update
rosdep install --from-paths src --ignore-src--rosdistro=${ROS_DISTRO} -y
编译功能包:
catkin_make_isolated --install --use-ninja
source install_isolated/setup.bash
可能出现的问题:
1.网络连接问题 修改src/.rosinstall文件中ceres-solver功能包源码的下载地址。
2.下载protobuf最新源码,编译安装:https://github.com/google/probuf
2)参数配置launch文件
这个包的运行是在它本身的功能包中运行的
<!-- 请复制该文件到cartographer_ros/cartographer_ros/launch中使用 -->
<launch>
<param name="/use_sim_time" value="true" />
<node name="cartographer_node" pkg="cartographer_ros"
type="cartographer_node" args="
-configuration_directory $(find cartographer_ros)/configuration_files
-configuration_basename rplidar.lua"
output="screen">
<remap from="scan" to="scan" />
</node>
<node name="rviz" pkg="rviz" type="rviz" required="true"
args="-d $(find cartographer_ros)/configuration_files/demo_2d.rviz" /> % demo_2d.rviz是rviz的配置文件,是保存好的
</launch>
主要的参数配置文件是激光雷达参数文件 rplidar.lua,文件内容如下:
include "map_builder.lua"
include "trajectory_builder.lua"
options = {
map_builder = MAP_BUILDER,
trajectory_builder = TRAJECTORY_BUILDER,
map_frame = "map",
tracking_frame = "base_link",
published_frame = "odom",
odom_frame = "odom",
provide_odom_frame = false,
use_odometry = true,
num_laser_scans = 1,
num_multi_echo_laser_scans = 0,
num_subdivisions_per_laser_scan = 1,
num_point_clouds = 0,
lookup_transform_timeout_sec = 0.2,
submap_publish_period_sec = 0.3,
pose_publish_period_sec = 5e-3,
trajectory_publish_period_sec = 30e-3,
}
MAP_BUILDER.use_trajectory_builder_2d = true
TRAJECTORY_BUILDER_2D.submaps.num_range_data = 35
TRAJECTORY_BUILDER_2D.min_range = 0.3
TRAJECTORY_BUILDER_2D.max_range = 8.
TRAJECTORY_BUILDER_2D.missing_data_ray_length = 1.
TRAJECTORY_BUILDER_2D.use_imu_data = false
TRAJECTORY_BUILDER_2D.use_online_correlative_scan_matching = true
TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.linear_search_window =
0.1
TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.translation_delta_cost_weight = 10.
TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.rotation_delta_cost_weight = 1e-1
SPARSE_POSE_GRAPH.optimization_problem.huber_scale = 1e2
SPARSE_POSE_GRAPH.optimize_every_n_scans = 35
SPARSE_POSE_GRAPH.constraint_builder.min_score = 0.65
return options
3)运行
编译功能包然后打开模型文件运行launch文件,最后运行键盘控制节点控制机器人建图
_______________________建图工作完成
使用move_base进行机器人路径规划(全局路径规划、本地实时路径规划(可以避障)) 在这个包中使用amcl(蒙特卡罗定位)进行定位,可以选用。
五、路径规划
1.安装move_base包
sudo apt-get install ros-kinetic-navigation
2.参数配置launch文件
<launch>
<node pkg="move_base" type="move_base" respawn="false" name="move_base"
output="screen" clear_params="true">
<rosparam file="$(find slam_beginner)/movebase_param/costmap_common_params.yaml"
command="load" ns="global_costmap" />
<rosparam file="$(find slam_beginner)/movebase_param/costmap_common_params.yaml"
command="load" ns="local_costmap" />
<rosparam file="$(find slam_beginner)/movebase_param/local_costmap_params.yaml"
command="load" />
<rosparam file="$(find slam_beginner)/movebase_param/global_costmap_params.yaml"
command="load" />
<rosparam file="$(find
slam_beginner)/movebase_param/base_local_planner_params.yaml" command="load" />
</node>
</launch>
这之中的yaml文件就是对于move_base包的参数配置,比较多。
运行的launch文件:
<launch>
<!-- 设置地图的配置文件 -->
<arg name="map" default="hector_slam0.yaml" />
<!-- 运行地图服务器,并且加载设置的地图-->
<node name="map_server" pkg="map_server" type="map_server" args="$(find
slam_beginner)/map/$(arg map)"/>
<!-- 运行move_base节点 -->
<include file="$(find
slam_beginner)/launch/move_base_slam/move_base_params.launch"/>
<!-- 启动AMCL节点 -->
<include file="$(find slam_beginner)/launch/move_base_slam/amcl.launch" />
<!-- 对于虚拟定位,需要设置一个/odom与/map之间的静态坐标变换 -->
<node pkg="tf" type="static_transform_publisher" name="map_odom_broadcaster"
args="0 0 0 0 0 0 /map /odom 100" />
<!-- 运行rviz -->
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find
slam_beginner)/rviz/nav.rviz"/>
</launch>
上面这个launch文件是直接将地图添加到rviz环境中,然后在地图上选点进行路径规划和避障。
<launch>
<include file="$(find slam_beginner)/launch/move_base_slam/gmapping_params.launch"/>
<!-- 运行move_base节点 -->
<include file="$(find slam_beginner)/launch/move_base_slam/move_base_params.launch"
/>
<!-- 运行rviz -->
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find
slam_beginner)/rviz/nav.rviz"/>
</launch>
这个launch文件则是启用了gmapping的地图构建包,是在运行过程中边运动边建图。所以与上面的launch文件相比,没有了地图添加、acml定位、以及虚拟定位。
amcl使用的参数文件内容是:
<launch>
<arg name="use_map_topic" default="false"/>
<arg name="scan_topic" default="scan"/>
<node pkg="amcl" type="amcl" name="amcl" clear_params="true">
<param name="use_map_topic" value="$(arg use_map_topic)"/>
<!-- Publish scans from best pose at a max of 10 Hz -->
<param name="odom_model_type" value="diff"/>
<param name="odom_alpha5" value="0.1"/>
<param name="gui_publish_rate" value="10.0"/>
<param name="laser_max_beams" value="60"/>
<param name="laser_max_range" value="12.0"/>
<param name="min_particles" value="500"/>
<param name="max_particles" value="2000"/>
<param name="kld_err" value="0.05"/>
<param name="kld_z" value="0.99"/>
<param name="odom_alpha1" value="0.2"/>
<param name="odom_alpha2" value="0.2"/>
<!-- translation std dev, m -->
<param name="odom_alpha3" value="0.2"/>
<param name="odom_alpha4" value="0.2"/>
<param name="laser_z_hit" value="0.5"/>
<param name="laser_z_short" value="0.05"/>
<param name="laser_z_max" value="0.05"/>
<param name="laser_z_rand" value="0.5"/>
<param name="laser_sigma_hit" value="0.2"/>
<param name="laser_lambda_short" value="0.1"/>
<param name="laser_model_type" value="likelihood_field"/>
<!-- <param name="laser_model_type" value="beam"/> -->
<param name="laser_likelihood_max_dist" value="2.0"/>
<param name="update_min_d" value="0.25"/>
<param name="update_min_a" value="0.2"/>
<param name="odom_frame_id" value="odom"/>
<param name="resample_interval" value="1"/>
<!-- Increase tolerance because the computer can get quite busy -->
<param name="transform_tolerance" value="1.0"/>
<param name="recovery_alpha_slow" value="0.0"/>
<param name="recovery_alpha_fast" value="0.0"/>
<remap from="scan" to="$(arg scan_topic)"/>
</node>
</launch>
3.运行
先打开gazebo模型文件然后分别运行两个launch文件,查看不同。
上面都是有人为干预的建图和路径规划。;以下是通过编写程序实现机器人独立确定目标点并实现建图mdash;mdash;mdash;mdash;
通过在运行机器人边运动边建图的launch文件后,再运行自己编写的生成目标点的python就可以实现,机器人的自主导航与建图
rosrun mbot_navigation exploring_slam.py
这两张图片表示的是机器人使用acml蒙特卡罗定位在地图中的定位,绿色部分表示机器人可能所在的位置,因为是一个概率,所以这些位置都有可能,在刚刚将机器人加入环境后会产生机器人来回抖动现象或者地图与机器人激光雷达扫描出来的不符,这是由于机器人不确定自己的位置所造成的。可以使用rviz界面上面的2D_poseEstimate来给机器人指定实际所在的位置。
上图是机器人进行路径规划,其中绿色的线是机器人所规划出来的全局路径,绿色箭头是机器人的目标点的位置以及最终机器人的方向。
上图也是机器人前往目标点的路径规划,产生了地图偏移,原因猜测可能是地图建立的时候尺寸太大,没有很多参照物供机器人定位时使用,因而产生了地图漂移。(还未进行验证)
这张图片是手动在地图上面选择机器人所到达的点,机器人边进行路径规划边进行建图。其中红色点是激光雷达的扫描点。