Apollo 8.0 Monitor逻辑梳理

前言

本文是针对Apollo 8.0中的Monitor进行阐述,旨在通过其架构和业务逻辑来掌握Monitor。

Monitor总体介绍

架构图

Apollo官网给出的模块关系图

由此可见,Monitor模块定期检测架构中被监控软、硬模块的状态信息,计算出当前系统的整体的健康状态,及时反馈给下游模块(Guardian)。

PS: 个人感觉HMI和Monitor的Data Lines应该是双向的

  • Monitor给HMI定期输出最终系统状态

  • Monitor通过HMI拿到当前的HMI状态

分类图

每一个模块都有一个单独的xxxMonitor类来监控。种类较多,文章下面逐一剖析。

类图

下图可简单表示Monitor重要类之间的关系

Monitor子模块介绍

Monitor

是整个监控的入口模块,Cyber框架的应用模块之一,最终被编译成libmonitor.so被mainboard启动。

继承了Cyber框架的定时组件,所以内部逻辑相当简单,持有若干个xxxMonitor的指针

  • Init

  • 初始化Monitor Manager、xxxMonitor实例

  • Proc

  • 串行调度各模块监控的任务,最后产出监控结果

  • 一次监控检测任务顺序

  • EsdCanMonitor-->SocketCanMonitor-->GpsMonitor-->LocalizationMonitor-->CameraMonitor-->ProcessMonitor-->ModuleMonitor-->LatencyMonitor-->ChannelMonitor-->ResourceMonitor-->SummaryMonitor-->(FunctionalSafetyMonitor)

Monitor Manager

此类被声明为单例模式,被*Monitor调用

主要作用

  • 被Monitor类调用

  • StartFrame、EndFrame成员函数来开始&&结束一次监控任务。

  • StartFrame

  • 创建人机交互模块的reader,并获取最新的状态,如果获取不到,直接停止本次监控任务(这也是为什么要同时启动人机交互模块)

  • Channel: hmi_status_topic, /apollo/hmi/status

  • 消息: modules/common_msgs/dreamview_msgs/hmi_status.proto: HMIStatus

  • 判断上次的运行方式与本次的运行方式(HMIStatus.current_mode)是否改变,

  • 改变

  • 记录当前运行方式

  • 获取当前运行方式的配置(apollo::dreamview::HMIMode)

  • 初始化系统状态中各组件状态字段

  • 没改变

  • 清理历史上其他模块的结果

  • 更新自动驾驶标识字段并返回true

  • EndFrame: 调用log_buffer_对象来发布消息

  • 监控结果channel: /apollo/monitor

  • 消息类型: modules/common_msgs/monitor_msgs/monitor_log.proto: MonitorMessage

  • 被xxxMonitor类调用

  • CreateReader、CreateWriter成员模板函数来创建不同类型的reader和writer

  • reader被缓存在Monitor Manager内部

  • Getters

  • GetStatus : 获取当前系统整体的状态(SystemStatus: status_)

  • SystemStatus: modules/common_msgs/monitor_msgs/system_status.proto

  • IsInAutonomousMode: 判断当前是否为自动驾驶模式

  • 如果当前是离线模式(use_sim_time被设置true) 为false

  • 创建底盘的reader,如果创建不成功,为false

  • Channel: chassis_topic, /apollo/canbus/chassis

  • 消息: modules/common_msgs/chassis_msgs/chassis.proto: Chassis

  • 通过底盘reader获取最新的底盘状态,如果Chassis消息中的头部模块名字被标记为SimControl, 为false (因为仿真不需要安全检查)

  • 判断消息是否过期,过期为否

  • 消息时间 + FLAGS_system_status_lifetime_seconds(default: 30s) < 当前时间即为过时

  • 判断底盘消息中的驾驶模式是否为自动驾驶模式,直接返回

  • GetHMIMode: 获取人机交互模块的配置

其内部的node成员是Monitor继承TimerComponet而来的。

RecurrentRunner

是所有xxxMonitor的父类,其内部有两个主要的方法

  • Tick

  • 根据xxxMonitor的监控周期来调用RunOnce方法

  • RunOnce

  • 此方法为纯虚函数,xxxMonitor实现自己的监控逻辑。

软件模块

Camera Monitor

  • 消息来源:

  • CameraCompent : modules/drivers/camera (未移植)

  • Channel name(实际上应该与modules/drivers/camera/conf/camera*.pb.txt中channel name一致)

  • FLAGS_image_long_topic

  • Default: /apollo/sensor/camera/traffic/image_long

  • FLAGS_camera_image_long_topic

  • Default: /apollo/sensor/camera/image_long

  • FLAGS_camera_image_short_topic

  • Default: /apollo/sensor/camera/image_short

  • FLAGS_camera_front_6mm_topic

  • Default: /apollo/sensor/camera/front_6mm/image

  • FLAGS_camera_front_6mm_2_topic

  • Default: /apollo/sensor/camera/front_6mm_2/image

  • FLAGS_camera_front_12mm_topic

  • Default: /apollo/sensor/camera/front_12mm/image

  • 消息

  • 类型: apollo::drivers::Image

  • 定义: modules/common_msgs/sensor_msgs/sensor_image.proto

  • 模块用途

  • 摄像头是否存在且只能存在一个

  • 监控检测逻辑

  • 串行判断所有摄像头的Channel,记录下frame_id,如果检测到当前摄像头存在且已经有摄像头存在即报错

  • 最终一个都没有检测到即报错,否则报正常

  • 如何开启

  • 在modules/dreamview/conf/hmi_modes下的配置文件中monitored_components模块里面指定FLAGS_camera_component_name的名字

Channel Monitor

  • 模块用途

  • 监控modules/dreamview/conf/hmi_modes下配置文件中monitored_components里面指定channel数据是否有效(为空或者缺失字段)、时延、发送频率等指标

  • 监控检测逻辑

  • 获取当前的HMImode

  • 如果被监控组件配置中有channel字段,则计算更新频率

  • 创建相对应的reader并且获取最新的message

  • reader创建不成功时,直接下发UNKNOWN状态

  • 最新message为空时,直接下发FATAL状态

  • 检查reader中的channel延迟情况, 不符合预期则下发FATAL状态

  • reader->GetDelaySec()

  • 检查message中是否缺失字段,不符合预期则下发ERROR状态

  • 被监控字段定义: modules/dreamview/proto/hmi_mode.proto: ChannelMonitorConfig.mandatory_fields 目前并没有被使用

  • 检查更新频率是否在预期范围内,不符合预期则下发WARN状态

  • 内部持有LatencyMonitor的指针,并通过GetFrequency来计算更新频率

  • 如果以上全部符合预期,下发OK状态

  • 如何开启

  • modules/dreamview/conf/hmi_modes下配置文件中monitored_components里面指定channel字段即自动开启。

Functional Satety Monitor

  • 模块用途

  • 此模块在Summay Monitor之后执行,会根据汇总的结果来确定是否要采取一定的措施,比如说紧急停车

  • 开启方法

  • FLAGS_enable_functional_safety, 默认是开启的

  • 监控检测逻辑

  • 确定当前是否安全,如果安全,则跳过本次监控

  • 如果当前是非自动驾驶模式,则认为是安全的

  • 检查HMI Modules、Monitored Component的状态,如果没有任何的ERROR或者FATAL,则认为是安全的

  • 判断请求停车是否被触发过,触发过则跳过本次监控

  • 判断是否有安全模式触发时间,如果没有,设置新的安全模式触发时间,跳过本次监控

  • 判断在safety_mode_seconds_before_estop(10s)时间内有没有采取任何措施,如果没有,则设置紧急停车状态位

  • 安全模式触发时间 + safety_mode_seconds_before_estop < 当前时间,即认为没有采取任何措施

Latency Monitor

  • 模块用途

  • 计算所有模块时延,本身并不下发状态码,统计的数据下发到指定channel中去

  • 为ChannelMonitor提供channel更新频率数据

  • 消息来源

  • 哪个模块需要被监控时延,需要模块自己创建LatencyRecorder实例

  • 时延记录输入

  • Channel: latency_recording_topic /apollo/common/latency_records

  • 消息: modules/common/latency_recorder/proto/latency_record.proto: LatencyRecordMap

  • 统计输出

  • Channel: latency_reporting_topic /apollo/common/latency_reports

  • 消息:modules/common/latency_recorder/proto/latency_record.proto: LatencyReport

  • 监控检测逻辑

  • 创建输入时延记录channel的reader,并设置最大取消息数量(30条)

  • 获取多条LatencyRecordMap消息,记录并计算频率保存在成员变量里,以供查询

  • 如果满足时延报告周期,则对外发布消息

  • 当前时间-上次报告时间 > 报告周期

  • 如果开启

  • 自动开启,只要有模块把延时上报,监控模块就会有统计报告

Localization Monitor

  • 模块用途

  • 主要用来监控定位数据,最后根据订阅来的状态码来更新最终的状态

  • 消息来源

  • modules/localization

  • 输入Channel

  • localization_msf_status: /apollo/localization/msf_status

  • 消息

  • modules/common_msgs/localization_msgs/localization.proto: LocalizationStatus

  • 监控检测逻辑

  • 检查定位模块是否被监控,如果没被监控,跳过

  • 创建reader并获取最新message

  • 如果最新message为空则下发ERROR状态

  • 透传定位状态码到组件状态码并下发,对应关系

  • MeasureState::OK : ComponentStatus::OK

  • MeasureState::WARNNING : ComponentStatus::WARN

  • MeasureState::ERROR : ComponentStatus::WARN

  • MeasureState::CRITICAL_ERROR: ComponentStatus::ERROR

  • MeasureState::FATAL_ERROR: ComponentStatus::FATAL

Module Monitor

  • 模块用途

  • 这是通过Cyber框架中Node服务发现手段来检测被监控模块是否还存在

  • 监控检测逻辑

  • 对于每一个被监控的模块,用NodeManager去查看是否有模块Node,如果在启动时配置的Node任意一个不存在,则下发FATAL状态码

  • NodeManager即为cyber::service_discovery::NodeManager,可以找到所有存在的Node节点,一个正常运行的模块至少存在一个Node节点

Process Monitor

  • 模块用途

  • 这是通过当前所有正在运行的进程,检测预期进程是否还存在

  • 监控检测逻辑

  • 通过所有正在运行的进程(/proc/<PID>/cmdline)来获取所有的命令字符串

  • 分别检查HMI Modules、Monitored Components、 other components中的所有启动关键字是否在存活进程列表中,如果有一个不存在,则下发FATAL

Recorder Monitor

  • 模块用途

  • 监控SmartRecorder模块的状态,最后根据SmartRecorder模块的状态来下发状态

  • 输入

  • Channel: recorder_status_topic

  • 消息: modules/common_msgs/monitor_msgs/smart_recorder_status.proto: SmartRecorderStatus

  • 监控检测逻辑

  • 检查SmartComponent组件是否被监控,如果没有则跳过

  • 创建reader并且获取最新的message

  • 如果没有最新message,则下发error

  • 直接映射透传最新message中的recording_state

  • RecordingState::RECORDING: ComponentStatus::OK

  • RecordingState::TERMINATING: ComponentStatus::WARN

  • RecordingState::STOPPED: ComponentStatus::OK

Summary Monitor

  • 模块用途

  • 这个模块是整个监控体系中最重要的,xxxMonitor都调用此模块来修改Monitor Manager中的SystemStatus,内部具有优先级的判断。另外,本身也有一些汇总状态升级的逻辑。

  • 组件状态优先级: FATAL > ERROR > WARN > OK > UNKNOWN

  • 监控监测逻辑

  • 将SystemStatus中的组件状态(Process、Module、Channel、Resource、Other)汇总到最严重的级别

  • 序列化SystemStatus,并判断是否达到监控结果广播周期,如果判断到周期后,则广播

  • 判断系统状态hash值和上一次是否一致

  • 当前时间 - 上次广播时间 > 系统状态广播间隔(system_status_publish_interval: 1s)

硬件模块

Esdcan Monitor

  • 模块用途

  • 用来监控ESD-CAN设备的,看设备是否在线

  • 如何开启

  • 编译之前需要加上USE_ESD_CAN编译参数,现在默认不开启

  • 监控检测任务

  • 获取Canbus组件,如果没有获取不到,则跳过

  • 根据can_id创建一个handle,然后通过canIoctl来获取设备状态,如果一切正常,说明设备在线,下发OK,反之不在,下发ERROR

GPS Monitor

  • 模块用途

  • 用来监控GPS的状态

  • 输入

  • Channel: gnss_best_pose_topic

  • 消息: modules/common_msgs/sensor_msgs/gnss_best_pose.proto: GnssBestPose

  • 监控监测逻辑

  • 获取GPS组件,如果获取不到,跳过本次监控

  • 创建reader并且获取最新的message

  • 根据最新message的SolutionType来确定组件状态

  • SolutionType::NARROW_INT: ComponentStatus::OK

  • SolutionType::SINGLE: ComponentStatus::WARN

  • Default: ComponentStatus::ERROR

Resource Monitor

  • 模块用途

  • 根据预设的阈值来监控服务器的资源,

  • 如何开启

  • modules/dreamview/conf/hmi_modes下配置monitored_modules只要有resource相关配置就会开启

  • 监控检测逻辑

  • 获取被监控的组件,逐一检查是否配置resource字段,如果没有配置,跳过

  • 对于有资源阈值的别监控组件,逐一检查硬件资源,有任何不符合预期即下发ERROR和WARN

  • 检查磁盘空间

  • 检查CPU使用率

  • 检查内存使用率

  • 检查磁盘负载

SocketCan Monitor

  • 模块用途

  • 用来监控Socket Can设备,与Edscan Monitor类似

  • 监控检测逻辑

  • 根据名字获取相关的组件,获取不到即跳过本次监控

  • 打开Socket CAN的handler

  • 设置Message Filter, 失败即返回ERROR

  • 允许CAN的响应

  • 利用ioctl和bind来测试设备是否正常运转,出错返回ERROR

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值