程序代码篇---Pytorch实现LATM+APF轨迹预测

发布于:2025-05-22 ⋅ 阅读:(17) ⋅ 点赞:(0)


前言

针对对轨迹预测高精度的要求以及路径规划、动态避障决策优化的需求,我们需要研究一种利用 LSTM 强大的时序特征捕获能力,充分利用车辆历史运动数据中的历史时序信息,精准预测未来运动轨迹,为无人驾驶系统提供可靠的决策依据。同时结合 APF 基于环境实时生成无碰撞路径的优势,APF在考虑目标引力与障碍物斥力的基础上,根据道路障碍物等实时道路状态灵活调整权重,实现高效路径规划与动态避障。最后通过 LSTM 与 APF 的深度融合,更能整合历史道路状态与当下环境信息,将时序预测与物理约束相结合,降低无人驾驶汽车碰撞风险,生成平滑、安全且符合实际道路情况的行驶轨迹,提升无人驾驶系统在雨雾天气、交通拥堵、行人横穿等复杂场景下的决策能力与适应性。


LSTM(长短期记忆网络)与APF(人工势场法):

针对项目中无人驾驶轨迹预测、路径规划、动态避障、决策优化的需求。
我们通过摄像头实时采集道路交通参与者(行人、障碍物等)的信息,通过LSTM(长短期记忆网络)与APF(人工势场法)算法进行未来轨迹预测,实时避开突然出现的障碍物,应对交通参与者的不规则运动,更好的结合历史数据和环境感知,生成契合当前道路情况的驾驶决策。

LSTM(长短期记忆网络)

首先考虑到LSTM能捕获车辆历史运动的时序特征(位置和时间),预测未来的轨迹。作为一种特殊的循环神经网络(RNN),通过输入门、遗忘门和输出门的门控机制,可以很好的捕获时间序列中的长期依赖信息,可以为之后实时的无人驾驶汽车运动轨迹提供准确的预测。

1. 门控机制

遗忘门:决定历史信息的遗忘程度ft=σ(Wf⋅[ht-1,xt]+bf)
输入门:控制当前输入的信息存储it=σ(Wi⋅[ht-1,xt]+bi)C~t=tanh(WC⋅[ht-1,xt]+bC)
输出门:确定最终输出的信息ot=σ(Wo⋅[ht-1,xt]+bo)ht=ot⋅tanh(Ct)
其中:
σ 为 Sigmoid 激活函数;tanh 为双曲正切激活函数;
\(W_f,W_i,W_C,W_(o\) )为各门将的权重矩阵,\(b_f,b_i,b_C,b_(o\) )为偏置项;
\(h_({t-1}\) )为上一时刻隐藏状态,\(x_(t\)) 为当前时刻输入(如车辆位置坐标 \((x,y)\)、速度 v 等)。

2. 细胞状态更新

(C_t= f_t⋅C_{t-1} + i_t⋅{C}(t))) 通过遗忘门 (f(t) )保留历史有效信息,结合输入门 (i_(t)) 与候选状态 (~{C}(t) )更新细胞状态 (C(t)),最终输出隐藏状态 (h_(t) )用于轨迹预测。

3. 轨迹预测输出

将 LSTM 的隐藏状态映射到未来轨迹坐标(以二维平面为例):(hat{x}{t+k} ,hat{y}{t+k} = {Linear}(h_t )) 其中 ({Linear}) 为线性层,输出未来 k 时刻的位置预测值 ((hat{x}{t+k} ,hat{y}{t+k} ))。

APF(人工势场)

然后就APF基于能根据当前环境生成无碰撞路径的优势。利用目标点产生引力,吸引物体靠近;障碍物产生斥力,排斥物体远离的原理。通过计算无人驾驶汽车所受的合力,确定无人驾驶汽车的运动方向和速度,规划出一条既能避让障碍物又能到达目的地的路径。在LSTM路径预测下,APF跟关注当下道路情况,根据当前位置、目标位置、障碍物位置以及自身速度、加速度等属性动态调整权重。

合力计算:

Ftotal=Fatt+Frep
引力场(目标点pgoalpgoal):
Fatt=katt⋅∥p-pgoal∥2⋅n^goal
katt: 引力增益系数
n^goal: 指向目标点的单位向量

斥力场(障碍物pobs):

Frep={krep(d/1-d0/1)d2/1⋅n^obs0 if d≤d0
0 0 if d>d0
d=∥p-pobs∥: 与障碍物距离
d0: 斥力影响阈值
n^obs: 远离障碍物的单位向量

动态权重调整(融合LSTM预测):

katt,krep=f(ht,v,a)
权重系数由LSTM隐藏状态ht和当前速度v、加速度a动态调整。

3. 运动控制(物理约束)

加速度决策:

a=mFtotal(牛顿第二定律)
m: 车辆质量

速度更新(非holonomic约束):

vt+1=vt+a⋅Δtθt+1=θt+ω⋅Δt
ω: 角速度(由合力方向决定)
Δt: 时间步长

最后通过LSTM和APF结合,利用LSTM更好的关注历史道路状态,并结合APF当下道路状态分析,融合时序预测和物理约束,大幅度降低碰撞风险,生成更平滑的行驶轨迹,更好地应对复杂的道路场景(如雨雾天气、交通拥堵、行人横穿等)

4. 多模态融合(LSTM + APF)

轨迹平滑优化:

pt+1=α⋅p^t+1+(1-α)⋅(pt+vtΔt+21aΔt2)
α: 融合系数(权衡预测与物理约束)

Pytorch实现

1. 环境设置与PyTorch模型定义

import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt

# 环境参数(与之前相同)
GRID_SIZE = 20  
START = (1, 1)
GOAL = (18, 18)
OBSTACLES = [(5, 5), (10, 10), (15, 15)]

# APF参数
K_ATT = 0.5
K_REP = 1.0
D0 = 3.0

# LSTM参数
TIME_STEPS = 5
HIDDEN_DIM = 16

2. PyTorch LSTM模型定义

class LSTMPredictor(nn.Module):
    def __init__(self):
        super().__init__()
        self.lstm = nn.LSTM(input_size=2, hidden_size=HIDDEN_DIM, batch_first=True)
        self.linear = nn.Linear(HIDDEN_DIM, 2)  # 输出(x,y)偏移量
        
    def forward(self, x):
        # x形状: (batch_size, time_steps, 2)
        out, (h_n, c_n) = self.lstm(x)
        return self.linear(out[:, -1, :])  # 只取最后一个时间步的输出

# 生成模拟数据(转换为PyTorch张量)
def generate_data():
    path = np.array([(i, i) for i in range(1, 19)], dtype=np.float32)
    X, y = [], []
    for i in range(len(path) - TIME_STEPS):
        X.append(path[i:i+TIME_STEPS])
        y.append(path[i+TIME_STEPS])
    return torch.FloatTensor(np.array(X)), torch.FloatTensor(np.array(y))

# 训练函数
def train_model():
    model = LSTMPredictor()
    criterion = nn.MSELoss()
    optimizer = torch.optim.Adam(model.parameters())
    
    X_train, y_train = generate_data()
    for epoch in range(50):
        optimizer.zero_grad()
        outputs = model(X_train)
        loss = criterion(outputs, y_train)
        loss.backward()
        optimizer.step()
    return model

lstm_model = train_model()

3. APF实现(与之前相同,但转换为PyTorch张量运算)

def attraction_force(position, goal):
    direction = goal - position
    distance = torch.norm(direction)
    return K_ATT * direction / (distance + 1e-6)  # 避免除以零

def repulsion_force(position, obstacles):
    force = torch.zeros(2)
    for obs in obstacles:
        obs_pos = torch.FloatTensor(obs)
        direction = position - obs_pos
        distance = torch.norm(direction)
        if distance <= D0:
            force += K_REP * (1/(distance+1e-6) - 1/D0) * (1/(distance**2+1e-6)) * (direction / (distance+1e-6))
    return force

def total_force(position, goal, obstacles):
    return attraction_force(position, goal) + repulsion_force(position, obstacles)

4. 路径规划主逻辑(PyTorch版本)

def plan_path():
    position = torch.FloatTensor(START)
    goal = torch.FloatTensor(GOAL)
    path = [position.clone().numpy()]
    history = [position.clone()] * TIME_STEPS
    
    for step in range(100):
        # LSTM预测
        if len(history) >= TIME_STEPS:
            lstm_input = torch.stack(history[-TIME_STEPS:]).unsqueeze(0)  # 形状(1, T, 2)
            with torch.no_grad():
                pred = lstm_model(lstm_input)[0]  # 预测下一步
        
        # APF计算
        force = total_force(position, goal, OBSTACLES)
        
        # 融合策略
        alpha = 0.3
        new_position = position + alpha * (pred - position) + (1 - alpha) * force
        
        # 更新状态
        position = new_position
        path.append(position.clone().numpy())
        history.append(position.clone())
        
        # 终止条件
        if torch.norm(position - goal) < 1.0:
            break
    
    return np.array(path)

5. 可视化(与之前相同)

def plot_path(path):
    plt.figure(figsize=(8, 8))
    plt.scatter(*START, c='green', marker='o', label='Start')
    plt.scatter(*GOAL, c='red', marker='*', label='Goal')
    plt.scatter(*zip(*OBSTACLES), c='black', marker='s', label='Obstacles')
    plt.plot(path[:, 0], path[:, 1], 'b-', label='Path')
    plt.legend()
    plt.grid()
    plt.xlim(0, GRID_SIZE)
    plt.ylim(0, GRID_SIZE)
    plt.title("PyTorch LSTM + APF Path Planning")
    plt.show()

path = plan_path()
plot_path(path)

PyTorch实现关键变化说明

部分 TensorFlow/Keras实现 PyTorch实现
模型定义 使用Sequential API 继承nn.Module自定义类
数据格式 NumPy数组直接输入 显式转换为torch.FloatTensor
训练循环 使用Keras内置fit() 手动实现梯度清零、反向传播和参数更新
预测阶段 直接调用model.predict() 使用with torch.no_grad()上下文管理器
张量操作 使用NumPy的np.linalg.norm 使用torch.norm

PyTorch特有优化点

GPU加速

GPU加速:通过model.to(‘cuda’)和tensor.cuda()利用GPU加速

自定义损失

自定义损失:可灵活修改LSTM的损失函数(如加入APF力的正则项)

动态计算图

动态计算图:适合更复杂的融合策略(如基于注意力机制的权重调整)

# 示例:GPU加速版本
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
lstm_model = lstm_model.to(device)
position = position.to(device)
goal = goal.to(device)

扩展建议

数据加载

数据加载:使用torch.utils.data.Dataset实现更高效的数据管道

模型保存

模型保存:通过torch.save(lstm_model.state_dict(), ‘model.pth’)保存训练好的模型

实时部署

实时部署:使用torch.jit.script导出为脚本模型优化推理速度

这个实现保留了原始算法的核心思想,同时充分利用了PyTorch的灵活性和动态计算优势。