Apollo 11.0
自动驾驶开放平台
latency_statistic_component.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2023 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
17
18#include <limits>
19
20#include "modules/common_msgs/control_msgs/control_cmd.pb.h"
21#include "modules/common_msgs/perception_msgs/perception_obstacle.pb.h"
22#include "modules/common_msgs/planning_msgs/planning.pb.h"
23#include "modules/common_msgs/prediction_msgs/prediction_obstacle.pb.h"
24#include "modules/common_msgs/sensor_msgs/pointcloud.pb.h"
25
29
30namespace apollo {
31namespace latency_statistic {
32
33// the max sample number for calculating latency
34constexpr uint32_t MAX_SAMPLE_SIZE = 50;
35// the expired time set to 3 seconds
36constexpr uint32_t EXPIRED_NANOSECONDS = 3000000000;
37constexpr uint32_t NANO_TO_MILLI = 1000000;
38
40 // hook: Apollo License Verification: v_apollo_park
41 // Init Channel Defines
42 compensator_topic = FLAGS_compensator_topic;
43 perception_topic = FLAGS_perception_obstacle_topic;
44 prediction_topic = FLAGS_prediction_topic;
45 planning_topic = FLAGS_planning_trajectory_topic;
46 control_topic = FLAGS_control_command_topic;
47 // create readers
48 CreateReaders();
49 // create metric writer
50 metric_writer_ = node_->CreateWriter<LatencyMetrics>(FLAGS_latency_statistic_topic);
51 return true;
52}
53
55 auto metrics = std::make_shared<LatencyMetrics>();
56 apollo::common::util::FillHeader(node_->Name(), metrics.get());
57
58 Result result;
59 // get result from metric data
60 std::lock_guard<std::mutex> guard(lock_);
61 for (auto it = latency_map_.begin(); it != latency_map_.end();) {
62 auto& lidar_timestamp = it->first;
63 if (latest_stamp_ - lidar_timestamp > EXPIRED_NANOSECONDS || latency_map_.size() > MAX_SAMPLE_SIZE) {
64 it = latency_map_.erase(it);
65 continue;
66 }
67 auto& metric = it->second;
68 FillResult(lidar_timestamp, metric, &result);
69 ++it;
70 }
71 // calculate latency
72 CalculateLatency(result, metrics);
73 // write latency metrics
74 metric_writer_->Write(metrics);
75 return true;
76}
77
78void LatencyStatisticComponent::FillResult(const uint64_t& lidar_timestamp, const Metric& metric, Result* result) {
79 AINFO << "metric compensator: " << metric.compensator << ", lidar_timestamp: " << lidar_timestamp;
80 if (metric.compensator > 0) {
81 result->compensator_chain_list.push_back((metric.compensator - lidar_timestamp) / NANO_TO_MILLI);
82 result->compensator_proc_list.push_back((metric.compensator - lidar_timestamp) / NANO_TO_MILLI);
83 }
84 if (metric.perception > 0) {
85 result->perception_chain_list.push_back((metric.perception - lidar_timestamp) / NANO_TO_MILLI);
86 if (metric.compensator > 0) {
87 result->perception_proc_list.push_back((metric.perception - metric.compensator) / NANO_TO_MILLI);
88 }
89 }
90 if (metric.prediction > 0) {
91 result->prediction_chain_list.push_back((metric.prediction - lidar_timestamp) / NANO_TO_MILLI);
92 if (metric.perception > 0) {
93 result->prediction_proc_list.push_back((metric.prediction - metric.perception) / NANO_TO_MILLI);
94 }
95 }
96 if (metric.planning > 0) {
97 result->planning_chain_list.push_back((metric.planning - lidar_timestamp) / NANO_TO_MILLI);
98 if (metric.prediction > 0) {
99 result->planning_proc_list.push_back((metric.planning - metric.prediction) / NANO_TO_MILLI);
100 }
101 }
102 if (metric.control > 0) {
103 result->control_chain_list.push_back((metric.control - lidar_timestamp) / NANO_TO_MILLI);
104 if (metric.planning > 0) {
105 result->control_proc_list.push_back((metric.control - metric.planning) / NANO_TO_MILLI);
106 }
107 }
108}
109
110void LatencyStatisticComponent::CalculateLatency(const Result& result, std::shared_ptr<LatencyMetrics> metrics) {
111 // lidar compensator latency
112 auto lidar_compensator = metrics->mutable_lidar_compensator();
113 GetLatencyMetric(result.compensator_chain_list, lidar_compensator->mutable_chain_ms());
114 GetLatencyMetric(result.compensator_proc_list, lidar_compensator->mutable_proc_ms());
115 // perception latency
116 auto perception = metrics->mutable_perception();
117 GetLatencyMetric(result.perception_chain_list, perception->mutable_chain_ms());
118 GetLatencyMetric(result.perception_proc_list, perception->mutable_proc_ms());
119 // prediction latency
120 auto prediction = metrics->mutable_prediction();
121 GetLatencyMetric(result.prediction_chain_list, prediction->mutable_chain_ms());
122 GetLatencyMetric(result.prediction_proc_list, prediction->mutable_proc_ms());
123 // planning latency
124 auto planning = metrics->mutable_planning();
125 GetLatencyMetric(result.planning_chain_list, planning->mutable_chain_ms());
126 GetLatencyMetric(result.planning_proc_list, planning->mutable_proc_ms());
127 // control latency
128 auto control = metrics->mutable_control();
129 GetLatencyMetric(result.control_chain_list, control->mutable_chain_ms());
130 GetLatencyMetric(result.control_proc_list, control->mutable_proc_ms());
131}
132
133void LatencyStatisticComponent::GetLatencyMetric(const std::vector<uint64_t>& items, LatencyMetrics_Metric* metric) {
134 if (items.empty()) {
135 return;
136 }
137 metric->set_sample_size(items.size());
138
139 uint64_t min = std::numeric_limits<uint64_t>::max();
140 uint64_t max = 0;
141 uint64_t sum = 0;
142 for (auto& item : items) {
143 if (item > max)
144 max = item;
145 if (item < min)
146 min = item;
147 sum += item;
148 }
149 uint64_t avg = sum / items.size();
150 metric->set_min(min);
151 metric->set_max(max);
152 metric->set_avg(avg);
153}
154
155void LatencyStatisticComponent::CreateReaders() {
156 // lidar compensator
157 CreateReader<apollo::drivers::PointCloud>(compensator_topic);
158 // perception
159 CreateReader<apollo::perception::PerceptionObstacles>(perception_topic);
160 // prediction
161 CreateReader<apollo::prediction::PredictionObstacles>(prediction_topic);
162 // planing
163 CreateReader<apollo::planning::ADCTrajectory>(planning_topic);
164 // control
165 CreateReader<apollo::control::ControlCommand>(control_topic);
166}
167
168template <class T>
169void LatencyStatisticComponent::CreateReader(const std::string& channel_name) {
170 node_->CreateReader<T>(channel_name, [this, &channel_name](const std::shared_ptr<T>& msg) {
171 if (!msg->has_header() || !msg->header().has_timestamp_sec() || !msg->header().has_lidar_timestamp()
172 || msg->header().lidar_timestamp() == 0) {
173 return;
174 }
175 auto lidar_timestamp = msg->header().lidar_timestamp();
176 uint64_t timestamp = cyber::Time(msg->header().timestamp_sec()).ToNanosecond();
177 std::lock_guard<std::mutex> guard(lock_);
178 if (latency_map_.find(lidar_timestamp) == latency_map_.end()) {
179 latency_map_.emplace(lidar_timestamp, Metric());
180 }
181 auto& metric = latency_map_.at(lidar_timestamp);
182 if (channel_name == compensator_topic) {
183 metric.compensator = timestamp;
184 } else if (channel_name == perception_topic) {
185 metric.perception = timestamp;
186 } else if (channel_name == prediction_topic) {
187 metric.prediction = timestamp;
188 } else if (channel_name == planning_topic) {
189 metric.planning = timestamp;
190 } else if (channel_name == control_topic) {
191 metric.control = timestamp;
192 }
193 latest_stamp_ = timestamp;
194 });
195}
196
197} // namespace latency_statistic
198} // namespace apollo
std::shared_ptr< Node > node_
bool Proc() override
The Proc logic of the component, which called by the CyberRT frame.
Planning module main class.
#define AINFO
Definition log.h:42
Some string util functions.
class register implement
Definition arena_queue.h:37