如何在x-y轴上检查碰撞

4

我正在Ubuntu用C/C++编写一款移动机器人应用程序,目前,我使用激光传感器扫描环境,在机器人运动时检测与物体的碰撞。

该激光具有270°的扫描区域和最大半径4000mm。它能够在此范围内检测物体并报告其与传感器的距离。

每个距离都是平面坐标,所以为了获得更易读的数据,我将它们从平面坐标转换为笛卡尔坐标,然后将它们打印到文本文件中,再在MatLab中绘制它们以查看激光检测到的内容。

这张图片展示了笛卡尔坐标下的一个典型检测结果。 enter image description here 数值以米为单位,所以0.75表示75厘米,2表示两米。相邻的蓝色点都是检测到的物体,而靠近(0,0)的点是激光位置,并且必须舍弃。 y < 0 下方的蓝色点是由于激光扫描区域为270°而产生的。我添加了红线方框(1.5 x 2米)以确定我想要实现碰撞检查的区域。 因此,我希望实时检测是否有点(物体)在该区域内,如果是,则调用一些函数。这有点棘手,因为这个检查还应该能够检测到连续的点,以确定物体是否真实存在(即如果它检测到一个点,那么它应该搜索最近的点来确定它们是否组成一个物体,或者它仅是一个可能是检测误差的点)。

这是我用于执行单次扫描的函数:

struct point pt[limit*URG_POINTS];
//..
 for(i = 0; i < limit; i++){
 for(j = 0; j < URG_POINTS; j++){
  ang2 = kDeg2Rad*((j*240/(double)URG_POINTS)-120);
  offset = 0.03;     //it depends on sensor module [m]

  dis = (double) dist[cnt] / 1000.0;
  //THRESHOLD of RANGE
  //      if(dis > MAX_RANGE) dis = 0;  //MAX RANGE = 4[m]
  //      if(dis < MIN_RANGE) dis = 0;
  pt[cnt].x = dis * cos(ang2) * cos(ang1) + (offset*sin(ang1)); // <-- X POINTS
  pt[cnt].y = dis * sin(ang2); // <-- Y POINTS
 // pt[cnt].z = dis * cos(ang2) * sin(ang1) - (offset*cos(ang1)); <- I disabled 3D mapping at the moment
  cnt++;
}
ang1 += diff;
}

每次扫描后,pt包含所有在x-y坐标中检测到的点。

我想做这样的事情:

  • 执行一次扫描,然后在结束时,
  • 对每个pt.x和pt.y应用碰撞检查
  • 如果您在内部区域中找到一个点,则检查其他附近的点,如果是,则停止机器人;
  • 如果没有或者没有找到其他附近的点,请开始另一次扫描。

我想知道如何轻松检查前面定义的区域内的对象(由多个单个点组成)。

可以帮帮我吗?对我来说看起来很困难:(

1个回答

3
我不认为我能给出一个完整的答案,但是可以提供一些思路。您说的实时是什么意思?任何给定算法运行需要多长时间?您的程序运行在什么处理器上?
通过检查 abs(x) < 0.75y< 2 && y > 0 是否成立,过滤掉在检测范围内的点应该非常容易。此外,您应该只考虑远离0的点,这样x^2 + y^2 > d
但这应该是微不足道的部分。
更有趣的是检测点的组。 DBSCAN 已被证明是用于检测二维点组的相当好的聚类算法。关键问题是DBSCAN是否足够快以用于实时应用程序。如果不是,您可能需要考虑优化算法(您可以使用一些聪明的索引结构将其复杂度压缩到n * log(n))。
此外,值得考虑的是如何将你从上一次迭代中获得的知识融入到当前问题中(假设数据点高频率,数据点不应该发生太大变化)。
值得看看其他机器人项目 - 我可以想象解释传感器数据以构建周围环境信息的问题是一个相当普遍的问题。
更新
在不知道你在应用DBSCAN算法时遇到了哪些问题的情况下,很难给你提供好的建议。但让我尝试给你一个逐步指南,说明算法可能如何工作:
- 对于每个接收到的数据点,检查它是否位于你想要观察的区域内。(我给出的条件应该有效)。 - 如果数据点位于该区域内,则将其保存到某种列表中。 - 读取所有数据点后,请检查列表是否为空。如果是,则一切正常。否则,我们必须检查是否有更大的数据点组需要绕过。
现在是更困难的部分。您需要对这些点使用DBSCAN并尝试找到点的组。我不知道哪些参数适用于该算法 - 这需要尝试。之后,您应该有一些点的聚类。我不确定您将如何处理这些组 - 一个想法是检测每个组中具有极坐标最小和最大度数的点。通过这种方式,您可以决定必须转动您的车辆多远。如果两个群组非常接近,以至于无法在它们之间导航,则必须特别小心。
有关DBSCAN的实现,您可以在这里或询问谷歌以获取帮助。这是一个非常常见的算法,已经编码了成千上万次。为了进一步优化速度,创建自己的实现可能会有所帮助。但是,如果您发现其中一个实现似乎可用,请先尝试使用该实现,然后再开始自己的实现。
如果您在实施算法时遇到具体问题,我建议您提出新问题,因为它与此问题相距甚远,并且您可能会得到更多愿意帮助您的人。

我希望现在事情更清楚了。如果还有疑问,请指出具体的疑点。


我正在使用主频为1.66GHz和4GB DDR2内存的Intel® Atom™处理器D410。每次扫描不到1.5秒,我希望以尽可能快的方式在每次扫描后检查碰撞。 不幸的是,我没有找到类似项目的任何信息 :( - Marcus Barnet
我犯了一个错误,我的意思是每次扫描之间有80毫秒的暂停,每次扫描需要少于150毫秒。 - Marcus Barnet
我建议尝试使用DBScan算法。首先对数据进行过滤,这样可以留下相对较少的需要分组的数据。在几毫秒内完成分组应该是可能的。但这只是猜测,你需要亲自尝试一下。 - Thilo
我已经了解了DBScan算法,但是在我的程序中如何使用这个算法还有点难理解。 :( - Marcus Barnet
非常感谢你,Thilo!现在我明白多了!我将在接下来的几个小时内实现这个算法! - Marcus Barnet
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接