Apollo 11.0
自动驾驶开放平台
control_component.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2017 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 atis_control_test_mode
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 *****************************************************************************/
16
17#include "absl/strings/str_cat.h"
18
19#include "cyber/common/file.h"
20#include "cyber/common/log.h"
21#include "cyber/time/clock.h"
26
27namespace apollo {
28namespace control {
29
37
38const double kDoubleEpsilon = 1e-6;
39
41 : monitor_logger_buffer_(common::monitor::MonitorMessageItem::CONTROL) {}
42
44 injector_ = std::make_shared<DependencyInjector>();
45 init_time_ = Clock::Now();
46
47 AINFO << "Control init, starting ...";
48
49 ACHECK(
50 cyber::common::GetProtoFromFile(FLAGS_pipeline_file, &control_pipeline_))
51 << "Unable to load control pipeline file: " + FLAGS_pipeline_file;
52
53 AINFO << "ControlTask pipeline config file: " << FLAGS_pipeline_file
54 << " is loaded.";
55
56 // initial controller agent when not using control submodules
57 ADEBUG << "FLAGS_use_control_submodules: " << FLAGS_use_control_submodules;
58 if (!FLAGS_is_control_ut_test_mode) {
59 if (!FLAGS_use_control_submodules &&
60 !control_task_agent_.Init(injector_, control_pipeline_).ok()) {
61 // set controller
62 ADEBUG << "original control";
63 monitor_logger_buffer_.ERROR(
64 "Control init controller failed! Stopping...");
65 return false;
66 }
67 }
68
69 cyber::ReaderConfig chassis_reader_config;
70 chassis_reader_config.channel_name = FLAGS_chassis_topic;
71 chassis_reader_config.pending_queue_size = FLAGS_chassis_pending_queue_size;
72
73 chassis_reader_ =
74 node_->CreateReader<Chassis>(chassis_reader_config, nullptr);
75 ACHECK(chassis_reader_ != nullptr);
76
77 cyber::ReaderConfig planning_reader_config;
78 planning_reader_config.channel_name = FLAGS_planning_trajectory_topic;
79 planning_reader_config.pending_queue_size = FLAGS_planning_pending_queue_size;
80
81 trajectory_reader_ =
82 node_->CreateReader<ADCTrajectory>(planning_reader_config, nullptr);
83 ACHECK(trajectory_reader_ != nullptr);
84
85 cyber::ReaderConfig planning_command_status_reader_config;
86 planning_command_status_reader_config.channel_name =
87 FLAGS_planning_command_status;
88 planning_command_status_reader_config.pending_queue_size =
89 FLAGS_planning_status_msg_pending_queue_size;
90 planning_command_status_reader_ =
92 planning_command_status_reader_config, nullptr);
93 ACHECK(planning_command_status_reader_ != nullptr);
94
95 cyber::ReaderConfig localization_reader_config;
96 localization_reader_config.channel_name = FLAGS_localization_topic;
97 localization_reader_config.pending_queue_size =
98 FLAGS_localization_pending_queue_size;
99
100 localization_reader_ = node_->CreateReader<LocalizationEstimate>(
101 localization_reader_config, nullptr);
102 ACHECK(localization_reader_ != nullptr);
103
104 cyber::ReaderConfig pad_msg_reader_config;
105 pad_msg_reader_config.channel_name = FLAGS_pad_topic;
106 pad_msg_reader_config.pending_queue_size = FLAGS_pad_msg_pending_queue_size;
107
108 pad_msg_reader_ =
109 node_->CreateReader<PadMessage>(pad_msg_reader_config, nullptr);
110 ACHECK(pad_msg_reader_ != nullptr);
111
112 if (!FLAGS_use_control_submodules) {
113 control_cmd_writer_ =
114 node_->CreateWriter<ControlCommand>(FLAGS_control_command_topic);
115 ACHECK(control_cmd_writer_ != nullptr);
116 } else {
117 local_view_writer_ =
118 node_->CreateWriter<LocalView>(FLAGS_control_local_view_topic);
119 ACHECK(local_view_writer_ != nullptr);
120 }
121 control_interactive_writer_ = node_->CreateWriter<ControlInteractiveMsg>(
122 FLAGS_control_interative_topic);
123 ACHECK(control_interactive_writer_ != nullptr);
124
125 // set initial vehicle state by cmd
126 // need to sleep, because advertised channel is not ready immediately
127 // simple test shows a short delay of 80 ms or so
128 AINFO << "Control resetting vehicle state, sleeping for 1000 ms ...";
129 std::this_thread::sleep_for(std::chrono::milliseconds(1000));
130
131 // should init_vehicle first, let car enter work status, then use status msg
132 // trigger control
133
134 AINFO << "Control default driving action is "
135 << DrivingAction_Name((enum DrivingAction)FLAGS_action);
136 pad_msg_.set_action((enum DrivingAction)FLAGS_action);
137
138 return true;
139}
140
141void ControlComponent::OnPad(const std::shared_ptr<PadMessage> &pad) {
142 std::lock_guard<std::mutex> lock(mutex_);
143 pad_msg_.CopyFrom(*pad);
144 ADEBUG << "Received Pad Msg:" << pad_msg_.DebugString();
145 AERROR_IF(!pad_msg_.has_action()) << "pad message check failed!";
146}
147
148void ControlComponent::OnChassis(const std::shared_ptr<Chassis> &chassis) {
149 ADEBUG << "Received chassis data: run chassis callback.";
150 std::lock_guard<std::mutex> lock(mutex_);
151 latest_chassis_.CopyFrom(*chassis);
152}
153
154void ControlComponent::OnPlanning(
155 const std::shared_ptr<ADCTrajectory> &trajectory) {
156 ADEBUG << "Received chassis data: run trajectory callback.";
157 std::lock_guard<std::mutex> lock(mutex_);
158 latest_trajectory_.CopyFrom(*trajectory);
159}
160
161void ControlComponent::OnPlanningCommandStatus(
162 const std::shared_ptr<external_command::CommandStatus>
163 &planning_command_status) {
164 ADEBUG << "Received plannning command status data: run planning command "
165 "status callback.";
166 std::lock_guard<std::mutex> lock(mutex_);
167 planning_command_status_.CopyFrom(*planning_command_status);
168}
169
170void ControlComponent::OnLocalization(
171 const std::shared_ptr<LocalizationEstimate> &localization) {
172 ADEBUG << "Received control data: run localization message callback.";
173 std::lock_guard<std::mutex> lock(mutex_);
174 latest_localization_.CopyFrom(*localization);
175}
176
177void ControlComponent::OnMonitor(
178 const common::monitor::MonitorMessage &monitor_message) {
179 for (const auto &item : monitor_message.item()) {
180 if (item.log_level() == common::monitor::MonitorMessageItem::FATAL) {
181 estop_ = true;
182 return;
183 }
184 }
185}
186
187Status ControlComponent::ProduceControlCommand(
188 ControlCommand *control_command) {
189 Status status = CheckInput(&local_view_);
190 // check data
191 if (!status.ok()) {
192 AERROR_EVERY(100) << "Control input data failed: "
193 << status.error_message();
194 control_command->mutable_engage_advice()->set_advice(
196 control_command->mutable_engage_advice()->set_reason(
197 status.error_message());
198 estop_ = true;
199 estop_reason_ = status.error_message();
200 } else {
201 estop_ = false;
202 Status status_ts = CheckTimestamp(local_view_);
203 if (!status_ts.ok()) {
204 AERROR << "Input messages timeout";
205 // Clear trajectory data to make control stop if no data received again
206 // next cycle.
207 // keep the history trajectory for control compute.
208 // latest_trajectory_.Clear();
209 estop_ = true;
210 status = status_ts;
211 if (local_view_.chassis().driving_mode() !=
213 control_command->mutable_engage_advice()->set_advice(
215 control_command->mutable_engage_advice()->set_reason(
216 status.error_message());
217 }
218 } else {
219 control_command->mutable_engage_advice()->set_advice(
221 estop_ = false;
222 }
223 }
224
225 // check estop
226 estop_ = FLAGS_enable_persistent_estop
227 ? estop_ || local_view_.trajectory().estop().is_estop()
228 : local_view_.trajectory().estop().is_estop();
229
230 if (local_view_.trajectory().estop().is_estop()) {
231 estop_ = true;
232 estop_reason_ = "estop from planning : ";
233 estop_reason_ += local_view_.trajectory().estop().reason();
234 }
235
236 if (local_view_.trajectory().trajectory_point().empty()) {
237 AWARN_EVERY(100) << "planning has no trajectory point. ";
238 estop_ = true;
239 estop_reason_ = "estop for empty planning trajectory, planning headers: " +
240 local_view_.trajectory().header().ShortDebugString();
241 }
242
243 if (FLAGS_enable_gear_drive_negative_speed_protection) {
244 const double kEpsilon = 0.001;
245 auto first_trajectory_point = local_view_.trajectory().trajectory_point(0);
246 if (local_view_.chassis().gear_location() == Chassis::GEAR_DRIVE &&
247 first_trajectory_point.v() < -1 * kEpsilon) {
248 estop_ = true;
249 estop_reason_ = "estop for negative speed when gear_drive";
250 }
251 }
252
253 if (!estop_) {
254 if (local_view_.chassis().driving_mode() == Chassis::COMPLETE_MANUAL) {
255 control_task_agent_.Reset();
256 AINFO_EVERY(100) << "No estop. Reset Controllers in Manual Mode";
257 }
258
259 auto debug = control_command->mutable_debug()->mutable_input_debug();
260 debug->mutable_localization_header()->CopyFrom(
261 local_view_.localization().header());
262 debug->mutable_canbus_header()->CopyFrom(local_view_.chassis().header());
263 debug->mutable_trajectory_header()->CopyFrom(
264 local_view_.trajectory().header());
265
266 if (local_view_.trajectory().is_replan()) {
267 latest_replan_trajectory_header_ = local_view_.trajectory().header();
268 }
269
270 if (latest_replan_trajectory_header_.has_sequence_num()) {
271 debug->mutable_latest_replan_trajectory_header()->CopyFrom(
272 latest_replan_trajectory_header_);
273 }
274 }
275
276 if (!estop_) {
277 if (!local_view_.trajectory().trajectory_point().empty()) {
278 // controller agent
279 Status status_compute = control_task_agent_.ComputeControlCommand(
280 &local_view_.localization(), &local_view_.chassis(),
281 &local_view_.trajectory(), control_command);
282 ADEBUG << "status_compute is " << status_compute;
283
284 if (!status_compute.ok()) {
285 AERROR << "Control main function failed" << " with localization: "
286 << local_view_.localization().ShortDebugString()
287 << " with chassis: " << local_view_.chassis().ShortDebugString()
288 << " with trajectory: "
289 << local_view_.trajectory().ShortDebugString()
290 << " with cmd: " << control_command->ShortDebugString()
291 << " status:" << status_compute.error_message();
292 estop_ = true;
293 estop_reason_ = status_compute.error_message();
294 status = status_compute;
295 }
296 }
297 } else {
298 control_task_agent_.Reset();
299 AINFO_EVERY(10) << "Estop trigger, Reset Controllers in Auto Mode";
300 }
301
302 // if planning set estop, then no control process triggered
303 if (estop_) {
304 AWARN_EVERY(100) << "Estop triggered! No control core method executed!";
305 // set Estop command
306 control_command->set_speed(0.0);
307 control_command->set_throttle(0.0);
308 control_command->set_brake(FLAGS_soft_estop_brake);
309 control_command->set_acceleration(FLAGS_soft_estop_acceleration);
310 control_command->set_gear_location(latest_chassis_.gear_location());
311 control_command->set_parking_brake(latest_chassis_.parking_brake());
312 previous_steering_command_ =
313 injector_->previous_control_command_mutable()->steering_target();
314 control_command->set_steering_target(previous_steering_command_);
315 }
316 // check signal
317 if (local_view_.trajectory().decision().has_vehicle_signal()) {
318 control_command->mutable_signal()->CopyFrom(
319 local_view_.trajectory().decision().vehicle_signal());
320 }
321 return status;
322}
323
325 AINFO << "control proc start.";
326 const auto start_time = Clock::Now();
327
328 injector_->control_debug_info_clear();
329
330 chassis_reader_->Observe();
331 const auto &chassis_msg = chassis_reader_->GetLatestObserved();
332 if (chassis_msg == nullptr) {
333 AERROR << "Chassis msg is not ready!";
334 injector_->set_control_process(false);
335 return false;
336 }
337 OnChassis(chassis_msg);
338
339 trajectory_reader_->Observe();
340 const auto &trajectory_msg = trajectory_reader_->GetLatestObserved();
341 if (trajectory_msg == nullptr) {
342 AERROR << "planning msg is not ready!";
343 } else {
344 // Check if new planning data received.
345 if (latest_trajectory_.header().sequence_num() !=
346 trajectory_msg->header().sequence_num()) {
347 OnPlanning(trajectory_msg);
348 }
349 }
350
351 planning_command_status_reader_->Observe();
352 const auto &planning_status_msg =
353 planning_command_status_reader_->GetLatestObserved();
354 if (planning_status_msg != nullptr) {
355 OnPlanningCommandStatus(planning_status_msg);
356 ADEBUG << "Planning command status msg is \n"
357 << planning_command_status_.ShortDebugString();
358 }
359 injector_->set_planning_command_status(planning_command_status_);
360
361 localization_reader_->Observe();
362 const auto &localization_msg = localization_reader_->GetLatestObserved();
363 if (localization_msg == nullptr) {
364 AERROR << "localization msg is not ready!";
365 injector_->set_control_process(false);
366 return false;
367 }
368 OnLocalization(localization_msg);
369
370 pad_msg_reader_->Observe();
371 const auto &pad_msg = pad_msg_reader_->GetLatestObserved();
372 if (pad_msg != nullptr) {
373 OnPad(pad_msg);
374 }
375
376 {
377 // TODO(SHU): to avoid redundent copy
378 std::lock_guard<std::mutex> lock(mutex_);
379 local_view_.mutable_chassis()->CopyFrom(latest_chassis_);
380 local_view_.mutable_trajectory()->CopyFrom(latest_trajectory_);
381 local_view_.mutable_localization()->CopyFrom(latest_localization_);
382 if (pad_msg != nullptr) {
383 local_view_.mutable_pad_msg()->CopyFrom(pad_msg_);
384 }
385 }
386
387 // use control submodules
388 if (FLAGS_use_control_submodules) {
389 local_view_.mutable_header()->set_lidar_timestamp(
390 local_view_.trajectory().header().lidar_timestamp());
391 local_view_.mutable_header()->set_camera_timestamp(
392 local_view_.trajectory().header().camera_timestamp());
393 local_view_.mutable_header()->set_radar_timestamp(
394 local_view_.trajectory().header().radar_timestamp());
395 common::util::FillHeader(FLAGS_control_local_view_topic, &local_view_);
396
397 const auto end_time = Clock::Now();
398
399 // measure latency
400 static apollo::common::LatencyRecorder latency_recorder(
401 FLAGS_control_local_view_topic);
402 latency_recorder.AppendLatencyRecord(
403 local_view_.trajectory().header().lidar_timestamp(), start_time,
404 end_time);
405
406 local_view_writer_->Write(local_view_);
407 return true;
408 }
409
410 if (pad_msg != nullptr) {
411 ADEBUG << "pad_msg: " << pad_msg_.ShortDebugString();
412 ADEBUG << "pad_msg is not nullptr";
413 if (pad_msg_.action() == DrivingAction::RESET) {
414 AINFO << "Control received RESET action!";
415 estop_ = false;
416 estop_reason_.clear();
417 }
418 pad_received_ = true;
419 }
420
421 if (FLAGS_is_control_test_mode && FLAGS_control_test_duration > 0 &&
422 (start_time - init_time_).ToSecond() > FLAGS_control_test_duration) {
423 AERROR << "Control finished testing. exit";
424 injector_->set_control_process(false);
425 return false;
426 }
427
428 injector_->set_control_process(true);
429
430 injector_->mutable_control_debug_info()
431 ->mutable_control_component_debug()
432 ->Clear();
433 CheckAutoMode(&local_view_.chassis());
434
435 ControlCommand control_command;
436
437 Status status;
438 if (local_view_.chassis().driving_mode() ==
440 status = ProduceControlCommand(&control_command);
441 ADEBUG << "Produce control command normal.";
442 } else {
443 ADEBUG << "Into reset control command.";
444 ResetAndProduceZeroControlCommand(&latest_chassis_, &control_command);
445 }
446
447 AERROR_IF(!status.ok()) << "Failed to produce control command:"
448 << status.error_message();
449
450 if (pad_received_) {
451 control_command.mutable_pad_msg()->CopyFrom(pad_msg_);
452 pad_received_ = false;
453 }
454
455 // forward estop reason among following control frames.
456 if (estop_) {
457 control_command.mutable_header()->mutable_status()->set_msg(estop_reason_);
458 }
459
460 // set header
461 control_command.mutable_header()->set_lidar_timestamp(
462 local_view_.trajectory().header().lidar_timestamp());
463 control_command.mutable_header()->set_camera_timestamp(
464 local_view_.trajectory().header().camera_timestamp());
465 control_command.mutable_header()->set_radar_timestamp(
466 local_view_.trajectory().header().radar_timestamp());
467
468 if (FLAGS_is_control_test_mode) {
469 ADEBUG << "Skip publish control command in test mode";
470 return true;
471 }
472
473 if (fabs(control_command.debug().simple_lon_debug().vehicle_pitch()) <
475 injector_->vehicle_state()->Update(local_view_.localization(),
476 local_view_.chassis());
477 GetVehiclePitchAngle(&control_command);
478 }
479
480 const auto end_time = Clock::Now();
481 const double time_diff_ms = (end_time - start_time).ToSecond() * 1e3;
482 ADEBUG << "total control time spend: " << time_diff_ms << " ms.";
483
484 control_command.mutable_latency_stats()->set_total_time_ms(time_diff_ms);
485 control_command.mutable_latency_stats()->set_total_time_exceeded(
486 time_diff_ms > FLAGS_control_period * 1e3);
487 if (control_command.mutable_latency_stats()->total_time_exceeded()) {
488 AINFO << "total control cycle time is exceeded: " << time_diff_ms << " ms.";
489 }
490 status.Save(control_command.mutable_header()->mutable_status());
491
492 // measure latency
493 if (local_view_.trajectory().header().has_lidar_timestamp()) {
494 static apollo::common::LatencyRecorder latency_recorder(
495 FLAGS_control_command_topic);
496 latency_recorder.AppendLatencyRecord(
497 local_view_.trajectory().header().lidar_timestamp(), start_time,
498 end_time);
499 }
500
501 common::util::FillHeader(node_->Name(), &control_command);
502 if (FLAGS_sim_by_record) {
503 control_command.mutable_header()->set_timestamp_sec(
504 latest_chassis_.header().timestamp_sec());
505 }
506 ADEBUG << control_command.ShortDebugString();
507
508 control_cmd_writer_->Write(control_command);
509
510 // save current control command
511 injector_->Set_pervious_control_command(&control_command);
512 injector_->previous_control_command_mutable()->CopyFrom(control_command);
513 // save current control debug
514 injector_->previous_control_debug_mutable()->CopyFrom(
515 injector_->control_debug_info());
516
517 PublishControlInteractiveMsg();
518 const auto end_process_control_time = Clock::Now();
519 const double process_control_time_diff =
520 (end_process_control_time - start_time).ToSecond() * 1e3;
521 if (control_command.mutable_latency_stats()->total_time_exceeded()) {
522 AINFO << "control all spend time is exceeded.";
523 }
524 AINFO << "control proc finished, total time spend: "
525 << process_control_time_diff << " ms.";
526 return true;
527}
528
529Status ControlComponent::CheckInput(LocalView *local_view) {
530 ADEBUG << "Received localization:"
531 << local_view->localization().ShortDebugString();
532 ADEBUG << "Received chassis:" << local_view->chassis().ShortDebugString();
533
534 if (!local_view->trajectory().estop().is_estop() &&
535 local_view->trajectory().trajectory_point().empty()) {
536 AWARN_EVERY(100) << "planning has no trajectory point. ";
537 const std::string msg =
538 absl::StrCat("planning has no trajectory point. planning_seq_num:",
539 local_view->trajectory().header().sequence_num());
540 return Status(ErrorCode::CONTROL_COMPUTE_ERROR, msg);
541 }
542
543 for (auto &trajectory_point :
544 *local_view->mutable_trajectory()->mutable_trajectory_point()) {
545 if (std::abs(trajectory_point.v()) < FLAGS_minimum_speed_resolution &&
546 std::abs(trajectory_point.a()) < FLAGS_max_acceleration_when_stopped) {
547 trajectory_point.set_v(0.0);
548 trajectory_point.set_a(0.0);
549 }
550 }
551
552 injector_->vehicle_state()->Update(local_view->localization(),
553 local_view->chassis());
554
555 return Status::OK();
556}
557
558Status ControlComponent::CheckTimestamp(const LocalView &local_view) {
559 if (!FLAGS_enable_input_timestamp_check || FLAGS_is_control_test_mode) {
560 ADEBUG << "Skip input timestamp check by gflags.";
561 return Status::OK();
562 }
563 std::string err_msg = "";
564 double current_timestamp = FLAGS_sim_by_record
565 ? latest_chassis_.header().timestamp_sec()
567 double localization_diff =
568 current_timestamp - local_view.localization().header().timestamp_sec();
569 bool localization_consist_timeout = false;
570 if (localization_diff >
571 (FLAGS_max_localization_miss_num * FLAGS_localization_period)) {
572 localization_consist_timeout = true;
573 localization_timeout_count_++;
574 AERROR << "Localization msg lost for " << std::to_string(localization_diff)
575 << "s";
576 AERROR << "current_timestamp: " << std::to_string(current_timestamp)
577 << ", localization_timestamp: "
578 << std::to_string(
579 local_view.localization().header().timestamp_sec());
580 err_msg = err_msg + " Localization msg timeout. ";
581 } else {
582 localization_consist_timeout = false;
583 localization_timeout_count_ = 0;
584 }
585 if (localization_consist_timeout &&
586 (localization_timeout_count_ >= FLAGS_max_localization_miss_num)) {
587 localization_timeout_count_ = FLAGS_max_localization_miss_num;
588 AERROR << "write the monitor logger, localization msg lost "
589 << localization_timeout_count_ << " times.";
590 monitor_logger_buffer_.ERROR("Localization msg lost");
591 }
592
593 double chassis_diff =
594 current_timestamp - local_view.chassis().header().timestamp_sec();
595 bool chassis_consist_timeout = false;
596 if (chassis_diff > (FLAGS_max_chassis_miss_num * FLAGS_chassis_period)) {
597 chassis_consist_timeout = true;
598 chassis_timeout_count_++;
599 AERROR << "Chassis msg lost for " << std::to_string(chassis_diff) << "s";
600 AERROR << "current_timestamp: " << std::to_string(current_timestamp)
601 << ", chassis_timestamp: "
602 << std::to_string(local_view.chassis().header().timestamp_sec());
603 err_msg = err_msg + " Chassis msg timeout. ";
604 } else {
605 chassis_consist_timeout = false;
606 chassis_timeout_count_ = 0;
607 }
608 if (chassis_consist_timeout &&
609 (chassis_timeout_count_ >= FLAGS_max_chassis_miss_num)) {
610 chassis_timeout_count_ = FLAGS_max_chassis_miss_num;
611 AERROR << "write the monitor logger, chassis msg lost "
612 << chassis_timeout_count_ << " times.";
613 monitor_logger_buffer_.ERROR("Chassis msg lost");
614 }
615
616 double trajectory_diff =
617 current_timestamp - local_view.trajectory().header().timestamp_sec();
618 bool trajectory_consist_timeout = false;
619 if (trajectory_diff >
620 (FLAGS_max_planning_miss_num * FLAGS_trajectory_period)) {
621 trajectory_consist_timeout = true;
622 trajectory_timeout_count_++;
623 AERROR << "Trajectory msg lost for " << std::to_string(trajectory_diff)
624 << "s";
625 AERROR << "current_timestamp: " << std::to_string(current_timestamp)
626 << ", trajectory_timestamp: "
627 << std::to_string(local_view.trajectory().header().timestamp_sec());
628 err_msg = err_msg + " Trajectory msg lost. ";
629 } else {
630 trajectory_consist_timeout = false;
631 trajectory_timeout_count_ = 0;
632 }
633 if (trajectory_consist_timeout &&
634 (trajectory_timeout_count_ >= FLAGS_max_localization_miss_num)) {
635 trajectory_timeout_count_ = FLAGS_max_localization_miss_num;
636 AERROR << "write the monitor logger, trajectory msg lost "
637 << trajectory_timeout_count_ << " times.";
638 monitor_logger_buffer_.ERROR("Trajectory msg lost");
639 }
640
641 if (!err_msg.empty()) {
642 return Status(ErrorCode::CONTROL_COMPUTE_ERROR, err_msg);
643 } else {
644 return Status::OK();
645 }
646}
647
648void ControlComponent::ResetAndProduceZeroControlCommand(
649 const canbus::Chassis *chassis, ControlCommand *control_command) {
650 control_command->set_throttle(0.0);
651 control_command->set_steering_target(0.0);
652 control_command->set_steering_rate(0.0);
653 control_command->set_speed(0.0);
654 control_command->set_brake(0.0);
655 control_command->set_gear_location(chassis->gear_location());
656 control_command->set_parking_brake(chassis->parking_brake());
657 control_task_agent_.Reset();
658 latest_trajectory_.mutable_trajectory_point()->Clear();
659 latest_trajectory_.mutable_path_point()->Clear();
660 trajectory_reader_->ClearData();
661}
662
663void ControlComponent::GetVehiclePitchAngle(ControlCommand *control_command) {
664 double vehicle_pitch = injector_->vehicle_state()->pitch() * 180 / M_PI;
665 control_command->mutable_debug()
666 ->mutable_simple_lon_debug()
667 ->set_vehicle_pitch(vehicle_pitch + FLAGS_pitch_offset_deg);
668}
669
670void ControlComponent::CheckAutoMode(const canbus::Chassis *chassis) {
671 if (!injector_->previous_control_debug_mutable()
672 ->mutable_control_component_debug()
673 ->is_auto() &&
674 chassis->driving_mode() == apollo::canbus::Chassis::COMPLETE_AUTO_DRIVE) {
675 from_else_to_auto_ = true;
676 AINFO << "From else to auto!!!";
677 } else {
678 from_else_to_auto_ = false;
679 }
680 ADEBUG << "from_else_to_auto_: " << from_else_to_auto_;
681 injector_->mutable_control_debug_info()
682 ->mutable_control_component_debug()
683 ->set_from_else_to_auto(from_else_to_auto_);
684
685 if (chassis->driving_mode() == apollo::canbus::Chassis::COMPLETE_AUTO_DRIVE) {
686 is_auto_ = true;
687 } else {
688 is_auto_ = false;
689 }
690 injector_->mutable_control_debug_info()
691 ->mutable_control_component_debug()
692 ->set_is_auto(is_auto_);
693}
694
695void ControlComponent::PublishControlInteractiveMsg() {
696 auto control_interactive_msg = injector_->control_interactive_info();
697 common::util::FillHeader(node_->Name(), &control_interactive_msg);
698 ADEBUG << "control interactive msg is: "
699 << control_interactive_msg.ShortDebugString();
700 control_interactive_writer_->Write(control_interactive_msg);
701}
702
703} // namespace control
704} // 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
const std::string & error_message() const
returns the error message of the status, empty if the status is OK.
Definition status.h:91
void Save(StatusPb *status_pb)
save the error_code and error message to protobuf
Definition status.h:109
static Status OK()
generate a success status.
Definition status.h:60
bool Proc() override
The Proc logic of the component, which called by the CyberRT frame.
common::Status Reset()
reset ControlTaskAgent
common::Status Init(std::shared_ptr< DependencyInjector > injector, const ControlPipeline &control_pipeline)
initialize ControlTaskAgent
common::Status ComputeControlCommand(const localization::LocalizationEstimate *localization, const canbus::Chassis *chassis, const planning::ADCTrajectory *trajectory, control::ControlCommand *cmd)
compute control command based on current vehicle status and target trajectory
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 AINFO_EVERY(freq)
Definition log.h:82
#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
const double kDoubleEpsilon
bool GetProtoFromFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as a representation of protobufs,...
Definition file.cc:132
class register implement
Definition arena_queue.h:37
optional GearPosition gear_location
optional apollo::common::Header header
optional DrivingMode driving_mode
optional bool parking_brake
Definition chassis.proto:94
optional uint32 sequence_num
Definition header.proto:16
optional double timestamp_sec
Definition header.proto:9
optional uint64 camera_timestamp
Definition header.proto:22
optional uint64 lidar_timestamp
Definition header.proto:19
optional uint64 radar_timestamp
Definition header.proto:25
optional SimpleLongitudinalDebug simple_lon_debug
optional apollo::planning::ADCTrajectory trajectory
optional apollo::canbus::Chassis chassis
optional apollo::localization::LocalizationEstimate localization
optional DrivingAction action
Definition pad_msg.proto:17
uint32_t pending_queue_size
configuration for responding ChannelBuffer.
optional apollo::common::Header header
repeated apollo::common::TrajectoryPoint trajectory_point
optional apollo::common::Header header
optional apollo::planning::DecisionResult decision
optional string reason
LocalView contains all necessary data as planning input