http://wiki.ros.org/gmapping
Gmapping包包含OpenSlam的Gmapping的一个ROS封装。Gmapping 的ROS节点slam_gmapping提供基于激光的SLAM(同时定位和创建地图)。依靠移动机器人收集的激光和位姿数据,使用slam_gmapping可以创建2维栅格地图。
外部文档
主要是一个第三方包。
硬件需求
使用slam_gmapping,需要移动机器人提供里程计数据,并且水平安装固定激光测距仪。slam_gmapping节点试图转换每个扫描输入数据到odom(里程计)tf坐标系。见"Required tf transforms"更多需要的转换。
例子
机器人用激光扫描发布创建地图在base_scan话题上:
rosrun gmapping slam_gmapping scan:=base_scan
节点
slam_gmapping
节点slam_gmapping采用sensor_msgs/LaserScan消息,并且构建地图(nv_msgs/OccupancyGrid)。地图可以通过topic或service检索。
订阅话题
tf(tf/tfMessage)
转换需要涉及激光坐标系,基座坐标系和里程计坐标系。
scan(sensor_msgs/LaserScan)
从激光扫描创建地图
发布话题
map_metadata (nav_msgs/MapMetaData)
从这个话题获得地图数据,这个话题是被锁存的,并定期更新。
map (nav_msgs/OccupancyGrid)
从这个话题获得地图数据,这个话题是被锁存的,并定期更新。
~entropy (std_msgs/Float64)
机器人位姿分布熵的估计(值越高表示越大的不确定性)。
服务
dynamic_map(nav_msgs/GetMap)
调用这个服务来获取地图数据。
参数
http://wiki.ros.org/gmapping
· inverted_laser (string, default: "false")
(REMOVED in 1.1.1; transform data is used instead) 激光是朝上安装(扫描是逆时 针), 还 是朝下安装 (扫描是顺时针)?
· throttle_scans (int, default: 1)
激光雷达每扫描一周跳过多少扫描。
· base_frame (string, default: "base_link")
移动基座的坐标系。
· map_frame (string, default: "map")
地图坐标系。
· odom_frame (string, default: "odom")
里程计系统的坐标系。
· map_update_interval (float, default: 5.0)
地图更新的时间间隔(单位:seconds)。更新间隔越小,计算负荷越大。
· maxUrange (float, default: 80.0)
激光雷达最大可用距离。光束被裁减成这个值。
· sigma (float, default: 0.05)
用作结束点匹配。
· kernelSize (int, default: 1)
在内核内寻找一个对应。
· lstep (float, default: 0.05)
平移的最优步长。
· astep (float, default: 0.05)
旋转的最优步长。
· iterations (int, default: 5)
扫描匹配的迭代次数。
· lsigma (float, default: 0.075)
波束的sigma,用来计算似然估计。
· ogain (float, default: 3.0)
评估似然的增益,用来平滑重采样的影响。
· lskip (int, default: 0)
每次扫描跳过的波束。
· minimumScore (float, default: 0.0)
评价扫描匹配良好结果的最低分数。
· srr (float, default: 0.1)
平移函数在平移时的里程计误差 (rho/rho)。
· srt (float, default: 0.2)
旋转函数在平移时的里程计误差 (rho/theta)
· str (float, default: 0.1)
平移函数在旋转时的里程计误差 (theta/rho)
· stt (float, default: 0.2)
旋转函数在旋转时的里程计误差 (theta/theta)
· linearUpdate (float, default: 1.0)
机器人平移这么远,处理一次扫描。
· angularUpdate (float, default: 0.5)
机器人旋转这个角度,处理一次扫描。
· temporalUpdate (float, default: -1.0)
如果上一次扫描处理比更新时间长,处理一次扫描。值小于0,将会关闭更新相关 的时间。
· resampleThreshold (float, default: 0.5)
基于重采样阈值的Neff。
· particles (int, default: 30)
滤波器的粒子数。
· xmin (float, default: -100.0)
初始地图尺寸。
· ymin (float, default: -100.0)
初始地图尺寸。
· xmax (float, default: 100.0)
初始地图尺寸。
· ymax (float, default: 100.0)
初始地图尺寸。
· delta (float, default: 0.05)
处理参数 (地图的分辨率)。
· llsamplerange (float, default: 0.01)
似然的平移采样距离。
· llsamplestep (float, default: 0.01)
似然的平移采样步长。
· lasamplerange (float, default: 0.005)
似然的角度采样距离。
· lasamplestep (float, default: 0.005)
似然的角度采样步长。
· transform_publish_period (float, default: 0.05)
转换发布间隔,单位:seconds
· occ_thresh (float, default: 0.25)
Gmapping占用值的阈值。有大一些的占用值的单元格,被视为占用。
· maxRange (float)
传感器的最大距离。
需要的tf转换
通常是一个固定值, 由robot_state_publisher或 tf static_transform_publisher.定期广播。
base_link → odom
通常有里程计系统提供(例如,移动机器人的驱动)
提供的tf转换
map → odom
在地图坐标系中机器人位姿的当前估计。
(ros/navigation/slam_gmapping) map_server地图服务器
概述
map_server提供map_server ROS节点,它提供地图数据作为一个ROS服务器。也提供map_saver命令行功能,能动态生成保存到文件中的地图。
地图格式
包中通过工具操作的地图是以成堆的文件存储的。YAML文件描述地图的元数据,并命名image文件。Image文件编码占用数据。
Image 格式
Image 以对应单元的颜色描述世界中每个单元的占用状态。白色单元格表示自由,黑色单元格表示占用,两种颜色之间的单元表示未知。彩色和灰度图像都采用,但是大部分地图都是灰度图像(尽管它们存储的好像是以彩色的形式)。YAML文件的阈值划分为3类;阈值是在map_server内部完成的。
比较阈值参数时,图像单元占用概率的计算如下:occ = (255 - color_avg) / 255.0, color_avg是从所有通道平均出来的8位值结果,例如如果图像时24位颜色,一个单元的颜色0x0a0a0a有一个0.96的概率,这是一个完全占用((255-(0*16+10))/255.0=0.96)。颜色0xeeeeee的概率是0.07((255-(14*16+14))/255.0=0.07),完全没占用。
通过ROS消息通信时,占用表示为区间[0,100]的一个整数,0表示完全自由,100表示完全占用,特殊值-1表示完全未知。
图像数据经由SDL_Image读取;依靠SDL_Image提供的一个特殊平台,支持格式改变。一般来说,大部分流行的图像格式都广泛支持。一个需要注意的例外是PNG在OS X上不支持。
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: 到包含占用信息的image文件的路径;可以是绝对路径,也可以是到YAML文件的相对路径。
resolution:地图的分辨率,meters/pixel
origin: 地图左下角单元(像素)的2维位姿,(x,y,yaw),yaw逆时针旋转(yaw=0表示没有旋转)。系统的很多部分现在忽略yaw。
occupied_thresh:单元占用的概率大于这个阈值则认为完全占用。
free_thresh: 单元占用的概率小于这个阈值则认为完全自由。
negate: 不论白色/黑色,自由/占用,semantics(语义/符号)应该被反转(阈值的解释不受影响)。
命令行工具
Map_server
Map_server是一个ROS节点,从磁盘读取一个地图,并通过ROS服务提供地图。
Map_server的当前实现是转换地图图像数据中的色彩值为三元占用值:free(0), occupied(100), unknown(-1)。这个工具的未来版本是使用0到100之间的值来与占用的更精细层次交流。
Usage
map_server
Example
rosrun map_server map_server mymap.yaml
发布话题
map_metadata (nav_msgs/MapMetaData)
通过这个锁存话题来接受地图元数据(map metadata).
map (nav_msgs/OccupancyGrid)
通过这个锁存话题接收地图。
服务
static_map (nav_msgs/GetMap)
由该服务获取地图。
参数
~frame_id (string, default: "map")
设置在已发布地图的头(header)的坐标系。
Map_saver
Map_saver 保存地图到磁盘,例如从SLAM mapping 服务中保存。
Usage
map_saver [-f mapname]
Map_saver获取地图数据,并把它写到map.pgm和map.yaml。使用-f选项为输出文件提供一个不同的base name(基础名字)。
Example
rosrun map_server map_saver -f mymap
订阅话题
map (nav_msgs/OccupancyGrid)
通过这个锁存话题获取地图。
(ros//EnvironmentVariables)ros环境变量
http://wiki.ros.org/ROS/EnvironmentVariables
ROS/ EnvironmentVariables
在ROS中,可以设置很多环境变量。最需要理解的是ROS_MASTER_URI,ROS_ROOT和ROS_PACKAGE_PATH,因为他们频繁的在系统和文件中被用到。
环境变量在ROS中有多重角色:
1 寻找packages(Finding packages ):
首先,ROS_ROOT和ROS_PACKAGE_PATH使ROS在系统文件(filesystem)中能够定位packages和stacks。同样必须设置PYTHONPATH,这样Python解释器才能找到ROS库。
2 影响一个节点运行时间(Effecting a Node runtime ):
有几个环境变量会影响节点的运行。ROS_MASTER_URI是一个重要的环境变量来告诉节点Master(主机)在哪里。ROS_IP和ROS_HOSTNAME影响一个节点的网络地址,ROS_NAMESPACE能够让你改变命名空间。ROS_LOG_DIR可以让你设置日志文件写入的目录。这些也可以被映射参数覆盖,映射参数优先于环境变量。
3 修改构建系统(Modifying the build system):
ROS_BINDEPS_PATH,ROS_BOOST_ROOT,ROS_PARALLEL_JOBS和ROS_LANG_DISABLE影响在哪里寻找库,怎样构建他们,构建哪一个。
这些环境变量在下面将会有更详细的描述。
必需的ROS环境变量
大部分系统都要设置ROS_PACKGE_PATH,ROS只需要环境变量ROS_ROOT,ROS_MASTER_URI和PYTHONPATH。默认通过sourcing /opt/ros/fuerte/setup.bash来自动设置他们。
1. ROS_ROOT
ROS_ROOT设置ROS core包安装的位置。
export ROS_ROOT=/home/user/ros/ros
export PATH=$ROS_ROOT/bin:$PATH
2. ROS_MASTER_URI
ROS_MASTER_URI是一个必需的设置来告诉节点在哪里定位master。应该设置master的XML-RPC URI。使用localhost时需要格外小心,因为远程启动节点可能会导致意想不到的结果。
export ROS_MASTER_URI=http://mia:11311/
3. PYTHONPATH
ROS需要PYTHONPATH更新,尽管你可能不用Python编程!很多ROS基础工具都依靠Python,需要连接到roslib包来bootstrapping。
export PYTHONPATH=$PYTHONPATH:$ROS_ROOT/core/roslib/src
其他的PATH环境变量
1. ROS_PACKAGE_PATH
ROS_PACKAGE_PATH是一个可选,但很常用的环境变量,能够让你从源添加更多的ROS包到当前环境。ROS_PACKAGE_PATH可以由一个或多个路径组成,路径之间由标准操作系统路径间隔符(在Unix类的系统中,用’:’)分隔。这些有序的路径告诉ROS系统到哪里搜索更多的ROS包。如果多个包有相同的名字,ROS会首先选择出现在ROS_PACKAGE_PATH的那个。
export ROS_PACKAGE_PATH=/home/user/ros/ros-pkg:/another/path
注意ROS_PACKAGE_PATH的每个条目都被重复查找-路径中提到的包都会被找到。
引入catkin后,ROS_PACKAGE_PATH过时了,只是用来与rosbuild包保持向后兼容。
系统数据环境变量
1. ROS_HOME
默认,ROS写数据到~/.ros。可以通过设置ROS_HOME来改变这个位置。也可以在~/.ros中更改某个目录的位置(例如,ROS_TEST_RESULTS_DIR,ROS_LOG_DIR)。
2. ROS_LOG_DIR
默认,ROS写内部日志文件到ROS_HOME/log。如果这个位置对ROS不可写,或者希望日志文件写到别的地方,设置ROS_LOG_DIR到其他路径。
3. ROS_TEST_RESULTS_DIR
测试结果要写到的目录。
其他的Bash环境变量
1. ROS_LOCATIONS
ROS_LOCATIONS是一个可选的环境变量,为有用的位置提供键名。它是key-location对的分隔列表。每个key-location对用一个=分隔。例如:
export ROS_LOCATIONS="rospkg=/path/to/rospkg:stairpkg=/path/to/stairpkg"
然后这些键就可以用一些工具了,如roscd。
2. ROS_WORKSPACE
ROS_WORKSPACE由工具rosinstall/rosws引进的,当创建一个workspace时,通过这些工具生成的setup.sh设置。它指向workspace的文件夹,通过使用rosws命令使用,作为命令的默认目标。
不带参数的调用时,fuerte中的roscd工具也改用这个变量。此前,它默认改变ROS_ROOT.
节点环境变量
1. ROS_IP/ROS_HOSTNAME
ROS_IP和ROS_HOSTNAME是可选的环境变量,用来设置ROS节点或工具的公开网地址。这两个选项是互斥的,如果两者都设置优先使用ROS_HOSTNAME。如果你指定一个IP地址,使用ROS_IP;如果制定一个主机名(a host name),使用ROS_HOSTNAME。当一个ROS成员报告URI给master或者其他成员,这个值就会被用到。这个设置只用在一台计算机有多个地址,需要强制ROS到特定的一个的情况。
除了’localhost’(本地主机),ROS成员绑定到所有可用的网络接口,他不影响实际绑定地址。如果这个值设定为本地主机,ROS成员只绑定在环回接口。这将会阻止远程成员与本地成员交流。
2. ROS_NAMESPACE
ROS_NAMESPACE可以让你推一个节点到一个命名空间。节点中的所有名字都会相对于这个值解析,包括映射名称。
3. ROSCONSOLE_CONFIG_FIE
这是一个roscpp指定环境变量。Rosconsole让你定义用在log4cxx的配置文件,通过环境变量ROSCONSOLE_CONFIG_FILE定义。在这个配置文件中有任何定义都会覆盖默认的配置文件。
4. Console Output Formatting 控制台输出格式
Rosconsole允许指定怎样通过环境变量ROSCONSOLE_FORMAT在控制台输出。默认等效于:
export ROSCONSOLE_FORMAT='[${severity}] [${time}]: ${message}'
5. ROS_PYTHON_LOG_CONFIG_FILE
特定 rospy, rosmaster, roslaunch, and rostest.对于这些工具,可以指定使用自己的Python logging配置文件来代替默认配置文件,它保存在$ROS_ROOT/config/python_logging.conf.
构建系统环境变量
为了更好的了解这些环境变量,请看ROS Build System部分。
1. ROS_BOOST_ROOT
ROS_BOOST_ROOT是一个可选的环境变量,能让你覆盖哪里去寻找激励。如果ROS_BOOST_ROOT不设置,默认使用ROS_BINDEPS_PATH。
2. ROS_PARALLEL_JOBS
这个变量的值,如果设置,构建包的时候会传递给make。目的是充分使用多处理器机器。例如,如果有8处理器/核,想尽可能多的运行并行任务,只要系统负荷小于8,通过限制任务为8,可以在启动时阻止过冲:
export ROS_PARALLEL_JOBS='-j8 -l8'
或者,可以使用-j标识带一个参数来并行运行最多8个任务,系统负载独立:
export ROS_PARALLEL_JOBS=-j8
强烈建议使用-l标识来设置并行系统相关限制。在一个大的构建中并行过多可能会耗尽系统内存。
可以接受多少系统负载取决于有多少内核。
3. ROS_LANG_DISABLE
消息生成器/客户端库包名称应禁用一个冒号分隔的列表。Message-generation will not happen for languages in this list.
用catkin构建的包需要需要列出应当被忽视的消息生成器的名字,例如:
export ROS_LANG_DISABLE=genlisp
用rosbuild构建的包需要列出应当被忽视的消息生成器及客户端库的名字,例如:
export ROS_LANG_DISABLE=genlisp:roslisp
当忽视掉消息生成器的rosbuild和CMake配置步骤,将会显示一个警告,客户端库(例如,roslisp)不是一个已知的消息生成器。这个警告可以安全的忽略掉。
注意,禁用语言之前,首先必须确定你使用的代码没有与这个语言绑定。
4. ROS_OS_OVERRIDE
格式:"OS_NAME:OS_VERSION_STRING",这将会强制检测Ubuntu Lucid:
export ROS_OS_OVERRIDE=ubuntu:10.04
如果定义,这将覆盖系统的自动检测。在外来平台上调试rosdep依赖性时,当平台很相似可能需要强制,或自动检测失败时,很有用。
(ros/navigation)how to build a map using logged data 怎样用记录的数据创建地图
1 how to build a map using logged data 怎样用记录的数据创建地图
描述:怎样用记录的转换和激光扫描数据创建二维地图。
创建地图
1. 如果作为源校验(相对于二进制安装),构建gmapping:
rosmake gmapping
2. 获取一个包。有两个选择:
1 用机器人创建一个包
2 下载一个现有的包做测试
任何一种方式,都会得到一个包。
3. 启动核心
roscore
4. 在其他节点启动前,确保use_sim_time设置为true
"code" class="javascript"> rosparam set use_sim_time true
rosparam set use_sim_time true
5. 启动slam_gmapping,它将会接收激光扫描(在这个例子中,在base_scan话题上),并且创建地图:
rosrun gmapping slam_gmapping scan:=base_scan
注意:在PR2上,odom坐标系称为odom_combined。使用这个命令:
rosrun gmapping slam_gmapping scan:=base_scan _odom_frame:=odom_combined
6. 在一个新终端,开始回放bag文件,莱维slam_gmapping提供数据:
rosbag play --clock
等待rosbag完成并退出。
7. 使用map_server包的map_saver保存新地图到磁盘:
rosrun map_server map_saver
现在就有了一个地图,本地保存为map.pgm。可以用任何图像浏览器(gimp,eog,gthumb等)查看;
下载一个测试包
使用wget命令来下载测试包,
wget http://pr.willowgarage.com/data/gmapping/basic_localization_stage.bag
自己创建包
1 启动机器人,发布激光扫描和转换数据,摇杆操纵启用(不同机器人的细节不同);
2 开始记录扫描和转换(注意scan话题可能因为机器人不同而不同):
rosbag record -O mylaserdata /base_scan /tf
将会在当前目录开始写文件,文件名字为’mylaserdata_
3 驱动机器人转一圈。常用的建议:
Ø 尝试限制快速旋转,因为他们在扫描匹配上最难。降低操纵杆的最大允许速度比较有用。
Ø 用激光雷达可视化机器”看到”的;如果激光不能看到,则地图上就不会有。
Ø 人类走动通常不会出现问题,除非他随着机器人走,在激光的视野内。
Ø 回路闭合是最难的部分。关闭回路时,确保多行驶5-10米,来获得回路始端和终端之间的大量重叠。
4 杀掉rosbag实例,并且注意创建的文件的名字。
变化:查看创建地图的进展
如果看到结果前,不介意等待直到记录数据回放和创建地图过程完成,可以再rviz中查看进展:
rosrun rviz rviz
添加地图显示,设置话题 /map