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. git相关知识:如何避免某些文件无需提交

    查看所有命令 git help -a 查看所有概念解释 git help -g 某个命令的具体帮助信息 git help command 如何避免某些文件无需提交? 合作开发时个人的约定的不上传的文件 ...

  2. 深入理解AMD和RequireJS!

    AMD 基于commonJS规范的nodeJS出来以后,服务端的模块概念已经形成,很自然地,大家就想要客户端模块.而且最好两者能够兼容,一个模块不用修改,在服务器和浏览器都可以运行.但是,由于一个重大 ...

  3. 如何在不重启或重新格式化hadoop集群的情况下删除集群节点

    在master节点上的hadoop安装目录下 进入conf目录 配置hdfs-site.xml文件 添加节点如下: <property> <name>dfs.hosts.exc ...

  4. 【面试问题】—— 2019.3月前端面试之JS原理&CSS基础&Vue框架

    前言:三月中旬面试了两家公司,一家小型公司只有面试,另一家稍大型公司笔试之后一面定夺.笔试部分属于基础类型,网上的复习资料都有. 面试时两位面试官都有考到一些实际工作中会用到,但我还没接触过的知识点. ...

  5. idea tomcat 怎样出现update classes and resources

    idea Tomcat 出现update classes and resources 出现热加载 正确配置应该是这个 在 Deployment (调度,部署) 中点击 + 选择war explored ...

  6. bootstrap popover 如何在hover状态移动到弹出上不消失

    bootstrap中的popover其实就是对tooltip做了一定升级,拥有了标题和内容 概要 使用的时候依赖第三方插件 依赖tooltip插件 必须初始化 title 和 content 可以在p ...

  7. scp命令使下用

    先说下背景把,使用ubuntu,没有windows以下到xshell软件管理一下vps.正瞅着须要下载一个chrome(chrominum真的不好用).此刻大谷歌正墙外呢,无奈挂着ss firefox ...

  8. VLOOKUP多条件查找不使用辅助列

    问题描述: 可能很多人在使用VLOOKUP的时候,对于多条件时,则会使用辅助列进行查找,那么不使用辅助列是否也可以呢? 答案是:必须可以. 问题处理: 1.使用辅助列 2.不使用辅助列的操作如下: 公 ...

  9. 5.触摸touch,单点触摸,多点触摸,触摸优先和触摸事件的吞噬

     1 触摸 Coco2dx默认仅仅有CCLayer及其派生类才有触摸的功能. 2 单点触摸 打开触摸开关和触摸方式 setTouchEnabled(true); setTouchMode(kCCT ...

  10. CStdioFile类学习笔记<转>

    本文转自:http://www.cnblogs.com/JiMuStudio/archive/2011/07/17/2108496.html   CStdioFile类的声明保存再afx.h头文件中. ...