Apollo:Monitor模块如何监控通信中 channel 的时延?

上一篇文章分析了 Apollo 框架中 Monitor 模块如何监控硬件,这篇文章继续分析 Monitor 是如何监控软件的

受监控的内容

在这里插入图片描述
上图是之前的文章总结的,可以看到软件监控有 8 类对象:

  • Channel Monitor 数据通信频道监控
  • Functional Safety Monitor 功能安全监控
  • Latency Monitor 时延监控
  • Localization Monitor 定位监控
  • Module Monitor 模块监控
  • Process Monitor 监控
  • Recorder Monitor 数据记录监控
  • Summary Monitor 监控状态汇总

ChannelMonitor

Channel 是 CyberRT 中的通信渠道,它的监控是配合 LatencyMonitor 一起使用的
在这里插入图片描述

RunOnce() :

  • 从hmi中获取要被监控的channel
  • 从latency_monitor_查询channel的频率
  • 通过 update_freq 和 freq 更新channel的时延状态
    在这里插入图片描述
    所以,关键是获取 update_freq 和 freq 两个参数的赋值过程。
    在这里插入图片描述
    如果 LatencyMonitor 在自身查询到了相应 channel 的频率,则赋值给 freq,然后返回 true,否则返回 false。

有了这两个参数后,后面的逻辑判断就交给了 UpdateStatus()。

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

  • 通过 channel 的名字获取相应的 Reader 和最后一条 msg
  • 判断是否有 Reader,如果没有提示这个channel 没有注册,并返回
  • 通过 reader 判断时延,如果小于0或者大于则设置状态为 FATAL
  • 通过判断 msg 相应的 field 内容是否有缺失,如果有则设置为状态为 ERROR
  • 过判断 freq 的值是否在合理的最小与最大范围内,如果不是则设置状态为 WARN
  • 一切正常则判断为 OK

因为 SummaryMonitor 的评估提升状态时,不同的状态是为权重的,并且可以向下覆盖,比如FATAL 可以覆盖小于它的其它状态,ERROR 不能覆盖 FATAL 但能覆盖 WARN 和 OK 、UNKOWN。

到这里 Channel 如何被监控大的逻辑就弄清楚了,但还有 2 个小细节需要弄明白。

  • channel 配套的 Reader 和最后一条 msg
  • LatencyMonitor 工作流程

GetReaderAndLatestMessage

在这里插入图片描述
通过MonitorManager去创建不同的Reader,然后开始观测,并获取这个channel最后一次消息,然后保存下来病返回。

主要是通过配置变量信息决定是否创建想要的MonitorManager。这些变量有:

       {FLAGS_control_command_topic,
          {FLAGS_localization_topic,
          {FLAGS_perception_obstacle_topic,
          {FLAGS_prediction_topic,
         ......

包含了感知数据、定位、预测、规划、控制 topic 相关。

LatencyMonitor

ChannelMonitor 内部要借助 LatencyMonitor 提供的数据做一些判断,那么LatencyMonitor是如何产生实验数据呢?

LatencyMonitor 也是周期性执行任务的模块,不过相比其它的 Monitor,它额外实现了 3 个方法:

public:
	GetFrequency()  
private:
	PublishLatencyReport()
	AggregateLatency()

可以看到,它内部会聚合各种时延,然后会定期发布时延报告。并且有一个服务类的API供其它类进行频率查询。

DEFINE_double(latency_monitor_interval, 1.5,
              "Latency report interval in seconds.");

DEFINE_double(latency_report_interval, 15.0,
              "Latency report interval in seconds.");

DEFINE_int32(latency_reader_capacity, 30,
             "The max message numbers in latency reader queue.");

监控时延的周期是每 1.5s 一次,时延报告发布周期是每15s一次,时延相关的reader队列容量是30。

LatencyMonitor::RunOnce

在这里插入图片描述
可以看到,它创建了一个Reader用来监控 latency recording topic,其数据类型有相应的 proto 文件定义。

在这里插入图片描述
LatencyRecordMap包含:

  • 消息头 header
  • 模块名字
  • LatencyRecord 数组
    在这里插入图片描述

我们先看 LatencyRecord 它里面有 3 条信息:

  • 开始时间 begin_time
  • 结束时间 end_time
  • 信息的 id

UpdateStat

LatencyMonitor::RunOnce中,会 UpdateStat(*it);

在这里插入图片描述

其实现如下

在这里插入图片描述
主要做了两件事:

  • 保存每个msg的耗时信息到 track_map_
  • 更新 freq_map 中模块的频率信息

我们重点关注第 2 个逻辑,也是前面内容分析到的 channelmonitor 会主动来查询 freqmap 中的值。

这个逻辑就是一个 LatencyRecordMap 中有一组 LatencyRecord,获取第一条记录中的开始时间,获取最后一条的结束时间。

如果结束时间大于开始时间,表明通信没有紊乱,频率值由下面公式计算:

freq = size/durantion

比如总共有 5 条记录,5 条记录总共耗时 10s。那么频率就是 5/10 = 0.5也就是1/2,代表什么呢?代表的是 1s 内只能传0.5 条信息。

定期发布时延报告

RunOnce 运行时会根据传入的 currenttime 和 flush_time_之差与定期报告的时长作比较,如果大于后者则需要对外发布时延信息。

在这里插入图片描述
PublishLatencyReport内容如下:

在这里插入图片描述
在发布时延报告前,先要内部聚合一下信息,然后通过创建的 LatencyReport writer 发送出去。

主要是聚合模块的时延和 E2E 的时延。

E2E 是什么呢?是从点云信息到各个模块输出的时间,也就是端到端时间。

这里有个重要的变量kE2EStartPoint 。

它是什么呢?其实是一条字符串,它被赋值为FLAGS_pointcloud_topic。也就是:
在这里插入图片描述
E2E Latency 的逻辑:

  • 记录第一条点云数据的开始时间
  • 依次记录那些不是点云数据的记录的开始时间,计算它们之间的差值,就成了这一个测试周期的 E2E 时延。

总结

  • Channel监控时主要是监控注册过的channel,通过判断它的时延、内容、频率形成最终的状态报告
  • Latency也需要读取相关的topic,通过根据不同的topic时间信息产生模块时延和端到端时延。
  • Channel 和 Latency 的运行基于依靠于 CyberRT 的通信,所以,也必须保证 CyberRT 的 Channel 通信机制足够可靠,不然会产生误差。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值