文章目录
前言
本文简单介绍LSTM(长短期记忆网络)和ADF(人工势场法)这两种不同的轨迹预测方法。
LSTM 轨迹预测
原理
原理:LSTM 是一种特殊的循环神经网络(RNN)。它通过输入门、遗忘门和输出门的门控机制,能够学习长期依赖关系并有效解决传统 RNN 中的梯度消失问题。在轨迹预测中,它可以处理时间序列形式的轨迹数据,将过去的轨迹模式作为输入,通过学习这些模式来预测未来的轨迹点。
应用
在行人轨迹预测方面
如 Social LSTM 模型,通过为场景中的每个行人配备一个独立的 LSTM 网络预测其运动轨迹,同时通过社交池层相互连接来计算周围其他行人交互产生的影响。
在自动驾驶车辆的轨迹预测中
也有多种基于 LSTM 的方法,例如将轨迹预测问题转化为序列预测问题,利用 LSTM 网络获取预测车辆当前的位姿和关键交互信息;或采用注意力 Seq2Seq 网络,用 LSTM 编 - 解码器进行目标车辆的变道轨迹预测等。
优点
优点:能够有效捕捉时间序列中的长期依赖信息,对于具有复杂动态变化的轨迹数据有较好的学习和预测能力。可以处理不同长度的序列数据,具有较强的灵活性。通过大量数据训练后,能对各种场景下的轨迹进行较为准确的预测,泛化能力较强。
缺点
缺点:计算复杂度较高,训练和预测过程需要较大的计算资源和时间。对数据的要求较高,需要大量的高质量数据进行训练才能获得较好的预测效果。模型结构相对复杂,理解和调优较为困难,且难以对预测结果进行直观的解释。
APF 轨迹预测
原理
原理:APF 是一种虚拟力场方法,它将运动环境建模为势场。目标点产生引力,吸引物体靠近;障碍物产生斥力,排斥物体远离。通过计算物体所受的合力,确定其运动方向和速度,从而规划出一条既能避让障碍物又能到达目的地的路径。在轨迹预测中,可根据当前物体所受的引力和斥力情况,以及物体的当前状态,预测其未来可能的运动轨迹。
应用
在船舶运动规划
基于模型预测控制(MPC)的 APF 方法将 APF 融入 MPC 的优化目标函数中,利用 MPC 的预测能力和 APF 的实时性,规划出符合国际海上避碰规则(COLREGs)的最优路径。
在无人驾驶车辆避障轨迹跟踪
将 APF 与 MPC 相结合,通过调整 MPC 的优化目标函数,使车辆能根据 APF 计算出的虚拟排斥力,在面对障碍物时灵活调整轨迹。
优点
优点:具有较强的实时性,能够根据环境的变化实时更新势场,快速做出路径调整。不需要进行全局路径搜索,计算量相对较小,适合在资源有限的设备上运行。通过合理设计势场函数和调节参数,可以灵活处理复杂环境中的多障碍物情况,对环境的适应性较强。
缺点
缺点:传统的 APF 方法容易陷入局部极小值,导致规划失败,尤其是在复杂环境中。对障碍物的建模和参数设置较为敏感,不同的参数可能会导致不同的轨迹规划结果,需要进行大量的调试和优化。难以准确预测物体在复杂环境中的长期轨迹,因为它主要关注当前的局部环境信息,对全局信息的利用有限。
示例代码
apf_planner.py:
import numpy as np
class APFTrajectoryPlanner:
def __init__(self, k_att=1.0, k_rep=100.0, d0=0.5, max_iter=100, step_size=0.1, goal_threshold=0.1):
"""
初始化APF规划器参数
参数:
k_att: 引力系数
k_rep: 斥力系数
d0: 斥力作用范围
max_iter: 最大迭代次数
step_size: 步长
goal_threshold: 目标接近阈值
"""
self.k_att = k_att
self.k_rep = k_rep
self.d0 = d0
self.max_iter = max_iter
self.step_size = step_size
self.goal_threshold = goal_threshold
def plan(self, start, goal, obstacles):
"""
基于APF的轨迹规划
参数:
start: 起点坐标 [x, y]
goal: 目标点坐标 [x, y]
obstacles: 障碍物列表 [[x1, y1], [x2, y2], ...]
返回:
path: 规划路径 [[x0, y0], [x1, y1], ...]
"""
current_pos = np.array(start, dtype=np.float32)
path = [current_pos.copy()]
for i in range(self.max_iter):
# 计算引力
att_force = self._calculate_attraction(current_pos, goal)
# 计算斥力
rep_force = self._calculate_repulsion(current_pos, obstacles)
# 计算合力
total_force = att_force + rep_force
# 更新位置
current_pos += self.step_size * total_force / np.linalg.norm(total_force)
path.append(current_pos.copy())
# 检查是否到达目标
if np.linalg.norm(current_pos - goal) < self.goal_threshold:
break
return np.array(path)
def _calculate_attraction(self, pos, goal):
"""计算引力"""
return self.k_att * (goal - pos)
def _calculate_repulsion(self, pos, obstacles):
"""计算斥力"""