【Apollo Common代码解析-Box2d::HasOverlap(const Box2d &box)】

Box2d::HasOverlap(const Box2d &box)

最近看apollo的一些common函数,对于Box2d::HasOverlap函数仔细画了图研究了一下,根据前人的文章,用自己的习惯重新整理了一下。
矩形Box2d
是指世界坐标系下的一个矩形,其中IsPointIn、IsPointOnBoundary、DistanceTo(point)的计算都是先转成AABox2d的格式进行比较的(从绝对坐标系转到矩形坐标系),转个坐标系即可。
该函数主要是判断矩形是否与其他矩形相交
完整的函数代码如下:

bool Box2d::HasOverlap(const Box2d &box) const
      {
        if (box.max_x() < min_x() || box.min_x() > max_x() || box.max_y() < min_y() ||
            box.min_y() > max_y())
        {
          return false;
        }

        const double shift_x = box.center_x() - center_.x();
        const double shift_y = box.center_y() - center_.y();

        const double dx1 = cos_heading_ * half_length_;
        const double dy1 = sin_heading_ * half_length_;
        const double dx2 = sin_heading_ * half_width_;
        const double dy2 = -cos_heading_ * half_width_;
        const double dx3 = box.cos_heading() * box.half_length();
        const double dy3 = box.sin_heading() * box.half_length();
        const double dx4 = box.sin_heading() * box.half_width();
        const double dy4 = -box.cos_heading() * box.half_width();

        return std::abs(shift_x * cos_heading_ + shift_y * sin_heading_) <=
                   std::abs(dx3 * cos_heading_ + dy3 * sin_heading_) +
                       std::abs(dx4 * cos_heading_ + dy4 * sin_heading_) +
                       half_length_ &&
               std::abs(shift_x * sin_heading_ - shift_y * cos_heading_) <=
                   std::abs(dx3 * sin_heading_ - dy3 * cos_heading_) +
                       std::abs(dx4 * sin_heading_ - dy4 * cos_heading_) +
                       half_width_ &&
               std::abs(shift_x * box.cos_heading() + shift_y * box.sin_heading()) <=
                   std::abs(dx1 * box.cos_heading() + dy1 * box.sin_heading()) +
                       std::abs(dx2 * box.cos_heading() + dy2 * box.sin_heading()) +
                       box.half_length() &&
               std::abs(shift_x * box.sin_heading() - shift_y * box.cos_heading()) <=
                   std::abs(dx1 * box.sin_heading() - dy1 * box.cos_heading()) +
                       std::abs(dx2 * box.sin_heading() - dy2 * box.cos_heading()) +
                       box.half_width();
      }

判断相交主要是分成几个模块进行判断。下面这部分是粗检测。

if (box.max_x() < min_x() || box.min_x() > max_x() || box.max_y() < min_y() ||
    box.min_y() > max_y())
{
  return false;
}

AABB检测用于粗检测,根据自车和障碍物的box角点构建两个长宽分别平行于坐标轴的box,查看这两个box(两个虚线box表示)是否有交集,可以直接根据新构建的box的角点的坐标值来判断。如下图所示,通过这种方式可以粗略检测到A、B有碰撞,但是是否真的有碰撞还需要通过OBB进一步检测。
在这里插入图片描述
第二部分是分离轴定理进行检测。
首先是构造了几个向量:

        const double shift_x = box.center_x() - center_.x();
        const double shift_y = box.center_y() - center_.y();
        const double dx1 = cos_heading_ * half_length_;
        const double dy1 = sin_heading_ * half_length_;
        const double dx2 = sin_heading_ * half_width_;
        const double dy2 = -cos_heading_ * half_width_;
        const double dx3 = box.cos_heading() * box.half_length();
        const double dy3 = box.sin_heading() * box.half_length();
        const double dx4 = box.sin_heading() * box.half_width();
        const double dy4 = -box.cos_heading() * box.half_width();

其中:
shift_x,shift_f是向量 a b ⃗ \vec{ab} ab
dx1,dy1是向量 v 1 ⃗ \vec{v_1} v1
dx2,dy2是向量 v 2 ⃗ \vec{v_2} v2
dx3,dy3是向量 v 3 ⃗ \vec{v_3} v3
dx4,dxy4是向量 v 4 ⃗ \vec{v_4} v4
如下图所示。
在这里插入图片描述
接着看下面这行代码:

std::abs(shift_x * cos_heading_ + shift_y * sin_heading_) <=
                   std::abs(dx3 * cos_heading_ + dy3 * sin_heading_) +
                       std::abs(dx4 * cos_heading_ + dy4 * sin_heading_) +
                       half_length_

std::abs(shift_x * cos_heading_ + shift_y * sin_heading_)就是指向量 a b ⃗ \vec{ab} ab 在中轴线上的投影,其值为AB,我们以相离和相交的两种图展示,如下图所示。std::abs(dx3 * cos_heading_ + dy3 * sin_heading_)是向量 v 3 ⃗ \vec{v_3} v3 在中轴上的投影为b1,std::abs(dx4 * cos_heading_ + dy4 * sin_heading_)是指 v 4 ⃗ \vec{v_4} v4 的投影为b2,half_length_是指向量 v 1 ⃗ \vec{v_1} v1 在中轴线上的投影a,向量 v 2 ⃗ \vec{v_2} v2 在中轴线上的投影为零,可不计入。
在这里插入图片描述
在这里插入图片描述
如果AB<=a+b那么就会出现上面相交的情况,如果大于就是图1相离的情况。
同理下面的这段代码是指

 std::abs(shift_x * sin_heading_ - shift_y * cos_heading_) <=
                   std::abs(dx3 * sin_heading_ - dy3 * cos_heading_) +
                       std::abs(dx4 * sin_heading_ - dy4 * cos_heading_) +
                       half_width_ 

再向A矩形的横轴上进行投影
在这里插入图片描述

再往后就是计算往B纵轴上的投影,横轴上的投影,如果几面的投影都相交那么两个矩形就一定相交了。
主要参考的是这篇博客:
百度Apollo规划算法——OBB障碍物检测代码解析
主要用作个人学习、查询使用。
如有侵权,请联系删除。

  • 19
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
npm warn deprecated apollo-server-core@3.12.0: the `apollo-server-core` package has been deprecated. 这个警告意味着`apollo-server-core`包已被废弃。废弃意味着它将在将来的版本中不再被维护或更新。当我们在使用npm安装或更新项目依赖时,如果看到这个警告,就意味着有一些问题需要解决。 在本例中,警告涉及到`apollo-server-core` 版本3.12.0。这个包是Apollo的一个核心组件,用于构建GraphQL服务器。然而,该版本已被废弃,这意味着它存在一些问题或者有更好的替代选择。 废弃的软件包存在一些风险,因为它们不再得到维护或更新。这可能导致安全漏洞、缺陷或不兼容问题。所以,我们需要尽快寻找替代方案。 为了解决这个问题,我们可以查看`apollo-server-core`的文档或发布信息,以了解更多关于废弃的原因和可能的替代包的信息。通常,`apollo-server-core`的维护者会提供一些指导或建议,告诉我们如何迁移到更新的版本或其他相关的包。 我们可以使用命令`npm outdated`来检查是否有更近的版本可用,并尝试更新到最新的兼容版本。如果没有直接的替代包,我们可以考虑使用类似的库或搜索其他的GraphQL服务器解决方案。 总之,当我们看到npm的警告废弃某个软件包时,我们需要密切关注相关的文档和发布信息,寻找替代方案,并尽快做出调整以避免可能带来的问题或风险。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈喽汽车人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值