33using ::apollo::common::ErrorCode;
34using ::apollo::common::VehicleSignal;
35using ::apollo::control::ControlCommand;
36using ::apollo::drivers::canbus::ProtocolData;
39const int32_t kMaxFailAttempt = 10;
40const int32_t CHECK_RESPONSE_STEER_UNIT_FLAG = 1;
41const int32_t CHECK_RESPONSE_SPEED_UNIT_FLAG = 2;
47 CanSender<::apollo::canbus::Ch>*
const can_sender,
48 MessageManager<::apollo::canbus::Ch>*
const message_manager) {
50 AINFO <<
"ChController has already been initiated.";
51 return ErrorCode::CANBUS_ERROR;
55 common::VehicleConfigHelper::Instance()->GetConfig().vehicle_param());
57 if (!
params_.has_driving_mode()) {
58 AERROR <<
"Vehicle conf pb not set driving_mode.";
59 return ErrorCode::CANBUS_ERROR;
62 if (can_sender ==
nullptr) {
63 AERROR <<
"Canbus sender is null.";
64 return ErrorCode::CANBUS_ERROR;
68 if (message_manager ==
nullptr) {
69 AERROR <<
"protocol manager is null.";
70 return ErrorCode::CANBUS_ERROR;
77 if (brake_command_111_ ==
nullptr) {
78 AERROR <<
"Brakecommand111 does not exist in the ChMessageManager!";
79 return ErrorCode::CANBUS_ERROR;
84 if (gear_command_114_ ==
nullptr) {
85 AERROR <<
"Gearcommand114 does not exist in the ChMessageManager!";
86 return ErrorCode::CANBUS_ERROR;
91 if (steer_command_112_ ==
nullptr) {
92 AERROR <<
"Steercommand112 does not exist in the ChMessageManager!";
93 return ErrorCode::CANBUS_ERROR;
98 if (throttle_command_110_ ==
nullptr) {
99 AERROR <<
"Throttlecommand110 does not exist in the ChMessageManager!";
100 return ErrorCode::CANBUS_ERROR;
105 if (turnsignal_command_113_ ==
nullptr) {
106 AERROR <<
"Turnsignalcommand113 does not exist in the ChMessageManager!";
107 return ErrorCode::CANBUS_ERROR;
112 if (vehicle_mode_command_116_ ==
nullptr) {
113 AERROR <<
"Vehiclemodecommand116 does not exist in the ChMessageManager!";
114 return ErrorCode::CANBUS_ERROR;
127 AINFO <<
"ChController is initialized.";
130 return ErrorCode::OK;
137 AERROR <<
"ChController has NOT been initiated.";
140 const auto& update_func = [
this] { SecurityDogThreadFunc(); };
141 thread_.reset(
new std::thread(update_func));
148 AERROR <<
"ChController stops or starts improperly!";
152 if (thread_ !=
nullptr && thread_->joinable()) {
155 AINFO <<
"ChController stopped.";
170 chassis_.set_error_code(chassis_error_code());
172 chassis_.set_engine_started(
true);
176 if (chassis_detail.has_ecu_status_1_515() &&
178 chassis_.set_speed_mps(
181 chassis_.set_speed_mps(0);
188 if (chassis_detail.has_throttle_status__510() &&
190 chassis_.set_throttle_percentage(
static_cast<float>(
193 chassis_.set_throttle_percentage(0);
196 if (chassis_detail.has_brake_status__511() &&
198 chassis_.set_brake_percentage(
static_cast<float>(
201 chassis_.set_brake_percentage(0);
204 if (chassis_detail.has_gear_status_514() &&
225 chassis_.set_gear_location(gear_pos);
230 if (chassis_detail.has_steer_status__512() &&
232 chassis_.set_steering_percentage(
static_cast<float>(
236 chassis_.set_steering_percentage(0);
239 if (chassis_detail.has_ecu_status_2_516() &&
241 chassis_.set_battery_soc_percentage(
247 chassis_.mutable_engage_advice()->set_advice(
250 chassis_.mutable_engage_advice()->set_advice(
253 chassis_.mutable_engage_advice()->set_reason(
254 "Battery soc percentage is lower than 15%, please charge it "
261 std::string vin =
"";
262 if (chassis_detail.has_vin_resp1_51b()) {
264 vin += vin_51b.
vin01();
265 vin += vin_51b.
vin02();
266 vin += vin_51b.
vin03();
267 vin += vin_51b.
vin04();
268 vin += vin_51b.
vin05();
269 vin += vin_51b.
vin06();
270 vin += vin_51b.
vin07();
271 vin += vin_51b.
vin08();
273 if (chassis_detail.has_vin_resp2_51c()) {
275 vin += vin_51c.
vin09();
276 vin += vin_51c.
vin10();
277 vin += vin_51c.
vin11();
278 vin += vin_51c.
vin12();
279 vin += vin_51c.
vin13();
280 vin += vin_51c.
vin14();
281 vin += vin_51c.
vin15();
282 vin += vin_51c.
vin16();
284 if (chassis_detail.has_vin_resp3_51d()) {
286 vin += vin_51d.
vin17();
288 std::reverse(vin.begin(), vin.end());
289 chassis_.mutable_vehicle_id()->set_vin(vin);
292 if (chassis_detail.has_brake_status__511() &&
304 if (chassis_detail.has_brake_status__511() &&
316 if (chassis_detail.has_brake_status__511() &&
318 chassis_.mutable_check_response()->set_is_esp_online(
321 if (chassis_detail.has_steer_status__512() &&
323 chassis_.mutable_check_response()->set_is_eps_online(
326 if (chassis_detail.has_throttle_status__510() &&
328 chassis_.mutable_check_response()->set_is_vcu_online(
332 if (CheckChassisError()) {
333 chassis_.mutable_engage_advice()->set_advice(
335 chassis_.mutable_engage_advice()->set_reason(
336 "Chassis has some fault, please check the chassis_detail.");
341 chassis_.mutable_engage_advice()->set_advice(
343 chassis_.mutable_engage_advice()->set_reason(
344 "ch chassis detail is lost! Please check the communication error.");
352void ChController::Emergency() {
357ErrorCode ChController::EnableAutoMode() {
359 AINFO <<
"already in COMPLETE_AUTO_DRIVE mode";
360 return ErrorCode::OK;
369 AINFO <<
"set enable";
373 CHECK_RESPONSE_STEER_UNIT_FLAG | CHECK_RESPONSE_SPEED_UNIT_FLAG;
374 if (!CheckResponse(flag,
true)) {
375 AERROR <<
"Failed to switch to COMPLETE_AUTO_DRIVE mode. Please check the "
376 "emergency button or chassis.";
379 return ErrorCode::CANBUS_ERROR;
382 AINFO <<
"Switch to COMPLETE_AUTO_DRIVE mode ok.";
383 return ErrorCode::OK;
387ErrorCode ChController::DisableAutoMode() {
392 AINFO <<
"Switch to COMPLETE_MANUAL OK!";
393 return ErrorCode::OK;
396ErrorCode ChController::EnableSteeringOnlyMode() {
397 AFATAL <<
"SteeringOnlyMode Not supported!";
398 return ErrorCode::OK;
401ErrorCode ChController::EnableSpeedOnlyMode() {
402 AFATAL <<
"SpeedOnlyMode Not supported!";
403 return ErrorCode::OK;
410 AINFO <<
"this drive mode no need to set gear.";
415 switch (gear_position) {
448void ChController::Brake(
double pedal) {
452 AINFO <<
"The current drive mode does not need to set acceleration.";
461void ChController::Throttle(
double pedal) {
464 AINFO <<
"The current drive mode does not need to set acceleration.";
471void ChController::Acceleration(
double acc) {}
477void ChController::Steer(
double angle) {
480 AINFO <<
"The current driving mode does not need to set steer.";
492void ChController::Steer(
double angle,
double angle_spd) {
495 AINFO <<
"The current driving mode does not need to set steer.";
503void ChController::SetEpbBreak(
const ControlCommand& command) {}
505ErrorCode ChController::HandleCustomOperation(
506 const external_command::ChassisCommand& command) {
507 return ErrorCode::OK;
510void ChController::SetBeam(
const VehicleSignal& vehicle_signal) {
512 if (vehicle_signal.has_low_beam() && vehicle_signal.low_beam()) {
515 }
else if (vehicle_signal.has_low_beam() && !vehicle_signal.low_beam()) {
521void ChController::SetHorn(
const VehicleSignal& vehicle_signal) {}
523void ChController::SetTurningSignal(
const VehicleSignal& vehicle_signal) {
525 auto signal = vehicle_signal.turn_signal();
541bool ChController::VerifyID() {
543 AERROR <<
"Failed to get the vin. Get vin again.";
552bool ChController::CheckVin() {
554 AINFO <<
"Vin check success! Vehicel vin is "
558 AINFO <<
"Vin check failed! Current vin size is "
564void ChController::GetVin() {
571void ChController::ResetVin() {
574 AINFO <<
"Reset vin";
578void ChController::ResetProtocol() {
message_manager_->ResetSendMessages(); }
580bool ChController::CheckChassisError() {
582 AERROR_EVERY(100) <<
"ChassisDetail has no devkit vehicle info.";
587 if (chassis_detail.has_steer_status__512()) {
589 chassis_detail.steer_status__512().steer_err()) {
594 if (chassis_detail.has_throttle_status__510()) {
596 chassis_detail.throttle_status__510().drive_motor_err()) {
607 if (chassis_detail.has_brake_status__511()) {
609 chassis_detail.brake_status__511().brake_err()) {
616void ChController::SecurityDogThreadFunc() {
617 int32_t vertical_ctrl_fail = 0;
618 int32_t horizontal_ctrl_fail = 0;
621 AERROR <<
"Fail to run SecurityDogThreadFunc() because can_sender_ is "
626 std::this_thread::yield();
629 std::chrono::duration<double, std::micro> default_period{50000};
635 bool emergency_mode =
false;
640 CheckResponse(CHECK_RESPONSE_STEER_UNIT_FLAG,
false) ==
false) {
641 ++horizontal_ctrl_fail;
642 if (horizontal_ctrl_fail >= kMaxFailAttempt) {
643 emergency_mode =
true;
644 AERROR <<
"Driving_mode is into emergency by steer manual intervention";
648 horizontal_ctrl_fail = 0;
654 CheckResponse(CHECK_RESPONSE_SPEED_UNIT_FLAG,
false) ==
false) {
655 ++vertical_ctrl_fail;
656 if (vertical_ctrl_fail >= kMaxFailAttempt) {
657 emergency_mode =
true;
658 AERROR <<
"Driving_mode is into emergency by speed manual intervention";
662 vertical_ctrl_fail = 0;
666 if (CheckChassisError()) {
668 emergency_mode =
true;
684 std::chrono::duration<double, std::micro> elapsed{end - start};
685 if (elapsed < default_period) {
686 std::this_thread::sleep_for(default_period - elapsed);
688 AERROR <<
"Too much time consumption in ChController looping process:"
694bool ChController::CheckResponse(
const int32_t flags,
bool need_wait) {
695 int32_t retry_num = 20;
697 bool is_eps_online =
false;
698 bool is_vcu_online =
false;
699 bool is_esp_online =
false;
702 bool check_ok =
true;
703 if (flags & CHECK_RESPONSE_STEER_UNIT_FLAG) {
704 is_eps_online = chassis_.has_check_response() &&
707 check_ok = check_ok && is_eps_online;
710 if (flags & CHECK_RESPONSE_SPEED_UNIT_FLAG) {
711 is_vcu_online = chassis_.has_check_response() &&
714 is_esp_online = chassis_.has_check_response() &&
717 check_ok = check_ok && is_vcu_online && is_esp_online;
722 AINFO <<
"Need to check response again.";
726 std::this_thread::sleep_for(
727 std::chrono::duration<double, std::milli>(20));
729 }
while (need_wait && retry_num);
731 if (flags & CHECK_RESPONSE_STEER_UNIT_FLAG) {
732 AERROR <<
"steer check_response fail: is_eps_online:" << is_eps_online;
735 if (flags & CHECK_RESPONSE_SPEED_UNIT_FLAG) {
736 AERROR <<
"speed check_response fail: " <<
"is_vcu_online:" << is_vcu_online
737 <<
", is_esp_online:" << is_esp_online;
743void ChController::set_chassis_error_mask(
const int32_t mask) {
744 std::lock_guard<std::mutex> lock(chassis_mask_mutex_);
745 chassis_error_mask_ = mask;
748int32_t ChController::chassis_error_mask() {
749 std::lock_guard<std::mutex> lock(chassis_mask_mutex_);
750 return chassis_error_mask_;
754 std::lock_guard<std::mutex> lock(chassis_error_code_mutex_);
755 return chassis_error_code_;
758void ChController::set_chassis_error_code(
760 std::lock_guard<std::mutex> lock(chassis_error_code_mutex_);
761 chassis_error_code_ = error_code;