ROS(9)turtlebot仿真(利用karto)

12 篇文章 4 订阅

9. turtlebot仿真(利用karto)

参考链接
https://blog.csdn.net/qq_40078576/article/details/104773668
https://blog.csdn.net/lingchen2348/article/details/79503970

9.1. 安装Gazebo仿真软件

安装ros时已经安装。

9.2. 下载Gazobo的模型包

不需要再下载模型包了,turtlebot包会加载出模型。

9.3. 安装slam建图包

turtlebot3支持gmapping、cartographer、hector、karto、frontier_exploration。

9.3.1. karto安装

sudo apt-get install ros-melodic-slam-karto

9.3.2. 安装cartographer_turtlebot(待完善TODO)

注意这里不是cartographer_ros,参考链接https://www.ncnynl.com/archives/201801/2230.html

9.4. 安装turtlebot相关包

sudo apt-get install ros-melodic-turtlebot-*

9.5. 加载环境

roslaunch turtlebot3_gazebo turtlebot3_world.launch
报错:‘TURTLEBOT3_MODEL’ is not set。表示TURTLEBOT3_MODEL没有设置, 需要给它指定[burger, waffle, waffle_pi]中的一个, 我们随便指定一个:export TURTLEBOT3_MODEL=burger(可以写入.bashrc文件),重新执行命令。

9.6. 启动键盘遥控节点

可以遥控小车行走。新建终端,
roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch

9.7. 建图

这里选择了karto。新建终端,
roslaunch turtlebot3_slam turtlebot3_slam.launch slam_methods:=karto

9.8. 保存地图

控制小车扫描完地图后,保存地图:
mkdir -p ~/maps/turtlebot3
rosrun map_server map_saver -f ~/maps/turtlebot3/map1

9.9. 导航

利用刚才扫描的地图进行导航控制。关闭建图终端,关闭手动键盘控制后:
roslaunch turtlebot3_navigation turtlebot3_navigation.launch map_file:=~/maps/turtlebot3/map1.yaml
记录本机地址:roslaunch turtlebot3_navigation turtlebot3_navigation.launch map_file:=/mnt/e/wsl/maps/turtlebot3/map1.yaml
接下来首先要做的是调整RViz中turtlebot在地图中的位姿,使其与Gazebo中turtlebot在环境中的位姿一致。做法是用鼠标选中RViz工具栏中的“2D Pose Estimate”,然后根据Gazebo中tuetlebot的位姿点击RViz地图中的相应位置,注意姿态也要相同。
接下来我们就开始导航了,鼠标选择工具栏中的“2D Nav Goal”,在地图中任意设置一个目标位姿,turtlebot便会自动规划路径,然后慢悠悠地移动过去。

这里2D Pose Estimate会向/initialpose队列发送一个坐标,该队列会由/amcl节点监听。

9.10. 分析

9.10.1. 建图分析

9.10.1.1. 建图启动文件

建图的指令中用到了turtlebot3_slam.launch文件

 <launch>
  2   <!-- Arguments -->
  3   <arg name="model" default="$(env TURTLEBOT3_MODEL)" doc="model type [burger, waffle, waffle_pi]"/>
  4   <arg name="slam_methods" default="gmapping" doc="slam type [gmapping, cartographer, hector, karto, frontier    _exploration]"/>
  5   <arg name="configuration_basename" default="turtlebot3_lds_2d.lua"/>
  6   <arg name="open_rviz" default="true"/>
  7
  8   <!-- TurtleBot3 -->
  9   <include file="$(find turtlebot3_bringup)/launch/turtlebot3_remote.launch">
 10     <arg name="model" value="$(arg model)" />
 11   </include>
 12
 13   <!-- SLAM: Gmapping, Cartographer, Hector, Karto, Frontier_exploration, RTAB-Map -->
 14   <include file="$(find turtlebot3_slam)/launch/turtlebot3_$(arg slam_methods).launch">
 15     <arg name="model" value="$(arg model)"/>
 16     <arg name="configuration_basename" value="$(arg configuration_basename)"/>
 17   </include>
 18
 19   <!-- rviz -->
 20   <group if="$(arg open_rviz)">
 21     <node pkg="rviz" type="rviz" name="rviz" required="true"
 22           args="-d $(find turtlebot3_slam)/rviz/turtlebot3_$(arg slam_methods).rviz"/>
 23   </group>
 24 </launch>

可以看到默认的slam_methods是gmapping,我们传入的是karto。有三大部分:TurtleBot3、SLAM和rviz。
TurtleBot3加载了turtlebot3_remote.launch文件,对应了/robot_state_publisher节点,SLAM加载了turtlebot3_karto.launch,对应了/slam_karto节点,打开了rviz软件。

9.10.1.2. 建图节点视图

执行rosrun rqt_graph rqt_graph如图所示:
在这里插入图片描述

我们通过rosnode info /slam_karto查看到/slam_karto发布的主题/map是nav_msgs/OccupancyGrid类型,可以供保存地图使用。

9.10.2. 保存地图

保存地图使用的指令:
rosrun map_server map_saver -f ~/maps/turtlebot3/map1
这里利用了map_server的命令行功能,从/map中接收了[nav_msgs/OccupancyGrid]类型的数据,可以通过rosmsg show nav_msgs/OccupancyGrid查看数据的格式,并把它写到map1.pgm和map1.yaml中。
.pgm说明如下:

  • 该图像描述了相应像素的颜色中的世界的每个单元的占用状态。白色像素是自由的,黑色像素被占据,并且两者之间的像素是未知的。接受彩色和灰度图像,但大多数地图都是灰色的(即使它们可能存储为彩色)。YAML文件中的阈值用于划分三个类别; 阈值在map_server内部完成。
  • 当与阈值参数比较时,图像像素的占用概率计算如下:occ =(255-color_avg)/ 255.0其中color_avg是通过在所有通道上求平均值而得到的8位值,例如,如果图像是24位颜色,具有颜色0x0a0a0a的像素具有0.96的概率,这是非常占用的。颜色0xeeeeee产生0.07,这是非常空的。
  • 当通过ROS消息通信时,占用被表示为范围[0,100]中的整数,0意味着完全自由,100意味着完全被占用,并且特殊值-1用于完全未知。

.yaml格式如下:

image:包含占用数据的图像文件的路径; 可以是绝对的,或相对于YAML文件的位置
resolution:地图的分辨率,米/像素
origin:可以计算出地图的(0,0)点,[0,0,0]表示在地图的右下角![-1,-2,0]中x为-1表示地图右移1m,-2表示下移2m,0表示逆时针旋转的角度,一般为0。
occupancy_thresh:占据概率大于该阈值的像素被认为完全占用。
free_thresh:占有概率小于该阈值的像素被认为是完全自由的。
negate:白/黑自由/占用语义是否应该被反转(阈值的解释不受影响)
其余具体参考/map_server章节。

9.10.3. 导航分析

9.10.3.1. 启动文件

导航用的是turtlebot3_navigation.launch文件:

   <launch>
     <!-- Arguments -->
     <arg name="model" default="$(env TURTLEBOT3_MODEL)" doc="model type [burger, waffle, waffle_pi]"/> <!--模型-->
     <arg name="map_file" default="$(find turtlebot3_navigation)/maps/map.yaml"/> <!--地图参数-->
     <arg name="open_rviz" default="true"/>
     <arg name="move_forward_only" default="false"/>
  
     <!-- Turtlebot3 -->
     <include file="$(find turtlebot3_bringup)/launch/turtlebot3_remote.launch">
      <arg name="model" value="$(arg model)" />
    </include>
 
    <!-- Map server -->
    <node pkg="map_server" name="map_server" type="map_server" args="$(arg map_file)"/>
 
    <!-- AMCL -->
    <include file="$(find turtlebot3_navigation)/launch/amcl.launch"/>
 
    <!-- move_base -->
    <include file="$(find turtlebot3_navigation)/launch/move_base.launch">
      <arg name="model" value="$(arg model)" />
      <arg name="move_forward_only" value="$(arg move_forward_only)"/>
    </include>
 
    <!-- rviz -->
    <group if="$(arg open_rviz)">
      <node pkg="rviz" type="rviz" name="rviz" required="true"
            args="-d $(find turtlebot3_navigation)/rviz/turtlebot3_navigation.rviz"/>
    </group>
  </launch>
9.10.3.2. 节点视图

如图所示:
在这里插入图片描述

9.10.3.3. /tf和/tf_static

/tf : 多个时间的坐标系变换
/tf_static : 只保留最新的那个坐标系变换,查询的时候总会有。

9.10.3.4. /gazebo
  • 发布的消息队列

    std_msgs/Header header   #头部数据
     uint32 seq               #序列号
     time stamp               #时间戳
     string frame_id          #扫描数据的名称
    float32 angle_min        #开始扫描的角度[rad]
    float32 angle_max        #结束扫描的角度[rad]
    float32 angle_increment  #测量之间的角度增量[rad]
    float32 time_increment   #测量之间的时间增量[Sec]
    float32 scan_time        #扫描之间的时间[Sec]
    float32 range_min        #最小范围数值[m]
    float32 range_max        #最大范围数值[m]
    float32[] ranges         #范围内的数据[m]
    float32[] intensities    #强度数据  
    

    sensor_msgs::LaserScan转pcl::PointCloud:参考https://www.guyuehome.com/12913

    std_msgs/Header header #头部数据
      ...
    string child_frame_id
    geometry_msgs/PoseWithCovariance pose   #位姿,包含两部分
      geometry_msgs/Pose pose               #Pose,位姿
        ...
      float64[36] covariance              #6*6协方差矩阵
    geometry_msgs/TwistWithCovariance twist #线速度和角速度 协方差矩阵
      geometry_msgs/Twist twist
        ...
      float64[36] covariance
    

    协方差矩阵待完善

    • /joint_states [sensor_msgs/JointState]
      关节状态
    Header header
    string[] name       #名称,是数组,对应多个关节
    float64[] position  #the position of the joint (rad or m), 关节位置???
    float64[] velocity  #the velocity of the joint (rad/s or m/s),关节速度
    float64[] effort    #the effort that is applied in the joint (Nm or N) 施加在关节上的力
    

    这里name是wheel_right_joint, wheel_left_joint,关节位置应该是左右轮子的位置,但具体意义不明?

  • 订阅的消息队列

    • /cmd_vel [geometry_msgs/Twist]
      线速度和角速度
    geometry_msgs/Vector3 linear
     float64 x
     float64 y
     float64 z
    geometry_msgs/Vector3 angular
     float64 x
     float64 y
     float64 z
    
9.10.3.5. /robot_state_publisher

本节点订阅/joint_state队列,同时发布tf转换关系。发布的哪些坐标系是由robot_description描述的urdf格式文件决定的。

需要注意的是,本节点有两种发布方式,对于urdf文件中type为Floating的关节,会监听/joint_state来动态发布tf关系,而对于其他type的关节,只会发布一次static_tf关系。
推测在AGV中实际使用中,不需要发布数据到/joint_state队列。

9.10.3.6. /amcl

AMCL是ROS/ROS2系统中最官方的定位模块,是导航模块中唯一指定的定位算法,在ROS/ROS2系统中,乃至整个移动机器人领域都是举足轻重的重要地位。虽然陆续也有许多其它的定位算法出现,但是在ROS/ROS2系统中,目前也仅仅是为AMCL打些配合类辅助。AMCL并不是时髦的新技术,很传统,也迟早会被其它更优秀的技术所代替。然而就目前来说,是所有机器人技术的初学者来说,是不折不扣的必备知识。
AMCL是Adaptive Monte Carlo Localization(也即是自适应蒙特卡洛定位)的简称,是基于多种蒙特卡洛融合算法在ROS/ROS2系统中的一种实现。
主要步骤如下:

  • 随机生成粒子,每个粒子对应了一个AGV的位置和方向;
  • 里程计移动一段距离,各个粒子进行相应的距离和方向偏移;
  • 此时将一帧激光数据套入各个粒子上,然后对每个激光点坐标和背景障碍物进行概率估计,所有激光数据求出本粒子的权重;
  • 对所有粒子按权重进行重采样,筛选出权重高的,然后在权重高的附近再撒粒子;
  • 迭代多次后所有粒子就会聚集到一起。

似然域模型(Likelihood Field)是AMCL中推荐使用的传感器模型,计算出某个粒子的一个激光点位置和周围障碍物的最近距离d后,权重通过下面公式计算:
q = q * (Phit * 1/sqrt(2PI) * sig * exp(-d2/2sig2)) + Prand * 1/zmax) ,这里Phit sig Prand是需要给定的参数。其实后面括号中的第一部分是利用高斯计算的,落在中间轴的右边,d越大计算的结果越小,最终返回的是该粒子的概率,也即置信度。当然一批粒子算完后,置信度需进行归一化处理。

9.10.3.7. /map_server

map_server有两个功能:

  • 当做map_server节点服务,它从磁盘加载静态地图数据作为一个ROS服务提供地图数据。
  • 提供map_saver地图保存命令行功能,通过指令从/map中接收网格地图数据,然后保存成ROS专用格式的地图,参考上面的[保存地图]章节。

本节点发布话题/map给move_base用,具体格式参考上面的[保存地图]章节。

9.10.3.8. /move_base

参考链接https://www.pianshen.com/article/3044120500/
局部路径规划之DWAPlannerROS分析:https://www.cnblogs.com/sakabatou/p/8297479.html
参考<move_base详解>

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值