环境:Ubuntu18.04 + ROS melodic
在驱动机器人动起来后,可以开始考虑让机器人在实际环境中自主导航了。自主导航需要SLAM技术,本文主要利用机器人的传感器数据构建高质量的地图,主要包含以下内容:
1、ROS中的地图
2、创建地图
3、利用rosbag记录数据
4、启动地图服务器以及查看地图
1、ROS中的地图
参考链接:http://wiki.ros.org/map_server#Map_format
map_server包中地图存储在一对文件中,一个YAML文件,一个image文件。YAML文件描述了地图元数据,并命名了图像文件, 图像文件对占用数据进行编码。
1.1 图像文件
图像文件以对应像素的颜色描述环境中每个单元格的占用状态。 在标准配置中,更白的像素是空闲的,被占用的空间具有更黑的像素,中间颜色的像素表示未知。 接受彩色图像,但颜色值会被平均为灰度值。通过SDL_Image读入图像数据,支持的格式会有所不同,具体取决于SDL_Image在特定平台上提供的内容。 一般而言,大多数流行的图像格式得到广泛支持。 一个值得注意的例外是OS X不支持PNG。
1.2 YAML文件
YAML格式用一个简单,完整的例子来解释:
image: testmap.png
resolution: 0.1
origin: [0.0, 0.0, 0.0]
occupied_thresh: 0.65
free_thresh: 0.196
negate: 0
必填字段:
image:包含占用数据的图像文件的路径; 可以是绝对的,也可以是相对于YAML文件的位置
resolution:地图的分辨率,米/像素
origin:地图中左下角像素的二维姿态,为(x,y,yaw),偏航为逆时针旋转(偏航= 0表示无旋转)。 系统的许多部分目前忽略了偏航。
occupied_thresh:大于此阈值的像素被视为完全占用。
free_thresh:小于此阈值的像素被认为是完全空闲的。
negate:是否应该反转 白/黑 空闲/占用(阈值的解释不受影响)
可选参数:
mode:可以有三个值之一:trinary,scale或raw。 Trinary是默认值。
参数解释:
如果像素的COLOR值x在[0,255]范围内,我们应该如何解释这个值?首先,我们将整数x转换为一个浮点数p,转换公式具体取决于yaml中negate标志的定义。
如果negate为0,则p =(255 - x)/ 255.0。这意味着黑色(0)现在具有最高值(1.0)而白色(255)具有最低值(0.0)。
如果negate为1,则p = x / 255.0。这是图像的非标准解释。
trinary
标准解释是三元解释,即解释所有值,使输出最终成为三个值之一。
如果p> occupied_thresh,则输出值100以指示单元格已被占用。
如果p <free_thresh,则输出值0以指示单元格是空闲的。
否则,输出-1 a.k.a. 255(作为无符号字符),以指示该单元格未知。
scale
这将调整上述解释,以允许更多的输出值。
如前所述,如果p> occupied_thresh,则输出值100,如果p <free_thresh,则输出值0。
否则,输出99 *(p - free_thresh)/(occupied_thresh - free_thresh)
这将允许您输出范围为[0,100]的完整渐变值。要输出-1,只需使用png的alpha通道,其中任何透明度都将被解释为未知。
raw
此模式将为每个像素输出x,因此输出值为[0,255]。
2、创建地图
2.1 启动 turtlebot3 gazebo仿真环境(roslaunch turtlebot3_gazebo turtlebot3_stage_4.launch)
2.2 启动 turtlebot3_teleop_key 键盘驱动
(roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch 或者前面自己编写的键盘驱动代码)
process[turtlebot3_teleop_keyboard-1]: started with pid [7499]
Control Your TurtleBot3!
---------------------------
Moving around:
w
a s d
x
w/x : increase/decrease linear velocity (Burger : ~ 0.22, Waffle and Waffle Pi : ~ 0.26)
a/d : increase/decrease angular velocity (Burger : ~ 2.84, Waffle and Waffle Pi : ~ 1.82)
space key, s : force stop
CTRL-C to quit
2.3 启动 rviz 环境(roslaunch turtlebot3_gazebo turtlebot3_gazebo_rviz.launch )
在本文的开发环境下,启动了 turtlebot3_gazebo turtlebot3_gazebo_rviz.launch 才能建图,主要是启动后会增加一个/robot_state_publisher节点发布 /tf_static 话题,当然也可以通过别的方式发布这个话题,这里是为了方便起见用了现成的launch文件,rosrun gmapping slam_gmapping 建图时需要这个话题消息。
同样如果用rosbag记录话题消息用来建图也得记录/tf_static,即 rosbag record -o data.bag /tf /scan /tf_static 。
2.4 建图 (rosrun gmapping slam_gmapping )
结果如下,左上角为rviz里map话题的可视化结果,右上角为键盘驱动,右下角为gazebo仿真环境:
节点关系图为:
3、利用rosbag记录数据
3.1 记录数据
启动上一步中相关环境后,执行以下命令记录scan 、tf 、tf_static话题上发布的所有消息:
rosbag record -o data.bag /tf /scan /tf_static
wsc@wsc-pc:~$ rosbag record -h
Usage: rosbag record TOPIC1 [TOPIC2 TOPIC3 ...]
Record a bag file with the contents of specified topics.
Options:
-h, --help show this help message and exit
-a, --all record all topics
-e, --regex match topics using regular expressions
-x EXCLUDE_REGEX, --exclude=EXCLUDE_REGEX
exclude topics matching the follow regular expression
(subtracts from -a or regex)
-q, --quiet suppress console output
-o PREFIX, --output-prefix=PREFIX
prepend PREFIX to beginning of bag name (name will
always end with date stamp)
-O NAME, --output-name=NAME
record to bag with name NAME.bag
--split split the bag when maximum size or duration is reached
--max-splits=MAX_SPLITS
Keep a maximum of N bag files, when reaching the
maximum erase the oldest one to keep a constant number
of files.
--size=SIZE record a bag of maximum size SIZE MB. (Default:
infinite)
--duration=DURATION record a bag of maximum duration DURATION in seconds,
unless 'm', or 'h' is appended.
-b SIZE, --buffsize=SIZE
use an internal buffer of SIZE MB (Default: 256, 0 =
infinite)
--chunksize=SIZE Advanced. Record to chunks of SIZE KB (Default: 768)
-l NUM, --limit=NUM only record NUM messages on each topic
--node=NODE record all topics subscribed to by a specific node
-j, --bz2 use BZ2 compression
--lz4 use LZ4 compression
--tcpnodelay Use the TCP_NODELAY transport hint when subscribing to
topics.
--udp Use the UDP transport hint when subscribing to topics
比如:
rosbag record -a 记录所有话题
rosbag record -o foo scan tf 文件名前加上foo前缀
rosbag record -O foo.bag scan tf 指定文件名
3.2 回放数据
使用 rosbag play 播放之前记录的包,--clock 标志表示需要rosbag发布时间信息
rosbag play --clock data_2018-08-10-18-27-20.bag
使用 rosbag info foo.bag 显示包文件信息。
3. 3 利用回放数据建图
rosparam set use_sim_time true
rosrun gmapping slam_gmapping
4、启动地图服务器以及查看地图
执行 rosrun map_server map_saver 保存地图,执行rosrun map_server map_server map.yaml,发布地图话题:
wsc@wsc-pc:~$ rostopic list
/map
/map_metadata
/rosout
/rosout_agg
可以在rviz中查看/map 话题 地图。
5、其他命令记录
在完成本文任务的过程中,遇到了一些问题,比如一开始gmapping 装不上,编译不来,解决方法见,后来又遇到 缺少 /tf_static 话题而不能建图的问题,解决问题的过程中用到了一些命令,一并记录下:
#查看 tf tree
rosrun tf view_frames
evince frames.pdf
# 设置调试等级
wsc@wsc-pc:~$ rosconsole
rosconsole is a command-line tool for configuring the logger level of ROS nodes.
Commands:
rosconsole get display level for a logger
rosconsole list list loggers for a node
rosconsole set set level for a logger
rosconsole echo print logger messages
wsc@wsc-pc:~$ rosconsole list slam_gmapping
ros
ros.gmapping.message_filter
ros.roscpp
ros.roscpp.cached_parameters
ros.roscpp.roscpp_internal
ros.roscpp.roscpp_internal.connections
ros.roscpp.superdebug
rosconsole set slam_gmapping ros.gmapping.message_filter DEBUG
rosnode info /robot_state_publisher
--------------------------------------------------------------------------------
Node [/robot_state_publisher]
Publications:
* /rosout [rosgraph_msgs/Log]
* /tf [tf2_msgs/TFMessage]
* /tf_static [tf2_msgs/TFMessage]
Subscriptions:
* /clock [rosgraph_msgs/Clock]
* /joint_states [sensor_msgs/JointState]
Services:
* /robot_state_publisher/get_loggers
* /robot_state_publisher/set_logger_level