代码实践
📖 阅读信息
阅读时间:11 分钟 | 中文字符:4260
目标¶
首先明确一下整个的流程
- 强化学习最终的目的:
解释
- 在同一段道路上,驾驶员的操作(电门开度、方向盘转角等)完全固定不变的前提下,让训练出的智能体基于你提供的「激进 / 温和 / 谨慎」驾驶风格策略(至少控制电机扭矩),在不改变车速、车辆运行轨迹等核心驾驶体验的前提下,降低车辆能耗,最终达成节能效果。
- 让智能体成为「驾驶员操作的 “节能优化层”」—— 驾驶员的输入决定了 “驾驶意图”(比如要加速、要直行),智能体在不违背这个意图(车速 / 轨迹不变)的前提下,优化扭矩、动能回收等策略细节,减少无效能耗。结合你提供的策略表(以「温和 / 经济型」为核心优化方向)
代码实现¶
简单轨迹+电机扭矩控制¶
先针对某一驾驶员简单的直线加减速情况下,通过智能体学习,扭矩控制实现轨迹、速度的跟踪与节能
总之核心目标有两个——节能和速度跟踪
有着如下的四个大的部分
受控对象的仿真¶
对应代码类: StraightRoadScenario
这部分是在构建一个虚拟的新能源汽车以及它行驶的道路环境 。为了让 RL 智能体学到有用的策略,仿真必须符合基本的车辆纵向动力学。
- 纵向动力学模型: 在
step_vehicle方法中,代码计算了车辆的实时加速度。它考虑了电机输出扭矩转化来的驱动力,并扣除了线性空气阻力、二次空气阻力、坡度阻力以及弯道超速带来的额外阻力损耗。
\(a = c_{t} \cdot T - c_{v1} \cdot v - c_{v2} \cdot v^{2} - c_{g} \cdot \theta - c_{c} \cdot v_{over}\)
(其中 T 是扭矩,v 是车速,θ 是坡度) -
电机效率图 (Motor Map): 核心在
efficiency和_load_motor_map_csv方法。代码支持读取真实的电机 MAP 图(CSV格式),通过双线性插值 (_interp_bilinear) 来查表获取当前转速和扭矩下的电机效率。如果没有 CSV,它会用一个基于二维高斯分布的解析函数来模拟电机的高效区(中等转速和扭矩区域)。 -
电池能耗模型: 结合算出的机械功率和电机效率,计算电池的实际充放电功率 (
batt_power),进而实时更新 SOC(荷电状态)。它还特别对动能回收 (regen_eff) 做了效率打折。
控制器接口与目标设定¶
也就是整个强化学习训练的环境是什么(环境的状态空间,智能体会做出的动作空间,对智能体的奖励机制)
对应代码类: DriverReferenceEnergyEnv
这是控制算法的舞台。它将物理仿真封装成 RL 智能体可以交互的马尔可夫决策过程(MDP)。
-
状态空间 (State - 传感与预测数据): 在
_encode_state中,控制器不仅读取当前车速、SOC、扭矩,还会读取预测视界 (Preview Horizon) 内的道路坡度、限速,以及驾驶员未来的预期车速和扭矩 (ref_speed_p1,ref_torque_p1等)。这相当于车辆配备了地形预测(如 eHorizon)和驾驶员意图识别。 -
动作空间 (Action - 执行器干预): 智能体输出三个连续动作:
-
residual:扭矩修正值。智能体输出的不是绝对扭矩,而是叠加在驾驶员原始指令上的微调量(代码中有严格的限幅residual_limit,保证驾驶权始终在人类手中)。 -
regen_gain:动能回收增益。控制松油门或刹车时的能量回收强度。 -
coast_gain:滑行增益。决定是否切断动力进行滑行。
-
-
奖励函数 (Reward - 控制目标): 这是整个系统最复杂的地方(在
step方法后半段)。它包含了:-
跟踪惩罚 (Track Penalty): 速度和距离偏离驾驶员意图越远,扣分越狠。
-
能耗奖励 (Energy Term): 相比于纯人类驾驶基线,每节省一点能量就能获得奖励。
-
平顺性惩罚 (Smooth Penalty): 惩罚扭矩的剧烈波动,保证 NVH(振动噪声)和驾驶平顺性。
-
拉格朗日惩罚 (Lagrange Penalty): 对超越安全边界的行为施加硬约束惩罚。
-
智能决策大脑¶
对应代码类: ValueNet, PolicyNetContinuous, PPOContinuous
这是底层策略优化器。
-
Actor-Critic 架构:
ValueNet(Critic)负责评估当前车辆状态的好坏(预估未来还能拿多少分);PolicyNetContinuous(Actor)负责输出动作的高斯分布(均值 μ 和标准差 σ)。 -
安全探索: Actor 网络在输出时使用了
explore_decay,随着训练的进行,标准差会逐渐减小。这意味着控制器在初期会大胆尝试各种扭矩组合,后期则收敛到最优策略,减少随机动作。 -
PPO 更新逻辑: 在
update方法中,使用了 PPO 算法特有的裁剪机制(Clip)。这保证了控制器在更新策略时,新策略不会偏离老策略太远,防止因为一次糟糕的采样导致整个控制律崩溃。
说明
也就是神经网络和算法的方面的内容
标定与训练过程¶
对应代码片段: train_stage 函数及 if __name__ == "__main__": 的主流程。
让 AI 直接既兼顾安全又兼顾节能是不可能的,所以代码采用了课程学习(分阶段训练):
-
Track 阶段 (跟随阶段):
energy_weight=0.0。首先让控制器学会做个“老实人”,什么都不干,或者只做极小的微调,完全复刻人类驾驶员的速度和轨迹,确保绝对安全。 -
Energy 阶段 (节能阶段):
energy_weight从 0.9 逐渐增加到 2.35。在保证跟随误差不越界的前提下,逼迫控制器去“抠”能量。比如在下坡前提前一点点松油门,或者在电机低效区主动调整扭矩。 -
自适应修复 (Repair/Rescue): 代码里有大段的 Rescue 和 Repair 逻辑。如果在节能阶段,控制器为了省电导致车速跟不上(偏离太大),系统会自动调低
energy_weight,退回到上一个安全的检查点重新训练。这非常符合工业界安全第一的标定思路。
说明
就是整个训练的流程
第二个流程的解释(整个马尔科夫过程)¶
智能体的输入(环境给智能体的“状态观察”)¶
在每次智能体需要做决定前,环境会调用 _encode_state 方法,将当前汽车的所有内外部信息打包成一个 24维的浮点数向量(数组) 交给智能体。这相当于智能体的“眼睛”。
这个 24 维的输入被巧妙地归一化(取值尽量在 0 到 1 之间,方便神经网络学习),具体包含以下几大类信息:
-
车辆当前自身状态(3维):
-
当前车速 (
vehicle["speed"] / max_speed) -
当前电池剩余电量 SOC (
vehicle["soc"] / max_soc) -
当前电机实际输出扭矩 (
vehicle["torque"] / max_torque)
-
-
人类驾驶员指令及跟踪误差(4维):
-
人类驾驶员在这一步期望的车速和期望扭矩。
-
速度误差:当前实际车速减去人类期望车速(如果落后了是负数,超速了是正数)。
-
距离误差:实际行驶距离减去人类期望行驶距离(用来判断有没有掉队)。
-
-
道路环境“传感器”信息(3维):
-
当前的道路坡度(
slope_profile,上坡还是下坡)。 -
当前的弯道限速(
curve_speed_limit)。 -
当前的行驶进度(
step_idx / horizon,告诉智能体这条路走到百分之几了)。
-
-
“天眼”预览信息(8维):
-
智能体可以“看”到未来第 1 步、第 3 步、第 6 步的人类期望车速和期望扭矩。
-
还能看到未来第 1 步的速度和扭矩相较于当前的变化率(delta)。这相当于告诉智能体:“前面马上要减速了,你可以提前准备”。(实现了预测的功能)
-
-
自身动作历史与上下文(6维):
-
上一步的扭矩修正值、上一步的动能回收增益、上一步的滑行增益(让智能体知道自己刚才干了什么,保持动作连贯)。
-
人类驾驶风格的 One-hot 编码(代表 Eco节能、Normal普通、Sport运动中的一种)。
-
环境接收到的输入(智能体的“动作”)¶
当智能体看完上述 24 维状态后,它的神经网络(PolicyNetContinuous)会输出一个 3 维的连续动作向量 给环境的 step(action) 方法。
这三个维度并不是直接去踩油门或刹车,而是对人类驾驶员指令的“微调系数”:
-
action[0]-> 扭矩修正值 (Residual Torque)-
智能体会输出一个调整量。如果人类想输出 50 Nm 的扭矩,智能体可能会输出 −5 Nm(也就是劝系统只输出 45 Nm 稍微省点电)。
-
安全机制: 环境会对其进行极其严格的限幅(
_compute_action_limits)。如果当前速度误差很小,允许的修正范围就大一点;如果车子已经快跟不上人类的意图了,环境会直接把智能体的修正权限收窄,甚至强制其修正值为正(帮着加速追赶)。
-
-
action[1]-> 动能回收增益 (Regen Gain)- 控制范围在 −1.0 到 1.0 之间,映射后决定动能回收的强度。如果系统判断人类在减速,智能体可以调高这个值,尽可能多地把动能转化为电能存入电池。
-
action[2]-> 滑行增益 (Coast Gain)- 控制是否允许车辆切断电机输出进入“滑行(Coasting)”状态。在下坡或准备减速的空旷地带,切断扭矩让车子自己滑行是非常省电的高级技巧。
解释
现在只有这三个方面的调整
必须在驾驶员操纵的范围内进行调整
环境的变化(物理引擎的步进)¶
环境接收到这 3 个动作后,在 step 方法中会经历一个复杂且严谨的融合过程,然后推进物理状态:
第一步:指令融合与底层保护
-
环境首先拿出人类驾驶员的原始扭矩期望(
ref_torque)。 -
叠加上智能体刚才给出的扭矩修正值(
residual)。 -
底层兜底规则(Heuristics): 这是为了应对极端情况加的安全锁。如果车子严重掉队,环境会自己生成一个
drift_corr_torque(防掉队补偿) 和bias_corr_torque(误差积分补偿) 强行加到扭矩里。如果检测到前方急减速,还会加入preview_corr_torque。 -
合并以上所有项,得到最终要发给电机的指令
torque_cmd(并做物理极限截断,不能超过电机的最大扭矩)。
第二步:调用物理仿真更新状态
-
环境带着
torque_cmd(最终扭矩)、regen_gain(动能回收倍率)和当前的step_count(时间步),去调用底层的物理模型:self.scenario.step_vehicle(...)。 -
状态突变发生在这里: 在
step_vehicle里,物理引擎根据牛顿第二定律,算出身上的阻力、电机的驱动力,更新出下一时刻的新车速、新行驶距离,并根据电机效率 Map 计算耗电量,更新电池剩余电量(SOC)。 -
时间推进:
self.step_count += 1。
第三步:计算“成绩单”(Reward 计算)
-
环境拿到更新后的新状态,开始跟人类原本应有的状态做对比。
-
计算跟踪惩罚(如果新车速和新距离偏离人类意图太多,扣大分)。
-
计算节能奖励(如果耗电量比纯人类驾驶时少,且没有掉队,加分)。
-
计算平顺度惩罚(如果智能体上一步和这一步给的修正值跳跃太大,扣分,因为这会让乘客晕车)。
第四步:返回下一轮循环
-
根据新的
self.step_count,环境再次调用_encode_state(idx),把变化后的新车速、新 SOC、新的误差等信息重新打包成 24 维向量。 -
把 [新状态, 这步的奖励分数Reward, 是否结束当前回合Done, 附加信息Info] 返回给智能体。
自然语言描述学习的过程¶
这是一个非常好的问题。把生硬的代码转化为直观的过程,能帮助我们更好地理解AI的“思维模式”。
首先,我想轻轻纠正一个强化学习中常见的直觉误区:在这个基于 PPO 算法的系统中,智能体并不是在开车的同时“实时”修改自己大脑里的规则的。相反,它的学习过程更像是一个“先闭卷考试,考完再集中复盘”的过程。
在强化学习的术语里,跑完一次完整的路程叫做一个回合(Episode)。让我们用通俗的语言,模拟一下智能体跑完“一次路程”并从中学习的完整生命周期 :
第一阶段:发车前的准备(环境重置)¶
当一次新的路程开始时,系统会重置车辆状态(比如车速归零或设为初始速度、电池充满、把它放在路的起点)。
此时,智能体(这个AI副驾)睁开眼睛,环顾四周,它收到了一份“24维的当前路况简报”。这份简报里写着:我们当前车速是多少、电池还剩多少、前面有没有下坡、前面那个“人类老司机”打算踩多深的油门。
第二阶段:行驶中的“盲测”与记忆(数据收集)¶
车子启动了。在接下来的 220 个时间步(Horizon)里,智能体必须连续不断地做出决策:
-
大脑直觉输出(Actor网络): 智能体的策略网络根据当前路况,凭着它现有的经验,给出一个微调建议,比如“人类想输出 50Nm 扭矩,我建议减小 5Nm,并且稍微带点动能回收”。
-
加入“好奇心”扰动(Exploration): 为了发现更好的省电技巧,AI 不会每次都死板地输出一样的建议。代码中有一个
explore_decay参数,系统会在 AI 的建议上加上一点点随机的“高斯噪声”(试探性的盲盒动作)。有时候它会不小心多减了 2Nm,有时候会少减 1Nm。 -
物理世界反馈(Environment Step): 车子按照最终的指令往前开了一小段。系统充当了严厉的裁判,根据这一步的表现给出一个即时奖励(Reward)。如果车子没跟上人类的速度,裁判大喊“扣 5 分!”;如果这一步因为下坡滑行省了电,裁判说“加 2 分!”。
-
拿小本本记下来(Transition Dict): 智能体会把刚才发生的一切默默记在脑子里:“我在状态 A 下,做了动作 B,裁判给了我分数 R,并且车子开到了状态 C”。
注意:在这个行驶过程中,智能体的大脑(神经网络权重)是锁死的,它只是在拼命地体验和记录,收集“错题本”和“优秀日记”。
第三阶段:到达终点或半路淘汰(回合结束)¶
车子开到了终点(跑完了设定的时间步),或者因为 AI 乱指挥导致车速偏离人类意图太远,触发了安全底线(Fail Tolerance),系统直接强制结束这次路程并给出巨额惩罚(扣 120 分)。
此时,智能体的小本本里已经密密麻麻记录了这一路上几百次的“状态-动作-奖励”数据。
第四阶段:赛后闭门复盘(策略更新)¶
这才是真正发生“学习(Learning)”的时刻。智能体拿着记录本,开始在 agent.update() 方法中进行深度反思:
-
“神算子”预测对比(Critic评估): 智能体大脑里的价值网络(Critic)会回放刚才的录像。它会逐帧分析:“在第 50 秒那个下坡前,我原本以为这局只能拿 10 分。但实际上因为当时我偷偷试探性地加大了动能回收(加入了随机噪声的那个动作),最后总成绩比预期多拿了 3 分!”。这多出来的 3 分,就是所谓的优势(Advantage)。
-
“打工人”行为矫正(Actor更新): 策略网络(Actor)听到 Critic 的汇报后,恍然大悟。对于那些产生了“正优势(比预期好)”的试探性动作,Actor 会修改自己的神经元连接,提高下次在同样路况下做出这个动作的概率;反之,对于那些导致掉队扣分的“负优势”动作,它会降低做这些动作的概率。
-
PPO 的安全锁(Clip机制): 智能体在修改大脑时非常谨慎。它遵循 PPO 算法的死规定:每次复盘,行为习惯的改变幅度不能超过 20%(
eps = 0.2)。绝不能因为一次偶然的成功就完全推翻过去的驾驶习惯,防止“走火入魔”。
总结¶
这就是智能体在“一次路程”前后的学习全过程。当这套流程在不同的虚拟道路、不同的人类驾驶风格下循环往复执行成千上万次(比如代码里的几百个 Episodes)后,那个原本靠“随机乱猜”的 AI,就会被一点点打磨成一个能精准预判路况、毫厘不差地微调扭矩的“节能大师”。
