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

[pilot智驾系统] docs | 用户界面状态(UIState)

链接:https://docs.sunnypilot.ai/

docs:sunnypilot

在这里插入图片描述

sunnypilot是一个开源自动驾驶系统,能够增强汽车的各项功能。

它作为副驾驶,通过解析车辆数据和摄像头画面来预测路况和驾驶员行为。

系统随后生成精确的转向和速度指令,将其转换为汽车能理解的操作指令,同时持续监控驾驶员注意力以确保行车安全与专注度

所有运行数据和设置都通过*用户友好界面*进行持续管理和展示

可视化

在这里插入图片描述

章节列表

  1. 用户界面状态(UIState)
  2. 参数系统
  3. 自动驾驶守护进程(selfdrived)
  4. 控制守护进程(controlsd)
  5. 模型守护进程(modeld)
  6. 纵向规划器(LongitudinalPlanner)
  7. 驾驶员监控守护进程(dmonitoringd)
  8. 车辆接口(CarInterface)
  9. 横向控制(LatControl)
  10. Panda守护进程(pandad)

第1章:用户界面状态(UIState)

想象我们正在使用sunnypilot自动驾驶系统开车。看着屏幕,上面显示着大量信息:当前车速、sunnypilot是否处于激活驾驶状态(engaged)、各类警告提示、或是系统仍在初始化准备中。

所有这些信息都在实时变化。屏幕如何知道在任何特定时刻该显示什么内容?

这就是**用户界面状态(UIState)**发挥作用的地方!

UI State视为一块共享的数字白板。sunnypilot系统中所有收集信息的模块(如传感器、车辆数据、驾驶逻辑)都会将它们最重要的发现写在这块白板上。

然后,负责在屏幕上绘制内容的部分(用户界面,即UI)只需查看这块白板就能知道需要显示什么内容。

它是UI所需展示所有信息的唯一"真相来源",确保我们始终能看到关于sunnypilot当前状态的最新信息。

为什么需要UI State?

如果没有统一的UI State,屏幕上的每个单独元素(速度显示、警告信息、驾驶模式指示器)都需要独立获取车辆状态。这就像一个大团队中的每个人都试图在不同时间从不同人那里获取更新——混乱且低效

UI State通过创建一个集中存放所有关键显示信息的地方来解决这个问题。

这使得任何UI元素都能轻松获取正确渲染自身所需的数据。

用例:显示sunnypilot的驾驶状态

举个常见例子:了解sunnypilot当前是已激活(actively helping you drive)还是未激活(not actively controlling the car)。UI需要清晰地显示这一点,比如通过改变屏幕背景颜色。

UI如何知道是否处于激活状态?它只需查看UI State!

如何使用UI State

UIState对象始终可供UI的不同部分读取

在Python中,我们可以导入ui_state并访问其属性。

假设我们想知道sunnypilot是否已激活,以决定背景颜色。

# 摘自selfdrive/ui/layouts/main.py(简化版)
from openpilot.selfdrive.ui.ui_state import ui_state, UIStatusdef get_screen_background_color():"""检查UI State以确定适当的屏幕背景颜色"""current_status = ui_state.status # 从UI State读取当前状态if current_status == UIStatus.ENGAGED:return "💚 绿色(已激活)"elif current_status == UIStatus.OVERRIDE:return "💛 黄色(覆盖中)"else: # UIStatus.DISENGAGEDreturn "💙 蓝色(未激活)"# 假设每次屏幕需要更新时都会调用此函数:
print(f"屏幕背景应为:{get_screen_background_color()}")# 如果sunnypilot变为激活状态,ui_state.status会改变,
# 此函数将返回"💚 绿色(已激活)"

这段简短代码展示了UI元素(如背景)如何简单地向ui_state询问当前status。根据答案,它可以向驾驶员显示正确的颜色。这是UI保持更新的非常简洁直接的方式。

底层原理:UI State如何更新

那么这块神奇的ui_state白板是如何获取信息的?

UIState对象持续监听来自sunnypilot其他部分的"消息"。这些消息就像传递的小纸条,包含关于车辆、驾驶系统等的最新信息。当UIState收到新消息时,它会更新自己的内部变量以反映最新情况。

以下是这个过程的简化序列:

在这里插入图片描述

  1. 其他守护进程发送更新sunnypilot中的各种后台程序(称为"守护进程")持续监控车辆速度、是否踩油门、或sunnypilot的驾驶逻辑(Selfdrive守护进程(selfdrived))是否活跃等信息。它们将这些信息作为消息发送出去。
  2. UIState监听UIState有一个特殊的"监听器"(称为SubMaster)等待这些消息。
  3. UIState处理:当UIState收到新消息时,它会读取信息并更新自己的属性,如startedignitionstatusengaged
  4. UI元素读取:屏幕上的元素(如背景、速度显示、警告)然后从UIState读取这些更新的属性以正确绘制自己。

代码解析

sunnypilot中,UIState主要在Python(用于sunnypilot UI框架)和C++(用于较旧的openpilot UI框架)中实现。为简单起见,我们将重点介绍Python版本,因为它清晰地展示了这个概念。

UIState类被设计为"单例"(singleton),这意味着任何时候都只有一个实例在运行。

确保每个人都在查看同一块白板。

# 摘自selfdrive/ui/ui_state.py(简化版)
import cereal.messaging as messaging
from enum import Enum # 用于定义状态类型class UIStatus(Enum):DISENGAGED = "disengaged"ENGAGED = "engaged"OVERRIDE = "override"class UIState:_instance: 'UIState | None' = None # 确保只有一个实例的内部变量def __new__(cls):if cls._instance is None:cls._instance = super().__new__(cls)cls._instance._initialize() # 仅调用一次初始化器return cls._instancedef _initialize(self):# 这是"监听器",接收来自sunnypilot其他部分的消息self.sm = messaging.SubMaster(["deviceState",       # 告诉我们设备是否已"启动""selfdriveState",    # 告诉我们openpilot是否启用/激活"pandaStates",       # 告诉我们车辆点火状态等# ... 许多其他消息 ...])self.status: UIStatus = UIStatus.DISENGAGEDself.started: bool = Falseself.ignition: bool = False# ... 其他UI相关数据 ...# 全局'ui_state'对象,每个人都可以导入和使用:
# ui_state = UIState() # 这行代码实际创建单例实例

_initialize方法设置了SubMaster(self.sm),这是监听来自其他守护进程消息的关键组件。它定义了UIState感兴趣的所有不同类型消息。它还初始化了重要变量如statusstartedignition

接下来,update方法会被非常频繁地调用(每秒多次)以保持UIState最新。

# 摘自selfdrive/ui/ui_state.py(简化版)
class UIState:# ... (之前的代码) ...def update(self) -> None:# 1. 检查来自所有来源的新消息self.sm.update(0)# 2. 根据这些消息更新我们的内部状态变量self._update_state()# 3. 确定整体UI状态self._update_status()# 4. 更新设备特定内容如屏幕亮度device.update()

update方法是UIState的核心。它首先调用self.sm.update(0)读取任何新消息。然后,它调用两个重要的辅助方法:_update_state_update_status

以下是_update_state的简化工作原理:

# 摘自selfdrive/ui/ui_state.py(简化版)
import cereal.messaging as messaging
from cereal import log # 用于log.PandaState.PandaTypeclass UIState:# ... (之前的代码) ...def _update_state(self) -> None:# 是否有新的'pandaStates'消息到达?if self.sm.updated["pandaStates"]:panda_states = self.sm["pandaStates"]if len(panda_states) > 0:# 检查任何连接的panda是否有点火信号self.ignition = any(state.ignitionLine or state.ignitionCan for state in panda_states)# 是否有新的'deviceState'消息到达?if self.sm.updated["deviceState"]:# 根据设备状态更新我们的'started'变量self.started = self.sm["deviceState"].started and self.ignition

_update_state中,UIState检查特定消息是否已更新。

例如,它检查pandaStates看车辆是否点火,检查deviceState看整个sunnypilot系统是否被视为"已启动"。它结合这些来设置self.started标志。

最后,_update_status确定可见的UI状态(已激活、未激活、覆盖中):

# 摘自selfdrive/ui/ui_state.py(简化版)
from cereal import log # 用于log.SelfdriveState.OpenpilotStateclass UIState:# ... (之前的代码) ...def _update_status(self) -> None:# 如果有新的'selfdriveState'消息到达,更新UI状态if self.started and self.sm.updated["selfdriveState"]:ss = self.sm["selfdriveState"] # 获取selfdrive状态数据state = ss.state # 获取特定状态值(如preEnabled)if state in (log.SelfdriveState.OpenpilotState.preEnabled, log.SelfdriveState.OpenpilotState.overriding):self.status = UIStatus.OVERRIDE # 驾驶员正在覆盖else:# 如果selfdrive启用,我们就是已激活,否则未激活self.status = UIStatus.ENGAGED if ss.enabled else UIStatus.DISENGAGED# ... (更多关于在途/离途转换的逻辑) ...

_update_status方法对我们的例子至关重要。

它读取selfdriveState消息。如果sunnypilot是"enabled"(意味着它正在主动驾驶),self.status属性被设为UIStatus.ENGAGED

如果驾驶员正在覆盖,则是UIStatus.OVERRIDE。这就是前面背景颜色例子获取信息的方式!

虽然sunnypilot中的主要UI逻辑使用Python,但基础项目openpilot也有C++实现的UIState(selfdrive/ui/ui.ccselfdrive/ui/ui.h),其目的相同。两个版本都充当UI数据的中心枢纽

总结

**用户界面状态(UIState)**就像是sunnypilot显示系统的中枢神经系统。

它充当一块持续更新的白板,为所有UI元素提供必要信息,向驾驶员准确展示sunnypilot正在做什么。

通过集中这些数据sunnypilot确保用户界面始终一致、响应迅速且易于理解。(实现了ui和date的解耦,通过中端实现)

下一章,我们将了解**参数系统**,这是帮助sunnypilot管理持久设置和配置数据的另一个基本概念。

下一章:参数系统

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

相关文章:

  • 第十八节:骨骼动画 - 角色动画控制
  • 时间序列异常检测实战:HMM与LSTM方法解析
  • 在华为云服务器上使用Ansible部署LNMP环境【玩转华为云】
  • Ubuntu22.04 解决eth0未托管问题
  • golang 基础类 八股文400题
  • Redis面试精讲 Day 30:Redis面试真题解析与答题技巧
  • 蓝牙AOA定位方案:重塑精准定位新纪元,赋能行业智能化升级
  • 16-day13强化学习和训练大模型
  • 深入理解 Roo Code 的自动批准功能
  • Node.js(1)—— Node.js介绍与入门
  • 从0开始学习Java+AI知识点总结-25.web实战(AOP)
  • 人工智能-python-深度学习-数据准备
  • 路径总和。
  • 同一性和斗争性
  • 使用 gemini api + 异步执行,批量翻译文档
  • 【Task04】:向量及多模态嵌入(第三章1、2节)
  • 解锁表格数据处理的高效方法-通用表格识别接口
  • sudo 升级
  • Spring Boot 项目打包成可执行程序
  • 3秒传输大文件:cpolar+Localsend实现跨网络秒传
  • 内核编译 day61
  • Ubuntu安装及配置Git(Ubuntu install and config Git Tools)
  • Linux 磁盘文件系统
  • 【银河麒麟桌面系统】PXE实现arm、x86等多架构安装
  • Linux-进程相关函数
  • Vulkan学到什么程度才算学会
  • 关系轮-和弦图的可视化
  • VPS一键测试脚本NodeQuality,无痕体验+自动导出,服务器测试更轻松
  • illustrator-01
  • 我的项目管理之路-组织级项目管理(二)