碰撞检测 | 图解视线生成Bresenham算法(附ROS C++/Python/Matlab实现)

目录

  • 0 专栏介绍
  • 1 Bresenham算法介绍
  • 2 图解Bresenham算法
  • 3 算法流程
  • 4 仿真实现
    • 4.1 ROS C++实现
    • 4.2 Python实现
    • 4.3 Matlab实现

0 专栏介绍

🔥课设、毕设、创新竞赛必备!🔥本专栏涉及更高阶的运动规划算法轨迹优化实战,包括:曲线生成、碰撞检测、安全走廊、优化建模(QP、SQP、NMPC、iLQR等)、轨迹优化(梯度法、曲线法等),每个算法都包含代码实现加深理解

🚀详情:运动规划实战进阶:轨迹优化篇


1 Bresenham算法介绍

Bresenham视线生成算法是一种高效的算法,用于在二维网格上绘制直线。它是由Jack Bresenham在1962年提出的,广泛应用于计算机图形学和游戏开发中。该算法的主要优点是只使用整数运算,因此速度较快且易于实现。下面是该算法的动图案例

在这里插入图片描述

Bresenham算法可以巧妙地应用在栅格地图中进行一维碰撞检测:首先确定起点和终点,然后使用Bresenham算法绘制从起点到终点的线段,接着检查该路径上每个栅格点是否与障碍物重叠。

2 图解Bresenham算法

Bresenham碰撞测试在三种类型的移动中访问单元格:

  • x x x方向移动
  • y y y方向移动
  • 对角线移动

在栅格地图中,碰撞检测点连线经过若干离散栅格,因此每次移动都将产生非连续误差,Bresenham算法要求下一个移动偏差最小。通过迭代即可访问检测线经过的所有栅格,判断这些栅格的代价是否超过阈值即可完成碰撞检测。

具体地,设需要检测节点 v v v w w w间的连线是否经过障碍物,定义缩放误差分别为 δ x = ∣ w . x − v . x ∣ \delta _x=\left| w.x-v.x \right| δx=w.xv.x δ y = ∣ w . y − v . y ∣ \delta _y=\left| w.y-v.y \right| δy=w.yv.y;扩展误差分别为 e x e_x ex e y e_y ey;方向增量分别为 Δ x = s g n ( w . x − v . x ) \varDelta x=sgn\left( w.x-v.x \right) Δx=sgn(w.xv.x) Δ y = s g n ( w . y − v . y ) \varDelta y=sgn \left( w.y-v.y \right) Δy=sgn(w.yv.y)。下面考虑 δ x > δ y \delta _x>\delta _y δx>δy的情形, δ x ⩽ δ y \delta _x\leqslant \delta _y δxδy时可对称导出。

在这里插入图片描述

如图所示,根据三角形相似关系可得

{ e y e x = ∣ Δ y ∣ t t δ y = ∣ Δ x ∣ δ x ⇒ e y e x = ∣ Δ y ∣ ∣ Δ x ∣ ⋅ δ x δ y = δ x δ y \begin{cases} \frac{e_y}{e_x}=\frac{\left| \varDelta y \right|}{t}\\ \frac{t}{\delta _y}=\frac{\left| \varDelta x \right|}{\delta _x}\\\end{cases}\Rightarrow \frac{e_y}{e_x}=\frac{\left| \varDelta y \right|}{\left| \varDelta x \right|}\cdot \frac{\delta _x}{\delta _y}=\frac{\delta _x}{\delta _y} {exey=tΔyδyt=δxΔxexey=ΔxΔyδyδx=δyδx

不妨令 e y = δ x e_y=\delta _x ey=δx e x = δ y e_x=\delta _y ex=δy,则沿 x x x方向移动将产生负向偏差 δ y \delta _y δy,沿 y y y方向移动将产生正向偏差 δ x \delta _x δx,根据最小化偏差原则选择移动方向

( x , y ) ← { ( x + Δ x , y ) , i f ∣ e + δ x ∣ > ∣ e − δ y ∣ ( x , y + Δ y ) , i f ∣ e + δ x ∣ < ∣ e − δ y ∣ ( x + Δ x , y + Δ y ) , i f ∣ e + δ x ∣ = ∣ e − δ y ∣ \left( x,y \right) \gets \begin{cases} \left( x+\varDelta x,y \right) , \mathrm{if} \left| e+\delta _x \right|>\left| e-\delta _y \right|\\ \left( x,y+\varDelta y \right) , \mathrm{if} \left| e+\delta _x \right|<\left| e-\delta _y \right|\\ \left( x+\varDelta x,y+\varDelta y \right) , \mathrm{if} \left| e+\delta _x \right|=\left| e-\delta _y \right|\\\end{cases} (x,y)(x+Δx,y),ife+δx>eδy(x,y+Δy),ife+δx<eδy(x+Δx,y+Δy),ife+δx=eδy

下图为Bresenham扩展节点的实例

在这里插入图片描述

3 算法流程

算法流程如下所示

在这里插入图片描述

4 仿真实现

4.1 ROS C++实现

核心代码如下所示

template <typename Point, typename F_is_obs>
static bool BresenhamCollisionDetection(const Point& pt1, const Point& pt2, F_is_obs func_is_obs)
{int s_x = (pt1.x() - pt2.x() == 0) ? 0 : (pt1.x() - pt2.x()) / std::abs(pt1.x() - pt2.x());int s_y = (pt1.y() - pt2.y() == 0) ? 0 : (pt1.y() - pt2.y()) / std::abs(pt1.y() - pt2.y());int d_x = std::abs(pt1.x() - pt2.x());int d_y = std::abs(pt1.y() - pt2.y());// check if any obstacle exists between pt1 and pt2if (d_x > d_y){int tau = d_y - d_x;int x = pt2.x(), y = pt2.y();int e = 0;while (x != pt1.x()){if (e * 2 > tau){x += s_x;e -= d_y;}else if (e * 2 < tau){y += s_y;e += d_x;}else{x += s_x;y += s_y;e += d_x - d_y;}if (func_is_obs(Point(x, y)))// obstacle detectedreturn true;}}else{// similar. swap x and yint tau = d_x - d_y;int x = pt2.x(), y = pt2.y();int e = 0;while (y != pt1.y()){if (e * 2 > tau){y += s_y;e -= d_x;}else if (e * 2 < tau){x += s_x;e += d_y;}else{x += s_x;y += s_y;e += d_y - d_x;}if (func_is_obs(Point(x, y)))// obstacle detectedreturn true;}}return false;
}

4.2 Python实现

核心代码如下所示

def BresenhamCollisionDetection(self, node1: Node, node2: Node) -> bool:if node1.current in self.obstacles or node2.current in self.obstacles:return Falsex1, y1 = node1.currentx2, y2 = node2.currentif x1 < 0 or x1 >= self.env.x_range or y1 < 0 or y1 >= self.env.y_range:return Falseif x2 < 0 or x2 >= self.env.x_range or y2 < 0 or y2 >= self.env.y_range:return Falsed_x = abs(x2 - x1)d_y = abs(y2 - y1)s_x = 0 if (x2 - x1) == 0 else (x2 - x1) / d_xs_y = 0 if (y2 - y1) == 0 else (y2 - y1) / d_yx, y, e = x1, y1, 0# check if any obstacle exists between node1 and node2if d_x > d_y:tau = (d_y - d_x) / 2while not x == x2:if e > tau:x = x + s_xe = e - d_yelif e < tau:y = y + s_ye = e + d_xelse:x = x + s_xy = y + s_ye = e + d_x - d_yif (x, y) in self.obstacles:return False# swap x and yelse:tau = (d_x - d_y) / 2while not y == y2:if e > tau:y = y + s_ye = e - d_xelif e < tau:x = x + s_xe = e + d_yelse:x = x + s_xy = y + s_ye = e + d_y - d_xif (x, y) in self.obstacles:return Falsereturn True

4.3 Matlab实现

核心代码如下所示

function flag = BresenhamCollisionDetection(map, node1, node2)
% @breif: Judge collision when moving from node1 to node2 using Bresenham.if (map(node1(1), node1(2)) == 2) || (map(node2(1), node2(2)) == 2)flag = true;returnendx1 = node1(1); y1 = node1(2);x2 = node2(1); y2 = node2(2);d_x = abs(x2 - x1);d_y = abs(y2 - y1);if  (x2 - x1) == 0s_x = 0;elses_x = (x2 - x1) / d_x;endif  (y2 - y1) == 0s_y = 0;elses_y = (y2 - y1) / d_y;endx = x1; y = y1; e = 0;% check if any obstacle exists between node1 and node2if d_x > d_ytao = (d_y - d_x) / 2;while x ~= x2if e > taox = x + s_x;e = e - d_y;elseif e < taoy = y + s_y;e = e + d_x;elsex = x + s_x;y = y + s_y;e = e + d_x - d_y;endif map(x, y) == 2flag = true;return;endend% swap x and yelsetao = (d_x - d_y) / 2;while y ~= y2if e > taoy = y + s_y;e = e - d_x;elseif e < taox = x + s_x;e = e + d_y;elsex = x + s_x;y = y + s_y;e = e + d_y - d_x;endif map(x, y) == 2flag = true;return;endendendflag = false;
end

完整工程代码请联系下方博主名片获取


🔥 更多精彩专栏

  • 《ROS从入门到精通》
  • 《Pytorch深度学习实战》
  • 《机器学习强基计划》
  • 《运动规划实战精讲》

👇源码获取 · 技术交流 · 抱团学习 · 咨询分享 请联系👇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1557340.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

C语言 | 第十一章 | static 日期函数 数学函数

P 100 变量作用域基本规则 2023/1/9 一、基本介绍 概念&#xff1a;所谓变量作用域&#xff08;Scope&#xff09;&#xff0c;就是指变量的有效范围。 函数内部声明/定义的局部变量&#xff0c;作用域仅限于函数内部。 #include<stdio.h> void sayHello() {char nam…

手机怎样改网络ip地址?内容详尽实用

随着网络技术的发展&#xff0c;更改手机IP地址已成为一种常见需求。本文将详细介绍如何在不同网络环境下更改手机IP地址&#xff0c;包括移动网络和WiFi网络&#xff0c;以及同时适用于两种网络的方法&#xff0c;内容详尽实用&#xff0c;干货满满。 一、适用于移动网络&…

为什么目录站这么多导出链接,却不影响排名?

导出链接就是网站或者页面中有指向别的网站的单向链接&#xff0c;导出链接过多会导致网站的权重流向对方的网站&#xff0c;所以除非您网站内容有极大的参考价值&#xff0c;并且专业性很强&#xff0c;在业界有口皆碑&#xff0c;否则很难让别的站长主动单向链接到您的网站。…

ChatGPT助力文献综述写作:提升效率与写作技巧!

文献综述在论文写作中占有举足轻重的地位。它不仅帮助我们梳理已有的研究成果&#xff0c;还能为自己的研究奠定基础。许多同学在撰写文献综述时常常感到头疼&#xff1a;如何处理海量的信息&#xff1f;如何将不同的观点有条理地整合起来&#xff1f;再加上学术语言的高要求&a…

VSCode运行QT界面

VSCode用久了,感觉Qt Creator的写起代码来还是不如VSCode得心应手,虽然目前还是存在一些问题,先把目前实现的状况做个记录,后续有机会再进一步优化。 当前方式 通过QtCreator创建一个CMake项目,然后使用CMake的方式在VSCode中进行编译。 claude给出的建议 左上角的名字会…

普通人也能看懂的大语言模型入门,不要错过哦

1. 引言 本文旨在为没有计算机科学背景的人士提供关于ChatGPT及类似AI系统&#xff08;GPT-3、GPT-4、Bing Chat、Bard等&#xff09;的工作原理的洞察。ChatGPT是一种聊天机器人——一种基于大型语言模型构建的对话式AI。这些肯定是些专业术语&#xff0c;我们将逐一解析。在…

【汇编语言】寄存器(CPU工作原理)(四)—— “段地址x16 + 偏移地址 = 物理地址”的本质含义以及段的概念和小结

文章目录 前言1. "段地址x16 偏移地址 物理地址"的本质含义2. 段的概念3. 内存单元地址小结结语 前言 &#x1f4cc; 汇编语言是很多相关课程&#xff08;如数据结构、操作系统、微机原理&#xff09;的重要基础。但仅仅从课程的角度出发就太片面了&#xff0c;其实…

react crash course 2024(4) 番外 使用class创建组件

1.创建 import React from reactexport default class Home extends React.Component{render(){return(<button>点我发送一个action</button>)} } 2.使用

《数据结构》学习系列——树(上)

系列文章目录 目录 树的基本概念树的定义树的特点树的相关术语度层数高度路径二叉树定义特点定理满二叉树定义特点完全二叉树定义特点二叉树的存储结构顺序存储结点结构优点缺点 链式存储 结点结构三叉链表表示法算法搜索结点的父结点搜索符合数据域条件的结点删除给定结点及其…

手机IMEI号为空

1、问题描述 售后反馈&#xff0c;几台机器出现无IMEI问题&#xff0c;需要分析确认 2、分析过程 抓取开机日志&#xff0c;发现radio log中&#xff0c;RILD一直处于重启状态。 Line 1589: 12-19 14:44:42.836240 3156 3156 I IMS_RILA: getMtkRadioProxy service d…

javaweb-请求和响应

1.http协议 1.1请求 1.2.响应 常见响应状态码&#xff1a; 状态码大全&#xff1a;https://cloud.tencent.com/developer/chapter/13553 常见的响应头&#xff1a; 2.请求和响应 2.1.请求 2.1.1postman 作用&#xff1a;常用于接口测试 使用&#xff1a;官网安装-->注册…

Java 根据字符生成背景透明的图片

上代码 package com.example.demotest.controller;/*** Author shaolin* Date 2024-10-08 10:11**/import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.WritableRaster; impor…

Github 2024-10-08 Python开源项目日报Top10

根据Github Trendings的统计,今日(2024-10-08统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目10JavaScript项目1系统设计指南 创建周期:2507 天开发语言:Python协议类型:OtherStar数量:241693 个Fork数量:42010 次关注人数…

深入了解音频剪辑在线工具的特色与优势

在数字时代&#xff0c;音频内容已成为连接人心的重要桥梁。如果你也有同样的兴趣爱好&#xff0c;那不妨看看我今天要介绍的音频剪辑在线相关的工具们吧。 1.福昕音频剪辑 链接直达>>https://www.foxitsoftware.cn/audio-clip/ 福昕音频剪辑工具&#xff0c;专为音乐…

【含开题报告+文档+PPT+源码】基于SSM框架的民宿酒店预定系统的设计与实现

开题报告 随着人们旅游需求的增加&#xff0c;民宿行业呈现出快速发展的趋势。传统的住宿方式逐渐无法满足人们对个性化、舒适、便捷的需求&#xff0c;而民宿作为一种新型的住宿选择&#xff0c;逐渐受到人们的青睐。民宿的特点是具有独特的风格、便捷的地理位置、相对亲近的…

Spring Aop实现日志收集和重复属性赋值

Spring Aop实现日志收集和重复属性赋值 简介 ​ AOP(Aspect-Oriented Programming)&#xff0c;即面向切面编程&#xff0c;用人话说就是把公共的逻辑抽出来&#xff0c;让开发者可以更专注于业务逻辑开发。 ​ 和IOC一样&#xff0c;AOP也指的是一种思想。AOP思想是OOP&…

电商行业应用 WMS 的成功案例

【大家好&#xff0c;我是唐Sun&#xff0c;唐Sun的唐&#xff0c;唐Sun的Sun。一站式数智工厂解决方案服务商】 京东&#xff1a;作为国内知名的电商巨头&#xff0c;京东拥有庞大的仓储体系。通过应用先进的 WMS 系统&#xff0c;实现了高效的库存管理、精准的订单拣选和快速…

Java中HashMap和HashTable的区别

HashTable&#xff1a; HashMap&#xff1a; HashMap和Hashtable将键和值对存储在哈希表中。使用 Hashtable 或 HashMap 时&#xff0c;我们指定一个用作键的对象以及要链接到该键的值。然后对键进行哈希处理&#xff0c;并将生成的哈希码用作表中存储值的索引。现在让我们借助…

基于java SpringBoot和Vue校园求职招聘系统设计

摘要 随着信息技术的迅猛发展&#xff0c;基于Java Spring Boot和Vue的校园求职招聘系统设计成为了解决高校就业难问题的重要手段。本文旨在探讨如何利用Java Spring Boot框架构建后端服务&#xff0c;以及使用Vue.js进行前端开发&#xff0c;从而创建一个高效、易用且功能全面…