Apollo 10.0
自动驾驶开放平台
preprocessor_submodule.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2019 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 *****************************************************************************/
16
22
23#include <string>
24
25#include "cyber/time/clock.h"
30
31namespace apollo {
32namespace control {
33
41
43 : monitor_logger_buffer_(common::monitor::MonitorMessageItem::CONTROL) {}
44
46
47std::string PreprocessorSubmodule::Name() const {
48 return FLAGS_preprocessor_submodule_name;
49}
50
52 injector_ = std::make_shared<DependencyInjector>();
53
54 // Preprocessor writer
55 preprocessor_writer_ =
56 node_->CreateWriter<Preprocessor>(FLAGS_control_preprocessor_topic);
57
58 ACHECK(preprocessor_writer_ != nullptr);
59 return true;
60}
61
62bool PreprocessorSubmodule::Proc(const std::shared_ptr<LocalView> &local_view) {
63 ADEBUG << "Preprocessor started ....";
64 const auto start_time = Clock::Now();
65
66 Preprocessor control_preprocessor;
67 // handling estop
68 auto *preprocessor_status =
69 control_preprocessor.mutable_header()->mutable_status();
70
71 control_preprocessor.mutable_local_view()->CopyFrom(*local_view);
72
73 Status status = ProducePreprocessorStatus(&control_preprocessor);
74 AERROR_IF(!status.ok()) << "Failed to produce control preprocessor:"
75 << status.error_message();
76
77 if (status.ok() && !estop_) {
78 preprocessor_status->set_error_code(ErrorCode::OK);
79 } else {
80 estop_ = true;
81 preprocessor_status->set_error_code(status.code());
82 preprocessor_status->set_msg(status.error_message());
83 }
84
85 if (control_preprocessor.local_view().has_pad_msg()) {
86 const auto &pad_message = control_preprocessor.local_view().pad_msg();
87 if (pad_message.action() == DrivingAction::RESET) {
88 AINFO << "Control received RESET action!";
89 estop_ = false;
90 preprocessor_status->set_error_code(ErrorCode::OK);
91 preprocessor_status->set_msg("");
92 }
93 control_preprocessor.set_received_pad_msg(true);
94 }
95
96 control_preprocessor.mutable_header()->set_lidar_timestamp(
97 local_view->header().lidar_timestamp());
98 control_preprocessor.mutable_header()->set_camera_timestamp(
99 local_view->trajectory().header().camera_timestamp());
100 control_preprocessor.mutable_header()->set_radar_timestamp(
101 local_view->trajectory().header().radar_timestamp());
102 common::util::FillHeader(Name(), &control_preprocessor);
103
104 const auto end_time = Clock::Now();
105
106 static apollo::common::LatencyRecorder latency_recorder(
107 FLAGS_control_preprocessor_topic);
108 latency_recorder.AppendLatencyRecord(
109 control_preprocessor.header().lidar_timestamp(), start_time, end_time);
110
111 preprocessor_writer_->Write(control_preprocessor);
112 ADEBUG << "Preprocessor finished.";
113
114 return true;
115}
116
117Status PreprocessorSubmodule::ProducePreprocessorStatus(
118 Preprocessor *control_preprocessor) {
119 // TODO(SJiang): rename this function since local view got changed in this
120 // function.
121 Status status = CheckInput(control_preprocessor->mutable_local_view());
122
123 if (!status.ok()) {
124 AERROR_EVERY(100) << "Control input data failed: "
125 << status.error_message();
126 auto mutable_engage_advice = control_preprocessor->mutable_engage_advice();
127 mutable_engage_advice->set_advice(
129 mutable_engage_advice->set_reason(status.error_message());
130 // skip checking time stamp when failed input check
131 return status;
132 }
133
134 Status status_ts = CheckTimestamp(control_preprocessor->local_view());
135
136 if (!status_ts.ok()) {
137 AERROR << "Input messages timeout";
138 status = status_ts;
139 if (control_preprocessor->local_view().chassis().driving_mode() !=
141 control_preprocessor->mutable_engage_advice()->set_advice(
143 control_preprocessor->mutable_engage_advice()->set_reason(
144 status.error_message());
145 }
146 return status;
147 }
148 control_preprocessor->mutable_engage_advice()->set_advice(
150
151 estop_ =
152 FLAGS_enable_persistent_estop
153 ? estop_ || control_preprocessor->local_view()
154 .trajectory()
155 .estop()
156 .is_estop()
157 : control_preprocessor->local_view().trajectory().estop().is_estop();
158
159 if (control_preprocessor->local_view().trajectory().estop().is_estop()) {
160 return Status(
161 ErrorCode::CONTROL_ESTOP_ERROR,
162 absl::StrCat(
163 "estop from planning : ",
164 control_preprocessor->local_view().trajectory().estop().reason()));
165 }
166
167 if (FLAGS_enable_gear_drive_negative_speed_protection) {
168 const double kEpsilon = 0.001;
169 auto first_trajectory_point =
170 control_preprocessor->local_view().trajectory().trajectory_point(0);
171 if (control_preprocessor->local_view().chassis().gear_location() ==
173 first_trajectory_point.v() < -1 * kEpsilon) {
174 return Status(
175 ErrorCode::CONTROL_ESTOP_ERROR,
176 absl::StrCat(
177 "estop for empty planning trajectory, planning headers: ",
178 control_preprocessor->local_view()
179 .trajectory()
180 .header()
181 .ShortDebugString()));
182 }
183 }
184
185 auto input_debug = control_preprocessor->mutable_input_debug();
186 input_debug->mutable_localization_header()->CopyFrom(
187 control_preprocessor->local_view().localization().header());
188 input_debug->mutable_canbus_header()->CopyFrom(
189 control_preprocessor->local_view().chassis().header());
190 input_debug->mutable_trajectory_header()->CopyFrom(
191 control_preprocessor->local_view().trajectory().header());
192
193 if (control_preprocessor->local_view().trajectory().is_replan()) {
194 latest_replan_trajectory_header_.CopyFrom(
195 control_preprocessor->local_view().trajectory().header());
196 }
197
198 if (latest_replan_trajectory_header_.has_sequence_num()) {
199 input_debug->mutable_latest_replan_trajectory_header()->CopyFrom(
200 latest_replan_trajectory_header_);
201 }
202
203 return status;
204}
205
206Status PreprocessorSubmodule::CheckInput(LocalView *local_view) {
207 ADEBUG << "Received localization:"
208 << local_view->localization().ShortDebugString();
209 ADEBUG << "Received chassis:" << local_view->chassis().ShortDebugString();
210
211 if (!local_view->trajectory().estop().is_estop() &&
212 local_view->trajectory().trajectory_point().empty()) {
213 AWARN_EVERY(100) << "planning has no trajectory point. ";
214 const std::string msg =
215 absl::StrCat("planning has no trajectory point. planning_seq_num: ",
216 local_view->trajectory().header().sequence_num());
217 return Status(ErrorCode::CONTROL_COMPUTE_ERROR, msg);
218 }
219 {
220 std::lock_guard<std::mutex> lock(mutex_);
221 for (auto trajectory_point : local_view->trajectory().trajectory_point()) {
222 if (std::abs(trajectory_point.v()) < FLAGS_minimum_speed_resolution &&
223 std::abs(trajectory_point.a()) <
224 FLAGS_max_acceleration_when_stopped) {
225 trajectory_point.set_v(0.0);
226 trajectory_point.set_a(0.0);
227 }
228 }
229 }
230 injector_->vehicle_state()->Update(local_view->localization(),
231 local_view->chassis());
232
233 return Status::OK();
234}
235
236Status PreprocessorSubmodule::CheckTimestamp(const LocalView &local_view) {
237 if (!FLAGS_enable_input_timestamp_check || FLAGS_is_control_test_mode) {
238 ADEBUG << "Skip input timestamp check by gflags.";
239 return Status::OK();
240 }
241
242 double current_timestamp = Clock::NowInSeconds();
243 double localization_diff =
244 current_timestamp - local_view.localization().header().timestamp_sec();
245
246 if (localization_diff >
247 (FLAGS_max_localization_miss_num * FLAGS_localization_period)) {
248 AERROR << "Localization msg lost for " << std::setprecision(6)
249 << localization_diff << "s";
250 monitor_logger_buffer_.ERROR("Localization msg lost");
251 return Status(ErrorCode::CONTROL_COMPUTE_ERROR, "Localization msg timeout");
252 }
253
254 double chassis_diff =
255 current_timestamp - local_view.chassis().header().timestamp_sec();
256
257 if (chassis_diff > (FLAGS_max_chassis_miss_num * FLAGS_chassis_period)) {
258 AERROR << "Chassis msg lost for " << std::setprecision(6) << chassis_diff
259 << "s";
260 monitor_logger_buffer_.ERROR("Chassis msg lost");
261 return Status(ErrorCode::CONTROL_COMPUTE_ERROR, "Chassis msg timeout");
262 }
263
264 double trajectory_diff =
265 current_timestamp - local_view.trajectory().header().timestamp_sec();
266
267 if (trajectory_diff >
268 (FLAGS_max_planning_miss_num * FLAGS_trajectory_period)) {
269 AERROR << "Trajectory msg lost for " << std::setprecision(6)
270 << trajectory_diff << "s";
271 monitor_logger_buffer_.ERROR("Trajectory msg lost");
272 return Status(ErrorCode::CONTROL_COMPUTE_ERROR, "Trajectory msg timeout");
273 }
274
275 return Status::OK();
276}
277
278} // namespace control
279} // namespace apollo
void AppendLatencyRecord(const uint64_t message_id, const apollo::cyber::Time &begin_time, const apollo::cyber::Time &end_time)
A general class to denote the return status of an API call.
Definition status.h:43
bool ok() const
check whether the return status is OK.
Definition status.h:67
ErrorCode code() const
get the error code
Definition status.h:73
const std::string & error_message() const
returns the error message of the status, empty if the status is OK.
Definition status.h:91
static Status OK()
generate a success status.
Definition status.h:60
std::string Name() const
Get name of the node
bool Init() override
Initialize the submodule
PreprocessorSubmodule()
Construct a new Preprocessor Submodule object
bool Proc(const std::shared_ptr< LocalView > &local_view) override
a singleton clock that can be used to get the current timestamp.
Definition clock.h:39
static double NowInSeconds()
gets the current time in second.
Definition clock.cc:56
static Time Now()
PRECISION >= 1000000 means the precision is at least 1us.
Definition clock.cc:40
std::shared_ptr< Node > node_
#define ACHECK(cond)
Definition log.h:80
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AERROR_EVERY(freq)
Definition log.h:86
#define AWARN_EVERY(freq)
Definition log.h:84
#define AERROR_IF(cond)
Definition log.h:74
#define AINFO
Definition log.h:42
class register implement
Definition arena_queue.h:37
optional GearPosition gear_location
optional apollo::common::Header header
optional DrivingMode driving_mode
optional uint64 lidar_timestamp
Definition header.proto:19
optional apollo::planning::ADCTrajectory trajectory
optional PadMessage pad_msg
optional apollo::canbus::Chassis chassis
optional apollo::localization::LocalizationEstimate localization
optional apollo::common::Header header
optional apollo::common::Header header
repeated apollo::common::TrajectoryPoint trajectory_point
optional apollo::common::Header header
optional string reason
LocalView contains all necessary data as planning input