24#include "absl/strings/str_cat.h"
25#include "absl/strings/str_split.h"
26#include "google/protobuf/compiler/parser.h"
27#include "google/protobuf/descriptor.h"
28#include "google/protobuf/dynamic_message.h"
30#include "modules/common_msgs/chassis_msgs/chassis_detail.pb.h"
31#include "modules/common/latency_recorder/proto/latency_record.pb.h"
32#include "modules/common_msgs/control_msgs/control_cmd.pb.h"
33#include "modules/common_msgs/sensor_msgs/conti_radar.pb.h"
34#include "modules/common_msgs/sensor_msgs/pointcloud.pb.h"
35#include "modules/common_msgs/localization_msgs/pose.pb.h"
36#include "modules/common_msgs/planning_msgs/navigation.pb.h"
37#include "modules/common_msgs/perception_msgs/perception_obstacle.pb.h"
38#include "modules/common_msgs/planning_msgs/planning.pb.h"
39#include "modules/common_msgs/prediction_msgs/prediction_obstacle.pb.h"
49 "Name of the channel monitor.");
52 "Channel monitor checking interval in seconds.");
58using ReaderAndMessagePair =
59 std::pair<std::shared_ptr<cyber::ReaderBase>,
60 std::shared_ptr<google::protobuf::Message>>;
63ReaderAndMessagePair CreateReaderAndLatestsMessage(
const std::string& channel) {
64 const auto reader = MonitorManager::Instance()->CreateReader<T>(channel);
66 const auto message = reader->GetLatestObserved();
67 return {reader, message};
72ReaderAndMessagePair GetReaderAndLatestMessage(
const std::string& channel) {
73 static const auto channel_function_map =
74 std::unordered_map<std::string, std::function<ReaderAndMessagePair(
75 const std::string& channel)>>{
76 {FLAGS_control_command_topic,
77 &CreateReaderAndLatestsMessage<control::ControlCommand>},
78 {FLAGS_localization_topic,
79 &CreateReaderAndLatestsMessage<localization::LocalizationEstimate>},
80 {FLAGS_perception_obstacle_topic,
81 &CreateReaderAndLatestsMessage<perception::PerceptionObstacles>},
82 {FLAGS_prediction_topic,
83 &CreateReaderAndLatestsMessage<prediction::PredictionObstacles>},
84 {FLAGS_planning_trajectory_topic,
85 &CreateReaderAndLatestsMessage<planning::ADCTrajectory>},
86 {FLAGS_conti_radar_topic,
87 &CreateReaderAndLatestsMessage<drivers::ContiRadar>},
88 {FLAGS_relative_map_topic,
89 &CreateReaderAndLatestsMessage<relative_map::MapMsg>},
90 {FLAGS_pointcloud_topic,
91 &CreateReaderAndLatestsMessage<drivers::PointCloud>},
92 {FLAGS_pointcloud_16_topic,
93 &CreateReaderAndLatestsMessage<drivers::PointCloud>},
94 {FLAGS_pointcloud_16_raw_topic,
95 &CreateReaderAndLatestsMessage<drivers::PointCloud>},
96 {FLAGS_pointcloud_128_topic,
97 &CreateReaderAndLatestsMessage<drivers::PointCloud>},
98 {FLAGS_pointcloud_16_front_up_topic,
99 &CreateReaderAndLatestsMessage<drivers::PointCloud>},
100 {FLAGS_chassis_detail_topic,
101 &CreateReaderAndLatestsMessage<canbus::ChassisDetail>},
102 {FLAGS_pointcloud_hesai_40p_topic,
103 &CreateReaderAndLatestsMessage<drivers::PointCloud>}
107 auto entry = channel_function_map.find(channel);
108 if (entry != channel_function_map.end()) {
109 return (entry->second)(channel);
112 AERROR <<
"Channel is not handled by ChannelMonitor: " << channel;
113 return {
nullptr,
nullptr};
116bool ValidateFields(
const google::protobuf::Message& message,
117 const std::vector<std::string>& fields,
118 const size_t field_step) {
119 if (field_step >= fields.size()) {
122 const auto* desc = message.GetDescriptor();
123 const auto* refl = message.GetReflection();
124 const auto field_count = desc->field_count();
125 for (
int field_idx = 0; field_idx < field_count; ++field_idx) {
126 const auto* field_desc = desc->field(field_idx);
127 if (field_desc->name() == fields[field_step]) {
128 if (field_desc->is_repeated()) {
130 const auto size = refl->FieldSize(message, field_desc);
131 return size > 0 && field_step == fields.size() - 1;
133 if (field_desc->type() !=
134 google::protobuf::FieldDescriptor::TYPE_MESSAGE) {
135 return refl->HasField(message, field_desc) &&
136 field_step == fields.size() - 1;
138 return ValidateFields(refl->GetMessage(message, field_desc), fields,
148 const std::shared_ptr<LatencyMonitor>& latency_monitor)
150 FLAGS_channel_monitor_interval),
151 latency_monitor_(latency_monitor) {}
154 auto manager = MonitorManager::Instance();
155 const auto& mode = manager->GetHMIMode();
156 auto* components = manager->GetStatus()->mutable_components();
157 for (
const auto& iter : mode.monitored_components()) {
158 const std::string& name = iter.first;
159 const auto& config = iter.second;
160 if (config.has_channel()) {
162 const auto update_freq =
163 latency_monitor_->GetFrequency(config.channel().name(), &freq);
164 UpdateStatus(config.channel(),
165 components->at(name).mutable_channel_status(), update_freq,
171void ChannelMonitor::UpdateStatus(
173 ComponentStatus* status,
const bool update_freq,
const double freq) {
174 status->clear_status();
176 const auto reader_message_pair = GetReaderAndLatestMessage(config.
name());
177 const auto reader = reader_message_pair.first;
178 const auto message = reader_message_pair.second;
180 if (reader ==
nullptr) {
182 ComponentStatus::UNKNOWN,
183 absl::StrCat(config.
name(),
" is not registered in ChannelMonitor."),
188 if (message ==
nullptr || message->ByteSize() == 0) {
190 ComponentStatus::FATAL,
191 absl::StrCat(
"the message ", config.
name(),
" reseived is empty."),
197 const double delay = reader->GetDelaySec();
200 ComponentStatus::FATAL,
201 absl::StrCat(config.
name(),
" delayed for ", delay,
" seconds."),
206 const std::string field_sepr =
".";
207 if (message !=
nullptr) {
208 for (
const auto& field : config.mandatory_fields()) {
209 if (!ValidateFields(*message, absl::StrSplit(field, field_sepr), 0)) {
211 ComponentStatus::ERROR,
212 absl::StrCat(config.
name(),
" missing field ", field), status);
221 ComponentStatus::WARN,
222 absl::StrCat(config.
name(),
" has frequency ", freq,
228 ComponentStatus::WARN,
229 absl::StrCat(config.
name(),
" has frequency ", freq,
DEFINE_string(channel_monitor_name, "ChannelMonitor", "Name of the channel monitor.")
DEFINE_double(channel_monitor_interval, 5, "Channel monitor checking interval in seconds.")
void RunOnce(const double current_time) override
ChannelMonitor(const std::shared_ptr< LatencyMonitor > &latency_monitor)
static void EscalateStatus(const ComponentStatus::Status new_status, const std::string &message, ComponentStatus *current_status)
optional double min_frequency_allowed
optional double delay_fatal
optional double max_frequency_allowed