You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带加减速及中途目标变更的一维运动轨迹解析求解技术问询

一维运动控制器解析解方案

问题背景

给定一维运动控制器的初始条件与参数:

  • 初始状态:x=0,v=0
  • 运动参数:加速加速度a_acc=50,减速加速度a_dec=30,最大速度v_max=40
  • 运动规则:需从当前状态出发,先加速至v_max(若可行),必要时巡航,最终减速至目标位置时速度为0;支持中途实时变更目标位置。

此前采用每帧离散积分(delta≈33ms)更新速度与位置,存在误差累积、速度曲线错误、过冲/漂移等问题,需改用解析解实现精准轨迹控制。


核心算法实现

1. 轨迹类型判断

先计算无巡航阶段时,从当前状态加速后再减速到0的总距离,与目标相对距离对比,判断轨迹类型:

定义变量

  • 当前位置:x_curr,当前速度:v_curr
  • 目标位置:x_target,相对距离:D = x_target - x_curr(正负代表运动方向)
  • 取绝对值计算:abs_D = |D|,加速加速度取方向值:a_acc_dir = a_acc * sign(D),减速加速度取反向值:a_dec_dir = -a_dec * sign(D)(保证减速是阻碍当前运动方向的加速度)

无巡航时的最大可行速度计算

若全程仅加速后减速到0,可达到的最大速度v_switch满足:

v_{switch} = \sqrt{\frac{2 \cdot a_{acc} \cdot a_{dec} \cdot abs\_D + a_{dec} \cdot v_{curr}^2}{a_{acc} + a_{dec}}}

轨迹类型判定

  • 若 v_switch ≤ v_max:轨迹为加速→减速(无巡航阶段)
  • 若 v_switch > v_max:轨迹为加速→巡航→减速

2. 各阶段距离与时间计算

情况1:加速→减速(无巡航)

  • 加速时间:t_acc = (v_switch - v_curr) / a_acc_dir
  • 加速距离:s_acc = v_curr * t_acc + 0.5 * a_acc_dir * t_acc²
  • 减速时间:t_dec = v_switch / abs(a_dec_dir)
  • 减速距离:s_dec = 0.5 * abs(a_dec_dir) * t_dec²
  • 总运动时间:t_total = t_acc + t_dec

情况2:加速→巡航→减速

  • 加速到v_max的时间:t_acc = (v_max * sign(D) - v_curr) / a_acc_dir
  • 加速距离:s_acc = v_curr * t_acc + 0.5 * a_acc_dir * t_acc²
  • 从v_max减速到0的时间:t_dec = v_max / a_dec
  • 减速距离:s_dec = 0.5 * a_dec * t_dec²
  • 巡航距离:s_cruise = abs_D - s_acc - s_dec
  • 巡航时间:t_cruise = s_cruise / v_max
  • 总运动时间:t_total = t_acc + t_cruise + t_dec

3. 实时位置与速度计算

每帧根据轨迹启动后的累计时间t_elapsed,判断当前所处阶段,直接计算位置与速度:

# 伪代码示例
import math

def get_current_state(t_elapsed, x_curr, v_curr, x_target, a_acc, a_dec, v_max):
    D = x_target - x_curr
    sign_D = 1 if D > 0 else -1
    abs_D = abs(D)
    a_acc_dir = a_acc * sign_D
    a_dec_dir = -a_dec * sign_D

    # 计算无巡航时的切换速度
    numerator = 2 * a_acc * a_dec * abs_D + a_dec * v_curr**2
    v_switch = math.sqrt(numerator / (a_acc + a_dec))

    if v_switch <= v_max:
        # 加速→减速阶段
        t_acc = (v_switch - v_curr) / a_acc_dir
        s_acc = v_curr * t_acc + 0.5 * a_acc_dir * t_acc**2
        if t_elapsed < t_acc:
            # 加速中
            v = v_curr + a_acc_dir * t_elapsed
            x = x_curr + v_curr * t_elapsed + 0.5 * a_acc_dir * t_elapsed**2
        else:
            # 减速中
            t_in_dec = t_elapsed - t_acc
            v = v_switch + a_dec_dir * t_in_dec
            x = x_curr + s_acc + v_switch * t_in_dec + 0.5 * a_dec_dir * t_in_dec**2
    else:
        # 加速→巡航→减速阶段
        t_acc = (v_max * sign_D - v_curr) / a_acc_dir
        s_acc = v_curr * t_acc + 0.5 * a_acc_dir * t_acc**2
        t_dec = v_max / a_dec
        s_dec = 0.5 * a_dec * t_dec**2
        s_cruise = abs_D - s_acc - s_dec
        t_cruise = s_cruise / v_max
        t_cruise_end = t_acc + t_cruise

        if t_elapsed < t_acc:
            # 加速中
            v = v_curr + a_acc_dir * t_elapsed
            x = x_curr + v_curr * t_elapsed + 0.5 * a_acc_dir * t_elapsed**2
        elif t_elapsed < t_cruise_end:
            # 巡航中
            v = v_max * sign_D
            x = x_curr + s_acc + v_max * (t_elapsed - t_acc)
        else:
            # 减速中
            t_in_dec = t_elapsed - t_cruise_end
            v = v_max * sign_D + a_dec_dir * t_in_dec
            x = x_curr + s_acc + s_cruise + v_max * sign_D * t_in_dec + 0.5 * a_dec_dir * t_in_dec**2
    return x, v

4. 目标变更处理

当目标位置实时变更时,立即执行以下操作:

  1. 记录当前的x_curr、v_curr作为新的初始状态
  2. 重置轨迹累计时间t_elapsed为0
  3. 以新的目标位置x_new_target重新计算轨迹(重复上述轨迹判断、阶段计算流程)

标签

game-development physics-simulation kinematics motion-planning math

内容的提问来源于stack exchange,提问作者Spartak Aghababyan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 00:34:57