Apollo 10.0
自动驾驶开放平台
ge3_controller.cc
浏览该文件的文档.
1/* Copyright 2019 The Apollo Authors. All Rights Reserved.
2
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9Unless required by applicable law or agreed to in writing, software
10distributed under the License is distributed on an "AS IS" BASIS,
11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12See the License for the specific language governing permissions and
13limitations under the License.
14==============================================================================*/
15
17
18#include "modules/common_msgs/basic_msgs/vehicle_signal.pb.h"
19
20#include "cyber/time/time.h"
25
26namespace apollo {
27namespace canbus {
28namespace ge3 {
29
30using ::apollo::common::ErrorCode;
31using ::apollo::common::VehicleSignal;
32using ::apollo::control::ControlCommand;
33using ::apollo::drivers::canbus::ProtocolData;
34
35namespace {
36
37const int32_t kMaxFailAttempt = 10;
38const int32_t CHECK_RESPONSE_STEER_UNIT_FLAG = 1;
39const int32_t CHECK_RESPONSE_SPEED_UNIT_FLAG = 2;
40
41} // namespace
42
44 const VehicleParameter& params, CanSender<Ge3>* const can_sender,
45 MessageManager<::apollo::canbus::Ge3>* const message_manager) {
46 if (is_initialized_) {
47 AINFO << "Ge3Controller has already been initiated.";
48 return ErrorCode::CANBUS_ERROR;
49 }
50
51 vehicle_params_.CopyFrom(
52 common::VehicleConfigHelper::Instance()->GetConfig().vehicle_param());
53 params_.CopyFrom(params);
54 if (!params_.has_driving_mode()) {
55 AERROR << "Vehicle conf pb not set driving_mode.";
56 return ErrorCode::CANBUS_ERROR;
57 }
58
59 if (can_sender == nullptr) {
60 AERROR << "Canbus sender is null.";
61 return ErrorCode::CANBUS_ERROR;
62 }
63 can_sender_ = can_sender;
64
65 if (message_manager == nullptr) {
66 AERROR << "protocol manager is null.";
67 return ErrorCode::CANBUS_ERROR;
68 }
69 message_manager_ = message_manager;
70
71 // sender part
72 pc_bcm_201_ = dynamic_cast<Pcbcm201*>(
73 message_manager_->GetMutableProtocolDataById(Pcbcm201::ID));
74 if (pc_bcm_201_ == nullptr) {
75 AERROR << "Pcbcm201 does not exist in the Ge3MessageManager!";
76 return ErrorCode::CANBUS_ERROR;
77 }
78
79 pc_bcs_202_ = dynamic_cast<Pcbcs202*>(
80 message_manager_->GetMutableProtocolDataById(Pcbcs202::ID));
81 if (pc_bcs_202_ == nullptr) {
82 AERROR << "Pcbcs202 does not exist in the Ge3MessageManager!";
83 return ErrorCode::CANBUS_ERROR;
84 }
85
86 pc_epb_203_ = dynamic_cast<Pcepb203*>(
87 message_manager_->GetMutableProtocolDataById(Pcepb203::ID));
88 if (pc_epb_203_ == nullptr) {
89 AERROR << "Pcepb203 does not exist in the Ge3MessageManager!";
90 return ErrorCode::CANBUS_ERROR;
91 }
92
93 pc_eps_204_ = dynamic_cast<Pceps204*>(
94 message_manager_->GetMutableProtocolDataById(Pceps204::ID));
95 if (pc_eps_204_ == nullptr) {
96 AERROR << "Pceps204 does not exist in the Ge3MessageManager!";
97 return ErrorCode::CANBUS_ERROR;
98 }
99
100 pc_vcu_205_ = dynamic_cast<Pcvcu205*>(
101 message_manager_->GetMutableProtocolDataById(Pcvcu205::ID));
102 if (pc_vcu_205_ == nullptr) {
103 AERROR << "Pcvcu205 does not exist in the Ge3MessageManager!";
104 return ErrorCode::CANBUS_ERROR;
105 }
106
107 can_sender_->AddMessage(Pcbcm201::ID, pc_bcm_201_, false);
108 can_sender_->AddMessage(Pcbcs202::ID, pc_bcs_202_, false);
109 can_sender_->AddMessage(Pcepb203::ID, pc_epb_203_, false);
110 can_sender_->AddMessage(Pceps204::ID, pc_eps_204_, false);
111 can_sender_->AddMessage(Pcvcu205::ID, pc_vcu_205_, false);
112
113 // Need to sleep to ensure all messages received
114 AINFO << "Ge3Controller is initialized.";
115
116 is_initialized_ = true;
117 return ErrorCode::OK;
118}
119
121
123 if (!is_initialized_) {
124 AERROR << "Ge3Controller has NOT been initialized.";
125 return false;
126 }
127 const auto& update_func = [this] { SecurityDogThreadFunc(); };
128 thread_.reset(new std::thread(update_func));
129
130 return true;
131}
132
134 if (!is_initialized_) {
135 AERROR << "Ge3Controller stops or starts improperly!";
136 return;
137 }
138
139 if (thread_ != nullptr && thread_->joinable()) {
140 thread_->join();
141 thread_.reset();
142 AINFO << "Ge3Controller stopped.";
143 }
144}
145
147 chassis_.Clear();
148
149 Ge3 chassis_detail;
150 message_manager_->GetSensorData(&chassis_detail);
151
152 // 21, 22, previously 1, 2
154 set_chassis_error_code(Chassis::NO_ERROR);
155 }
156
157 chassis_.set_driving_mode(driving_mode());
158 chassis_.set_error_code(chassis_error_code());
159
160 // 3
161 chassis_.set_engine_started(true);
162
163 // 5
164 if (chassis_detail.has_scu_bcs_3_308()) {
165 Scu_bcs_3_308 scu_bcs_3_308 = chassis_detail.scu_bcs_3_308();
166 if (scu_bcs_3_308.has_bcs_rrwheelspd()) {
167 if (chassis_.has_wheel_speed()) {
168 chassis_.mutable_wheel_speed()->set_is_wheel_spd_rr_valid(
169 scu_bcs_3_308.bcs_rrwheelspdvd());
170 chassis_.mutable_wheel_speed()->set_wheel_direction_rr(
172 chassis_.mutable_wheel_speed()->set_wheel_spd_rr(
173 scu_bcs_3_308.bcs_rrwheelspd());
174 }
175 }
176
177 if (scu_bcs_3_308.has_bcs_rlwheelspd()) {
178 if (chassis_.has_wheel_speed()) {
179 chassis_.mutable_wheel_speed()->set_is_wheel_spd_rl_valid(
180 scu_bcs_3_308.bcs_rlwheelspdvd());
181 chassis_.mutable_wheel_speed()->set_wheel_direction_rl(
183 chassis_.mutable_wheel_speed()->set_wheel_spd_rl(
184 scu_bcs_3_308.bcs_rlwheelspd());
185 }
186 }
187
188 if (scu_bcs_3_308.has_bcs_frwheelspd()) {
189 if (chassis_.has_wheel_speed()) {
190 chassis_.mutable_wheel_speed()->set_is_wheel_spd_fr_valid(
191 scu_bcs_3_308.bcs_frwheelspdvd());
192 chassis_.mutable_wheel_speed()->set_wheel_direction_fr(
194 chassis_.mutable_wheel_speed()->set_wheel_spd_fr(
195 scu_bcs_3_308.bcs_frwheelspd());
196 }
197 }
198
199 if (scu_bcs_3_308.has_bcs_flwheelspd()) {
200 if (chassis_.has_wheel_speed()) {
201 chassis_.mutable_wheel_speed()->set_is_wheel_spd_fl_valid(
202 scu_bcs_3_308.bcs_flwheelspdvd());
203 chassis_.mutable_wheel_speed()->set_wheel_direction_fl(
205 chassis_.mutable_wheel_speed()->set_wheel_spd_fl(
206 scu_bcs_3_308.bcs_flwheelspd());
207 }
208 }
209 }
210
211 if (chassis_detail.has_scu_bcs_2_307() &&
212 chassis_detail.scu_bcs_2_307().has_bcs_vehspd()) {
213 chassis_.set_speed_mps(
214 static_cast<float>(chassis_detail.scu_bcs_2_307().bcs_vehspd()));
215 } else {
216 chassis_.set_speed_mps(0);
217 }
218
219 // 7
220 // ge3 only has fuel percentage
221 // to avoid confusing, just don't set
222 chassis_.set_fuel_range_m(0);
223
224 if (chassis_detail.has_scu_vcu_1_312() &&
225 chassis_detail.scu_vcu_1_312().has_vcu_accpedact()) {
226 chassis_.set_throttle_percentage(
227 static_cast<float>(chassis_detail.scu_vcu_1_312().vcu_accpedact()));
228 } else {
229 chassis_.set_throttle_percentage(0);
230 }
231 // 9
232 if (chassis_detail.has_scu_bcs_1_306() &&
233 chassis_detail.scu_bcs_1_306().has_bcs_brkpedact()) {
234 chassis_.set_brake_percentage(
235 static_cast<float>(chassis_detail.scu_bcs_1_306().bcs_brkpedact()));
236 } else {
237 chassis_.set_brake_percentage(0);
238 }
239 // 23, previously 10
240 if (chassis_detail.has_scu_vcu_1_312() &&
241 chassis_detail.scu_vcu_1_312().has_vcu_gearact()) {
242 switch (chassis_detail.scu_vcu_1_312().vcu_gearact()) {
244 chassis_.set_gear_location(Chassis::GEAR_INVALID);
245 } break;
247 chassis_.set_gear_location(Chassis::GEAR_DRIVE);
248 } break;
250 chassis_.set_gear_location(Chassis::GEAR_NEUTRAL);
251 } break;
253 chassis_.set_gear_location(Chassis::GEAR_REVERSE);
254 } break;
256 chassis_.set_gear_location(Chassis::GEAR_PARKING);
257 } break;
258 default:
259 chassis_.set_gear_location(Chassis::GEAR_INVALID);
260 break;
261 }
262 } else {
263 chassis_.set_gear_location(Chassis::GEAR_INVALID);
264 }
265
266 // 11
267 if (chassis_detail.has_scu_eps_311() &&
268 chassis_detail.scu_eps_311().has_eps_steerangle()) {
269 chassis_.set_steering_percentage(
270 static_cast<float>(chassis_detail.scu_eps_311().eps_steerangle() /
271 vehicle_params_.max_steer_angle() * M_PI / 1.80));
272 } else {
273 chassis_.set_steering_percentage(0);
274 }
275
276 // 13
277 if (chassis_detail.has_scu_epb_310() &&
278 chassis_detail.scu_epb_310().has_epb_sysst()) {
279 chassis_.set_parking_brake(chassis_detail.scu_epb_310().epb_sysst() ==
281 } else {
282 chassis_.set_parking_brake(false);
283 }
284
285 // 14, 15: ge3 light control
286 if (chassis_detail.has_scu_bcm_304() &&
287 chassis_detail.scu_bcm_304().has_bcm_highbeamst() &&
289 chassis_detail.scu_bcm_304().bcm_highbeamst()) {
290 if (chassis_.has_signal()) {
291 chassis_.mutable_signal()->set_high_beam(true);
292 }
293 } else {
294 if (chassis_.has_signal()) {
295 chassis_.mutable_signal()->set_high_beam(false);
296 }
297 }
298
299 // 16, 17
300 if (chassis_detail.has_scu_bcm_304()) {
301 Scu_bcm_304 scu_bcm_304 = chassis_detail.scu_bcm_304();
302 if (scu_bcm_304.has_bcm_leftturnlampst() &&
304 scu_bcm_304.bcm_leftturnlampst()) {
305 chassis_.mutable_signal()->set_turn_signal(
307 } else if (scu_bcm_304.has_bcm_rightturnlampst() &&
309 scu_bcm_304.bcm_rightturnlampst()) {
310 chassis_.mutable_signal()->set_turn_signal(
312 } else {
313 chassis_.mutable_signal()->set_turn_signal(
315 }
316 } else {
317 chassis_.mutable_signal()->set_turn_signal(
319 }
320 // 18
321 if (chassis_detail.has_scu_bcm_304() &&
322 chassis_detail.scu_bcm_304().has_bcm_hornst() &&
324 chassis_detail.scu_bcm_304().bcm_hornst()) {
325 chassis_.mutable_signal()->set_horn(true);
326 } else {
327 chassis_.mutable_signal()->set_horn(false);
328 }
329
330 // vin number will be written into KVDB once.
331 chassis_.mutable_vehicle_id()->set_vin("");
332 if (chassis_detail.has_scu_1_301() && chassis_detail.has_scu_2_302() &&
333 chassis_detail.has_scu_3_303()) {
334 Scu_1_301 scu_1_301 = chassis_detail.scu_1_301();
335 Scu_2_302 scu_2_302 = chassis_detail.scu_2_302();
336 Scu_3_303 scu_3_303 = chassis_detail.scu_3_303();
337 if (scu_2_302.has_vin00() && scu_2_302.has_vin01() &&
338 scu_2_302.has_vin02() && scu_2_302.has_vin03() &&
339 scu_2_302.has_vin04() && scu_2_302.has_vin05() &&
340 scu_2_302.has_vin06() && scu_2_302.has_vin07() &&
341 scu_3_303.has_vin08() && scu_3_303.has_vin09() &&
342 scu_3_303.has_vin10() && scu_3_303.has_vin11() &&
343 scu_3_303.has_vin12() && scu_3_303.has_vin13() &&
344 scu_3_303.has_vin14() && scu_3_303.has_vin15() &&
345 scu_1_301.has_vin16()) {
346 int n[17];
347 n[0] = scu_2_302.vin00();
348 n[1] = scu_2_302.vin01();
349 n[2] = scu_2_302.vin02();
350 n[3] = scu_2_302.vin03();
351 n[4] = scu_2_302.vin04();
352 n[5] = scu_2_302.vin05();
353 n[6] = scu_2_302.vin06();
354 n[7] = scu_2_302.vin07();
355 n[8] = scu_3_303.vin08();
356 n[9] = scu_3_303.vin09();
357 n[10] = scu_3_303.vin10();
358 n[11] = scu_3_303.vin11();
359 n[12] = scu_3_303.vin12();
360 n[13] = scu_3_303.vin13();
361 n[14] = scu_3_303.vin14();
362 n[15] = scu_3_303.vin15();
363 n[16] = scu_1_301.vin16();
364
365 char ch[17];
366 memset(&ch, '\0', sizeof(ch));
367 for (int i = 0; i < 17; i++) {
368 ch[i] = static_cast<char>(n[i]);
369 }
370 if (chassis_.has_vehicle_id()) {
371 chassis_.mutable_vehicle_id()->set_vin(ch);
372 }
373 }
374 }
375
376 // give engage_advice based on error_code and canbus feedback
377 if (chassis_error_mask_) {
378 if (chassis_.has_engage_advice()) {
379 chassis_.mutable_engage_advice()->set_advice(
381 chassis_.mutable_engage_advice()->set_reason("Chassis error!");
382 }
383 } else if (chassis_.parking_brake() || CheckSafetyError(chassis_detail)) {
384 if (chassis_.has_engage_advice()) {
385 chassis_.mutable_engage_advice()->set_advice(
387 chassis_.mutable_engage_advice()->set_reason(
388 "Vehicle is not in a safe state to engage!");
389 }
390 } else {
391 if (chassis_.has_engage_advice()) {
392 chassis_.mutable_engage_advice()->set_advice(
394 }
395 }
396
397 // 19 add checkresponse signal
398 if (chassis_detail.has_scu_bcs_1_306() &&
399 chassis_detail.scu_bcs_1_306().has_bcs_drvmode()) {
400 chassis_.mutable_check_response()->set_is_esp_online(
401 chassis_detail.scu_bcs_1_306().bcs_drvmode() == 1);
402 }
403 if (chassis_detail.has_scu_eps_311() &&
404 chassis_detail.scu_eps_311().has_eps_drvmode()) {
405 chassis_.mutable_check_response()->set_is_eps_online(
406 chassis_detail.scu_eps_311().eps_drvmode() == 1);
407 }
408 if (chassis_detail.has_scu_vcu_1_312() &&
409 chassis_detail.scu_vcu_1_312().has_vcu_drvmode()) {
410 chassis_.mutable_check_response()->set_is_vcu_online(
411 chassis_detail.scu_vcu_1_312().vcu_drvmode() == 1);
412 }
413
414 return chassis_;
415}
416
417bool Ge3Controller::VerifyID() { return true; }
418
419void Ge3Controller::Emergency() {
421 ResetProtocol();
422 // In emergency case, the hazard lamp should be on
424 set_chassis_error_code(Chassis::CHASSIS_ERROR);
425}
426
427ErrorCode Ge3Controller::EnableAutoMode() {
429 AINFO << "already in COMPLETE_AUTO_DRIVE mode";
430 return ErrorCode::OK;
431 }
437
438 can_sender_->Update();
439 const int32_t flag =
440 CHECK_RESPONSE_STEER_UNIT_FLAG | CHECK_RESPONSE_SPEED_UNIT_FLAG;
441 if (!CheckResponse(flag, true)) {
442 AERROR << "Failed to switch to COMPLETE_AUTO_DRIVE mode.";
443 Emergency();
444 set_chassis_error_code(Chassis::CHASSIS_ERROR);
445 return ErrorCode::CANBUS_ERROR;
446 }
448 // If the auto mode can be set normally, the harzad lamp should be off.
450 AINFO << "Switch to COMPLETE_AUTO_DRIVE mode ok.";
451 return ErrorCode::OK;
452}
453
454ErrorCode Ge3Controller::DisableAutoMode() {
455 ResetProtocol();
456 can_sender_->Update();
458 set_chassis_error_code(Chassis::NO_ERROR);
459 AINFO << "Switch to COMPLETE_MANUAL OK.";
460 return ErrorCode::OK;
461}
462
463ErrorCode Ge3Controller::EnableSteeringOnlyMode() {
467 AINFO << "Already in AUTO_STEER_ONLY mode";
468 return ErrorCode::OK;
469 }
475
476 can_sender_->Update();
477 if (!CheckResponse(CHECK_RESPONSE_STEER_UNIT_FLAG, true)) {
478 AERROR << "Failed to switch to AUTO_STEER_ONLY mode.";
479 Emergency();
480 set_chassis_error_code(Chassis::CHASSIS_ERROR);
481 return ErrorCode::CANBUS_ERROR;
482 }
484 // If the auto mode can be set normally, the harzad lamp should be off.
486 AINFO << "Switch to AUTO_STEER_ONLY mode ok.";
487 return ErrorCode::OK;
488}
489
490ErrorCode Ge3Controller::EnableSpeedOnlyMode() {
494 AINFO << "Already in AUTO_SPEED_ONLY mode";
495 return ErrorCode::OK;
496 }
502
503 can_sender_->Update();
504 if (!CheckResponse(CHECK_RESPONSE_SPEED_UNIT_FLAG, true)) {
505 AERROR << "Failed to switch to AUTO_SPEED_ONLY mode.";
506 Emergency();
507 set_chassis_error_code(Chassis::CHASSIS_ERROR);
508 return ErrorCode::CANBUS_ERROR;
509 }
511 // If the auto mode can be set normally, the harzad lamp should be off.
513 AINFO << "Switch to AUTO_SPEED_ONLY mode ok.";
514 return ErrorCode::OK;
515}
516
517// NEUTRAL, REVERSE, DRIVE
518void Ge3Controller::Gear(Chassis::GearPosition gear_position) {
521 AINFO << "This drive mode no need to set gear.";
522 return;
523 }
524 switch (gear_position) {
527 break;
528 }
531 break;
532 }
533 case Chassis::GEAR_DRIVE: {
535 break;
536 }
539 break;
540 }
541 case Chassis::GEAR_LOW: {
543 break;
544 }
545 case Chassis::GEAR_NONE: {
547 break;
548 }
550 AERROR << "Gear command is invalid!";
552 break;
553 }
554 default: {
556 break;
557 }
558 }
559}
560
561// brake with new acceleration
562// acceleration:0.00~99.99, unit:
563// acceleration:0.0 ~ 7.0, unit:m/s^2
564// acceleration_spd:60 ~ 100, suggest: 90
565// -> pedal
566void Ge3Controller::Brake(double pedal) {
567 // Update brake value based on mode
570 AINFO << "The current drive mode does not need to set acceleration.";
571 return;
572 }
573 pc_bcs_202_->set_pc_brkpedreq(pedal);
574}
575
576// drive with old acceleration
577// gas:0.00~99.99 unit:
578void Ge3Controller::Throttle(double pedal) {
581 AINFO << "The current drive mode does not need to set acceleration.";
582 return;
583 }
584 pc_vcu_205_->set_pc_accpedreq(pedal);
585}
586
587// ge3 default, -470 ~ 470, left:+, right:-
588// need to be compatible with control module, so reverse
589// steering with old angle speed
590// angle:-99.99~0.00~99.99, unit:, left:-, right:+
591void Ge3Controller::Steer(double angle) {
594 AINFO << "The current driving mode does not need to set steer.";
595 return;
596 }
597 const double real_angle =
598 vehicle_params_.max_steer_angle() / M_PI * 180 * angle / 100.0;
599 pc_eps_204_->set_pc_steerangreq(real_angle)->set_pc_steerspdreq(500);
600}
601
602// drive with acceleration/deceleration
603// acc:-7.0 ~ 5.0, unit:m/s^2
604void Ge3Controller::Acceleration(double acc) {
607 AINFO << "The current drive mode does not need to set acceleration.";
608 return;
609 }
610 // None
611}
612
613// steering with new angle speed
614// angle:-99.99~0.00~99.99, unit:, left:-, right:+
615// angle_spd:0.00~99.99, unit:deg/s
616void Ge3Controller::Steer(double angle, double angle_spd) {
619 AINFO << "The current driving mode does not need to set steer.";
620 return;
621 }
622 const double real_angle =
623 vehicle_params_.max_steer_angle() / M_PI * 180 * angle / 100.0;
624 const double real_angle_spd =
625 ProtocolData<::apollo::canbus::Ge3>::BoundedValue(
628 vehicle_params_.max_steer_angle_rate() / M_PI * 180 * angle_spd /
629 100.0);
630 pc_eps_204_->set_pc_steerangreq(real_angle)
631 ->set_pc_steerspdreq(static_cast<int>(real_angle_spd));
632}
633
634void Ge3Controller::SetEpbBreak(const ControlCommand& command) {
635 if (command.parking_brake()) {
637 } else {
639 }
640}
641ErrorCode Ge3Controller::HandleCustomOperation(
642 const external_command::ChassisCommand& command) {
643 return ErrorCode::OK;
644}
645
646void Ge3Controller::SetBeam(const VehicleSignal& vehicle_signal) {
647 if (vehicle_signal.has_high_beam() && vehicle_signal.high_beam()) {
650 } else if (vehicle_signal.has_low_beam() && vehicle_signal.low_beam()) {
653 } else {
656 }
657}
658
659void Ge3Controller::SetHorn(const VehicleSignal& vehicle_signal) {
660 if (vehicle_signal.horn()) {
662 } else {
664 }
665}
666
667void Ge3Controller::SetTurningSignal(const VehicleSignal& vehicle_signal) {
668 // Set Turn Signal
669 auto signal = vehicle_signal.turn_signal();
670 if (signal == common::VehicleSignal::TURN_LEFT) {
673 } else if (signal == common::VehicleSignal::TURN_RIGHT) {
676 } else {
679 }
680}
681
682void Ge3Controller::ResetProtocol() { message_manager_->ResetSendMessages(); }
683
684bool Ge3Controller::CheckChassisError() {
685 Ge3 chassis_detail;
686 message_manager_->GetSensorData(&chassis_detail);
687 if (!chassis_.has_check_response()) {
688 AERROR_EVERY(100) << "ChassisDetail has NO ge3 vehicle info.";
689 return false;
690 }
691
692 // check steer error
693 if (chassis_detail.has_scu_eps_311()) {
695 chassis_detail.scu_eps_311().eps_faultst()) {
696 return true;
697 }
698 }
699
700 // check vcu error
701 if (chassis_detail.has_scu_vcu_1_312() &&
703 chassis_detail.scu_vcu_1_312().vcu_faultst()) {
704 return true;
705 }
706
707 // check braking error
708 if (chassis_detail.has_scu_bcs_1_306()) {
710 chassis_detail.scu_bcs_1_306().bcs_faultst()) {
711 return true;
712 }
713 }
714
715 // check gear error
716 if (chassis_detail.has_scu_vcu_1_312()) {
718 chassis_detail.scu_vcu_1_312().vcu_gearfaultst()) {
719 return true;
720 }
721 }
722
723 // check parking error
724 if (chassis_detail.has_scu_epb_310()) {
726 chassis_detail.scu_epb_310().epb_faultst()) {
727 return true;
728 }
729 }
730
731 // check the whole vehicle error
732 if (chassis_detail.has_scu_1_301()) {
734 chassis_detail.scu_1_301().scu_faultst()) {
735 return true;
736 }
737 }
738 return false;
739}
740
741void Ge3Controller::SecurityDogThreadFunc() {
742 int32_t vertical_ctrl_fail = 0;
743 int32_t horizontal_ctrl_fail = 0;
744
745 if (can_sender_ == nullptr) {
746 AERROR << "Failed to run SecurityDogThreadFunc() because can_sender_ is "
747 "nullptr.";
748 return;
749 }
750 while (!can_sender_->IsRunning()) {
751 std::this_thread::yield();
752 }
753
754 std::chrono::duration<double, std::micro> default_period{50000};
755 int64_t start = 0;
756 int64_t end = 0;
757 while (can_sender_->IsRunning()) {
759 const Chassis::DrivingMode mode = driving_mode();
760 bool emergency_mode = false;
761
762 // 1. horizontal control check
763 if ((mode == Chassis::COMPLETE_AUTO_DRIVE ||
764 mode == Chassis::AUTO_STEER_ONLY) &&
765 !CheckResponse(CHECK_RESPONSE_STEER_UNIT_FLAG, false)) {
766 ++horizontal_ctrl_fail;
767 if (horizontal_ctrl_fail >= kMaxFailAttempt) {
768 emergency_mode = true;
769 set_chassis_error_code(Chassis::MANUAL_INTERVENTION);
770 }
771 } else {
772 horizontal_ctrl_fail = 0;
773 }
774
775 // 2. vertical control check
776 if ((mode == Chassis::COMPLETE_AUTO_DRIVE ||
777 mode == Chassis::AUTO_SPEED_ONLY) &&
778 !CheckResponse(CHECK_RESPONSE_SPEED_UNIT_FLAG, false)) {
779 ++vertical_ctrl_fail;
780 if (vertical_ctrl_fail >= kMaxFailAttempt) {
781 emergency_mode = true;
782 set_chassis_error_code(Chassis::MANUAL_INTERVENTION);
783 }
784 } else {
785 vertical_ctrl_fail = 0;
786 }
787 if (CheckChassisError()) {
788 set_chassis_error_code(Chassis::CHASSIS_ERROR);
789 emergency_mode = true;
790 }
791
792 if (emergency_mode && mode != Chassis::EMERGENCY_MODE) {
794 message_manager_->ResetSendMessages();
795 }
797 std::chrono::duration<double, std::micro> elapsed{end - start};
798 if (elapsed < default_period) {
799 std::this_thread::sleep_for(default_period - elapsed);
800 } else {
801 AERROR << "Too much time consumption in Ge3Controller looping process:"
802 << elapsed.count();
803 }
804 }
805}
806
807bool Ge3Controller::CheckResponse(const int32_t flags, bool need_wait) {
808 int32_t retry_num = 20;
809 Ge3 chassis_detail;
810 bool is_eps_online = false;
811 bool is_vcu_online = false;
812 bool is_esp_online = false;
813
814 do {
815 if (message_manager_->GetSensorData(&chassis_detail) != ErrorCode::OK) {
816 AERROR_EVERY(100) << "get chassis detail failed.";
817 return false;
818 }
819 bool check_ok = true;
820 if (flags & CHECK_RESPONSE_STEER_UNIT_FLAG) {
821 is_eps_online = chassis_.has_check_response() &&
822 chassis_.check_response().has_is_eps_online() &&
823 chassis_.check_response().is_eps_online();
824 check_ok = check_ok && is_eps_online;
825 }
826
827 if (flags & CHECK_RESPONSE_SPEED_UNIT_FLAG) {
828 is_vcu_online = chassis_.has_check_response() &&
829 chassis_.check_response().has_is_vcu_online() &&
830 chassis_.check_response().is_vcu_online();
831 is_esp_online = chassis_.has_check_response() &&
832 chassis_.check_response().has_is_esp_online() &&
833 chassis_.check_response().is_esp_online();
834 check_ok = check_ok && is_vcu_online && is_esp_online;
835 }
836 if (check_ok) {
837 return true;
838 }
839 AINFO << "Need to check response again.";
840 if (need_wait) {
841 --retry_num;
842 std::this_thread::sleep_for(
843 std::chrono::duration<double, std::milli>(20));
844 }
845 } while (need_wait && retry_num);
846
847 AINFO << "check_response fail: is_eps_online:" << is_eps_online
848 << ", is_vcu_online:" << is_vcu_online
849 << ", is_esp_online:" << is_esp_online;
850 return false;
851}
852
853void Ge3Controller::set_chassis_error_mask(const int32_t mask) {
854 std::lock_guard<std::mutex> lock(chassis_mask_mutex_);
855 chassis_error_mask_ = mask;
856}
857
858int32_t Ge3Controller::chassis_error_mask() {
859 std::lock_guard<std::mutex> lock(chassis_mask_mutex_);
860 return chassis_error_mask_;
861}
862
863Chassis::ErrorCode Ge3Controller::chassis_error_code() {
864 std::lock_guard<std::mutex> lock(chassis_error_code_mutex_);
865 return chassis_error_code_;
866}
867
868void Ge3Controller::set_chassis_error_code(
869 const Chassis::ErrorCode& error_code) {
870 std::lock_guard<std::mutex> lock(chassis_error_code_mutex_);
871 chassis_error_code_ = error_code;
872}
873
874bool Ge3Controller::CheckSafetyError(
875 const ::apollo::canbus::Ge3& chassis_detail) {
876 return false;
877}
878
879} // namespace ge3
880} // namespace canbus
881} // namespace apollo
Defines SenderMessage class and CanSender class.
virtual void set_driving_mode(const Chassis::DrivingMode &driving_mode)
MessageManager< ::apollo::canbus::Ge3 > * message_manager_
::apollo::common::ErrorCode Init(const VehicleParameter &params, CanSender<::apollo::canbus::Ge3 > *const can_sender, MessageManager<::apollo::canbus::Ge3 > *const message_manager) override
Chassis chassis() override
calculate and return the chassis.
bool Start() override
start the vehicle controller.
void Stop() override
stop the vehicle controller.
Pcbcm201 * set_pc_highbeamreq(Pc_bcm_201::Pc_highbeamreqType pc_highbeamreq)
Definition pc_bcm_201.cc:96
Pcbcm201 * set_pc_leftturnlampreq(Pc_bcm_201::Pc_leftturnlampreqType pc_leftturnlampreq)
static const int32_t ID
Definition pc_bcm_201.h:29
Pcbcm201 * set_pc_hazardlampreq(Pc_bcm_201::Pc_hazardlampreqType pc_hazardlampreq)
Pcbcm201 * set_pc_lowbeamreq(Pc_bcm_201::Pc_lowbeamreqType pc_lowbeamreq)
Definition pc_bcm_201.cc:77
Pcbcm201 * set_pc_rightturnlampreq(Pc_bcm_201::Pc_rightturnlampreqType pc_rightturnlampreq)
Pcbcm201 * set_pc_hornreq(Pc_bcm_201::Pc_hornreqType pc_hornreq)
Pcbcs202 * set_pc_brkpedenable(Pc_bcs_202::Pc_brkpedenableType pc_brkpedenable)
Definition pc_bcs_202.cc:72
Pcbcs202 * set_pc_brkpedreq(double pc_brkpedreq)
Definition pc_bcs_202.cc:48
static const int32_t ID
Definition pc_bcs_202.h:29
Pcepb203 * set_pc_epbenable(Pc_epb_203::Pc_epbenableType pc_epbenable)
Definition pc_epb_203.cc:66
static const int32_t ID
Definition pc_epb_203.h:29
Pcepb203 * set_pc_epbreq(Pc_epb_203::Pc_epbreqType pc_epbreq)
Definition pc_epb_203.cc:48
static const int32_t ID
Definition pc_eps_204.h:29
Pceps204 * set_pc_steerangreq(double pc_steerangreq)
Definition pc_eps_204.cc:93
Pceps204 * set_pc_steerenable(Pc_eps_204::Pc_steerenableType pc_steerenable)
Definition pc_eps_204.cc:74
Pceps204 * set_pc_steerspdreq(int pc_steerspdreq)
Definition pc_eps_204.cc:50
Pcvcu205 * set_pc_gearenable(Pc_vcu_205::Pc_gearenableType pc_gearenable)
static const int32_t ID
Definition pc_vcu_205.h:29
Pcvcu205 * set_pc_gearreq(Pc_vcu_205::Pc_gearreqType pc_gearreq)
Pcvcu205 * set_pc_accpedenable(Pc_vcu_205::Pc_accpedenableType pc_accpedenable)
Definition pc_vcu_205.cc:80
Pcvcu205 * set_pc_accpedreq(double pc_accpedreq)
Definition pc_vcu_205.cc:56
uint64_t ToMicrosecond() const
convert time to microsecond (us).
Definition time.cc:85
static Time Now()
get the current time.
Definition time.cc:57
#define AERROR
Definition log.h:44
#define AERROR_EVERY(freq)
Definition log.h:86
#define AINFO
Definition log.h:42
class register implement
Definition arena_queue.h:37
The class of ProtocolData
optional CheckResponse check_response
optional bool parking_brake
Definition chassis.proto:94
optional Scu_vcu_1_312 scu_vcu_1_312
Definition ge3.proto:630
optional Scu_3_303 scu_3_303
Definition ge3.proto:625
optional Scu_eps_311 scu_eps_311
Definition ge3.proto:631
optional Scu_bcs_2_307 scu_bcs_2_307
Definition ge3.proto:628
optional Scu_bcs_3_308 scu_bcs_3_308
Definition ge3.proto:617
optional Scu_bcs_1_306 scu_bcs_1_306
Definition ge3.proto:627
optional Scu_epb_310 scu_epb_310
Definition ge3.proto:629
optional Scu_2_302 scu_2_302
Definition ge3.proto:624
optional Scu_1_301 scu_1_301
Definition ge3.proto:623
optional Scu_bcm_304 scu_bcm_304
Definition ge3.proto:626
optional int32 vin16
Definition ge3.proto:242
optional int32 vin06
Definition ge3.proto:256
optional int32 vin02
Definition ge3.proto:264
optional int32 vin00
Definition ge3.proto:268
optional int32 vin03
Definition ge3.proto:262
optional int32 vin04
Definition ge3.proto:260
optional int32 vin07
Definition ge3.proto:254
optional int32 vin01
Definition ge3.proto:266
optional int32 vin05
Definition ge3.proto:258
optional int32 vin14
Definition ge3.proto:276
optional int32 vin15
Definition ge3.proto:274
optional int32 vin11
Definition ge3.proto:282
optional int32 vin09
Definition ge3.proto:286
optional int32 vin08
Definition ge3.proto:288
optional int32 vin12
Definition ge3.proto:280
optional int32 vin13
Definition ge3.proto:278
optional int32 vin10
Definition ge3.proto:284
optional Bcm_highbeamstType bcm_highbeamst
Definition ge3.proto:360
optional Bcm_leftturnlampstType bcm_leftturnlampst
Definition ge3.proto:354
optional Bcm_hornstType bcm_hornst
Definition ge3.proto:358
optional Bcm_rightturnlampstType bcm_rightturnlampst
Definition ge3.proto:346
optional double bcs_brkpedact
Definition ge3.proto:418
optional Bcs_drvmodeType bcs_drvmode
Definition ge3.proto:432
optional double bcs_vehspd
Definition ge3.proto:446
optional double bcs_frwheelspd
Definition ge3.proto:126
optional Bcs_rrwheelspdvdType bcs_rrwheelspdvd
Definition ge3.proto:102
optional Bcs_frwheeldirectionType bcs_frwheeldirection
Definition ge3.proto:128
optional double bcs_flwheelspd
Definition ge3.proto:130
optional Bcs_rlwheeldirectionType bcs_rlwheeldirection
Definition ge3.proto:124
optional Bcs_flwheeldirectionType bcs_flwheeldirection
Definition ge3.proto:132
optional double bcs_rlwheelspd
Definition ge3.proto:122
optional Bcs_rrwheeldirectionType bcs_rrwheeldirection
Definition ge3.proto:120
optional Bcs_rlwheelspdvdType bcs_rlwheelspdvd
Definition ge3.proto:106
optional double bcs_rrwheelspd
Definition ge3.proto:118
optional Bcs_flwheelspdvdType bcs_flwheelspdvd
Definition ge3.proto:114
optional Bcs_frwheelspdvdType bcs_frwheelspdvd
Definition ge3.proto:110
optional Epb_sysstType epb_sysst
Definition ge3.proto:483
optional Eps_drvmodeType eps_drvmode
Definition ge3.proto:612
optional double eps_steerangle
Definition ge3.proto:608
optional double vcu_accpedact
Definition ge3.proto:564
optional Vcu_drvmodeType vcu_drvmode
Definition ge3.proto:576
optional Vcu_gearactType vcu_gearact
Definition ge3.proto:582
The class of VehicleController