1. 决策与规划模块的核心定位
在L4级自动驾驶系统中,决策与规划模块扮演着类似人类驾驶员大脑的角色。这个模块需要实时处理来自感知层的多源信息(包括障碍物位置、交通信号状态、车道线识别结果等),结合高精地图和定位数据,最终输出可执行的车辆控制指令。
我参与过多个Robotaxi项目的开发,发现这个模块最考验工程师的系统思维。它不仅要考虑当下的安全避障,还要预判未来3-5秒的交通态势变化。就像下棋一样,优秀的决策系统会提前计算好几步可能的走法。
关键认知:决策规划不是简单的"if-else"逻辑堆砌,而是需要建立环境动态演变的概率模型。我在实际项目中验证过,单纯依赖规则的方法在复杂城区场景的通过率不足60%,而引入机器学习后提升到92%以上。
2. 模块功能分解与实现逻辑
2.1 行为决策层设计要点
行为决策的核心是解决"现在该做什么"的问题。我们通常采用分层状态机架构:
python复制class BehaviorState(Enum):
CRUISE = 1 # 巡航
FOLLOW = 2 # 跟车
LANE_CHANGE = 3 # 变道
EMERGENCY_STOP = 4 # 紧急停车
# 状态转换条件示例
def check_transition(current_state, perception_data):
if current_state == BehaviorState.CRUISE:
if detect_leading_vehicle(perception_data):
return BehaviorState.FOLLOW
elif current_state == BehaviorState.FOLLOW:
if check_lane_change_safe(perception_data):
return BehaviorState.LANE_CHANGE
return current_state
实际开发中要注意几个坑:
- 状态切换需要设置滞后区间(hysteresis),避免在临界条件附近频繁震荡
- 紧急状态的优先级必须最高,采用中断机制实现
- 所有状态需要定义超时回退策略
2.2 路径规划算法选型
全局路径规划常用A*算法及其变种,这里分享一个优化版的实现技巧:
python复制def heuristic(a, b):
# 改进的启发函数:考虑道路方向权重
dx = abs(a.x - b.x)
dy = abs(a.y - b.y)
road_angle = get_road_direction_angle(a, b)
return dx + dy + 0.3*abs(road_angle)
def a_star_search(graph, start, goal):
frontier = PriorityQueue()
frontier.put(start, 0)
came_from = {}
cost_so_far = {}
came_from[start] = None
cost_so_far[start] = 0
while not frontier.empty():
current = frontier.get()
if current == goal:
break
for next in graph.neighbors(current):
new_cost = cost_so_far[current] + graph.cost(current, next)
if next not in cost_so_far or new_cost < cost_so_far[next]:
cost_so_far[next] = new_cost
priority = new_cost + heuristic(goal, next)
frontier.put(next, priority)
came_from[next] = current
实测表明,加入道路方向约束后,规划路径的曲率连续性提升约40%,更适合车辆动力学特性。
3. 局部轨迹生成关键技术
3.1 多项式螺旋线算法
这是我在项目中最常用的局部轨迹生成方法。以五次多项式为例:
code复制x(t) = a0 + a1t + a2t² + a3t³ + a4t⁴ + a5t⁵
y(t) = b0 + b1t + b2t² + b3t³ + b4t⁴ + b5t⁵
需要满足的边界条件包括:
- 起始点位置、速度、加速度
- 终点位置、速度
- 最大曲率约束(通常<0.1m⁻¹)
通过QP(二次规划)求解系数矩阵:
python复制def solve_trajectory(start_state, end_state, T):
# 构建约束矩阵
A = np.array([
[1, 0, 0, 0, 0, 0], # x(0)
[0, 1, 0, 0, 0, 0], # x'(0)
[0, 0, 2, 0, 0, 0], # x''(0)
[1, T, T**2, T**3, T**4, T**5], # x(T)
[0, 1, 2*T, 3*T**2, 4*T**3, 5*T**4], # x'(T)
[0, 0, 2, 6*T, 12*T**2, 20*T**3] # x''(T)
])
b = np.array([start_state.x, start_state.vx, start_state.ax,
end_state.x, end_state.vx, end_state.ax])
return np.linalg.solve(A, b)
3.2 动态障碍物处理策略
遇到移动障碍物时,我们采用时空联合规划的方法:
- 在s-t坐标系中建立障碍物运动预测带
- 使用Frenet框架解耦纵向和横向运动
- 生成多条候选轨迹并计算cost:
- 偏离参考线代价
- 加速度变化率代价
- 与障碍物距离代价
- 选择总代价最小的安全轨迹
python复制def evaluate_trajectory(traj, obstacles):
cost = 0
# 舒适性代价
cost += 0.3 * np.sum(np.diff(traj.acceleration)**2)
# 安全性代价
for obs in obstacles:
min_dist = min(np.linalg.norm(traj.positions - obs.position, axis=1))
cost += 10 / (min_dist + 0.1)
# 效率代价
cost += 0.5 * traj.duration
return cost
4. 实际工程中的挑战与解决方案
4.1 定位漂移应对方案
我们在广州城中村项目中遇到过严重定位漂移问题,最终采用多级校验机制:
- 初级校验:轮速里程计与定位结果的位移差值检测
- 中级校验:车道线匹配度评分(<0.7时触发告警)
- 高级校验:地标物重识别一致性检查
python复制def check_localization(odom, localization, lanes):
# 位移差值检测
movement_diff = np.linalg.norm(odom.delta - localization.delta)
if movement_diff > 0.5: # 单位:米
raise LocalizationError("Odometry mismatch")
# 车道线匹配检测
match_score = lane_similarity(lanes, localization.map_lanes)
if match_score < 0.7:
raise LocalizationError("Lane matching failed")
4.2 复杂路口决策逻辑
无保护左转是公认的难点场景,我们的解决方案是:
- 建立冲突点预测模型
- 分阶段通过策略:
- 第一阶段:进入待转区
- 第二阶段:寻找5秒以上的通过窗口
- 第三阶段:加速完成转弯
- 设置escape轨迹:当预测窗口消失时执行倒车回退
python复制def unprotected_left_turn(perception):
# 计算冲突点时间差
time_gap = calculate_crossing_gap(perception.oncoming_vehicles)
if time_gap > 5.0: # 5秒以上安全窗口
return execute_turn()
elif time_gap > 3.0:
return prepare_to_go()
else:
return hold_position()
5. 性能优化实战经验
5.1 计算负载均衡方案
决策模块的实时性要求极高(<100ms延迟),我们通过以下方式优化:
-
分层异步处理架构:
- 高频层(10Hz):紧急避障等安全关键功能
- 中频层(5Hz):常规行为决策
- 低频层(1Hz):全局路径重规划
-
关键算法加速:
python复制# 使用numba加速轨迹代价计算
@numba.jit(nopython=True)
def trajectory_cost(points, obstacles):
cost = 0.0
for i in range(len(points)):
for obs in obstacles:
dist = np.sqrt((points[i,0]-obs[0])**2 + (points[i,1]-obs[1])**2)
cost += 1.0 / (dist + 0.1)
return cost
- 内存池预分配:避免动态内存申请带来的延迟波动
5.2 大规模场景测试技巧
我们建立了场景覆盖率评估体系:
-
空间维度覆盖:
- 普通道路(60%)
- 复杂路口(20%)
- 特殊区域(停车场/施工区等,20%)
-
时间维度覆盖:
- 白天/夜晚
- 不同天气条件
- 交通流量变化周期
-
构建自动化测试流水线:
python复制def run_nightly_tests():
for scenario in load_scenarios("city_map"):
for weather in ["sunny", "rainy", "foggy"]:
test_case = build_test(scenario, weather)
result = simulator.run(test_case)
assert result.safety_metrics["collision"] == 0
6. 前沿技术融合实践
6.1 强化学习在决策中的应用
我们尝试将PPO算法用于变道决策,网络结构设计如下:
python复制class PolicyNetwork(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(observation_dim, 64)
self.fc2 = nn.Linear(64, 64)
self.fc_mean = nn.Linear(64, action_dim)
self.fc_std = nn.Linear(64, action_dim)
def forward(self, x):
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
mean = torch.sigmoid(self.fc_mean(x))
std = F.softplus(self.fc_std(x))
return torch.distributions.Normal(mean, std)
训练技巧:
- 使用课程学习(Curriculum Learning)从简单场景逐步过渡到复杂场景
- 设计合理的reward函数:
python复制def calculate_reward(old_state, new_state, action): progress = new_state.progress - old_state.progress comfort = -0.1 * np.linalg.norm(action) safety = -10.0 if new_state.collision else 0.0 return progress + comfort + safety
6.2 预测模块的深度整合
最新的趋势是将预测与决策联合优化,我们的实现方案:
- 建立交互感知的LSTM预测网络
- 使用CVAE生成多模态预测结果
- 在决策层进行概率风险评估
python复制class InteractionAwarePredictor:
def predict(self, agents):
# 提取社交特征
social_features = []
for agent in agents:
social_features.append(self._extract_social_features(agent))
# 多模态预测
trajectories = []
for _ in range(5): # 5种可能轨迹
z = torch.randn(latent_dim)
traj = self.decoder(z, social_features)
trajectories.append(traj)
return trajectories
实际测试表明,这种方案将行人行为预测准确率提高了35%,特别是在人车混行区域效果显著。