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

[pilot智驾系统] 自动驾驶守护进程(selfdrived)

第3章:自动驾驶守护进程(selfdrived)

在前几章中,我们探讨了sunnypilot如何使用用户界面状态(UIState)更新屏幕显示,以及通过参数系统记住重要设置。

sunnypilot实际上是如何思考并决定该做什么的?它如何知道何时驾驶、何时警告我们或何时退出控制?

这就是**自动驾驶守护进程(selfdrived)**发挥作用的地方

selfdrived视为sunnypilot中央大脑指挥官

它是核心组件,接收所有传入信息——如车辆速度、转向、传感器数据、驾驶模型的预测,甚至我们作为驾驶员的操作——并利用这些信息做出关于sunnypilot整体行为的关键决策。

基于所有这些输入,selfdrived不断确定sunnypilot的当前"状态"(如已激活、未激活、警告中),并为系统的其他部分(包括屏幕)发布必要的命令和信息。

它在管理安全警报和整体系统行为以确保行车安全方面也起着关键作用。

为什么需要自动驾驶守护进程?

没有selfdrivedsunnypilot将是一堆互不关联的部件。一个部件可能知道车速,另一个可能知道车道线,但没有一个组件负责将所有信息整合成对驾驶情况的连贯理解,并决定系统的整体行动。

selfdrived通过成为决策者来解决这个问题。

聚合数据,根据安全规则和操作条件评估当前情况,然后指导sunnypilot的行为,确保统一且安全的驾驶体验。

用例:决定sunnypilot的驾驶状态

想象我们正在驾驶,按下"启用"按钮激活sunnypilotselfdrived如何决定是否应该真正激活并开始辅助驾驶?或者,如果sunnypilot已激活,但突然车门打开,selfdrived会如何反应?

这是通过selfdrived持续评估其"状态"来处理的,这些状态可以是:

  • 禁用sunnypilot关闭,不控制车辆。
  • 预启用:等待条件(如松开刹车)以完全激活。
  • 已启用sunnypilot正在主动控制车辆。
  • 覆盖中:我们在sunnypilot技术上仍启用时轻微转向或踩踏板。
  • 软禁用sunnypilot由于非关键问题优雅地关闭控制,给我们时间接管。
  • 立即禁用sunnypilot由于关键安全问题快速关闭控制。

selfdrived始终监视可能触发这些状态变化的情况。

自动驾驶守护进程的工作原理

selfdrived想象成飞机驾驶舱中训练有素的飞行员。

这位飞行员不断接收来自所有仪器和传感器的信息,听取空中交通管制,并监控副驾驶。基于所有这些输入,飞行员做出关于飞行的决策(起飞、巡航、着陆、应急程序),并将这些决策传达给飞机其他系统。

以下是selfdrived主要任务的简化视图:

  1. 收集信息:它读取来自许多其他sunnypilot组件的消息,如:
    • 车辆状态:当前速度、转向角度、踏板输入、档位等。
    • 模型守护进程:关于道路、车道线和其他车辆的预测。
    • 驾驶员监控:驾驶员是否在注意路况。
    • 传感器:设备温度、剩余存储、摄像头状态。
  2. 生成事件:基于收集的信息,selfdrived生成"事件"。事件就是值得注意的情况,如"驾驶员踩踏板"、“车门打开”、“低于激活速度"或"系统过热”。
  3. 确定状态:它使用"状态机"来确定sunnypilot的整体驾驶状态(如已启用禁用)。这个决策很大程度上受刚刚生成的事件影响。
  4. 管理警报:然后,它根据当前状态和事件确定应向驾驶员显示哪些视觉或听觉警报(如"接管控制"、“驾驶员分心”)。
  5. 发布输出:最后,selfdrived发布其计算的selfdriveStateonroadEvents消息。其他守护进程,如UI(使用用户界面状态(UIState)),读取这些消息以更新屏幕并执行其他操作。

让我们可视化这个流程:

在这里插入图片描述

如何使用自动驾驶守护进程(与其输出交互)

作为初学者,我们不会像使用Params那样直接"使用"selfdrived调用其函数。

相反,我们会读取它发布的消息以了解sunnypilot的当前驾驶状态和警报。selfdrived发布的最重要消息是selfdriveState

以下是sunnypilot的其他部分(如用户界面状态(UIState))读取此信息的方式:

import cereal.messaging as messaging
from cereal import log # 访问SelfdriveState枚举# 创建SubMaster以监听消息
sm = messaging.SubMaster(["selfdriveState"])# 在运行非常频繁的循环中(如UI的更新循环)
while True:sm.update(0) # 检查新消息if sm.updated["selfdriveState"]:current_selfdrive_state = sm["selfdriveState"]# 检查sunnypilot的驾驶状态if current_selfdrive_state.enabled:print("sunnypilot当前已激活并正在驾驶!")elif current_selfdrive_state.state == log.SelfdriveState.OpenpilotState.softDisabling:print(f"sunnypilot正在软禁用。原因:{current_selfdrive_state.alertText2}")else:print("sunnypilot未激活。")# 检查活动警报if current_selfdrive_state.alertText1:print(f"活动警报:{current_selfdrive_state.alertText1} - {current_selfdrive_state.alertText2}")print(f"  状态:{current_selfdrive_state.alertStatus}, 声音:{current_selfdrive_state.alertSound}")# ... 其他逻辑 ...

这段代码展示了从selfdrived获取当前selfdriveState是多么简单。

它允许任何组件(如仪表盘显示)立即知道sunnypilot是否已激活、为何可能正在软禁用或需要显示哪些警报。

这个selfdriveState消息正是用户界面状态(UIState)监听其许多显示属性的内容

底层原理:selfdrived核心循环

selfdrived是一个Python程序(selfdrive/selfdrived/selfdrived.py),在后台持续运行。

其核心是一个run方法,该方法重复调用step方法。这个step方法协调我们讨论的所有任务

让我们看看step方法的简化版本:
在这里插入图片描述

# 摘自selfdrive/selfdrived/selfdrived.py(简化版)
class SelfdriveD:# ... (初始化方法) ...def step(self):# 1. 收集所有必要的输入数据CS = self.data_sample()# 2. 更新当前驾驶事件列表self.update_events(CS)# 3. 使用事件更新sunnypilot的整体状态self.enabled, self.active = self.state_machine.update(self.events)# 4. 确定应显示哪些警报self.update_alerts(CS)# 5. 发布结果供其他守护进程读取self.publish_selfdriveState(CS)# 记住下一次循环迭代的车辆状态self.CS_prev = CS

这个step方法每秒运行多次(100 Hz),确保selfdrived始终快速响应新信息。让我们分解最重要的部分。

1. 生成事件:update_events

update_events方法是selfdrived将原始传感器数据、车辆状态和其他系统信息转换为有意义"事件"的地方。

# 摘自selfdrive/selfdrived/selfdrived.py(简化版)
from cereal import car, log
from openpilot.selfdrive.selfdrived.events import Events # 我们的事件管理器class SelfdriveD:# ... (初始化和其他方法) ...def update_events(self, CS):self.events.clear() # 为这个周期开始一个全新的事件列表# 示例:如果驾驶员踩下油门踏板if CS.gasPressed and not self.CS_prev.gasPressed and self.disengage_on_accelerator:self.events.add(log.OnroadEvent.EventName.pedalPressed) # 添加'pedalPressed'事件# 示例:如果车门打开if CS.doorOpen:self.events.add(log.OnroadEvent.EventName.doorOpen)# 示例:如果系统过热if self.sm['deviceState'].thermalStatus >= log.DeviceState.ThermalStatus.red:self.events.add(log.OnroadEvent.EventName.overheat)# ... 更多对各种条件的检查 ...

update_events中,selfdrived检查各种条件(如CS.gasPressedCS.doorOpen、设备温度),并向其self.events对象添加相应的EventName

Events类(来自selfdrive/selfdrived/events.py)本质上是当前正在发生或检测到的所有事情的列表。这些事件对下一步至关重要。

2. 确定系统状态:StateMachine

一旦selfdrived有了所有当前Events的列表,它就将它们传递给其StateMachineselfdrive/selfdrived/state.py)。StateMachine就像一本规则手册,规定了sunnypilot应如何在其不同驾驶状态之间转换。

# 摘自selfdrive/selfdrived/state.py(简化版)
from cereal import log
from openpilot.selfdrive.selfdrived.events import Events, ET # ET表示事件类型State = log.SelfdriveState.OpenpilotState # 例如enabled, disabled, softDisablingclass StateMachine:def __init__(self):self.state = State.disabled # 从禁用状态开始self.soft_disable_timer = 0def update(self, events: Events):# 如果当前状态不是禁用,检查退出触发条件if self.state != State.disabled:if events.contains(ET.USER_DISABLE): # 例如驾驶员按下取消按钮或踏板self.state = State.disabled        # 转换为禁用# self.current_alert_types.append(ET.USER_DISABLE) # 用于警报elif events.contains(ET.IMMEDIATE_DISABLE): # 例如关键传感器故障self.state = State.disabled        # 转换为禁用# self.current_alert_types.append(ET.IMMEDIATE_DISABLE)elif self.state == State.enabled:if events.contains(ET.SOFT_DISABLE): # 例如系统过热self.state = State.softDisabling  # 转换为软禁用self.soft_disable_timer = 300 # 大约3秒(300步@100Hz)# self.current_alert_types.append(ET.SOFT_DISABLE)elif self.state == State.softDisabling:if not events.contains(ET.SOFT_DISABLE):self.state = State.enabled # 如果软禁用条件清除,返回启用elif self.soft_disable_timer <= 0:self.state = State.disabled # 如果软禁用时间用完,完全禁用# 如果当前状态是禁用,检查激活触发条件elif self.state == State.disabled:if events.contains(ET.ENABLE): # 例如驾驶员按下恢复按钮if not events.contains(ET.NO_ENTRY): # 检查是否存在"禁止进入"条件self.state = State.enabled       # 转换为启用# self.current_alert_types.append(ET.ENABLE)# 最后,确定openpilot是否实际"启用"和"活跃"enabled = self.state in (State.preEnabled, State.enabled, State.softDisabling, State.overriding)active = self.state in (State.enabled, State.softDisabling, State.overriding)return enabled, active

StateMachineupdate方法是核心逻辑。它查看events列表和self.state来决定sunnypilot是否应改变其模式。例如:

  • 如果self.stateenabledevents.contains(ET.SOFT_DISABLE)(如overheat),它转换为softDisabling
  • 如果self.statedisabledevents.contains(ET.ENABLE)(如按下恢复)且events.contains(ET.NO_ENTRY)(如"车门打开"),它转换为enabled

3. 管理警报:update_alerts

确定状态后,selfdrived使用AlertManager处理Events并决定应向驾驶员显示哪些特定警报(如"注意"或"转向暂时不可用")。这是实际警报文本、声音和视觉提示确定的地方。

4. 发布输出publish_selfdriveState

最后,selfdrived创建并发送selfdriveState消息,其中包含:

  • enabled:指示sunnypilot是否已激活的布尔值。
  • state:来自StateMachine的当前状态(如enableddisabled)。
  • alertText1alertText2alertStatus等:关于要显示的最高优先级警报的详细信息。
  • personality:我们选择的驾驶个性(如激进、标准)。

这个消息对用户界面状态(UIState)和其他守护进程做出适当反应至关重要

总结

**自动驾驶守护进程(selfdrived)**确实是sunnypilot的大脑。

持续监控大量信息,将其处理为可理解的Events,使用StateMachine确定sunnypilot的整体驾驶状态,管理关键安全警报,并发布其决策供系统其余部分执行。通过集中这种复杂的决策,selfdrived确保sunnypilot在道路上安全、响应迅速且智能地运行

在下一章中,我们将通过深入研究**控制守护进程(controlsd)**,了解selfdrived的这些决策如何转化为车辆的实际动作。

下一章:控制守护进程(controlsd)

http://www.dtcms.com/a/350547.html

相关文章:

  • linux - jvm相关命令
  • 操作系统中,进程与线程的定义与区别
  • 雷卯针对香橙派Orange 4G-IOT开发板防雷防静电方案
  • `lock()` 和 `unlock()` 线程同步函数
  • THM Bricks Heist靶机
  • Java 学习笔记(基础篇10)
  • HTML应用指南:利用POST请求获取全国三星门店位置信息
  • 【目标跟踪】《FastTracker: Real-Time and Accurate Visual Tracking》论文阅读笔记
  • 目前城投债
  • MySQL常见报错分析及解决方案总结(1)---Can‘t connect to MySQL server on ‘localhost‘(10061)
  • Docker:技巧汇总
  • 利用matlab实现CST超表面阵列的自动建模
  • 数据结构:单链表(详解)
  • SSL移动接入方案和移动资源发布
  • 【学习笔记】怎么解决/dev/sda3: clean, XXX files, XXX blocks
  • 【Wrangler(Cloudflare 的官方 CLI)和 npm/npx 的区别一次讲清】
  • SpringCloud微服务技术自用笔记
  • day52_2025-08-25
  • 【猿人学】web第一届 第13题 入门级 cookie
  • 【动态规划】卡特兰数
  • 文件读取结束的判定方法:正确使用feof函数避免文件读取错误
  • CAN总线详解(四)CANFD报文结构
  • 小红书链接uid等批量转换,界面软件工具
  • 【COMSOL】COMSOL帮助文档无法打开的解决办法
  • 智能专网升级:4G与5G混合组网加速企业数字化转型
  • leetcode算法刷题的第十七天
  • 房地产模式的运行逻辑与内在风险
  • Acrobat DC 中的条件格式化
  • 失眠——记录安东尼威廉饮食习惯的250天
  • 推三返一链动模式裂变图解