Apollo application and source code analysis: Monitor monitoring-software monitoring-channel time delay monitoring

 

9d19bbdcc540b0d301bcadeed734fc5b.png

Table of contents

 

the code

analyze

The main structure

judgment logic

Remark


 

the code

class ChannelMonitor : public RecurrentRunner {
 public:
  explicit ChannelMonitor(
      const std::shared_ptr<LatencyMonitor>& latency_monitor);
  void RunOnce(const double current_time) override;

 private:
  static void UpdateStatus(
      const apollo::dreamview::ChannelMonitorConfig& config,
      ComponentStatus* status, const bool update_freq, const double freq);
  std::shared_ptr<LatencyMonitor> latency_monitor_;
};

void ChannelMonitor::RunOnce(const double current_time) {
  auto manager = MonitorManager::Instance();
  const auto& mode = manager->GetHMIMode();
  auto* components = manager->GetStatus()->mutable_components();
  for (const auto& iter : mode.monitored_components()) {
    const std::string& name = iter.first;
    const auto& config = iter.second;
    if (config.has_channel()) {
      double freq;
      const auto update_freq =
          latency_monitor_->GetFrequency(config.channel().name(), &freq);
      UpdateStatus(config.channel(),
                   components->at(name).mutable_channel_status(), update_freq,
                   freq);
    }
  }
}

analyze

The main structure

The same routine in runOnce:

  1. First obtain all configured monitoring items from the HMI mode;
  2. Traversing the monitoring items, use latency_monitor_->GetFrequency to get the frequency of the channel;
  3. Use UpdateStatus to update status, generate alarm

judgment logic

void ChannelMonitor::UpdateStatus(
    const apollo::dreamview::ChannelMonitorConfig& config,
    ComponentStatus* status, const bool update_freq, const double freq) {
  status->clear_status();

  const auto reader_message_pair = GetReaderAndLatestMessage(config.name());
  const auto reader = reader_message_pair.first;
  const auto message = reader_message_pair.second;

  if (reader == nullptr) {
    SummaryMonitor::EscalateStatus(
        ComponentStatus::UNKNOWN,
        absl::StrCat(config.name(), " is not registered in ChannelMonitor."),
        status);
    return;
  }

  if (message == nullptr || message->ByteSize() == 0) {
    SummaryMonitor::EscalateStatus(
        ComponentStatus::FATAL,
        absl::StrCat("the message ", config.name(), " reseived is empty."),
        status);
    return;
  }

  // Check channel delay
  const double delay = reader->GetDelaySec();
  if (delay < 0 || delay > config.delay_fatal()) {
    SummaryMonitor::EscalateStatus(
        ComponentStatus::FATAL,
        absl::StrCat(config.name(), " delayed for ", delay, " seconds."),
        status);
  }

  // Check channel fields
  const std::string field_sepr = ".";
  if (message != nullptr) {
    for (const auto& field : config.mandatory_fields()) {
      if (!ValidateFields(*message, absl::StrSplit(field, field_sepr), 0)) {
        SummaryMonitor::EscalateStatus(
            ComponentStatus::ERROR,
            absl::StrCat(config.name(), " missing field ", field), status);
      }
    }
  }

  // Check channel frequency
  if (update_freq) {
    if (freq > config.max_frequency_allowed()) {
      SummaryMonitor::EscalateStatus(
          ComponentStatus::WARN,
          absl::StrCat(config.name(), " has frequency ", freq,
                       " > max allowed ", config.max_frequency_allowed()),
          status);
    }
    if (freq < config.min_frequency_allowed()) {
      SummaryMonitor::EscalateStatus(
          ComponentStatus::WARN,
          absl::StrCat(config.name(), " has frequency ", freq,
                       " < min allowed ", config.max_frequency_allowed()),
          status);
    }
  }

  SummaryMonitor::EscalateStatus(ComponentStatus::OK, "", status);
}
  1. Create a reader through the channel to get the last msg;
  2. If the reader fails to be created, set the state to unknown;
  3. If the last frame message is empty, set the status to FATAL;
  4. double delay = reader->GetDelaySec(); Get the delay; if the delay is <0 or greater than the threshold, FATAL alarms;
  5. Check whether the required fields are missing, and ERROR if missing;
  6. Check whether the sending frequency is normal, and report WARN if it is not within the threshold range;

Remark

template <typename MessageT>
double Reader<MessageT>::GetDelaySec() const {
  if (latest_recv_time_sec_ < 0) {
    return -1.0;
  }
  if (second_to_lastest_recv_time_sec_ < 0) {
    return Time::Now().ToSecond() - latest_recv_time_sec_;
  }
  return std::max((Time::Now().ToSecond() - latest_recv_time_sec_),
                  (latest_recv_time_sec_ - second_to_lastest_recv_time_sec_));
}

The way for the Reader to obtain the time delay is to subscribe to the received data and then make the difference of the previous frame time

 

 

Guess you like

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