如何使寻路算法适应受限运动?


10

想象一下类似汽车的运动,其中实体无法打开一角钱。为了便于讨论,请说在高速行驶时它们可以每秒旋转90度。在许多情况下,这将更改最佳路径,并因此更改寻路。它甚至可能使“常规”路径完全无法遍历。

是否有任何寻路算法或运动计划算法可以牢记这一点,或者是否有简单的方法来适应流行的算法?


寻路还将包括速度数据吗?例如,以X km / h(或mph)从A转到B,还是恒定速度?同样,低速下每秒90度可能会变成非常封闭的转弯,甚至在物理上也是不可能的。(除非所有4个车轮都旋转xD)
Brian H.

@BrianH。这就是为什么我说“全速”。在合理的情况下,将设置最小和最大阈值。但理想情况下,我希望算法寻找“理想”路径,其中可能包括速度变化。
Weckar E.

我发现这是一个非常有趣的问题,我给我+1,迫不及待想看到一些简洁的答案:)
Brian H.


我认为这是某种看不见的墙。而且,大多数路径资助算法对每条路径都有一个“权重”(例如,在水中行走比在陆地上行走慢),因此您可以为难以获得的路径增加额外的权重。这只能通过汽车的速度和方向才能知道。
the_lotus

Answers:


10

欢迎来到非完整运动计划的美好世界。我建议使用点阵网格路径规划器进行此操作。其他替代方案包括运动动力学RRT轨迹优化。非完整系统包括汽车,轮船,单轮脚踏车,或什至是车辆无法沿任何方向行驶的任何事物。计划这些系统比完整系统要困难得多,直到2000年才成为学术研究的边缘。如今,有很多算法可供选择,以使其工作得体。

在此处输入图片说明

运作方式如下。

你的车的配置q实际上是包含汽车的x,y位置的3D状态它的方向牛逼。A *算法中的节点实际上是3D向量。

class Node
{
    // The position and orientation of the car.
    float x, y, theta;
}

动作

那么边缘呢?

这有点困难,因为您的汽车实际上可以选择无数种方法来转动方向盘。因此,我们可以通过将汽车可以执行的动作数量限制为离散集合A,从而使点阵网格规划器可以访问此函数。为了简单起见,让我们假设汽车没有加速,而是可以瞬间改变其速度。在我们的情况下,A可以如下:

class Action
{
    // The direction of the steering wheel.
    float wheelDirection;

    // The speed to go at in m/s.
    float speed;

    // The time that it takes to complete an action in seconds.
    float dt;
}

现在,我们可以创建汽车可以随时执行的一系列离散操作。例如,在完全按下加油口0.5秒钟的同时,硬硬的右键将如下所示:

Action turnRight;
turnRight.speed = 1;
turnRight.wheelDirection = 1;
turnRight.dt = 0.5;

将汽车倒退并备份将如下所示:

Action reverse;
reverse.speed = -1;
reverse.wheelDirection = 0;
reverse.dt = 0.5;

您的操作列表如下所示:

List<Action> actions = { turnRight, turnLeft, goStraight, reverse ...}

您还需要一种方法来定义在节点上执行的操作如何导致新节点。这称为系统的前向动力学

// These forward dynamics are for a dubin's car that can change its
// course instantaneously.
Node forwardIntegrate(Node start, Action action) 
{
    // the speed of the car in theta, x and y.
    float thetaDot = action.wheelDirection * TURNING_RADIUS;

    // the discrete timestep in seconds that we integrate at.
    float timestep = 0.001;

    float x = start.x;
    float y = start.y;
    float theta = start.theta;

    // Discrete Euler integration over the length of the action.
    for (float t = 0; t < action.dt; t += timestep)
    {
       theta += timestep * thetaDot;
       float xDot = action.speed * cos(theta);
       float yDot = action.speed * sin(theta);
       x += timestep * xDot;
       y += timestep * yDot;
    }

    return Node(x, y, theta);
}

离散网格单元

现在,要构造晶格网格,我们要做的就是将汽车的状态散列到离散的网格单元中。这会将它们变成离散的节点,后跟A *。这是非常重要的,因为否则A *将无法知道两个汽车状态是否实际上是相同的以便进行比较。通过散列为整数网格单元格值,这变得微不足道。

GridCell hashNode(Node node)
{
    GridCell cell;
    cell.x = round(node.x / X_RESOLUTION);
    cell.y = round(node.y / Y_RESOLUTION);
    cell.theta = round(node.theta / THETA_RESOLUTION);
    return cell; 
}

现在,我们可以执行一个A *计划,其中GridCells是节点,Actions是节点之间的边缘,并且开始和目标均以GridCells表示。两个GridCell之间的启发式方法是x和y中的距离加上theta中的角距离。

遵循路径

现在我们已经有了关于GridCells和Actions的路径,我们可以为汽车编写路径跟随器了。由于网格单元是离散的,因此汽车会在单元之间跳跃。因此,我们将不得不平滑汽车沿路径的运动。如果您的游戏使用的是物理引擎,则可以通过编写一个转向控制器来尝试使汽车尽可能地靠近路径来实现。否则,您可以使用贝塞尔曲线或仅通过平均路径中最近的几个点来为路径设置动画。


优秀的职位(甚至短!我为船做类似的事情-滑:-)。Otoh,还有更多空间,
暴风城

4

大多数路径查找算法可在任意图形上工作,而不受几何图形的限制。

因此,您需要做的是将汽车的方向添加到每个探索的节点,并限制实际连接的节点。


问题在于,汽车可能会访问从不同方向接近的同一节点,这对可从那里经过的连接施加了不同的限制。
Weckar E.

6
@WeckarE。但是汽车不会访问相同的节点。它访问两个碰巧具有相同位置但方向不同的
棘手怪胎

3
@WeckarE。将它们视为两个单独的节点。物理图和逻辑图不必完全相同。
BlueRaja-Danny Pflughoeft

1

我的想法,还没有检验!

  1. 从开始到目标运行A *,返回路径。
  2. 在路径上循环,当您检测到转弯时,请使用贝塞尔曲线算法(或类似的算法),该算法使用搜寻器的当前速度来预测将创建平滑转弯的节点。确保它尝试返回最近的路径节点。
  3. 如果可以转弯,则以较大的速度转弯(如果不能转弯),否则转弯会更锐利。
  4. 一旦创建了正确的路径,在进行转弯之前,请先通过调整搜寻器速度的路径返回,以便在启动转弯之前将其减速至正确的速度。
  5. 如果根本无法转弯,请重新运行整个过程。只要确保所有无法处理的转弯已处理节点都在封闭列表中,即可将其忽略。您可以从转弯处开始,这样就可以跳过路径的成功部分,但是,在某些情况下,这可能会导致路径不理想。

您还应该能够执行此操作而不必先完成路径,所以:ergo:在A *期间处理转弯,可能会更好地进行优化,但是也可能会出现问题和故障,我真的不知道,但不幸的是,我没有时间自己测试。

寻找路径


0

如果您的经纪人完全控制了汽车,请反过来进行。从头到尾先连接一条线,然后找出每转弯可以以什么速度导航,类似于丹尼斯的答案。

但是不要从固定点绘制贝塞尔曲线。为了使速度损失最小化,您需要移动整条线,因此,首先以大约或多或少均匀的距离插入额外的节点,然后再移动以实现能量最小化或类似策略。有关详细信息,您需要研究赛车游戏(最好是SIM卡或半SIM卡)中的AI系列。

运行AI线系统后,运行A *搜索,对于每条路径至少向前走一个角,然后计算AI线,即可估算时间。这就是您的成本函数。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.