costmap_2d:

无论是激光雷达还是如kinect 或xtion pro深度相机作为传感器跑出的2D或3D SLAM地图,都不能直接用于实际的导航,必须将地图转化为costmap(代价地图),ROS的costmap通常采用grid(网格)形式。以前一直没有搞明白每个栅格的概率是如何算出来的,原因是之前一直忽略了内存的存储结构,栅格地图一个栅格占1个字节,也就是八位,可以存0-255中数据,也就是每个cell cost(网格的值)从0~255我们只需要三种情况:Occupied被占用(有障碍), Free自由区域(无障碍),  Unknown Space未知区域。笔者根据以下第二个图进行形象的讲解。这个值究竟是什么,接下来会讲到。

bresenham算法:

在介绍costmap_2d之前,要先介绍个算法bresenham算法,Bresenham直线算法是用来描绘由两点所决定的直线的算法,它会算出一条线段在n维光栅上最接近的点。这个算法只会用到较为快速的整数加法、减法和位元移位,常用于绘制电脑画面中的直线。是计算机图形学中最先发展出来的算法。
 
过各行各列象素中心构造一组虚拟网格线如上图。按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后根据误差项的符号确定该列象素中与此交点最近的象素。
 
核心思想:
假设:k=dy/dx。因为直线的起始点在象素中心,所以误差项d的初值d0=0。X下标每增加1,d的值相应递增直线的斜率值k,即d=d+k。一旦d≥1,就把它减去1,这样保证d在0、1之间。当d≥0.5时,最接近于当前象素的右上方象素(x+1,y+1)而当d<0.5时,更接近于右方象素(x+1,y)为方便计算,令e=d-0.5,e的初值为-0.5,增量为k。当e≥0时,取当前象素(xi,yi)的右上方象素(x+1,y+1)而当e<0时,更接近于右方象素(x+1,y)可以改用整数以避免除法。由于算法中只用到误差项的符号,因此可作如下替换:e1 = 2*e*dx
 

算法推导:

假设我们需要由(x0,y0)这一点,绘画一直线至右下角的另一点(x1,y1),x,y分别代表其水平及垂直座标,并且x1-x0>y1-y0。在此我们使用计算机视觉常用坐标系即,x座标值沿x轴向右增长,y座标值沿y轴向下增长。

因此x及y之值分别向右及向下增加,而两点之水平距离为 且垂直距离为y1-y0。由此得之,该线的斜率必定介乎于1至0之间。而此算法之目的,就是找出在之间,第x行相对应的第y列,从而得出一像素点,使得该像素点的位置最接近原本的线。

对于由(x0,y0)及(x1,y1)两点所组成之直线,公式如下:

因此,对于每一点的x,其y的值是

因为x及y皆为整数,但并非每一点x所对应的y皆为整数,故此没有必要去计算每一点x所对应之y值。反之由于此线之斜率介乎于1至0之间,故此我们只需要找出当x到达那一个数值时,会使y上升1,若x尚未到此值,则y不变。至于如何找出相关的x值,则需依靠斜率。斜率之计算方法为。由于此值不变,故可于运算前预先计算,减少运算次数。

要实行此算法,我们需计算每一像素点与该线之间的误差。于上述例子中,误差应为每一点x中,其相对的像素点之y值与该线实际之y值的差距。每当x的值增加1,误差的值就会增加m。每当误差的值超出0.5,线就会比较靠近下一个映像点,因此y的值便会加1,且误差减1。

下列伪代码是这算法的简单表达(其中的plot(x,y)绘画该点,abs返回的是绝对值)。虽然用了代价较高的浮点运算,但很容易就可以改用整数运算。

function line(x0, x1, y0, y1)
int deltax := x1 - x0
int deltay := y1 - y0
real error :=
real deltaerr := deltay / deltax // 假設deltax != 0(非垂直線),
// 注意:需保留除法運算結果的小數部份
int y := y0
for x from x0 to x1
plot(x,y)
error := error + deltaerr
if abs (error) ≥ 0.5 then
y := y +
error := error - 1.0

  

costmap_2d:

以激光雷达为传感器(或者kinect之类的深度相机的伪激光雷达),根据激光测量的障碍物距离机器人中心的距离,结合机器人的内切和外切半径,搞一个映射,例如,机器人内切半径为0.5m,外切半径为0.7m,当激光返回障碍距离在机器人中心附近,叫致命障碍,机器人一定能碰到障碍物,比如说0m,直接贴着机器人,或会取小于栅格的边长,比如小于0.1m范围内,则这个栅格值就设为254;当返回来的数值在0.1-0.5m之间,就设253;当在0.5-0.7之间,则可以设128,或者在252-128找个比例值(程序中可以控制),这些是被占用(有障碍)区域;当0.7-膨胀半径之间,设1-127之间的映射值,可能碰撞障碍物;当大于膨胀距离,则设为0,称为freespace。Unknown -- 意味着给定的单元没有相应的信息。
3d的结合z轴信息,进行设置,把这些区域归一化,就得到了每个栅格的概率。
 
costmap是分层的:比如静态地图是一层,障碍物是一层,我自己定义的障碍物是一层(假如我不想让机器人通过一个freespace就可以自己插入个障碍物主要的接口是costmap_2d::Costmap2DROS,每一层中使用pluginlib实例化Costmap2DROS和每一层都被添加到LayeredCostmap)各个层可以被独立的编译。
 
利用bresenham算法可以填充由激光雷达的位置到障碍物之间的栅格概率了。
 
 

ROS导航之地图costmap_2d与bresenham算法的更多相关文章

  1. ROS导航包的介绍

    博客转载自:https://blog.csdn.net/handsome_for_kill/article/details/53130707#t3 ROS导航包的应用 利用ROS Navigation ...

  2. ROS机器人导航一 : 从英雄联盟到ROS导航

    写在前面: 这是这个系列的第一篇 本系列主要从零开始深入探索ROS(机器人操作系统)的导航和规划. 这个系列的目标,是让大家了解: 1.ROS的导航是怎么实现的 2.认识ROS里各种已有的导航算法,清 ...

  3. 《图形学》实验七:中点Bresenham算法画椭圆

    开发环境: VC++6.0,OpenGL 实验内容: 使用中点Bresenham算法画椭圆. 实验结果: 代码: #include <gl/glut.h> #define WIDTH 50 ...

  4. 《图形学》实验六:中点Bresenham算法画圆

    开发环境: VC++6.0,OpenGL 实验内容: 使用中点Bresenham算法画圆. 实验结果: 代码: #include <gl/glut.h> #define WIDTH 500 ...

  5. 《图形学》实验五:改进的Bresenham算法画直线

    开发环境: VC++6.0,OpenGL 实验内容: 使用改进的Bresenham算法画直线. 实验结果: 代码: //中点Bresenham算法生成直线 #include <gl/glut.h ...

  6. 《图形学》实验四:中点Bresenham算法画直线

    开发环境: VC++6.0,OpenGL 实验内容: 使用中点Bresenham算法画直线. 实验结果: 代码: //中点Bresenham算法生成直线 #include <gl/glut.h& ...

  7. 利用canvas实现的中点Bresenham算法

    Bresenham提出的直线生成算法的基本原理是,每次在最大位移方向上走一步,而另一个方向是走步还是不走步取决于误差项的判别,具体的实现过程大家可以去问度娘.我主要是利用canvas画布技术实现了这个 ...

  8. 通过Bresenham算法实现完成矢量线性多边形向栅格数据的转化

    1.实验目的与要求 目的:通过本次实验,完成矢量线性多边形向栅格数据的转化过程: 要求:采用VC++6.0实现. 2.实验方法 采用Bresenham算法实现 3.实验材料 直线的定义:y = x/3 ...

  9. Bresenham算法画填充圆及SDL代码实现

    画圆是计算机图形操作中一个非常重要的需求.普通的画圆算法需要大量的浮点数参与运算,而众所周知,浮点数的运算速度远低于整形数.而最终屏幕上影射的像素的坐标均为整形,不可能是连续的线,所以浮点数运算其实纯 ...

随机推荐

  1. Lucene的学习及使用实验

    实验一下Lucene是怎么使用的. 参考:http://www.importnew.com/12715.html (例子比较简单) http://www.yiibai.com/lucene/lucen ...

  2. (如何理解gamma校准)GAMMA测试方法及分析

    http://wenku.baidu.com/link?url=Wz5oXJsFQ-TVe3qxm9Zd4pp207cQ4jmjuBnwmWAvD1ibgoI2U8y7KCFhaR9xWtu9cGLE ...

  3. Scala实现冒泡排序、归并排序和快速排序

    1.冒泡排序 def sort(list: List[Int]): List[Int] = list match { case List() => List() case head :: tai ...

  4. asp.net购物车,订单以及模拟支付宝支付(二)---订单表

    购物车准备完毕之后,就要着手订单表的设计了 表结构如下: T_Orders T_OrderBooks 为什么这里要分为两个表? 仔细想想,现实生活中的发票 特地去网上找了一张,不是很清晰 但是,正常人 ...

  5. Django——如何在Django模板中注入全局变量?——part1

    问题:TEMPLATE_CONTEXT_PROCESSORS代表着什么? 问题描述:无法在项目的settings.py文件中找到TEMPLATE_CONTEXT_PROCESSORS. ——————— ...

  6. NSight统计数据的颜色,缩写意义是什么?来自NV Jeff Kiel 比较官方的解释!

    结合这个图示来看:https://dl.dropboxusercontent.com/u/32077444/nsight.pdf 1) The bars you see in the Summary ...

  7. Node.js进阶篇-koa、钩子函数、websocket、嵌入式开发

    代码地址如下:http://www.demodashi.com/demo/12932.html 一.简介     koa是由Express原班人马打造的,致力于成为一个更小.更富有表现力.更健壮的We ...

  8. XYWi-Fi v2.0 简单的笔记本无线热点分享工具【Win】

    [软件名称]XYWi-Fi [版本号]v2.0 [适用系统]Windows 7/8/8.1/10 [功能特性]简单的笔记本无线热点分享工具 [下载地址]pan.baidu.com/s/1mgmOpJi ...

  9. MongoDB笔记(三):Document 数据插入、删除、更新

    实例数据库caliven.集合users 一.插入文档 1.插入文档 db.[documentName].insert({}) 2.批量插入文档 .shell 这样执行是错误的db.[document ...

  10. freemarker相关

    大部分引入:http://www.blogjava.net/alinglau36/archive/2011/02/23/344970.html Freemarker操作字符串 1.substring( ...