当前位置: 首页 > news >正文

自动驾驶控制算法——Stanley 控制器

自动驾驶控制算法——Stanley 控制器

文章目录

  • 自动驾驶控制算法——Stanley 控制器
  • 一、Stanley 控制器是什么?
    • 1.1 定义与核心思想
    • 1.2 Stanley 控制器与传统横向控制(如 Pure Pursuit、PID)的区别
    • 1.3 自动驾驶中 Stanley 控制器的典型应用场景
  • 二、Stanley 控制器的原理(参考图文详解)
  • 三、Stanley 控制器的实现步骤
    • 3.1 控制流程结构
    • 3.2 每一时刻的完整工作步骤
    • 3.3 伪代码示例
    • 3.4 关键实现细节与注意事项
  • 四、参数设计与调优
    • 4.1 增益系数 kkk 的作用
    • 4.2 参数选择原则
    • 4.3 速度自适应优化
    • 4.4 附加优化策略
      • 4.4.1 转向角限制
      • 4.4.2 滤波抖动抑制
      • 4.4.3 与纵向控制协同
    • 4.5 调试建议
  • 五、Stanley 控制器与其他横向控制方法对比
    • 5.1 与纯跟踪法(Pure Pursuit)的对比
    • 5.2 与 PID 横向控制的对比
    • 5.3 与 MPC 横向控制的对比
    • 5.4 总结对比表
  • 六、典型应用与扩展
    • 6.1 无人车直道与弯道跟踪案例
    • 6.2 车道保持(Lane Keeping)
    • 6.3 低速自动驾驶平台
    • 6.4 改进型 Stanley 控制器
      • 6.4.1 加速度补偿项
      • 6.4.2 动态增益调节
      • 6.4.3 与 MPC 融合
    • 6.5 总结
  • 七、python可视化代码

一、Stanley 控制器是什么?


1.1 定义与核心思想

Stanley 控制器是一种用于车辆横向控制(Lateral Control)的路径跟踪算法,由斯坦福大学在 2005 年 DARPA Grand Challenge 自动驾驶比赛中提出并成功应用,其搭载的“Stanley”无人车获得冠军,因此该方法得名。

其核心思想是通过同时修正航向误差与横向误差,使车辆前轮中心点尽量贴合参考路径。控制律利用车辆速度自适应地调整横向修正力度,高速时抑制过度转向,低速时提高响应速度,从而在不同速度下保持稳定的路径跟踪性能。

Stanley 控制器的控制律为:

δ=eθ+arctan⁡(k⋅eyv)\delta = e_\theta + \arctan\left( \frac{k \cdot e_y}{v} \right)δ=eθ+arctan(vkey)

其中:

  • δ\deltaδ:转向角(Steering Angle)
  • eθe_\thetaeθ:航向误差(Heading Error)
  • eye_yey:横向误差(Cross-Track Error)
  • kkk:增益系数(Stanley Gain)
  • vvv:车辆速度(Vehicle Speed)

直观理解

  • 第一项 eθe_\thetaeθ 负责对准路径方向
  • 第二项 arctan⁡(keyv)\arctan\left( \frac{k e_y}{v} \right)arctan(vkey) 负责回到路径中心,且随车速变化自动调整修正幅度。

1.2 Stanley 控制器与传统横向控制(如 Pure Pursuit、PID)的区别

对比维度Stanley 控制器纯跟踪法(Pure Pursuit)PID 横向控制
误差类型同时考虑航向误差与横向误差主要基于几何圆弧拟合,考虑位置误差直接用偏差计算控制量
速度适应性自带速度自适应机制(低速修正大,高速修正小)无速度自适应,需额外调节无速度自适应,需额外调节
实现复杂度简单(仅需计算两个误差)简单简单,但需调三个参数
高速稳定性较好(速度项抑制过度转向)高速易抖动高速时可能超调大
低速响应性响应快响应快取决于 PID 参数

1.3 自动驾驶中 Stanley 控制器的典型应用场景

  1. 轨迹跟踪(Trajectory Tracking)
    在自动驾驶路径跟踪中,Stanley 控制器常用于将车辆的实际轨迹与规划轨迹进行对齐,确保车辆沿规划路线平稳行驶。
  2. 车道保持(Lane Keeping)
    在高速公路或城市道路上,Stanley 控制器可保持车辆在车道中心行驶,即使车道有轻微弯曲,也能通过连续修正航向和横向误差保持稳定。
  3. 低速自动驾驶平台
    适用于自动送货车、巡逻车、园区摆渡车等低中速场景,算法简单、计算量低,方便嵌入式系统实时运行。
  4. 仿真验证与教学
    许多自动驾驶仿真平台(如 Carla、MATLAB Automated Driving Toolbox)内置 Stanley 控制器作为横向控制基线算法,便于研究人员和工程师进行算法比较与验证。

二、Stanley 控制器的原理(参考图文详解)


2.1 车辆运动学模型与误差定义

Stanley 控制器的推导一般基于 单轨(自行车)运动学模型(Kinematic Bicycle Model),该模型将四轮车辆简化为前后两个虚拟轮轴,忽略悬挂与车身侧倾等高阶动力学影响,适合低中速横向控制分析。

2.1.1 单轨(自行车)模型

{x˙=vcos⁡θy˙=vsin⁡θθ˙=vLtan⁡δ\begin{cases} \dot{x} = v \cos\theta \\ \dot{y} = v \sin\theta \\ \dot{\theta} = \frac{v}{L} \tan\delta \end{cases}x˙=vcosθy˙=vsinθθ˙=Lvtanδ

其中:

  • x,yx, yx,y:车辆质心坐标
  • θ\thetaθ:车辆航向角
  • vvv:车速
  • LLL:轴距(Wheelbase)
  • δ\deltaδ​:前轮转向角

在这里插入图片描述


2.1.2 横向误差 eye_yey 与航向误差 eθe_\thetaeθ 定义

  • 横向误差 eye_yey
    前轮中心到参考路径最近点的垂直距离(Cross-Track Error)。
  • 航向误差 eθe_\thetaeθ
    车辆当前航向与参考路径切线方向的夹角(Heading Error)。

几何直观

  • ey>0e_y > 0ey>0:车辆在路径左侧;
  • ey<0e_y < 0ey<0:车辆在路径右侧;
  • eθ>0e_\theta > 0eθ>0:车辆朝向左偏离路径方向;
  • eθ<0e_\theta < 0eθ<0:车辆朝向右偏离路径方向。

2.2 控制律推导

Stanley 控制器的核心控制律为:

δ=eθ+arctan⁡(k⋅eyv)\delta = e_\theta + \arctan\left( \frac{k \cdot e_y}{v} \right)δ=eθ+arctan(vkey)

2.2.1 控制律分解

  1. 航向修正项 eθe_\thetaeθ
    直接使车头朝向路径切线方向。
  2. 横向位置修正项 arctan⁡(k⋅eyv)\arctan\left( \frac{k \cdot e_y}{v} \right)arctan(vkey)
    通过横向误差产生额外转向量,使车辆回到路径中心;速度 vvv 位于分母,意味着高速时修正幅度会减小,避免过度转向。

2.2.2 增益系数 kkk 的作用

  • kkk 越大 → 横向误差修正力度越强,响应快但可能振荡;
  • kkk 越小 → 横向修正平缓,稳定性好但回归慢;
  • 通常 kkk 通过实验调优或经验公式选取(如考虑车辆轴距、最大转角等)。

2.3 控制特性分析

2.3.1 高速稳定性

由于修正项中有 1v\frac{1}{v}v1,高速时横向修正量减小,可防止频繁大角度转向,提高高速稳定性。

2.3.2 低速响应性

低速时 keyv\frac{k e_y}{v}vkey 数值大,横向修正迅速,可以在狭窄道路或转弯时快速对齐路径。

2.3.3 误差收敛过程

在闭环控制中,eye_yeyeθe_\thetaeθ 会随时间逐渐减小,车辆轨迹会逐渐与参考路径重合。

三、Stanley 控制器的实现步骤


3.1 控制流程结构

Stanley 控制器的核心执行流程是实时获取车辆与路径的相对状态计算误差代入控制律求解转向角发送执行命令,形成一个连续的闭环控制系统。

该过程在自动驾驶系统中通常位于横向控制模块,上层由轨迹规划模块提供参考路径,下层由执行器控制模块将转向命令发送给转向系统。


3.2 每一时刻的完整工作步骤

在离散时间 tkt_ktk(第 kkk 个控制周期)执行以下步骤:

Step 1:获取车辆状态与路径信息

  • 车辆位置(x,y)(x, y)(x,y)
  • 航向角 θ\thetaθ
  • 车速vvv
  • 路径曲线及其切线方向 ψ(s)\psi(s)ψ(s)

Step 2:计算横向误差 eye_yey

  • 找到车辆前轮中心到参考路径的最近点 KaTeX parse error: Undefined control sequence: \* at position 3: P^\̲*̲

  • 计算前轮中心与 KaTeX parse error: Undefined control sequence: \* at position 3: P^\̲*̲ 的有符号垂直距离

  • 符号规则:

    ey>0⇒车辆在路径左侧,ey<0⇒车辆在路径右侧e_y > 0 \ \Rightarrow \ \text{车辆在路径左侧} \quad , \quad e_y < 0 \ \Rightarrow \ \text{车辆在路径右侧}ey>0  车辆在路径左侧,ey<0  车辆在路径右侧

Step 3:计算航向误差 eθe_\thetaeθ

KaTeX parse error: Undefined control sequence: \* at position 40: …theta - \psi(s^\̲*̲))

其中 wrap 表示将角度归一化到区间 [−π,π][−π,π][π,π]

Step 4:代入控制律求解转向角 δ\deltaδ

δk=eθ+arctan⁡(k⋅eyv+ϵ)\delta_k = e_\theta + \arctan\left( \frac{k \cdot e_y}{v + \epsilon} \right)δk=eθ+arctan(v+ϵkey)

  • ϵ\epsilonϵ为防止低速时除零的极小常数(例如 0.1 m/s)
  • kkk 为横向增益系数

Step 5:发送转向命令至底层执行器

  • 输出 δk\delta_kδk 到车辆转向控制系统
  • 若与纵向控制配合,则还需同时输出期望速度或加速度

3.3 伪代码示例

# Stanley 控制器执行流程
def stanley_control(x, y, theta, v, path_points, k, epsilon=0.1):# Step 1: 找到最近路径点idx, nearest_point = find_closest_point(x, y, path_points)# Step 2: 横向误差 e_ye_y = compute_signed_lateral_error(x, y, nearest_point, path_points)# Step 3: 航向误差 e_thetapath_heading = path_points[idx].headinge_theta = wrap_angle(theta - path_heading)# Step 4: 控制律计算delta = e_theta + math.atan2(k * e_y, v + epsilon)# Step 5: 输出转向角return delta

3.4 关键实现细节与注意事项

  1. 低速抖动问题
    • 低速时 keyv\frac{k e_y}{v}vkey 项会非常大,容易导致转向过大,应在分母加上 ϵ\epsilonϵ 或限制最大转向角。
  2. 路径平滑与采样
    • 路径需平滑处理,否则计算出的最近点和切线方向会在离散点之间突变,导致控制不稳定。
  3. 与纵向控制的协同
    • 高速行驶时横向修正幅度会自动减小,但仍需配合速度规划,避免在急弯高速进入。

四、参数设计与调优


4.1 增益系数 kkk 的作用

Stanley 控制器只有一个核心调节参数——横向增益系数 kkk。它直接影响横向误差修正项的幅度,从而影响车辆回到路径中心的速度与稳定性。

控制律回顾:

δ=eθ+arctan⁡(k⋅eyv+ϵ)\delta = e_\theta + \arctan\left( \frac{k \cdot e_y}{v + \epsilon} \right)δ=eθ+arctan(v+ϵkey)

  • kkk:横向修正力度强,响应速度快,但可能导致振荡甚至超调;
  • kkk:修正力度弱,稳定性好,但收敛速度慢,可能在急弯处偏离路径过大。

4.2 参数选择原则

在实际车辆或仿真中,可根据以下经验步骤调节 kkk

  1. 初始值设置
    • 一般从 k=0.5∼1.0k = 0.5\sim1.0k=0.51.0 开始(单位:m/s)。
  2. 低速测试
    • 在低速(3–5 m/s)测试急弯路径,确保车辆能够平稳回到路径中心。
  3. 高速测试
    • 在高速(≥15 m/s)下测试长直道和缓弯,确保转向平滑,不发生高速抖动。
  4. 微调与平衡
    • 如果低速响应慢 → 增大 kkk
    • 如果高速易振荡 → 减小kkk

4.3 速度自适应优化

虽然 Stanley 控制律中 1v\frac{1}{v}v1 已经实现了速度自适应,但在极端低速时,横向修正项会非常大,容易导致急剧转向。
可在分母加上一个极小常数 ϵ\epsilonϵ:

δ=eθ+arctan⁡(k⋅eyv+ϵ)\delta = e_\theta + \arctan\left( \frac{k \cdot e_y}{v + \epsilon} \right)δ=eθ+arctan(v+ϵkey)

其中 ϵ\epsilonϵ 通常取 0.1–0.5 m/s,用于抑制低速过度转向。


4.4 附加优化策略

4.4.1 转向角限制

在机械转向极限和舒适性范围内限制δ\deltaδ

δcmd=clip(δ,δmin⁡,δmax⁡)\delta_{\text{cmd}} = \text{clip}(\delta, \delta_{\min}, \delta_{\max})δcmd=clip(δ,δmin,δmax)

4.4.2 滤波抖动抑制

  • 对横向误差 eye_yey 和航向误差 eθe_\thetaeθ 使用低通滤波器,减少传感器噪声带来的控制抖动:

e^y(k)=αey(k)+(1−α)e^y(k−1)\hat{e}_y(k) = \alpha e_y(k) + (1 - \alpha) \hat{e}_y(k-1)e^y(k)=αey(k)+(1α)e^y(k1)

其中 α∈[0.1,0.3]\alpha \in [0.1, 0.3]α[0.1,0.3]

4.4.3 与纵向控制协同

  • 在高速急弯时,纵向控制应主动减速,避免因转向限制导致路径跟踪误差过大。

4.5 调试建议

  1. 仿真优先:在 Carla、MATLAB 等平台先调整出合适的 kkk 区间,减少实车调试风险。
  2. 分速段调参:根据低速/中速/高速场景,建立分段kkk 值或速度映射表。
  3. 数据记录:记录 ey,eθ,δe_y, e_\theta, \deltaey,eθ,δ 等时序数据,便于分析振荡和延迟来源。
  4. 渐进试验:从低速直道 → 低速弯道 → 高速直道 → 高速弯道,逐步增加测试难度。

五、Stanley 控制器与其他横向控制方法对比


5.1 与纯跟踪法(Pure Pursuit)的对比

原理差异

  • Pure Pursuit:基于几何圆弧模型,将车辆转向设定为使车辆驶向路径上某个“前视点”(look-ahead point),转向角由车辆到前视点的圆弧半径计算。
  • Stanley 控制器:直接利用横向误差 eye_yey 与航向误差 eθe_\thetaeθ 构建转向控制律,并在公式中引入速度自适应项 1v\frac{1}{v}v1

性能差异

  • Pure Pursuit 依赖前视距离 LdL_dLd 选取,前视距离过短易振荡,过长则响应慢;
  • Stanley 控制器自适应速度变化,低速响应快,高速稳定性好;
  • Pure Pursuit 在曲率变化剧烈的路径上易产生超调,而 Stanley 控制器在此类场景下更稳。

5.2 与 PID 横向控制的对比

原理差异

  • PID 横向控制:直接将横向误差作为输入,通过比例、积分、微分三项计算转向角。
  • Stanley 控制器:结合横向误差与航向误差两种信息,并在横向修正项中加入速度因子。

性能差异

  • PID 参数多(Kp, Ki, Kd),调试复杂;
  • Stanley 控制器参数少(仅一个增益 kkk),调参简单;
  • PID 对高速场景敏感,容易振荡;Stanley 控制器高速抑制性更好;
  • PID 可在低速精准对齐路径,但在曲率变化剧烈的弯道表现不如 Stanley 控制器稳定。

5.3 与 MPC 横向控制的对比

原理差异

  • MPC:基于车辆模型和预测时域,优化未来一段时间内的控制量,使得目标函数(误差、控制量变化等)最小化。
  • Stanley 控制器:基于几何与误差反馈的单步控制律,不进行未来状态预测。

性能差异

  • MPC 可同时考虑路径跟踪与控制约束(如最大转角、加速度限制),在复杂场景更优;
  • Stanley 控制器计算量小,实时性强,适合嵌入式平台和低速应用;
  • MPC 对模型精度依赖大,建模不准可能引入偏差,而 Stanley 控制器依赖较少;
  • MPC 调参涉及权重矩阵 Q、R,较复杂;Stanley 控制器仅需调整 kkk

5.4 总结对比表

方法核心思想参数数量优点缺点典型应用
Stanley 控制器航向 + 横向误差反馈 + 速度自适应1(k)稳定性好,调参简单,实时性强高速急弯性能有限自动驾驶低/中速横向控制
Pure Pursuit圆弧几何追踪前视点1(前视距离)原理简单,易实现对前视距离敏感,高速不稳移动机器人、低速路径跟踪
PID 横向控制横向误差比例/积分/微分控制3(Kp, Ki, Kd)控制平滑,可精准对齐调参复杂,高速易振荡工业控制、低速 AGV
MPC 横向控制基于模型的预测优化控制多(Q, R, 时域长度等)能处理约束,性能最优计算量大,调参复杂高速公路自动驾驶、赛车

六、典型应用与扩展


6.1 无人车直道与弯道跟踪案例

场景描述

  • 路径包含直道与中等曲率弯道;
  • 车速在 5m/s5\text{ m/s}5 m/s(弯道)到 15m/s15\text{ m/s}15 m/s(直道)之间变化;
  • 车辆配备厘米级 GPS 与 IMU,参考路径由规划模块提供。

表现特点

  • 直道段:由于航向误差 eθe_\thetaeθ 较小,转向主要由横向误差修正项控制,车辆快速贴近路径中心,转向平滑。
  • 弯道段:横向误差与航向误差同时发挥作用,使车辆顺畅进入曲线段;高速进入急弯时需依赖纵向减速配合。

实际效果

  • 在中低速下,Stanley 控制器能在 1–2 秒内将横向误差收敛至 ±0.05 m;
  • 高速急弯中,如果纵向速度控制不足,可能出现轻微外飘现象。

6.2 车道保持(Lane Keeping)

应用背景
在高速公路或城市道路中,Stanley 控制器可直接用于基于车道线的车道保持系统(LKS)。

原理

  • 横向误差由车辆与车道中心线的垂距计算;
  • 航向误差由车辆航向与车道切线方向的夹角计算;
  • 控制律实时输出转向角,实现车辆始终保持在车道中间。

优点

  • 不依赖全局路径,只需局部车道线信息;
  • 对轻微曲率的高速路段稳定性好。

6.3 低速自动驾驶平台

典型场景

  • 园区摆渡车、物流车、巡检车等低速(< 8 m/s)自动驾驶车辆;
  • 通常路径规划为低曲率曲线,环境中包含较多转角与避障操作。

优势

  • 计算量小,嵌入式控制器(如 STM32、ROS 节点)可轻松实时运行;
  • 在低速场景中响应灵敏,几乎无需复杂模型预测;
  • 调参简单,仅需设置合理的 kkk 值。

6.4 改进型 Stanley 控制器

针对标准 Stanley 控制器的不足,可进行以下扩展:

6.4.1 加速度补偿项

在高速急弯中加入横向加速度补偿:

δ=eθ+arctan⁡(keyv+ϵ)+λ⋅ay\delta = e_\theta + \arctan\left( \frac{k e_y}{v + \epsilon} \right) + \lambda \cdot a_yδ=eθ+arctan(v+ϵkey)+λay

其中 aya_yay 为横向加速度,λ\lambdaλ 为补偿系数。

6.4.2 动态增益调节

根据速度或曲率动态调整 kkk:

k(v)=kmin⁡+(kmax⁡−kmin⁡)e−βvk(v) = k_{\min} + (k_{\max} - k_{\min}) e^{-\beta v}k(v)=kmin+(kmaxkmin)eβv

低速取较大 kkk,高速取较小 kkk

6.4.3 与 MPC 融合

在普通路段用 Stanley 控制器保证实时性,在复杂场景(急弯、避障)切换至 MPC 控制器,提高轨迹跟踪精度与稳定性。


6.5 总结

Stanley 控制器因其原理简单、实时性强、调参容易,在自动驾驶横向控制中得到广泛应用,尤其在低速至中速场景表现出色。
通过合理调节增益系数 kkk,并结合纵向速度控制,可以在绝大多数常规驾驶场景中实现稳定且平滑的路径跟踪。
针对高速急弯和噪声敏感问题,可以采用加速度补偿、动态增益调节或与 MPC 混合控制的方式进行优化。

在这里插入图片描述

图 1:Stanley Path Tracking: Trajectory vs Reference (Fixed)
该图展示了修正后的 Stanley 控制器在参考路径上的跟踪效果。

  • 蓝色曲线表示规划好的参考路径(Reference Path),包含一个中等幅度的 S 弯段和直道段。
  • 橙色曲线为车辆实际行驶轨迹(Vehicle Trajectory),起点与参考路径存在一定的横向与航向偏差。
  • 起点用“Path Start”和“Vehicle Start”标记,直观对比初始偏移。
  • 图中每隔一定距离绘制车辆姿态箭头,表明车辆的实时航向变化。
  • 从运行结果可见,车辆轨迹在短时间内快速贴合参考路径,进入稳态后几乎与参考路径完全重合,表明控制器能够有效消除初始横向与航向误差,并实现平滑跟踪。

在这里插入图片描述

图 2:Errors and Steering Over Time
该图给出了同一实验中横向误差、航向误差与转向角随时间的变化过程。

  • Lateral Error eye_yey(蓝线):初始时有明显的正值,表示车辆位于参考路径左侧;在约 3 秒内迅速收敛到接近零,并在后续保持稳定,说明横向偏移已被消除。
  • Heading Error eθe_\thetaeθ(橙线):初始偏航角约为 0.17 rad(约 10° 左偏),控制器快速调整使其接近零,且无明显振荡。
  • Steering Angle δ\deltaδ(绿色线):初始转向角较大,用于快速回到路径;随后转角减小并趋于稳定,表明车辆已进入稳态巡航。
    整体来看,控制过程平稳、误差收敛迅速,转角变化无剧烈抖动,验证了 Stanley 控制器在该路径上的有效性与鲁棒性。

七、python可视化代码

# -*- coding: utf-8 -*-
"""
Stanley 路径跟踪可视化(修正版)
- 误差在“前轴中心”计算
- e_theta = wrap(psi - yaw)
- 横向误差符号统一(e_y = -signed_lateral_error(...))
- 转角饱和,常速行驶
"""import math
import numpy as np
import matplotlib.pyplot as plt# ---------------- 工具函数 ----------------
def wrap(a: float) -> float:"""将角度归一化到 [-pi, pi]"""return (a + np.pi) % (2 * np.pi) - np.pidef nearest_point_index(px, py, path_xy):d2 = (path_xy[:, 0] - px) ** 2 + (path_xy[:, 1] - py) ** 2return int(np.argmin(d2))def signed_lateral_error(px, py, path_xy, path_yaw, idx):"""计算带符号的横向误差(以路径左法向为正)n = (-sin(psi), cos(psi))"""p = path_xy[idx]psi = path_yaw[idx]nx, ny = -math.sin(psi), math.cos(psi)  # 左法向ex, ey = px - p[0], py - p[1]return ex * nx + ey * ny# ---------------- 参考路径 ----------------
def make_reference_path():"""S 弯 + 缓弯 + 直道的平滑路径"""t1 = np.linspace(0, 40, 400)x1 = t1y1 = 1.5 * np.sin(0.2 * t1)t2 = np.linspace(0, 30, 300)x2 = 40 + t2y2 = 1.5 * np.sin(0.2 * 40) + 0.03 * (t2 ** 2)t3 = np.linspace(0, 40, 400)x3 = 70 + t3y3 = y2[-1] + 0.0 * t3x = np.concatenate([x1, x2, x3])y = np.concatenate([y1, y2, y3])dx = np.gradient(x)dy = np.gradient(y)yaw = np.arctan2(dy, dx)return np.stack([x, y], axis=1), yaw# ---------------- Stanley 控制律 ----------------
def stanley_delta(front_x, front_y, yaw, v, path_xy, path_yaw, k=1.5, eps=0.2):"""输入:前轴中心(front_x, front_y)、当前航向 yaw、速度 v输出:转向角 delta 及误差"""idx = nearest_point_index(front_x, front_y, path_xy)e_signed = signed_lateral_error(front_x, front_y, path_xy, path_yaw, idx)# 统一符号:让 e_y>0 时朝向回路径中心的转向为正e_y = -e_signed# 航向误差:期望(路径切线) - 实际e_theta = wrap(path_yaw[idx] - yaw)# 控制律delta = e_theta + math.atan2(k * e_y, v + eps)return delta, idx, e_y, e_theta# ---------------- 主程序 ----------------
if __name__ == "__main__":# 路径path_xy, path_yaw = make_reference_path()# 仿真参数dt = 0.02T = 28.0N = int(T / dt)L = 2.8                  # 轴距Lf = 1.4                 # 质心到前轴距离(近似)max_steer = np.deg2rad(35)v = 10.0                 # 常速# 初始状态:略偏离路径x = path_xy[0, 0] - 2.0y = path_xy[0, 1] + 1.5yaw = path_yaw[0] + np.deg2rad(10)xs, ys, yaws, deltas = [], [], [], []eys, eths = [], []for _ in range(N):# 前轴中心fx = x + Lf * math.cos(yaw)fy = y + Lf * math.sin(yaw)# Stanley 控制delta, idx, e_y, e_th = stanley_delta(fx, fy, yaw, v, path_xy, path_yaw,k=1.5, eps=0.2)# 转角饱和delta = float(np.clip(delta, -max_steer, max_steer))# 自行车模型更新(质心点)x += v * math.cos(yaw) * dty += v * math.sin(yaw) * dtyaw += (v / L) * math.tan(delta) * dtyaw = wrap(yaw)xs.append(x); ys.append(y); yaws.append(yaw); deltas.append(delta)eys.append(e_y); eths.append(e_th)# -------- 图1:轨迹对比 --------plt.figure(figsize=(11, 5))plt.plot(path_xy[:, 0], path_xy[:, 1], label="Reference Path", linewidth=2)plt.plot(xs, ys, label="Vehicle Trajectory", linewidth=2)plt.scatter(path_xy[0, 0], path_xy[0, 1], s=40, label="Path Start")plt.scatter(xs[0], ys[0], s=40, marker="x", label="Vehicle Start")# 朝向箭头for i in range(0, len(xs), 60):plt.arrow(xs[i], ys[i], 0.8 * np.cos(yaws[i]), 0.8 * np.sin(yaws[i]),head_width=0.2, length_includes_head=True)plt.axis("equal"); plt.grid(True)plt.xlabel("x [m]"); plt.ylabel("y [m]")plt.title("Stanley Path Tracking: Trajectory vs Reference (Fixed)")plt.legend(loc="best")plt.tight_layout()# plt.savefig("stanley_tracking.png", dpi=200)# -------- 图2:误差与转角 --------t = np.arange(len(eys)) * dtplt.figure(figsize=(11, 4.6))plt.plot(t, eys, label="Lateral Error e_y [m]")plt.plot(t, eths, label="Heading Error e_theta [rad]")plt.plot(t, deltas, label="Steering Angle delta [rad]")plt.grid(True); plt.xlabel("time [s]"); plt.ylabel("value")plt.legend(loc="best")plt.title("Errors and Steering Over Time")plt.tight_layout()# plt.savefig("stanley_errors.png", dpi=200)plt.show()
http://www.dtcms.com/a/324398.html

相关文章:

  • 构建健壮的商品数据采集服务:处理京东 API 限流与错误
  • python洛谷做题27:P5724 【深基4.习5】求极差 / 最大跨度值 / 最大值和最小值的差
  • mcp-go v0.37.0 版本发布:重大变更与新特性解析
  • 利用容器编排完成haproxy和nginx负载均衡架构实施
  • GitLab 零基础入门指南:从安装到项目管理全流程
  • Elasticsearch QueryDSL 教程
  • 应对高并发 - TCP/IP网络栈核心参数调优
  • 【递归、搜索与回溯算法】递归算法
  • 【代码随想录day 16】 力扣 513.找树左下角的值
  • 米哈游笔试——求强势顶点的个数
  • [python] typing 中的overload
  • Android视图回调机制:从post到ViewTreeObserver,从源码分析到最佳实践
  • MariaDB 数据库管理
  • 基于PyTorch一文讲清楚损失函数与激活函数并配上详细的图文讲解
  • Pytorch深度学习框架实战教程12:Pytorch混合精度推理,性能加速147%的技术实现
  • MPLS对LSP连通性的检测
  • 使用Blender可视化多传感器坐标系转换
  • 移动端常见的8大css兼容性问题和处理方法
  • #Linux内存管理# 浅析缺页中断中私有映射且发生写时复制COW的工作原理
  • 《Qt————Tcp通讯》
  • 容器网络隔离测试于VPS服务器环境的桥接模式验证
  • Docker 详细介绍及使用方法
  • 【大智慧数据】心智开花的时候
  • 数字图像处理3
  • 三、k8s 1.29 之 安装1网络 / ikuai路由器虚拟机安装
  • 【嵌入式】Linux的常用操作命令(2)
  • 防御保护10
  • AI优化SEO关键词实战应用
  • Java数据结构——LinkedList
  • scanpy单细胞转录组python教程(一):不同形式数据读取