Apollo application and source code analysis: Monitor monitoring - Monitor_manage&recurrent_runner analysis

Table of contents

monitor_manager analysis

structural analysis

Singleton pattern macro definition

Describe the current state of the system

Status information displayed on the HMI

Simulation Judgment Status

Judging whether it is an automatic driving state

log cache

current node

Reader management map for all monitors

Start a monitoring

start frame analysis

end frame analysis

recurrent_runner analysis

structural analysis

Tick ​​function analysis


monitor_manager analysis

structural analysis

// 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)

Singleton pattern macro definition

#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)

Describe the current state of the system

SystemStatus status_

Status information displayed on the HMI

std::string current_mode_

Simulation Judgment Status

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

Judging whether it is an automatic driving state

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

log cache

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

current node

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

Reader management map for all monitors

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

Start a monitoring

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 analysis

1. Get the latest HMI status

        1.1. Return false if not available

2. If the current state is different from the last state (HMI state), update

         2.1. status_ update latest status

3. If the current state is the same as the last state (HMI state), clear the component summary

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

end frame analysis

Print and publish the log information added by MonitorLogBuffrt::AddMonitorMsgItem in the current monitoring process

Publish 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 analysis

structural analysis

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;
};

It can be seen from the naming of the class that this class is responsible for repeated work.

The meaning of Tick is the ticking of the clock, which can represent the periodic execution of tasks. It has also been written above. The Tick function may execute the RunOnce function, but it may not. The execution cycle is specified by the following interval_.

The round count refers to how many rounds were executed.

next round refers to the next execution time.

RunOnce is a pure virtual function, so this class is an interface and cannot be directly new.

Tick ​​function analysis

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);
  }
}

Execute once to update the time to be executed next time, then execute the runOnce function and pass in the current time.

Guess you like

Origin blog.csdn.net/qq_32378713/article/details/128052990