(ros/navigation/gmapping)导航/建地图

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话题上:

 

[html] view plain copy

  1. rosrun gmapping slam_gmapping scan:=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转换

 → base_link

         通常是一个固定值, 由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格式最好用一个简单而完全的例子来解释:

 

[html] view plain copy

  1. image: testmap.png  
  2. resolution: 0.1  
  3. origin: [0.0, 0.0, 0.0]  
  4. occupied_thresh: 0.65  
  5. free_thresh: 0.196  
  6. negate: 0  
 
  1. image: testmap.png

  2. resolution: 0.1

  3. origin: [0.0, 0.0, 0.0]

  4. occupied_thresh: 0.65

  5. free_thresh: 0.196

  6. 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

 

[html] view plain copy

  1. map_server   
map_server 

 

 

Example

 

[html] view plain copy

  1. rosrun map_server map_server mymap.yaml  
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

 

[html] view plain copy

  1. rosrun map_server map_saver -f mymap  
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包安装的位置。

 

[html] view plain copy

  1. export ROS_ROOT=/home/user/ros/ros  
  2. export PATH=$ROS_ROOT/bin:$PATH  
 
  1. export ROS_ROOT=/home/user/ros/ros

  2. export PATH=$ROS_ROOT/bin:$PATH

 

 

2. ROS_MASTER_URI

ROS_MASTER_URI是一个必需的设置来告诉节点在哪里定位master。应该设置master的XML-RPC URI。使用localhost时需要格外小心,因为远程启动节点可能会导致意想不到的结果。

 

[html] view plain copy

  1. export ROS_MASTER_URI=http://mia:11311/  
                 export ROS_MASTER_URI=http://mia:11311/

 

 

 

 

3. PYTHONPATH

   ROS需要PYTHONPATH更新,尽管你可能不用Python编程!很多ROS基础工具都依靠Python,需要连接到roslib包来bootstrapping。

 

[html] view plain copy

  1. export PYTHONPATH=$PYTHONPATH:$ROS_ROOT/core/roslib/src  
              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的那个。

 

[html] view plain copy

  1. export ROS_PACKAGE_PATH=/home/user/ros/ros-pkg:/another/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对用一个=分隔。例如:

 

[html] view plain copy

  1. export ROS_LOCATIONS="rospkg=/path/to/rospkg:stairpkg=/path/to/stairpkg"  
              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在控制台输出。默认等效于:

 

[html] view plain copy

  1. export ROSCONSOLE_FORMAT='[${severity}] [${time}]: ${message}'  
          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,可以在启动时阻止过冲:

 

[html] view plain copy

  1. export ROS_PARALLEL_JOBS='-j8 -l8'  
             export ROS_PARALLEL_JOBS='-j8 -l8'

 

 

 

 

  或者,可以使用-j标识带一个参数来并行运行最多8个任务,系统负载独立:

 

[html] view plain copy

  1. export ROS_PARALLEL_JOBS=-j8  
           export ROS_PARALLEL_JOBS=-j8

 

 

 

 

     强烈建议使用-l标识来设置并行系统相关限制。在一个大的构建中并行过多可能会耗尽系统内存。

   可以接受多少系统负载取决于有多少内核。

3. ROS_LANG_DISABLE

    消息生成器/客户端库包名称应禁用一个冒号分隔的列表。Message-generation will not happen for languages in this list.

   用catkin构建的包需要需要列出应当被忽视的消息生成器的名字,例如:

 

[html] view plain copy

  1. export ROS_LANG_DISABLE=genlisp  
           export ROS_LANG_DISABLE=genlisp

 

 

 

 

   用rosbuild构建的包需要列出应当被忽视的消息生成器及客户端库的名字,例如:

 

[html] view plain copy

  1. export ROS_LANG_DISABLE=genlisp:roslisp  
            export ROS_LANG_DISABLE=genlisp:roslisp

 

 

 

 

当忽视掉消息生成器的rosbuild和CMake配置步骤,将会显示一个警告,客户端库(例如,roslisp)不是一个已知的消息生成器。这个警告可以安全的忽略掉。

注意,禁用语言之前,首先必须确定你使用的代码没有与这个语言绑定。

4. ROS_OS_OVERRIDE

格式:"OS_NAME:OS_VERSION_STRING",这将会强制检测Ubuntu Lucid:

 

[html] view plain copy

  1. export ROS_OS_OVERRIDE=ubuntu:10.04  
              export ROS_OS_OVERRIDE=ubuntu:10.04

 

 

 

 

如果定义,这将覆盖系统的自动检测。在外来平台上调试rosdep依赖性时,当平台很相似可能需要强制,或自动检测失败时,很有用。

(ros/navigation)how to build a map using logged data 怎样用记录的数据创建地图                         

 

how to build a map using logged data 怎样用记录的数据创建地图

描述:怎样用记录的转换和激光扫描数据创建二维地图。

创建地图

 1.  如果作为源校验(相对于二进制安装),构建gmapping:

 

[javascript] view plain copy

  1. rosmake gmapping  
  rosmake gmapping

 

 

 2. 获取一个包。有两个选择:

         1 用机器人创建一个包

         2 下载一个现有的包做测试

     任何一种方式,都会得到一个包。

  3. 启动核心

 

[html] view plain copy

  1. roscore   
  roscore 


 

 

 

 

 

 

  4. 在其他节点启动前,确保use_sim_time设置为true

 

[javascript] view plain copy

  1.      rosparam set use_sim_time true  
     rosparam set use_sim_time true
 

 

   5. 启动slam_gmapping,它将会接收激光扫描(在这个例子中,在base_scan话题上),并且创建地图:

 

[javascript] view plain copy

  1. rosrun gmapping slam_gmapping scan:=base_scan   
    rosrun gmapping slam_gmapping scan:=base_scan 

 

 

注意:在PR2上,odom坐标系称为odom_combined。使用这个命令:

 

[javascript] view plain copy

  1. rosrun gmapping slam_gmapping scan:=base_scan _odom_frame:=odom_combined   
 rosrun gmapping slam_gmapping scan:=base_scan _odom_frame:=odom_combined 

 

 

  6. 在一个新终端,开始回放bag文件,莱维slam_gmapping提供数据:

 

[javascript] view plain copy

  1. rosbag play --clock    
      rosbag play --clock  

 

 

 等待rosbag完成并退出。

  7. 使用map_server包的map_saver保存新地图到磁盘:

 

[javascript] view plain copy

  1. rosrun map_server map_saver   
   rosrun map_server map_saver 

 

 

现在就有了一个地图,本地保存为map.pgm。可以用任何图像浏览器(gimp,eog,gthumb等)查看;

 

下载一个测试包

使用wget命令来下载测试包,

 

[javascript] view plain copy

  1. wget http://pr.willowgarage.com/data/gmapping/basic_localization_stage.bag  
wget http://pr.willowgarage.com/data/gmapping/basic_localization_stage.bag

 

 

自己创建包

    1   启动机器人,发布激光扫描和转换数据,摇杆操纵启用(不同机器人的细节不同);

     2  开始记录扫描和转换(注意scan话题可能因为机器人不同而不同):

 

[html] view plain copy

  1. rosbag record -O mylaserdata /base_scan /tf   
 rosbag record -O mylaserdata /base_scan /tf 

 

 

 

 

 

      将会在当前目录开始写文件,文件名字为’mylaserdata_-topic.bag’

    3  驱动机器人转一圈。常用的建议:

                    Ø    尝试限制快速旋转,因为他们在扫描匹配上最难。降低操纵杆的最大允许速度比较有用。

                    Ø     用激光雷达可视化机器”看到”的;如果激光不能看到,则地图上就不会有。

                    Ø    人类走动通常不会出现问题,除非他随着机器人走,在激光的视野内。

                    Ø      回路闭合是最难的部分。关闭回路时,确保多行驶5-10米,来获得回路始端和终端之间的大量重叠。

    4 杀掉rosbag实例,并且注意创建的文件的名字。

变化:查看创建地图的进展

如果看到结果前,不介意等待直到记录数据回放和创建地图过程完成,可以再rviz中查看进展:

 

[javascript] view plain copy

  1. rosrun rviz rviz   
 rosrun rviz rviz 

 

 

添加地图显示,设置话题 /map

你可能感兴趣的:(slam,ROS)