Apollo 应用与源码分析:Monitor监控 - Monitor_managerecurrent_runner分析

news2024/10/6 0:31:53

目录

monitor_manager 分析

结构分析

单例模式宏定义

描述现在的系统状态

HMI上显示的状态信息

仿真判断状态

判断是不是自动驾驶状态

日志缓存

当前node

所有monitor 的reader 管理map

开启一次监控

start frame分析

end frame分析

recurrent_runner 分析

结构分析

Tick 函数分析


monitor_manager 分析

结构分析

// Centralized monitor config and status manager.
class MonitorManager {
public:
void Init(const std::shared_ptr<apollo::cyber::Node>& node);

// Start and end a monitoring frame.
bool StartFrame(const double current_time);
void EndFrame();

// Getters.
const apollo::dreamview::HMIMode& GetHMIMode() const { return mode_config_; }
bool IsInAutonomousMode() const { return in_autonomous_driving_; }
SystemStatus* GetStatus() { return &status_; }
apollo::common::monitor::MonitorLogBuffer& LogBuffer() { return log_buffer_; }

// Cyber reader / writer creator.
template <class T>
std::shared_ptr<cyber::Reader<T>> CreateReader(const std::string& channel) {
    if (readers_.find(channel) == readers_.end()) {
        readers_.emplace(channel, node_->CreateReader<T>(channel));
    }
    return std::dynamic_pointer_cast<cyber::Reader<T>>(readers_[channel]);
}

template <class T>
std::shared_ptr<cyber::Writer<T>> CreateWriter(const std::string& channel) {
    return node_->CreateWriter<T>(channel);
}

private:
SystemStatus status_;

// Input statuses.
std::string current_mode_;
const apollo::dreamview::HMIConfig hmi_config_;
apollo::dreamview::HMIMode mode_config_;
bool in_autonomous_driving_ = false;
bool CheckAutonomousDriving(const double current_time);

apollo::common::monitor::MonitorLogBuffer log_buffer_;
std::shared_ptr<apollo::cyber::Node> node_;
std::unordered_map<std::string, std::shared_ptr<cyber::ReaderBase>> readers_;

DECLARE_SINGLETON(MonitorManager)
};
DECLARE_SINGLETON(MonitorManager)

单例模式宏定义

#define DECLARE_SINGLETON(classname)                                      \
 public:                                                                  \
  static classname *Instance(bool create_if_needed = true) {              \
    static classname *instance = nullptr;                                 \
    if (!instance && create_if_needed) {                                  \
      static std::once_flag flag;                                         \
      std::call_once(flag,                                                \
                     [&] { instance = new (std::nothrow) classname(); }); \
    }                                                                     \
    return instance;                                                      \
  }                                                                       \
                                                                          \
  static void CleanUp() {                                                 \
    auto instance = Instance(false);                                      \
    if (instance != nullptr) {                                            \
      CallShutdown(instance);                                             \
    }                                                                     \
  }                                                                       \
                                                                          \
 private:                                                                 \
  classname();                                                            \
  DISALLOW_COPY_AND_ASSIGN(classname)

描述现在的系统状态

SystemStatus status_

HMI上显示的状态信息

std::string current_mode_

仿真判断状态

const apollo::dreamview::HMIConfig hmi_config_;
apollo::dreamview::HMIMode mode_config_;

判断是不是自动驾驶状态

bool in_autonomous_driving_ = false;
bool CheckAutonomousDriving(const double current_time);

日志缓存

  apollo::common::monitor::MonitorLogBuffer log_buffer_;

当前node

std::shared_ptr<apollo::cyber::Node> node_;

所有monitor 的reader 管理map

 std::unordered_map<std::string, std::shared_ptr<cyber::ReaderBase>> readers_;

开启一次监控

bool StartFrame(const double current_time);
void EndFrame();

bool MonitorManager::StartFrame(const double current_time) {
  // Get latest HMIStatus.
  static auto hmi_status_reader =
      CreateReader<apollo::dreamview::HMIStatus>(FLAGS_hmi_status_topic);
  hmi_status_reader->Observe();
  const auto hmi_status = hmi_status_reader->GetLatestObserved();
  if (hmi_status == nullptr) {
    AERROR << "No HMIStatus was received.";
    return false;
  }

  if (current_mode_ != hmi_status->current_mode()) {
    // Mode changed, update configs and monitored.
    current_mode_ = hmi_status->current_mode();
    mode_config_ = HMIWorker::LoadMode(hmi_config_.modes().at(current_mode_));
    status_.clear_hmi_modules();
    for (const auto& iter : mode_config_.modules()) {
      status_.mutable_hmi_modules()->insert({iter.first, {}});
    }
    status_.clear_components();
    for (const auto& iter : mode_config_.monitored_components()) {
      status_.mutable_components()->insert({iter.first, {}});
    }
    status_.clear_other_components();
    for (const auto& iter : mode_config_.other_components()) {
      status_.mutable_other_components()->insert({iter.first, {}});
    }
  } else {
    // Mode not changed, clear component summary from the last frame.
    for (auto& iter : *status_.mutable_components()) {
      iter.second.clear_summary();
    }
  }

  in_autonomous_driving_ = CheckAutonomousDriving(current_time);
  return true;
}

void MonitorManager::EndFrame() {
  // Print and publish all monitor logs.
  log_buffer_.Publish();
}

start frame分析

1. 获取最近的HMI状态

        1.1. 如果获取不到就返回false

2. 如果当前的状态和上一次的状态(HMI状态)不同,就update

         2.1. status_ update 最新的状态

3. 如果当前的状态与上一次的状态(HMI状态)相同,就清除component summary

 // Mode not changed, clear component summary from the last frame.
    for (auto& iter : *status_.mutable_components()) {
      iter.second.clear_summary();
    }

end frame分析

把当前的监控过程中利用MonitorLogBuffrt::AddMonitorMsgItem 添加的日志信息打印并发布出去

发布topic: /apollo/monitor

// modules/common/monitor_log/monitor_log_buffer.cc
void MonitorLogBuffer::AddMonitorMsgItem(
    const MonitorMessageItem::LogLevel log_level, const std::string &msg) {
  level_ = log_level;
  monitor_msg_items_.push_back(std::make_pair(log_level, msg));
}
//modules/common/monitor_log/monitor_logger.cc
MonitorLogger::MonitorLogger() {
  const std::string node_name =
      absl::StrCat("monitor_logger", Time::Now().ToNanosecond());
  node_ = cyber::CreateNode(node_name);
  if (node_ != nullptr) {
    monitor_msg_writer_ =
        node_->CreateWriter<MonitorMessage>("/apollo/monitor");
  }
}

recurrent_runner 分析

结构分析

class RecurrentRunner {
 public:
  RecurrentRunner(const std::string &name, const double interval);
  virtual ~RecurrentRunner() = default;

  // Tick once, which may or may not execute the RunOnce() function, based on
  // the interval setting.
  void Tick(const double current_time);

  // Do the actual work.
  virtual void RunOnce(const double current_time) = 0;

 protected:
  std::string name_;
  unsigned int round_count_ = 0;

 private:
  double interval_;
  double next_round_ = 0;
};

从类的命名上可以看出,这个类是要负责重复工作的。

Tick 的含义是钟表滴答,可以代表周期性执行任务,上面也有注视写了,Tick 函数可能会执行RunOnce函数,但是也可能不会,执行的周期是以下面的interval_来规定的。

roundcount指的是执行了多少轮。

nextround指的是下次执行的时间。

RunOnce是一个纯虚函数,所以这个类是一个接口,并不可以直接new。

Tick 函数分析

void RecurrentRunner::Tick(const double current_time) {
  if (next_round_ <= current_time) {
    ++round_count_;
    AINFO_EVERY(100) << name_ << " is running round #" << round_count_;
    next_round_ = current_time + interval_;
    RunOnce(current_time);
  }
}

执行一次更新下一次要执行的时间,然后执行runOnce 函数,并把当前时间传入。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/37516.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机键盘用途及快捷键

用途&#xff1a; 电脑键盘上有那么多按键&#xff0c;到底都有什么作用呢&#xff1f; 几个重要的按键&#xff0c;一起来了解一下吧。 最上面一排&#xff1a; F1帮助 F2改名 F3搜索 F4地址 F5刷新 F6切换 F10菜单 1、键盘中间区域的所有输入按键。 一共是26个英文字母…

初次接触氛围系统架构,聊聊我这三个月的理解

本文主要介绍了作者对于氛围中心的业务理解。从氛围的概念出发&#xff0c;阐述了氛围系统的必要性&#xff0c;然后展示了配置端的数据写入、调用端的配置读取等氛围系统的架构细节&#xff0c;最后作者提出了一些对于氛围中心未来的想法和思考。概述▐ 氛围的概念氛围是能够…

V5.1.1,新版发布|软件安全大于一切

主要内容&#xff1a;本次版本除了常规的BUG修复&#xff0c;最重要的是对系统安全全面升级&#xff0c;加强了系统安全检测机制&#xff0c;更新了Thinkphp核心版本&#xff0c;强化了密码等安全。 本次新增了在线用户&#xff0c;支持在线用户下强制下线处理。 本次新增的超级…

java项目-第161期ssm弹幕视频网站系统_ssm毕业设计_计算机毕业设计

java项目-第161期ssm弹幕视频网站系统_ssm毕业设计_计算机毕业设计 【源码请到资源专栏下载】 今天分享的项目是《ssm弹幕视频网站》 该项目分为2个角色&#xff0c;管理员、用户。 用户可以浏览前台视频信息、商品信息&#xff0c;并且可以进行购买。 管理员角色拥有的权限最…

基于jquery 实现导航条高亮显示的两种方法

本篇文章是基于jquery实现导航菜单高亮显示&#xff0c;当点击不同导航菜单实现当前点击的菜单是高亮的&#xff0c;有需要的朋友可以关注下本文 实现原理&#xff1a;当选中当前元素时&#xff0c;给当前元素添加样式&#xff0c;同级元素移除样式。 点击不同的导航菜单实现…

基于SpringBoot的校园志愿者管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SpringBoot 前端&#xff1a;HTML、Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#…

Java23种设计模式之第三弹-工厂模式

说起工厂&#xff0c;我们第一反应是制作什么东西的吧~。在现实生活中&#xff0c;工厂 &#xff0c; 就是用于生成一些特定事物的厂商。 回到我们此处说的工厂模式上&#xff0c;什么是工厂模式呢 &#xff0c; 顾名思义&#xff0c;就是生成我们的对象的类就会称成为工厂。 …

机器学习模型与backtrader框架整合

原创文章第116篇&#xff0c;专注“个人成长与财富自由、世界运作的逻辑&#xff0c; AI量化投资”。 北京疫情似乎还没有到拐点&#xff0c;但这三天结束后应该会到来。 今天重点说说&#xff0c;机器学习模型整合到我们的回测框架中&#xff0c;并与backtrader连接起来回测…

【Python模块】logging 日志模块

当入门一门语言时&#xff0c;最简单最直观的打印日志信息方式就是使用 print() 函数了&#xff0c;而这毕竟是自己练习和测试才会这样做。当参与项目时一定会去使用日志模块实现日志信息的打印和记录&#xff0c;而 Python 提供了内置的日志模块 logging&#xff0c;有必要深入…

解决每次打开pycharm都特别慢的几个方法

Python编写时&#xff0c;通常都会用vscode和pycharm两个工具&#xff0c;使用过程中&#xff0c;发现每次打开pycharm都特别特别慢&#xff0c;有时候要等十来分钟。相信大家可能都有遇到一样的情况&#xff0c;所以分享我自己的解决方法给大家参考。 1&#xff0c;每次需要关…

[附源码]java毕业设计置地房屋租赁信息系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

嵌入式驱动初级-中断

文章目录前言一、Linux 中断 API 函数二、Linux 中断实现三、中断上半部与下半部四、下半部机制之tasklet ---- 基于软中断五、按键中断下半部机制之tasklet六、下半部机制之workqueue ----- 基于内核线程七、按键中断下半部机制之workqueue前言 记录嵌入式驱动学习笔记 一、Li…

一文带你深入理解【Java基础】· 枚举类

写在前面 Hello大家好&#xff0c; 我是【麟-小白】&#xff0c;一位软件工程专业的学生&#xff0c;喜好计算机知识。希望大家能够一起学习进步呀&#xff01;本人是一名在读大学生&#xff0c;专业水平有限&#xff0c;如发现错误或不足之处&#xff0c;请多多指正&#xff0…

Vision Transformer这两年

作者&#xff5c;Maximilian Schambach OneFlow编译 翻译&#xff5c;胡燕君、杨婷 在NLP领域取得巨大成功后&#xff0c;Transformer架构在计算机视觉方面的作用日渐凸显&#xff0c;成为越来越普遍的CV工具。自2020年10月Vision Transformer模型推出以来&#xff0c;人们开始…

《研究生学术与职业素养讲座》第七讲~第九讲作业答案

第七讲 八千里路云和月—2015年意大利米兰世博会中国馆设计 填空题&#xff08;1分&#xff09;单选题&#xff08;1分&#xff09;判断题&#xff08;1分&#xff09;多选题&#xff08;2分&#xff09;第八讲 从纳米研究看工程创新 填空题&#xff08;1分&#xff09;单…

干货 | 一条语句更新多个表

众所周知&#xff0c;多个服务器命中会减慢应用程序的速度。出于这个原因&#xff0c;开发人员致力于找尋使用最少的语句更新数据的最有效方法。事实证明&#xff0c;SQL UPDATE 语句确实支持使用以下语法设置多个表的字段&#xff1a; UPDATE table1, table2, ...SET column1…

2022-11-14 西安 activiti工作流(01)

语言确实有其局限性&#xff0c;但我相信:一件值得做的事情即使做的不怎么样也是值得的! 概念 1.流程审批以前的实现方式 在没有专门的工作流引擎之前&#xff0c;为了实现流程控制&#xff0c;通常的做法就是采用状态字段的值来跟踪流程的变化情况。通过状态字段的取值来决定…

【数据结构】二叉树优先级队列——堆

文章目录1. 树的概念及结构1.1 树的相关概念1.2 树的表示2. 二叉树的概念及其结构2.1 二叉树的概念2.2 特殊的二叉树2.3 二叉树的性质2.4 二叉树的存储结构3. 堆3.1 堆的概念及结构3.2 堆的实现3.2.1 堆的创建3.2.2 堆的插入3.2.3 堆的向上调整算法3.2.4 堆的删除3.2.5 堆的向下…

javaSE--数据类型(复习)

一、变量和类型 变量 指的是 程序运行时 的 可变的量&#xff0c;相当于开辟一块内存空间来保存一些数据 类型 则是 对 变量的种类 进行了 划分&#xff0c;不同的类型 的 变量 具有不同特性 我们所讨论的"变量"主要 和 我们的"内存"这样的硬件设备密切相关…

value_counts()与count()的简单介绍

文章目录一&#xff0c;value_counts()&#xff08;一&#xff09;用法(二)参数介绍二&#xff0c;count()一&#xff0c;value_counts() &#xff08;一&#xff09;用法 value_counts&#xff08;&#xff09;是针对某一列的数据中存在不同的值进行汇总计算 举例 data[dis…