概率法——利用激光传感器构建占据栅格地图

2023-10-07 00:30

本文主要是介绍概率法——利用激光传感器构建占据栅格地图,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本篇主要介绍:机器人世界的几种地图;占据栅格地图的表示方法与更新方法;利用激光传感器数据构建占据栅格地图。



1. 机器人地图的分类



地图有很多种表示方式,例如,用经纬度标识地方的世界地图,城市的地铁图,校园指引图。


第一种我们称为尺度地图(Metric Map),每一个地点都可以用坐标来表示,比如北京在东经116°23′17'',北纬39°54′27'';


第二种我们称为拓扑地图(Topological Map),每一个地点用一个点来表示,用边来连接相邻的点,即图论中的图(Graph),比如从地铁路线图中我们知道地铁红磡站与旺角东站和尖东站相连;


第三种我们称为语义地图(Semantic Map),其中每一个地点和道路都会用标签的集合来表示,例如,有人问我中山大学教学楼E栋在哪里,我会说在图书馆正门右手边靠近图书馆的一侧。


在机器人领域,尺度地图常用于定位于地图构建(Mapping)、定位(Localization)和同时定位与地图构建(Simultaneous Localization And Mapping,SLAM),拓扑地图常用于路径规划(Path Planning),而语义地图常用于人机交互(Human Robot Interaction)。


这里我们将介绍如何用机器人传感器数据绘制尺度地图。这有什么难点呢?首先也是最重要的一点,传感器数据有噪音。用激光传感器检测前方障碍物距离机器人多远,不可能检测到一个准确的数值。如果准确值是120256iysd78ppr9udp08z米,有时会测出1.42米,有时甚至1.35米。另外,传感器数据是本地坐标系的,而机器人要构建的是一个全局的地图。最后,机器人会运动,运动也是有噪音的。总结起来就两个字,噪音。通俗点来讲,“不准”。


在本篇文章中,我们利用“概率”这一神奇的数学武器来处理机器人Mapping的问题。



2. 占据栅格地图



我们首先来介绍机器人Mapping用到的的传感器,它叫做激光传感器(Laser Sensor),如下图所示:


120256siu6mbpbb9vuayzy


激光传感器会向固定的方向发射激光束,发射出的激光遇到障碍物会被反射,这样就能得到激光从发射到收到的时间差,乘以速度除以二就得到了传感器到该方向上最近障碍物的距离。


这样看来,似乎利用激光传感器,机器人能够很好地完成Mapping这一任务。但是我们前面提到了,传感器数据是有噪音的。例如,假如我们在此时检测到距离障碍物4米,下一时刻检测到距离障碍物4.1米,我们是不是应该把4米和4.1米的地方都标记为障碍物?又或者怎么办呢?


为了解决这一问题,我们引入占据栅格地图(Occupancy Grid Map)的概念。


我们首先来解释这里的占据率(Occupancy)指的是什么。在通常的尺度地图中,对于一个点,它要么有(Occupied状态,下面用1来表示)障碍物,要么没有(Free状态,下面用0来表示)障碍物(旁白:那么问题来了,薛定谔状态呢?)。在占据栅格地图中,对于一个点,我们用120256ru21yojkuqm7y9o9来表示它是Free状态的概率,用120256vaoo7iorvoo7ovrt来表示它是Occupied状态的概率,当然两者的和为 。两个值太多了,我们引入两者的比值来作为点的状态:120256bozqq7j7n9f9s9n7


对于一个点,新来了一个测量值(Measurement,120256fp4n4hjzsn4pzbzt)之后我们需要更新它的状态。假设测量值来之前,该点的状态为120256lbxi1idihs6lxnhk ,我们要更新它为:120256tjjrxrc0amrrbqch 。这种表达方式类似于条件概率,表示在z发生的条件下s的状态。


根据贝叶斯公式,我们有:

 

120256dktf8zniptmlcfk5


带入之后,我们得


120256dr31klvu7rx67ll3


我们对两边取对数得:


120256wf2fbwfddmfd0g0d


这样,含有测量值的项就只剩下了120256ycnt7dimfhe1tcea 。我们称这个比值为测量值的模型(Measurement Model),标记为120256j5sqn8p8yvpkttzq。测量值的模型只有两种:120256vttv4thzfhnh5lls120256uzz08n367x43bxjo,而且都是定值。


这样,如果我们用120256w8dawjrocrm5mja1来表示位置s的状态S的话,我们的更新规则就进一步简化成了:120256tmmatcfiedfd5kkm 。其中120256nlo3n3r59oznpa5n120256d9zsnnswk99wkwca分别表示测量值之后和之前s的状态。


另外,在没有任何测量值的初始状态下,一个点的初始状态 。


120256essz5jbfte2e2e2s


经过这样的建模,更新一个点的状态就只需要做简单的加减法了。这,就是数学的魅力。

例如,假设我们设定120256iwnnnh2w8km9n9nr120256hf47f9fh7tfr8m6a。那么, 一个点状态的数值越大,就表示越肯定它是Occupied状态,相反数值越小,就表示越肯定它是Free状态。


120256teu6d1wrwhmdkq33


上图就展示了用两个激光传感器的数据更新地图的过程。在结果中,一个点颜色越深表示越肯定它是Free的,颜色越浅表示越肯定它是Occupied的。



3. 利用激光传感器构建占据栅格地图



前面讲到通常用激光传感器数据来构占据栅格地图,这一节我们将详细介绍其中的实现细节。具体来说,我们需要编写函数:


function myMap = occGridMapping(ranges, scanAngles, pose, param)


其中,scanAngles是一个120256x7gdwlidohihjid9的数组,表示激光传感器的N个激光发射方向(与机器人朝向的夹角,定值);ranges是一个K*N的数组,表示N个时间采样点激光传感器的读数(距离障碍物的距离);pose是一个3*N的数组,表示N个时间采样点机器人的位置和朝向信息(前两维为位置,第三维为朝向角度);param是一些传入的参数,param.origin是机器人的起点,param.lo_occ和param.lo_free分别是第二节中的looccu和lofree,param.max和param.min表示位置状态的阈值(超过则置为阈值边界),param.resol表示地图的分辨率,即实际地图中一米所表示的格点数目,param.size表示地图的大小。


首先,我们解决如何将真实世界中的坐标转化为栅格地图中的坐标。


考虑一维的情况:


120256n40nwxpnwpgzns6q


图中x是真实世界中的坐标,i为离散化了的地图(栅格地图)中的坐标, r为一格的长度, 1/r表示分辨率,显然我们有:120256ag4ze24ezn441234 。


同理,二维情况下:120256d1z1jme32tyteyyr 。


其次,我们来计算每一条激光所检测出的障碍物和非障碍物在栅格地图中的位置。


假设机器人的状态为120256he9lbe4b2vn39coe,激光与机器人朝向的夹角为120256eo9jo3bxg0btnuuy,测量的障碍物的距离为120256u84atrbn20enzej2


120256mng65r95jl5r6kjk


计算障碍物所在点的实际位置:


120256bzcyrymamzyza7w1
120256f5u7o538p5c7p4ao
 

再计算障碍物在栅格地图中的位置120256qot5tlfzo5fl9wjg ,以及机器人在栅格地图中的位置120256xiscl5jlus287z58。根据这两个坐标可以使用Bresenham算法来计算非障碍物格点的集合。

 

120256o7ejr8ryr7yjyjr5


最后,利用第二节中的结论,我们使用简单的加减法不断更新格点的状态即可。

完整的Matlab代码如下:


function myMap = occGridMapping(ranges, scanAngles, pose, param)


resol = param.resol; % the number of grids for 1 meter.

myMap = zeros(param.size); % the initial map size in pixels

origin = param.origin; % the origin of the map in pixels


% Log-odd parameters 

lo_occ = param.lo_occ;

lo_free = param.lo_free;

lo_max = param.lo_max;

lo_min = param.lo_min;


lidarn = size(scanAngles,1); % number of rays per timestamp

N = size(ranges,2); % number of timestamp


for i = 1:N % for each timestamp

    theta = pose(3,i); % orientation of robot

    % coordinate of robot in real world

    x = pose(1,i);

    y = pose(2,i);


    % local coordinates of occupied points in real world

    local_occs = [ranges(:,i).*cos(scanAngles+theta), -ranges(:,i).*sin(scanAngles+theta)];


    % coordinate of robot in metric map

    grid_rob = ceil(resol * [x; y]);


    % calc coordinates of occupied and free points in metric map

    for j=1:lidarn

        real_occ = local_occs(j,:) + [x, y]; % global coordinate of occ in real world

        grid_occ = ceil(resol * real_occ); % coordinate of occ in metric map


        % coordinates of free in metric map (by breshnham's algorithm)

        [freex, freey] = bresenham(grid_rob(1),grid_rob(2),grid_occ(1),grid_occ(2));


        % convert coordinate to offset to array

        free = sub2ind(size(myMap),freey+origin(2),freex+origin(1));

        occ = sub2ind(size(myMap), grid_occ(2)+origin(2), grid_occ(1)+origin(1));


        % update metric map

        myMap(free) = myMap(free) - lo_free;

        myMap(occ) = myMap(occ) + lo_occ;

    end

end


% reassign value if out of range

myMap(myMap < lo_min) = lo_min;

myMap(myMap > lo_max) = lo_max;


使用课程给的数据,我们最终画出下面这样的占据栅格地图(用灰度图显示出来的):

 

120256g66brmemlm89y3mm


结语:地图构建(Mapping)是机器人领域的一个重要问题,本文介绍了占据栅格地图的表示方法和利用激光传感器构建占据栅格地图的方法。但是,我们不难发现,使用的数据中机器人的位置和朝向是给定的。然而在实际的应用中,机器人不仅需要为未知环境构建地图,还要在未知环境中定位(Localization)以完成其他任务。我们发现,Mapping和Localization是相辅相成、不可分割的两部分,这就是同时定位与地图构建(SLAM)问题,机器人领域中的一个重要问题。


120256aggagpapg5upu9ul

END



这篇关于概率法——利用激光传感器构建占据栅格地图的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/154914

相关文章

nginx-rtmp-module构建流媒体直播服务器实战指南

《nginx-rtmp-module构建流媒体直播服务器实战指南》本文主要介绍了nginx-rtmp-module构建流媒体直播服务器实战指南,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有... 目录1. RTMP协议介绍与应用RTMP协议的原理RTMP协议的应用RTMP与现代流媒体技术的关系2

Python中构建终端应用界面利器Blessed模块的使用

《Python中构建终端应用界面利器Blessed模块的使用》Blessed库作为一个轻量级且功能强大的解决方案,开始在开发者中赢得口碑,今天,我们就一起来探索一下它是如何让终端UI开发变得轻松而高... 目录一、安装与配置:简单、快速、无障碍二、基本功能:从彩色文本到动态交互1. 显示基本内容2. 创建链

Golang使用etcd构建分布式锁的示例分享

《Golang使用etcd构建分布式锁的示例分享》在本教程中,我们将学习如何使用Go和etcd构建分布式锁系统,分布式锁系统对于管理对分布式系统中共享资源的并发访问至关重要,它有助于维护一致性,防止竞... 目录引言环境准备新建Go项目实现加锁和解锁功能测试分布式锁重构实现失败重试总结引言我们将使用Go作

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

maven 编译构建可以执行的jar包

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」👈,「stormsha的知识库」👈持续学习,不断总结,共同进步,为了踏实,做好当下事儿~ 专栏导航 Python系列: Python面试题合集,剑指大厂Git系列: Git操作技巧GO

嵌入式Openharmony系统构建与启动详解

大家好,今天主要给大家分享一下,如何构建Openharmony子系统以及系统的启动过程分解。 第一:OpenHarmony系统构建      首先熟悉一下,构建系统是一种自动化处理工具的集合,通过将源代码文件进行一系列处理,最终生成和用户可以使用的目标文件。这里的目标文件包括静态链接库文件、动态链接库文件、可执行文件、脚本文件、配置文件等。      我们在编写hellowor

利用命令模式构建高效的手游后端架构

在现代手游开发中,后端架构的设计对于支持高并发、快速迭代和复杂游戏逻辑至关重要。命令模式作为一种行为设计模式,可以有效地解耦请求的发起者与接收者,提升系统的可维护性和扩展性。本文将深入探讨如何利用命令模式构建一个强大且灵活的手游后端架构。 1. 命令模式的概念与优势 命令模式通过将请求封装为对象,使得请求的发起者和接收者之间的耦合度降低。这种模式的主要优势包括: 解耦请求发起者与处理者

Jenkins构建Maven聚合工程,指定构建子模块

一、设置单独编译构建子模块 配置: 1、Root POM指向父pom.xml 2、Goals and options指定构建模块的参数: mvn -pl project1/project1-son -am clean package 单独构建project1-son项目以及它所依赖的其它项目。 说明: mvn clean package -pl 父级模块名/子模块名 -am参数