前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自动驾驶 Apollo 源码分析系列,系统监控篇(二):Monitor模块如何监控硬件

自动驾驶 Apollo 源码分析系列,系统监控篇(二):Monitor模块如何监控硬件

作者头像
Frank909
发布2022-05-10 14:52:23
9980
发布2022-05-10 14:52:23
举报
文章被收录于专栏:Frank909Frank909

前面的文章有分析,Monitor 模块监控的内容分为 Hardware 和 Software 两位。

本篇分析硬件监控部分。

首先,可以观察一下 Apollo 官方文档给出的硬件连接图。

在这里插入图片描述
在这里插入图片描述

跟自动驾驶本身相关的无非是传感器和底盘。

在这里插入图片描述
在这里插入图片描述

当前 Monitor 系统支持的硬件类监控有 4 个:

  • ESD CAN
  • GPS
  • Resource
  • SOCKET CAN

监控 ESD CAN

ESD CAN 是一种 CanCard,在 Apollo 中通过 PCIe 接口连接到 6108 工控机上面,在 Apollo 1.0 版本的官方文档就有介绍过 ESD CAN 型号是 ESD CAN-PCIe/402-1。 它长这个样子:

在这里插入图片描述
在这里插入图片描述

ESD CAN 接收到的信号有 2 类:

  • 线控底盘 CAN 信号
  • 大陆毫米波雷达 CAN 信号
EsdCanMonitor

我在前面的文章中有写过,各类 xxxMonitor 其实是 RecurrentRunner 子类。

在这里插入图片描述
在这里插入图片描述

EsdMonitor 也是如此,它和 CameraMonitor 一样也是 RecurrentRunner 子类。

在这里插入图片描述
在这里插入图片描述

EsdCanMonitor 在初始化的时候设置了自己的模块名字和周期执行间隔,这里时间间隔是 3 秒,也就是 EsdCan 每 3 秒被监控 1 次。

在这里插入图片描述
在这里插入图片描述

我们也可以看到 EsdCanMonitor 的核心方法其实是 EsdCanTest。

在这里插入图片描述
在这里插入图片描述

在 EsdCanTest 中检测到的结果,最后会通过 SummaryMonitor.EscalateStatus 方法提升自身状态等级。

当然,如果 ESD CAN 根本不存在,那么就返回 ERROR 错误类型。

EsdCanTest 内部创建了 NT_HANDLE 类型变量 handle,并基于它进行测试。

在这里插入图片描述
在这里插入图片描述

应该是借助于 EsdCan 厂商自带的驱动测试函数。上面代码很简单,通过调用 3 个函数进行了 5 类测试。

  1. 通过 canOpen 测试设备是否能正常打开
  2. 通过 canStatu 测试设备是否能正常获取状态
  3. 通过 canIoctl 测试是否能获取 CANBUS 的分析数据
  4. 通过 canIoctl 测试是否能获取控制状态
  5. 通过 canIoctl 测试是否能获取波特率

然后根据测试的结果返回。

测试的可能结果还挺多的,就不一一列出了。

代码语言:javascript
复制
NTCAN_SUCCESS:
     
NTCAN_RX_TIMEOUT:
     
NTCAN_TX_TIMEOUT:

NTCAN_TX_ERROR:
 
NTCAN_CONTR_OFF_BUS:
  
NTCAN_CONTR_BUSY:
  
...

然后 EsdCan 的监控的基本逻辑就没有了,它的工作更多借助于厂商的驱动测试API完成。

GpsMonitor

在这里插入图片描述
在这里插入图片描述

GpsMonitor 的代码更简单。

监控周期也是每隔 3 秒一次。

主要逻辑是接收 GnssBestPose 这个 Topic,获取它的状态,结果有 3 种:

  1. 如果是 SolutionType::NARROW_INT,那么状态是 OK
  2. 如果是 SolutionType::SINGLE,那么状态是 WARN
  3. 其它情况,状态被标志为 ERROR

GnssBestPose 和 SolutionType 的定义都来自 GNSS 驱动,路径在。

代码语言:javascript
复制
modules/drivers/gnss/proto/gnss_best_pose.proto
在这里插入图片描述
在这里插入图片描述

Socket CAN

Socket CAN 是个什么东西呢?

我们知道 Socket,也知道在汽车行业中广泛通过 CAN 协议传输,那么 Socket CAN 是什么呢?

它是在 Linux 环境下基于 Socket 机制实现 CAN 协议的一套机制。

Apollo 中也支持对它的监控。

在这里插入图片描述
在这里插入图片描述

可以看到核心方法是 SocketCanTest。

在这里插入图片描述
在这里插入图片描述

通过 socket 方法得到一个 handler。

注意 socket() 中的参考,PF_CAN 有别于我们常使用的 TCP 类 Socket 开发。

代码语言:javascript
复制
socket(AF_INET,SOCK_STREAM,0)

这说明 SocketCAN 和普通的 TCP/IP 是不一样的。

SocketCanTest() 中通过 SocketCanHandlerTest 执行操作。

在这里插入图片描述
在这里插入图片描述

检测的逻辑也非常简单:

  1. 通过设置 filter,检测是否正常
  2. 通过尝试 enable CAN Frame 的接收检测是否正常
  3. 通过 bind socket 到网络接口检测是否正常

ResouceMonitor

ResourceMonitor 监控的对象是那些通用的物理资源,当前包含 CPU、内存、磁盘。

在这里插入图片描述
在这里插入图片描述

上面代码显示并没有多特别之处,下面是这的实现。

在这里插入图片描述
在这里插入图片描述

ResourceMonitor 每隔 5 秒监控 1 次,它需要从 HMI 中获取受监控的配置项目。

CheckDiskSpace
在这里插入图片描述
在这里插入图片描述

在代码检测磁盘空间是通过 boost::filesystem 中的 space() 方法。

得到的结果需要和 config 中规定的阈值进行判断,产生 ERROR 和 WARN 两种结果。

CheckCPUUsage
在这里插入图片描述
在这里插入图片描述

实际执行的是 GetSystemCPUUsage 或者 GetCPUUsage 方法。

在这里插入图片描述
在这里插入图片描述

核心逻辑无非就是通过代码执行命令行脚本 /proc/stat。这个命令包含了系统内核中很多信息,就如 CPU 信息。比如,我在我的 WIN11 系统中的 WSL 中查看 /proc/stat 信息,出现下面的结果 :

在这里插入图片描述
在这里插入图片描述

cpu 状态有很多信息,每一列有独特的意义。

;

cpu 统计时间的单位是 jiffies。 大家可能在想,代码如何拿到 /proc/stat 信息的呢?

在这里插入图片描述
在这里插入图片描述

因为在 Linux 中,万物皆文件。只要通过 ifstream 读取那个路径,然后 getLine 一行一行解析就好了。 然后,如果要统计单个进程 PID 的CPU 信息,则需要通过 /proc/pid/stat 命令。

在这里插入图片描述
在这里插入图片描述

有 4 种时间

  • utime 用户态时长
  • stime 内核时长
  • cutime 当前进程等待子进程的 utime
  • cstime 当前进程等待子进程的 stime

最终的 CPU 时长:

代码语言:javascript
复制
cputime = utime+stime+cutime+cstime

CPU 使用率公式:

代码语言:javascript
复制
usage = (time - pretime)/monitor_time

就是在一次监控周期内,两次 cputime 统计值的差占监控时间的比例。

CPU 状态是否报警取决于结果和配置中预设的值的比较。

在这里插入图片描述
在这里插入图片描述
CheckMemoryUsage

检查内存使用情况的逻辑和 CPU 差不多。

在这里插入图片描述
在这里插入图片描述

如果没有进程 DAG 则检测 SystemMemoryUsage 否则就通过 pid 一个个获取单个进程的内存信息。

在这里插入图片描述
在这里插入图片描述

通过命令行 /proc/meminfo 获取内存信息。

得到总共的内存,和当前使用的内存,然后求比例。 单个进程使用的内存信息通过 /proc/pid/statm 命令求得。

在这里插入图片描述
在这里插入图片描述

内存使用率公式:

代码语言:javascript
复制
usage = usedMem/TotalMem

计算已使用了的内存在整个内存容量的占比。

CheckDiskLoads

字面意思是检测磁盘负载。

在这里插入图片描述
在这里插入图片描述

需要通过 GetSystemDiskload 获取各个设备的负载值,然后和配置中的阈值做比较,最终得到 Error 或者 WARN 状态。

在这里插入图片描述
在这里插入图片描述

借助的是 /proc/diskstats 命令,这个命令可以查看磁盘的相关信息。

在这里插入图片描述
在这里插入图片描述

第2列也就是 ram0、loop0、sda 之类是 devicename。 第12列是 I/O 耗费的时间,单位是 ms。

磁盘负债的比例计算公式是:

代码语言:javascript
复制
usage = (当前I/O时间 - 上一次I/O时间)/监控间隔时长

总结

  1. Apollo 归类到硬件监控的内容不多,只有 4 个,ESD CAN、GPS、SocketCAN、Resource
  2. 监控本身的逻辑代码没有多少,更多借助于硬件本身的测试驱动方法,Monitor负责汇总
  3. SocketCAN 的监控主要是在一个监控周期对它进行常规的 API 调用
  4. System 健康问题被当成一个 Resource 对待
  5. 读取 /proc/stat 计算 cpu 使用率
  6. 读取 /proc/meminfo 计算磁盘使用率
  7. 读取 /proc/diskstats 计算磁盘负载
  8. 通过 Boost::FileSystem 的 space() 方法计算磁盘空间状态
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-01-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 监控 ESD CAN
    • EsdCanMonitor
    • GpsMonitor
    • Socket CAN
    • ResouceMonitor
      • CheckDiskSpace
        • CheckCPUUsage
          • CheckMemoryUsage
            • CheckDiskLoads
            • 总结
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档