• Apollo 应用与源码分析:Monitor监控-软件监控-channel时间延迟监控


     

    9d19bbdcc540b0d301bcadeed734fc5b.png

    目录

     

    代码

    分析

    主要结构

    判断逻辑

    备注


     

    代码

    1. class ChannelMonitor : public RecurrentRunner {
    2. public:
    3. explicit ChannelMonitor(
    4. const std::shared_ptr& latency_monitor);
    5. void RunOnce(const double current_time) override;
    6. private:
    7. static void UpdateStatus(
    8. const apollo::dreamview::ChannelMonitorConfig& config,
    9. ComponentStatus* status, const bool update_freq, const double freq);
    10. std::shared_ptr latency_monitor_;
    11. };
    12. void ChannelMonitor::RunOnce(const double current_time) {
    13. auto manager = MonitorManager::Instance();
    14. const auto& mode = manager->GetHMIMode();
    15. auto* components = manager->GetStatus()->mutable_components();
    16. for (const auto& iter : mode.monitored_components()) {
    17. const std::string& name = iter.first;
    18. const auto& config = iter.second;
    19. if (config.has_channel()) {
    20. double freq;
    21. const auto update_freq =
    22. latency_monitor_->GetFrequency(config.channel().name(), &freq);
    23. UpdateStatus(config.channel(),
    24. components->at(name).mutable_channel_status(), update_freq,
    25. freq);
    26. }
    27. }
    28. }

    分析

    主要结构

    runOnce 中不变的套路:

    1. 先从HMI mode 中获取所有配置的监控项目;
    2. 遍历监控项目,使用latency_monitor_->GetFrequency 获取channel的频率;
    3. 使用UpdateStatus 更新状态,生成报警

    判断逻辑

    1. void ChannelMonitor::UpdateStatus(
    2. const apollo::dreamview::ChannelMonitorConfig& config,
    3. ComponentStatus* status, const bool update_freq, const double freq) {
    4. status->clear_status();
    5. const auto reader_message_pair = GetReaderAndLatestMessage(config.name());
    6. const auto reader = reader_message_pair.first;
    7. const auto message = reader_message_pair.second;
    8. if (reader == nullptr) {
    9. SummaryMonitor::EscalateStatus(
    10. ComponentStatus::UNKNOWN,
    11. absl::StrCat(config.name(), " is not registered in ChannelMonitor."),
    12. status);
    13. return;
    14. }
    15. if (message == nullptr || message->ByteSize() == 0) {
    16. SummaryMonitor::EscalateStatus(
    17. ComponentStatus::FATAL,
    18. absl::StrCat("the message ", config.name(), " reseived is empty."),
    19. status);
    20. return;
    21. }
    22. // Check channel delay
    23. const double delay = reader->GetDelaySec();
    24. if (delay < 0 || delay > config.delay_fatal()) {
    25. SummaryMonitor::EscalateStatus(
    26. ComponentStatus::FATAL,
    27. absl::StrCat(config.name(), " delayed for ", delay, " seconds."),
    28. status);
    29. }
    30. // Check channel fields
    31. const std::string field_sepr = ".";
    32. if (message != nullptr) {
    33. for (const auto& field : config.mandatory_fields()) {
    34. if (!ValidateFields(*message, absl::StrSplit(field, field_sepr), 0)) {
    35. SummaryMonitor::EscalateStatus(
    36. ComponentStatus::ERROR,
    37. absl::StrCat(config.name(), " missing field ", field), status);
    38. }
    39. }
    40. }
    41. // Check channel frequency
    42. if (update_freq) {
    43. if (freq > config.max_frequency_allowed()) {
    44. SummaryMonitor::EscalateStatus(
    45. ComponentStatus::WARN,
    46. absl::StrCat(config.name(), " has frequency ", freq,
    47. " > max allowed ", config.max_frequency_allowed()),
    48. status);
    49. }
    50. if (freq < config.min_frequency_allowed()) {
    51. SummaryMonitor::EscalateStatus(
    52. ComponentStatus::WARN,
    53. absl::StrCat(config.name(), " has frequency ", freq,
    54. " < min allowed ", config.max_frequency_allowed()),
    55. status);
    56. }
    57. }
    58. SummaryMonitor::EscalateStatus(ComponentStatus::OK, "", status);
    59. }
    1. 通过channel 创建reader,获取最后一条msg;
    2. 如果reader 创建失败就把状态设置为unknow;
    3. 如果最后一帧消息是空,就把状态设置为FATAL;
    4. double delay = reader->GetDelaySec(); 获取延迟;如果延迟<0或者大于阈值就FATAL报警;
    5. 检查必要字段是否缺失,如果缺失就ERROR;
    6. 检查发送频率是否正常,如果不在阈值区间就报WARN;

    备注

    1. template <typename MessageT>
    2. double Reader::GetDelaySec() const {
    3. if (latest_recv_time_sec_ < 0) {
    4. return -1.0;
    5. }
    6. if (second_to_lastest_recv_time_sec_ < 0) {
    7. return Time::Now().ToSecond() - latest_recv_time_sec_;
    8. }
    9. return std::max((Time::Now().ToSecond() - latest_recv_time_sec_),
    10. (latest_recv_time_sec_ - second_to_lastest_recv_time_sec_));
    11. }

    Reader 获取时间延迟的方法就是通过订阅接收到数据的然后做上一帧时间的差值

     

     

  • 相关阅读:
    Deep Learning for Geophysics综述阅读(未完)
    EtherCAT主站SOEM -- 6 -- SOEM之ethercatcoe.h/c(ethercateoe/foe/soe)文件解析
    Vue模板语法
    G2024-04-24 开源项目日报 Top10
    MySQL——锁
    Spring循环依赖
    【原创】xenomai UDD介绍与UDD用户态驱动示例
    Linux head/tail
    极速视觉:揭秘YOLO如何革新目标检测速度
    SaaS案例分享:成功构建销售渠道的实战经验
  • 原文地址:https://blog.csdn.net/qq_32378713/article/details/128095090