Apollo 10.0
自动驾驶开放平台
lincoln_controller.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 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
18
19#include "modules/common_msgs/basic_msgs/vehicle_signal.pb.h"
20#include "cyber/common/log.h"
21#include "cyber/time/time.h"
32
33namespace apollo {
34namespace canbus {
35namespace lincoln {
36
37using ::apollo::common::VehicleSignal;
38using ::apollo::drivers::canbus::ProtocolData;
41
42namespace {
43
44const int32_t kMaxFailAttempt = 10;
45const int32_t CHECK_RESPONSE_STEER_UNIT_FLAG = 1;
46const int32_t CHECK_RESPONSE_SPEED_UNIT_FLAG = 2;
47
48} // namespace
49
51 const VehicleParameter &params,
52 CanSender<::apollo::canbus::Lincoln> *const can_sender,
53 MessageManager<::apollo::canbus::Lincoln> *const message_manager) {
54 if (is_initialized_) {
55 AINFO << "LincolnController has already been initiated.";
56 return ErrorCode::CANBUS_ERROR;
57 }
58 vehicle_params_.CopyFrom(
59 common::VehicleConfigHelper::Instance()->GetConfig().vehicle_param());
60 params_.CopyFrom(params);
61 if (!params_.has_driving_mode()) {
62 AERROR << "Vehicle conf pb not set driving_mode.";
63 return ErrorCode::CANBUS_ERROR;
64 }
65
66 if (can_sender == nullptr) {
67 AERROR << "Canbus sender is null.";
68 return ErrorCode::CANBUS_ERROR;
69 }
70 can_sender_ = can_sender;
71
72 if (message_manager == nullptr) {
73 AERROR << "Protocol manager is null.";
74 return ErrorCode::CANBUS_ERROR;
75 }
76 message_manager_ = message_manager;
77
78 // Sender part
79 brake_60_ = dynamic_cast<Brake60 *>(
80 message_manager_->GetMutableProtocolDataById(Brake60::ID));
81 if (brake_60_ == nullptr) {
82 AERROR << "Brake60 does not exist in the LincolnMessageManager!";
83 return ErrorCode::CANBUS_ERROR;
84 }
85
86 throttle_62_ = dynamic_cast<Throttle62 *>(
87 message_manager_->GetMutableProtocolDataById(Throttle62::ID));
88 if (throttle_62_ == nullptr) {
89 AERROR << "Throttle62 does not exist in the LincolnMessageManager!";
90 return ErrorCode::CANBUS_ERROR;
91 }
92
93 steering_64_ = dynamic_cast<Steering64 *>(
94 message_manager_->GetMutableProtocolDataById(Steering64::ID));
95 if (steering_64_ == nullptr) {
96 AERROR << "Steering64 does not exist in the LincolnMessageManager!";
97 return ErrorCode::CANBUS_ERROR;
98 }
99
100 gear_66_ = dynamic_cast<Gear66 *>(
101 message_manager_->GetMutableProtocolDataById(Gear66::ID));
102 if (gear_66_ == nullptr) {
103 AERROR << "Gear66 does not exist in the LincolnMessageManager!";
104 return ErrorCode::CANBUS_ERROR;
105 }
106 turnsignal_68_ = dynamic_cast<Turnsignal68 *>(
107 message_manager_->GetMutableProtocolDataById(Turnsignal68::ID));
108 if (turnsignal_68_ == nullptr) {
109 AERROR << "Turnsignal68 does not exist in the LincolnMessageManager!";
110 return ErrorCode::CANBUS_ERROR;
111 }
112
113 can_sender_->AddMessage(Brake60::ID, brake_60_, false);
114 can_sender_->AddMessage(Throttle62::ID, throttle_62_, false);
115 can_sender_->AddMessage(Steering64::ID, steering_64_, false);
116 can_sender_->AddMessage(Gear66::ID, gear_66_, false);
117 can_sender_->AddMessage(Turnsignal68::ID, turnsignal_68_, false);
118
119 // Need to sleep to ensure all messages received
120 AINFO << "LincolnController is initialized.";
121
122 gear_tmp_ = Chassis::GEAR_INVALID;
123 is_initialized_ = true;
124 return ErrorCode::OK;
125}
126
128 if (!is_initialized_) {
129 AERROR << "LincolnController has NOT been initiated.";
130 return false;
131 }
132 const auto &update_func = [this] { SecurityDogThreadFunc(); };
133 thread_.reset(new std::thread(update_func));
134
135 return true;
136}
137
139 if (!is_initialized_) {
140 AERROR << "LincolnController stops or starts improperly!";
141 return;
142 }
143
144 if (thread_ != nullptr && thread_->joinable()) {
145 thread_->join();
146 thread_.reset();
147 AINFO << "LincolnController stopped.";
148 }
149}
150
152 chassis_.Clear();
153
154 Lincoln chassis_detail;
155 message_manager_->GetSensorData(&chassis_detail);
156
157 // 21, 22, previously 1, 2
159 set_chassis_error_code(Chassis::NO_ERROR);
160 }
161
162 chassis_.set_driving_mode(driving_mode());
163 chassis_.set_error_code(chassis_error_code());
164
165 // 3
166 chassis_.set_engine_started(true);
167 // 4
168 if (chassis_detail.has_ems() && chassis_detail.ems().has_engine_rpm()) {
169 chassis_.set_engine_rpm(
170 static_cast<float>(chassis_detail.ems().engine_rpm()));
171 } else {
172 chassis_.set_engine_rpm(0);
173 }
174 // 5
175 if (chassis_detail.has_vehicle_spd() &&
176 chassis_detail.vehicle_spd().has_vehicle_spd()) {
177 chassis_.set_speed_mps(
178 static_cast<float>(chassis_detail.vehicle_spd().vehicle_spd()));
179 chassis_.mutable_wheel_speed()->set_is_wheel_spd_rr_valid(
180 chassis_detail.vehicle_spd().is_wheel_spd_rr_valid());
181 chassis_.mutable_wheel_speed()->set_wheel_direction_rr(
182 chassis_detail.vehicle_spd().wheel_direction_rr());
183 chassis_.mutable_wheel_speed()->set_wheel_spd_rr(
184 chassis_detail.vehicle_spd().wheel_spd_rr());
185
186 chassis_.mutable_wheel_speed()->set_is_wheel_spd_rl_valid(
187 chassis_detail.vehicle_spd().is_wheel_spd_rl_valid());
188 chassis_.mutable_wheel_speed()->set_wheel_direction_rl(
189 chassis_detail.vehicle_spd().wheel_direction_rl());
190 chassis_.mutable_wheel_speed()->set_wheel_spd_rl(
191 chassis_detail.vehicle_spd().wheel_spd_rl());
192
193 chassis_.mutable_wheel_speed()->set_is_wheel_spd_fr_valid(
194 chassis_detail.vehicle_spd().is_wheel_spd_fr_valid());
195 chassis_.mutable_wheel_speed()->set_wheel_direction_fr(
196 chassis_detail.vehicle_spd().wheel_direction_fr());
197 chassis_.mutable_wheel_speed()->set_wheel_spd_fr(
198 chassis_detail.vehicle_spd().wheel_spd_fr());
199
200 chassis_.mutable_wheel_speed()->set_is_wheel_spd_fl_valid(
201 chassis_detail.vehicle_spd().is_wheel_spd_fl_valid());
202 chassis_.mutable_wheel_speed()->set_wheel_direction_fl(
203 chassis_detail.vehicle_spd().wheel_direction_fl());
204 chassis_.mutable_wheel_speed()->set_wheel_spd_fl(
205 chassis_detail.vehicle_spd().wheel_spd_fl());
206
207 } else {
208 chassis_.set_speed_mps(0);
209 }
210 // 6
211 if (chassis_detail.has_basic() && chassis_detail.basic().has_odo_meter()) {
212 // odo_meter is in km
213 chassis_.set_odometer_m(
214 static_cast<float>(chassis_detail.basic().odo_meter() * 1000.0));
215 } else {
216 chassis_.set_odometer_m(0);
217 }
218
219 // 7
220 // lincoln only has fuel percentage
221 // to avoid confusing, just don't set
222 chassis_.set_fuel_range_m(0);
223 // 8
224 if (chassis_detail.has_gas() && chassis_detail.gas().has_throttle_output()) {
225 chassis_.set_throttle_percentage(
226 static_cast<float>(chassis_detail.gas().throttle_output()));
227 } else {
228 chassis_.set_throttle_percentage(0);
229 }
230 // 9
231 if (chassis_detail.has_brake() && chassis_detail.brake().has_brake_output()) {
232 chassis_.set_brake_percentage(
233 static_cast<float>(chassis_detail.brake().brake_output()));
234 } else {
235 chassis_.set_brake_percentage(0);
236 }
237 // 23, previously 10
238 if (chassis_detail.has_gear() && chassis_detail.gear().has_gear_state()) {
239 chassis_.set_gear_location(chassis_detail.gear().gear_state());
240 } else {
241 chassis_.set_gear_location(Chassis::GEAR_NONE);
242 }
243 // 11
244 if (chassis_detail.has_eps() && chassis_detail.eps().has_steering_angle()) {
245 chassis_.set_steering_percentage(
246 static_cast<float>(chassis_detail.eps().steering_angle() * 100.0 /
247 vehicle_params_.max_steer_angle() * M_PI / 180.0));
248 } else {
249 chassis_.set_steering_percentage(0);
250 }
251 // 12
252 if (chassis_detail.has_eps() && chassis_detail.eps().has_epas_torque()) {
253 chassis_.set_steering_torque_nm(
254 static_cast<float>(chassis_detail.eps().epas_torque()));
255 } else {
256 chassis_.set_steering_torque_nm(0);
257 }
258 // 13
259 if (chassis_detail.has_eps() &&
260 chassis_detail.epb().has_parking_brake_status()) {
261 chassis_.set_parking_brake(chassis_detail.epb().parking_brake_status() ==
263 } else {
264 chassis_.set_parking_brake(false);
265 }
266
267 // 14, 15
268 if (chassis_detail.has_light() &&
269 chassis_detail.light().has_lincoln_lamp_type()) {
270 chassis_.mutable_signal()->set_high_beam(
271 chassis_detail.light().lincoln_lamp_type() == Light::BEAM_HIGH);
272 } else {
273 chassis_.mutable_signal()->set_high_beam(false);
274 }
275
276 // 16, 17
277 if (chassis_detail.has_light() &&
278 chassis_detail.light().has_turn_light_type() &&
279 chassis_detail.light().turn_light_type() != Light::TURN_LIGHT_OFF) {
280 if (chassis_detail.light().turn_light_type() == Light::TURN_LEFT_ON) {
281 chassis_.mutable_signal()->set_turn_signal(
283 } else if (chassis_detail.light().turn_light_type() ==
285 chassis_.mutable_signal()->set_turn_signal(
287 } else {
288 chassis_.mutable_signal()->set_turn_signal(
290 }
291 } else {
292 chassis_.mutable_signal()->set_turn_signal(
294 }
295 // 18
296 if (chassis_detail.has_light() && chassis_detail.light().has_is_horn_on() &&
297 chassis_detail.light().is_horn_on()) {
298 chassis_.mutable_signal()->set_horn(true);
299 } else {
300 chassis_.mutable_signal()->set_horn(false);
301 }
302
303 // 19, lincoln wiper is too complicated
304 // 24
305 if (chassis_detail.has_eps() && chassis_detail.eps().has_timestamp_65()) {
306 chassis_.set_steering_timestamp(chassis_detail.eps().timestamp_65());
307 }
308 // 26
309 if (chassis_error_mask_) {
310 chassis_.set_chassis_error_mask(chassis_error_mask_);
311 }
312
313 // 6d, 6e, 6f, if gps valid is available, assume all gps related field
314 // available
315 if (chassis_detail.basic().has_gps_valid()) {
316 chassis_.mutable_chassis_gps()->set_latitude(
317 chassis_detail.basic().latitude());
318 chassis_.mutable_chassis_gps()->set_longitude(
319 chassis_detail.basic().longitude());
320 chassis_.mutable_chassis_gps()->set_gps_valid(
321 chassis_detail.basic().gps_valid());
322 chassis_.mutable_chassis_gps()->set_year(chassis_detail.basic().year());
323 chassis_.mutable_chassis_gps()->set_month(chassis_detail.basic().month());
324 chassis_.mutable_chassis_gps()->set_day(chassis_detail.basic().day());
325 chassis_.mutable_chassis_gps()->set_hours(chassis_detail.basic().hours());
326 chassis_.mutable_chassis_gps()->set_minutes(
327 chassis_detail.basic().minutes());
328 chassis_.mutable_chassis_gps()->set_seconds(
329 chassis_detail.basic().seconds());
330 chassis_.mutable_chassis_gps()->set_compass_direction(
331 chassis_detail.basic().compass_direction());
332 chassis_.mutable_chassis_gps()->set_pdop(chassis_detail.basic().pdop());
333 chassis_.mutable_chassis_gps()->set_is_gps_fault(
334 chassis_detail.basic().is_gps_fault());
335 chassis_.mutable_chassis_gps()->set_is_inferred(
336 chassis_detail.basic().is_inferred());
337 chassis_.mutable_chassis_gps()->set_altitude(
338 chassis_detail.basic().altitude());
339 chassis_.mutable_chassis_gps()->set_heading(
340 chassis_detail.basic().heading());
341 chassis_.mutable_chassis_gps()->set_hdop(chassis_detail.basic().hdop());
342 chassis_.mutable_chassis_gps()->set_vdop(chassis_detail.basic().vdop());
343 chassis_.mutable_chassis_gps()->set_quality(
344 chassis_detail.basic().quality());
345 chassis_.mutable_chassis_gps()->set_num_satellites(
346 chassis_detail.basic().num_satellites());
347 chassis_.mutable_chassis_gps()->set_gps_speed(
348 chassis_detail.basic().gps_speed());
349 } else {
350 chassis_.mutable_chassis_gps()->set_gps_valid(false);
351 }
352
353 // VIN number will be written into KVDB once.
354 if (chassis_detail.vehicle_id().has_vin()) {
355 chassis_.mutable_vehicle_id()->set_vin(chassis_detail.vehicle_id().vin());
356 if (!received_vin_) {
357 apollo::common::KVDB::Put("apollo:canbus:vin",
358 chassis_detail.vehicle_id().vin());
359 received_vin_ = true;
360 }
361 }
362
363 if (chassis_detail.has_surround()) {
364 chassis_.mutable_surround()->CopyFrom(chassis_detail.surround());
365 }
366 // Give engage_advice based on error_code and canbus feedback
367 if (chassis_error_mask_ || chassis_.throttle_percentage() == 0.0 ||
368 chassis_.brake_percentage() == 0.0) {
369 chassis_.mutable_engage_advice()->set_advice(
371 chassis_.mutable_engage_advice()->set_reason("Chassis error!");
372 } else if (chassis_.parking_brake() || CheckSafetyError(chassis_detail)) {
373 chassis_.mutable_engage_advice()->set_advice(
375 chassis_.mutable_engage_advice()->set_reason(
376 "Vehicle is not in a safe state to engage!");
377 } else {
378 chassis_.mutable_engage_advice()->set_advice(
380 }
381 return chassis_;
382}
383
384bool LincolnController::VerifyID() { return true; }
385
386void LincolnController::Emergency() {
388 ResetProtocol();
389 if (chassis_error_code() == Chassis::NO_ERROR) {
390 set_chassis_error_code(Chassis::CHASSIS_ERROR);
391 }
392}
393
394ErrorCode LincolnController::EnableAutoMode() {
396 AINFO << "Already in COMPLETE_AUTO_DRIVE mode";
397 return ErrorCode::OK;
398 }
399 brake_60_->set_enable();
400 throttle_62_->set_enable();
401 steering_64_->set_enable();
402
403 can_sender_->Update();
404 const int32_t flag =
405 CHECK_RESPONSE_STEER_UNIT_FLAG | CHECK_RESPONSE_SPEED_UNIT_FLAG;
406 if (!CheckResponse(flag, true)) {
407 AERROR << "Failed to switch to COMPLETE_AUTO_DRIVE mode.";
408 CheckChassisError();
409 Emergency();
410 return ErrorCode::CANBUS_ERROR;
411 }
413 AINFO << "Switch to COMPLETE_AUTO_DRIVE mode ok.";
414 return ErrorCode::OK;
415}
416
417ErrorCode LincolnController::DisableAutoMode() {
418 ResetProtocol();
419 can_sender_->Update();
421 set_chassis_error_code(Chassis::NO_ERROR);
422 AINFO << "Switch to COMPLETE_MANUAL ok.";
423 return ErrorCode::OK;
424}
425
426ErrorCode LincolnController::EnableSteeringOnlyMode() {
430 AINFO << "Already in AUTO_STEER_ONLY mode";
431 return ErrorCode::OK;
432 }
433 brake_60_->set_disable();
434 throttle_62_->set_disable();
435 steering_64_->set_enable();
436
437 can_sender_->Update();
438 if (!CheckResponse(CHECK_RESPONSE_STEER_UNIT_FLAG, true)) {
439 AERROR << "Failed to switch to AUTO_STEER_ONLY mode.";
440 CheckChassisError();
441 Emergency();
442 return ErrorCode::CANBUS_ERROR;
443 }
445 AINFO << "Switch to AUTO_STEER_ONLY mode ok.";
446 return ErrorCode::OK;
447}
448
449ErrorCode LincolnController::EnableSpeedOnlyMode() {
453 AINFO << "Already in AUTO_SPEED_ONLY mode";
454 return ErrorCode::OK;
455 }
456 brake_60_->set_enable();
457 throttle_62_->set_enable();
458 steering_64_->set_disable();
459
460 can_sender_->Update();
461 if (!CheckResponse(CHECK_RESPONSE_SPEED_UNIT_FLAG, true)) {
462 AERROR << "Failed to switch to AUTO_SPEED_ONLY mode.";
463 CheckChassisError();
464 Emergency();
465 return ErrorCode::CANBUS_ERROR;
466 }
468 AINFO << "Switch to AUTO_SPEED_ONLY mode ok.";
469 return ErrorCode::OK;
470}
471
472// NEUTRAL, REVERSE, DRIVE
473void LincolnController::Gear(Chassis::GearPosition ref_gear_position) {
476 AINFO << "This drive mode no need to set gear.";
477 return;
478 }
479
480 Lincoln chassis_detail;
481 message_manager_->GetSensorData(&chassis_detail);
482 const Chassis::GearPosition current_gear_position =
483 chassis_detail.gear().gear_state();
484 if (ref_gear_position == current_gear_position) {
485 return;
486 }
487
488 // Need to request neutral gear first if current gear location is not neutral
489 // or none
490 if (ref_gear_position != current_gear_position &&
491 current_gear_position != Chassis::GEAR_NEUTRAL &&
492 current_gear_position != Chassis::GEAR_NONE) {
493 gear_tmp_ = Chassis::GEAR_NEUTRAL;
494 } else if (current_gear_position == Chassis::GEAR_NEUTRAL) {
495 gear_tmp_ = ref_gear_position;
496 }
497
498 switch (gear_tmp_) {
500 gear_66_->set_gear_neutral();
501 break;
502 }
504 gear_66_->set_gear_reverse();
505 break;
506 }
507 case Chassis::GEAR_DRIVE: {
508 gear_66_->set_gear_drive();
509 break;
510 }
512 gear_66_->set_gear_park();
513 break;
514 }
515 case Chassis::GEAR_LOW: {
516 gear_66_->set_gear_low();
517 break;
518 }
519 case Chassis::GEAR_NONE: {
520 gear_66_->set_gear_none();
521 break;
522 }
524 AERROR << "Gear command is invalid!";
525 gear_66_->set_gear_none();
526 break;
527 }
528 default: {
529 gear_66_->set_gear_none();
530 break;
531 }
532 }
533}
534
535// brake with new acceleration
536// acceleration:0.00~99.99, unit:%
537// acceleration:0.0 ~ 7.0, unit:m/s^2
538// acceleration_spd:60 ~ 100, suggest: 90
539// -> pedal
540void LincolnController::Brake(double pedal) {
543 AINFO << "The current drive mode does not need to set acceleration.";
544 return;
545 }
546 brake_60_->set_pedal(pedal);
547}
548
549// drive with old acceleration
550// gas:0.00~99.99 unit:%
551void LincolnController::Throttle(double pedal) {
554 AINFO << "The current drive mode does not need to set acceleration.";
555 return;
556 }
557 throttle_62_->set_pedal(pedal);
558}
559
560// drive with acceleration/deceleration
561// acc:-7.0 ~ 5.0, unit:m/s^2
562void LincolnController::Acceleration(double acc) {
565 AINFO << "The current drive mode does not need to set acceleration.";
566 return;
567 }
568 // None
569}
570
571// lincoln default, -470 ~ 470, left:+, right:-
572// need to be compatible with control module, so reverse
573// steering with old angle speed
574// angle:-99.99~0.00~99.99, unit:%, left:-, right:+
575void LincolnController::Steer(double angle) {
578 AINFO << "The current driving mode does not need to set steer.";
579 return;
580 }
581 const double real_angle =
582 vehicle_params_.max_steer_angle() / M_PI * 180 * angle / 100.0;
583 // reverse sign
584 steering_64_->set_steering_angle(real_angle)->set_steering_angle_speed(200);
585}
586
587// steering with new angle speed
588// angle:-99.99~0.00~99.99, unit:%, left:-, right:+
589// angle_spd:0.00~99.99, unit:deg/s
590void LincolnController::Steer(double angle, double angle_spd) {
593 AINFO << "The current driving mode does not need to set steer.";
594 return;
595 }
596 const double real_angle =
597 vehicle_params_.max_steer_angle() / M_PI * 180 * angle / 100.0;
598 const double real_angle_spd =
599 ProtocolData<::apollo::canbus::Lincoln>::BoundedValue(
602 vehicle_params_.max_steer_angle_rate() / M_PI * 180 * angle_spd /
603 100.0);
604 steering_64_->set_steering_angle(real_angle)
605 ->set_steering_angle_speed(real_angle_spd);
606}
607
608void LincolnController::SetEpbBreak(const ControlCommand &command) {
609 if (command.parking_brake()) {
610 // None
611 } else {
612 // None
613 }
614}
615
616ErrorCode LincolnController::HandleCustomOperation(
617 const external_command::ChassisCommand &command) {
618 return ErrorCode::OK;
619}
620
621void LincolnController::SetBeam(const VehicleSignal &vehicle_signal) {
622 if (vehicle_signal.has_high_beam() && vehicle_signal.high_beam()) {
623 // None
624 } else if (vehicle_signal.has_low_beam() && vehicle_signal.low_beam()) {
625 // None
626 } else {
627 // None
628 }
629}
630
631void LincolnController::SetHorn(const VehicleSignal &vehicle_signal) {
632 if (vehicle_signal.horn()) {
633 // None
634 } else {
635 // None
636 }
637}
638
639void LincolnController::SetTurningSignal(const VehicleSignal &vehicle_signal) {
640 // Set Turn Signal
641 auto signal = vehicle_signal.turn_signal();
642 if (signal == common::VehicleSignal::TURN_LEFT) {
643 turnsignal_68_->set_turn_left();
644 } else if (signal == common::VehicleSignal::TURN_RIGHT) {
645 turnsignal_68_->set_turn_right();
646 } else {
647 turnsignal_68_->set_turn_none();
648 }
649}
650
651void LincolnController::ResetProtocol() {
652 message_manager_->ResetSendMessages();
653}
654
655bool LincolnController::CheckChassisError() {
656 Lincoln chassis_detail;
657 message_manager_->GetSensorData(&chassis_detail);
658
659 int32_t error_cnt = 0;
660 int32_t chassis_error_mask = 0;
661
662 // Steer fault
663 bool steer_fault = chassis_detail.eps().watchdog_fault() |
664 chassis_detail.eps().channel_1_fault() |
665 chassis_detail.eps().channel_2_fault() |
666 chassis_detail.eps().calibration_fault() |
667 chassis_detail.eps().connector_fault();
668
669 chassis_error_mask |=
670 ((chassis_detail.eps().watchdog_fault()) << (++error_cnt));
671 chassis_error_mask |=
672 ((chassis_detail.eps().channel_1_fault()) << (++error_cnt));
673 chassis_error_mask |=
674 ((chassis_detail.eps().channel_2_fault()) << (++error_cnt));
675 chassis_error_mask |=
676 ((chassis_detail.eps().calibration_fault()) << (++error_cnt));
677 chassis_error_mask |=
678 ((chassis_detail.eps().connector_fault()) << (++error_cnt));
679
680 if (!chassis_detail.has_brake()) {
681 AERROR_EVERY(100) << "Lincoln has NO brake."
682 << chassis_detail.DebugString();
683 return false;
684 }
685 // Brake fault
686 bool brake_fault = chassis_detail.brake().watchdog_fault() |
687 chassis_detail.brake().channel_1_fault() |
688 chassis_detail.brake().channel_2_fault() |
689 chassis_detail.brake().boo_fault() |
690 chassis_detail.brake().connector_fault();
691
692 chassis_error_mask |=
693 ((chassis_detail.brake().watchdog_fault()) << (++error_cnt));
694 chassis_error_mask |=
695 ((chassis_detail.brake().channel_1_fault()) << (++error_cnt));
696 chassis_error_mask |=
697 ((chassis_detail.brake().channel_2_fault()) << (++error_cnt));
698 chassis_error_mask |= ((chassis_detail.brake().boo_fault()) << (++error_cnt));
699 chassis_error_mask |=
700 ((chassis_detail.brake().connector_fault()) << (++error_cnt));
701
702 if (!chassis_detail.has_gas()) {
703 AERROR_EVERY(100) << "Lincoln has NO gas." << chassis_detail.DebugString();
704 return false;
705 }
706 // Throttle fault
707 bool throttle_fault = chassis_detail.gas().watchdog_fault() |
708 chassis_detail.gas().channel_1_fault() |
709 chassis_detail.gas().channel_2_fault() |
710 chassis_detail.gas().connector_fault();
711
712 chassis_error_mask |=
713 ((chassis_detail.gas().watchdog_fault()) << (++error_cnt));
714 chassis_error_mask |=
715 ((chassis_detail.gas().channel_1_fault()) << (++error_cnt));
716 chassis_error_mask |=
717 ((chassis_detail.gas().channel_2_fault()) << (++error_cnt));
718 chassis_error_mask |=
719 ((chassis_detail.gas().connector_fault()) << (++error_cnt));
720
721 if (!chassis_detail.has_gear()) {
722 AERROR_EVERY(100) << "Lincoln has NO gear." << chassis_detail.DebugString();
723 return false;
724 }
725 // Gear fault
726 bool gear_fault = chassis_detail.gear().canbus_fault();
727
728 chassis_error_mask |=
729 ((chassis_detail.gear().canbus_fault()) << (++error_cnt));
730
731 set_chassis_error_mask(chassis_error_mask);
732
733 if (steer_fault) {
734 set_chassis_error_code(Chassis::CHASSIS_ERROR_ON_STEER);
735 AERROR_EVERY(100) << "Steering fault detected: "
736 << chassis_detail.eps().watchdog_fault() << ", "
737 << chassis_detail.eps().channel_1_fault() << ", "
738 << chassis_detail.eps().channel_2_fault() << ", "
739 << chassis_detail.eps().calibration_fault() << ", "
740 << chassis_detail.eps().connector_fault();
741 }
742
743 if (brake_fault) {
744 set_chassis_error_code(Chassis::CHASSIS_ERROR_ON_BRAKE);
745 AERROR_EVERY(100) << "Brake fault detected: "
746 << chassis_detail.brake().watchdog_fault() << ", "
747 << chassis_detail.brake().channel_1_fault() << ", "
748 << chassis_detail.brake().channel_2_fault() << ", "
749 << chassis_detail.brake().boo_fault() << ", "
750 << chassis_detail.brake().connector_fault();
751 }
752
753 if (throttle_fault) {
754 set_chassis_error_code(Chassis::CHASSIS_ERROR_ON_THROTTLE);
755 AERROR_EVERY(100) << "Throttle fault detected: "
756 << chassis_detail.gas().watchdog_fault() << ", "
757 << chassis_detail.gas().channel_1_fault() << ", "
758 << chassis_detail.gas().channel_2_fault() << ", "
759 << chassis_detail.gas().connector_fault();
760 }
761
762 if (gear_fault) {
763 set_chassis_error_code(Chassis::CHASSIS_ERROR_ON_GEAR);
764 AERROR_EVERY(100) << "Gear fault detected: "
765 << chassis_detail.gear().canbus_fault();
766 }
767
768 if (steer_fault || brake_fault || throttle_fault) {
769 return true;
770 }
771
772 return false;
773}
774
775void LincolnController::SecurityDogThreadFunc() {
776 if (can_sender_ == nullptr) {
777 AERROR << "Failed to run SecurityDogThreadFunc() because can_sender_ is "
778 "nullptr.";
779 return;
780 }
781 while (!can_sender_->IsRunning()) {
782 std::this_thread::yield();
783 }
784
785 std::chrono::duration<double, std::micro> default_period{50000};
786 int64_t start = cyber::Time::Now().ToMicrosecond();
787
788 int32_t speed_ctrl_fail = 0;
789 int32_t steer_ctrl_fail = 0;
790
791 while (can_sender_->IsRunning()) {
792 const Chassis::DrivingMode mode = driving_mode();
793 bool emergency_mode = false;
794
795 // 1. Steer control check
796 if ((mode == Chassis::COMPLETE_AUTO_DRIVE ||
797 mode == Chassis::AUTO_STEER_ONLY) &&
798 !CheckResponse(CHECK_RESPONSE_STEER_UNIT_FLAG, false)) {
799 ++steer_ctrl_fail;
800 if (steer_ctrl_fail >= kMaxFailAttempt) {
801 emergency_mode = true;
802 set_chassis_error_code(Chassis::MANUAL_INTERVENTION);
803 }
804 } else {
805 steer_ctrl_fail = 0;
806 }
807
808 // 2. Speed control check
809 if ((mode == Chassis::COMPLETE_AUTO_DRIVE ||
810 mode == Chassis::AUTO_SPEED_ONLY) &&
811 !CheckResponse(CHECK_RESPONSE_SPEED_UNIT_FLAG, false)) {
812 ++speed_ctrl_fail;
813 if (speed_ctrl_fail >= kMaxFailAttempt) {
814 emergency_mode = true;
815 set_chassis_error_code(Chassis::MANUAL_INTERVENTION);
816 }
817 } else {
818 speed_ctrl_fail = 0;
819 }
820 if (CheckChassisError()) {
821 emergency_mode = true;
822 }
823
824 if (emergency_mode && mode != Chassis::EMERGENCY_MODE) {
825 Emergency();
826 }
827 int64_t end = cyber::Time::Now().ToMicrosecond();
828 std::chrono::duration<double, std::micro> elapsed{end - start};
829 if (elapsed < default_period) {
830 std::this_thread::sleep_for(default_period - elapsed);
832 } else {
833 AERROR_EVERY(100)
834 << "Too much time consumption in LincolnController looping process:"
835 << elapsed.count();
836 start = end;
837 }
838 }
839}
840
841bool LincolnController::CheckResponse(const int32_t flags, bool need_wait) {
842 // for Lincoln, CheckResponse commonly takes 300ms. We leave a 100ms buffer
843 // for it.
844 int32_t retry_num = 20;
845 Lincoln chassis_detail;
846 bool is_eps_online = false;
847 bool is_vcu_online = false;
848 bool is_esp_online = false;
849
850 do {
851 if (message_manager_->GetSensorData(&chassis_detail) != ErrorCode::OK) {
852 AERROR_EVERY(100) << "Get chassis detail failed.";
853 return false;
854 }
855 bool check_ok = true;
856 if (flags & CHECK_RESPONSE_STEER_UNIT_FLAG) {
857 is_eps_online = chassis_detail.has_check_response() &&
858 chassis_detail.check_response().has_is_eps_online() &&
859 chassis_detail.check_response().is_eps_online();
860 check_ok = check_ok && is_eps_online;
861 }
862
863 if (flags & CHECK_RESPONSE_SPEED_UNIT_FLAG) {
864 is_vcu_online = chassis_detail.has_check_response() &&
865 chassis_detail.check_response().has_is_vcu_online() &&
866 chassis_detail.check_response().is_vcu_online();
867 is_esp_online = chassis_detail.has_check_response() &&
868 chassis_detail.check_response().has_is_esp_online() &&
869 chassis_detail.check_response().is_esp_online();
870 check_ok = check_ok && is_vcu_online && is_esp_online;
871 }
872 if (check_ok) {
873 return true;
874 }
875 AINFO << "Need to check response again.";
876 if (need_wait) {
877 --retry_num;
878 std::this_thread::sleep_for(
879 std::chrono::duration<double, std::milli>(20));
880 }
881 } while (need_wait && retry_num);
882
883 AINFO << "check_response fail: is_eps_online:" << is_eps_online
884 << ", is_vcu_online:" << is_vcu_online
885 << ", is_esp_online:" << is_esp_online;
886 return false;
887}
888
889void LincolnController::set_chassis_error_mask(const int32_t mask) {
890 std::lock_guard<std::mutex> lock(chassis_mask_mutex_);
891 chassis_error_mask_ = mask;
892}
893
894int32_t LincolnController::chassis_error_mask() {
895 std::lock_guard<std::mutex> lock(chassis_mask_mutex_);
896 return chassis_error_mask_;
897}
898
899Chassis::ErrorCode LincolnController::chassis_error_code() {
900 std::lock_guard<std::mutex> lock(chassis_error_code_mutex_);
901 return chassis_error_code_;
902}
903
904void LincolnController::set_chassis_error_code(
905 const Chassis::ErrorCode &error_code) {
906 std::lock_guard<std::mutex> lock(chassis_error_code_mutex_);
907 chassis_error_code_ = error_code;
908}
909
910bool LincolnController::CheckSafetyError(
911 const ::apollo::canbus::Lincoln &chassis_detail) {
912 bool safety_error =
913 chassis_detail.safety().is_passenger_door_open() ||
914 chassis_detail.safety().is_rearleft_door_open() ||
915 chassis_detail.safety().is_rearright_door_open() ||
916 chassis_detail.safety().is_hood_open() ||
917 chassis_detail.safety().is_trunk_open() ||
918 (chassis_detail.safety().is_passenger_detected() &&
919 (!chassis_detail.safety().is_passenger_airbag_enabled() ||
920 !chassis_detail.safety().is_passenger_buckled()));
921 ADEBUG << "Vehicle safety error status is : " << safety_error;
922 return safety_error;
923}
924
925} // namespace lincoln
926} // namespace canbus
927} // namespace apollo
the class of Brake60 (for lincoln vehicle)
Defines SenderMessage class and CanSender class.
virtual void set_driving_mode(const Chassis::DrivingMode &driving_mode)
MessageManager< ::apollo::canbus::Lincoln > * message_manager_
one of the protocol data of lincoln vehicle
Definition brake_60.h:41
Brake60 * set_pedal(double pcmd)
set pedal based on pedal command
Definition brake_60.cc:52
Brake60 * set_enable()
set pedal_enable_ to true
Definition brake_60.cc:72
Brake60 * set_disable()
set pedal_enable_ to false
Definition brake_60.cc:77
static const int32_t ID
Definition brake_60.h:43
one of the protocol data of lincoln vehicle
Definition gear_66.h:41
Gear66 * set_gear_low()
set gear to low
Definition gear_66.cc:68
Gear66 * set_gear_reverse()
set gear to reverse
Definition gear_66.cc:53
static const int32_t ID
Definition gear_66.h:43
Gear66 * set_gear_park()
set gear to park
Definition gear_66.cc:48
Gear66 * set_gear_drive()
set gear to drive
Definition gear_66.cc:63
Gear66 * set_gear_none()
set gear to none
Definition gear_66.cc:43
Gear66 * set_gear_neutral()
set gear to neutral
Definition gear_66.cc:58
Chassis chassis() override
calculate and return the chassis.
void Stop() override
stop the vehicle controller.
common::ErrorCode Init(const VehicleParameter &params, CanSender<::apollo::canbus::Lincoln > *const can_sender, MessageManager<::apollo::canbus::Lincoln > *const message_manager) override
initialize the lincoln vehicle controller.
bool Start() override
start the vehicle controller.
one of the protocol data of lincoln vehicle
Definition steering_64.h:41
Steering64 * set_enable()
set steering request enable to true
Steering64 * set_steering_angle_speed(double angle_speed)
set steering angle speed
Steering64 * set_steering_angle(double angle)
set steering angle
Steering64 * set_disable()
set steering request disable to true
one of the protocol data of lincoln vehicle
Definition throttle_62.h:41
Throttle62 * set_disable()
set disable
Throttle62 * set_pedal(double pcmd)
set pedal based on pedal command
Throttle62 * set_enable()
set enable
one of the protocol data of lincoln vehicle
Turnsignal68 * set_turn_right()
set turn right based on pedal command
Turnsignal68 * set_turn_none()
set no-turn based on pedal command
Turnsignal68 * set_turn_left()
set turn left based on pedal command
static bool Put(std::string_view key, std::string_view value)
Store {key, value} to DB.
Definition kv_db.cc:94
uint64_t ToMicrosecond() const
convert time to microsecond (us).
Definition time.cc:85
static Time Now()
get the current time.
Definition time.cc:57
the class of Gear66 (for lincoln vehicle)
The class of LincolnController
the class of LincolnMessageManager
#define ADEBUG
Definition log.h:41
#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
the class of Steering64 (for lincoln vehicle)
optional int32 num_satellites
optional GpsQuality quality
optional double heading
optional double latitude
optional double altitude
optional double longitude
optional double odo_meter
optional double compass_direction
optional double gps_speed
optional double brake_output
optional float brake_percentage
Definition chassis.proto:82
optional bool parking_brake
Definition chassis.proto:94
optional float throttle_percentage
Definition chassis.proto:79
optional double engine_rpm
optional PBrakeType parking_brake_status
optional double epas_torque
optional double timestamp_65
optional double steering_angle
optional double throttle_output
optional Chassis::GearPosition gear_state
optional LincolnLampType lincoln_lamp_type
optional bool is_horn_on
optional TurnLightType turn_light_type
Definition gem.proto:464
optional BasicInfo basic
Definition lincoln.proto:15
optional apollo::common::VehicleID vehicle_id
Definition lincoln.proto:31
optional VehicleSpd vehicle_spd
Definition lincoln.proto:24
optional Brake brake
Definition lincoln.proto:22
optional Light light
Definition lincoln.proto:26
optional Surround surround
Definition lincoln.proto:29
optional WheelSpeed::WheelSpeedType wheel_direction_rr
optional WheelSpeed::WheelSpeedType wheel_direction_fl
optional bool is_wheel_spd_fl_valid
optional WheelSpeed::WheelSpeedType wheel_direction_rl
optional double wheel_spd_fr
optional double vehicle_spd
optional double wheel_spd_rr
optional bool is_wheel_spd_fr_valid
optional bool is_wheel_spd_rr_valid
optional double wheel_spd_fl
optional WheelSpeed::WheelSpeedType wheel_direction_fr
optional double wheel_spd_rl
optional bool is_wheel_spd_rl_valid
the class of Throttle62 (for lincoln vehicle)
the class of Turnsignal68 (for lincoln vehicle)
The class of VehicleController