Apollo 10.0
自动驾驶开放平台
zhongyun_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#include "cyber/common/log.h"
20#include "cyber/time/time.h"
25
26namespace apollo {
27namespace canbus {
28namespace zhongyun {
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} // namespace
41
43 const VehicleParameter& params,
44 CanSender<::apollo::canbus::Zhongyun>* const can_sender,
45 MessageManager<::apollo::canbus::Zhongyun>* const message_manager) {
46 if (is_initialized_) {
47 AINFO << "ZhongyunController has already been initialized.";
48 return ErrorCode::CANBUS_ERROR;
49 }
50 vehicle_params_.CopyFrom(
51 common::VehicleConfigHelper::Instance()->GetConfig().vehicle_param());
52 params_.CopyFrom(params);
53 if (!params_.has_driving_mode()) {
54 AERROR << "Vehicle conf pb not set driving_mode.";
55 return ErrorCode::CANBUS_ERROR;
56 }
57
58 if (can_sender == nullptr) {
59 AERROR << "Canbus sender is null.";
60 return ErrorCode::CANBUS_ERROR;
61 }
62 can_sender_ = can_sender;
63
64 if (message_manager == nullptr) {
65 AERROR << "Protocol manager is null.";
66 return ErrorCode::CANBUS_ERROR;
67 }
68 message_manager_ = message_manager;
69
70 // Sender part
71 brake_control_a4_ = dynamic_cast<Brakecontrola4*>(
72 message_manager_->GetMutableProtocolDataById(Brakecontrola4::ID));
73 if (brake_control_a4_ == nullptr) {
74 AERROR << "Brakecontrola4 does not exist in the ZhongyunMessageManager!";
75 return ErrorCode::CANBUS_ERROR;
76 }
77
78 gear_control_a1_ = dynamic_cast<Gearcontrola1*>(
79 message_manager_->GetMutableProtocolDataById(Gearcontrola1::ID));
80 if (gear_control_a1_ == nullptr) {
81 AERROR << "Gearcontrola1 does not exist in the ZhongyunMessageManager!";
82 return ErrorCode::CANBUS_ERROR;
83 }
84
85 parking_control_a5_ = dynamic_cast<Parkingcontrola5*>(
86 message_manager_->GetMutableProtocolDataById(Parkingcontrola5::ID));
87 if (parking_control_a5_ == nullptr) {
88 AERROR << "Parkingcontrola5 does not exist in the ZhongyunMessageManager!";
89 return ErrorCode::CANBUS_ERROR;
90 }
91
92 steering_control_a2_ = dynamic_cast<Steeringcontrola2*>(
93 message_manager_->GetMutableProtocolDataById(Steeringcontrola2::ID));
94 if (steering_control_a2_ == nullptr) {
95 AERROR << "Steeringcontrola2 does not exist in the ZhongyunMessageManager!";
96 return ErrorCode::CANBUS_ERROR;
97 }
98
99 torque_control_a3_ = dynamic_cast<Torquecontrola3*>(
100 message_manager_->GetMutableProtocolDataById(Torquecontrola3::ID));
101 if (torque_control_a3_ == nullptr) {
102 AERROR << "Torquecontrola3 does not exist in the ZhongyunMessageManager!";
103 return ErrorCode::CANBUS_ERROR;
104 }
105
106 can_sender_->AddMessage(Brakecontrola4::ID, brake_control_a4_, false);
107 can_sender_->AddMessage(Gearcontrola1::ID, gear_control_a1_, false);
108 can_sender_->AddMessage(Parkingcontrola5::ID, parking_control_a5_, false);
109 can_sender_->AddMessage(Steeringcontrola2::ID, steering_control_a2_, false);
110 can_sender_->AddMessage(Torquecontrola3::ID, torque_control_a3_, false);
111
112 // Need to sleep to ensure all messages received
113 AINFO << "ZhongyunController is initialized.";
114
115 is_initialized_ = true;
116 return ErrorCode::OK;
117}
118
120
122 if (!is_initialized_) {
123 AERROR << "ZhongyunController has not been initialized.";
124 return false;
125 }
126 const auto& update_func = [this] { SecurityDogThreadFunc(); };
127 thread_.reset(new std::thread(update_func));
128
129 return true;
130}
131
133 if (!is_initialized_) {
134 AERROR << "ZhongyunController stops or starts improperly!";
135 return;
136 }
137
138 if (thread_ != nullptr && thread_->joinable()) {
139 thread_->join();
140 thread_.reset();
141 AINFO << "ZhongyunController stopped.";
142 }
143}
144
146 chassis_.Clear();
147
148 Zhongyun chassis_detail;
149 message_manager_->GetSensorData(&chassis_detail);
150
151 // 1, 2
152 // if (driving_mode() == Chassis::EMERGENCY_MODE) {
153 // set_chassis_error_code(Chassis::NO_ERROR);
154 // }
155
156 chassis_.set_driving_mode(driving_mode());
157 chassis_.set_error_code(chassis_error_code());
158
159 // 3
160 chassis_.set_engine_started(true);
161
162 // 4 engine_rpm
163 if (chassis_detail.has_vehicle_state_feedback_2_c4() &&
164 chassis_detail.vehicle_state_feedback_2_c4().has_motor_speed()) {
165 chassis_.set_engine_rpm(static_cast<float>(
166 chassis_detail.vehicle_state_feedback_2_c4().motor_speed()));
167 } else {
168 chassis_.set_engine_rpm(0);
169 }
170 // 5 speed_mps
171 if (chassis_detail.has_vehicle_state_feedback_c1() &&
172 chassis_detail.vehicle_state_feedback_c1().has_speed()) {
173 chassis_.set_speed_mps(
174 static_cast<float>(chassis_detail.vehicle_state_feedback_c1().speed()));
175 } else {
176 chassis_.set_speed_mps(0);
177 }
178 // 6
179 chassis_.set_fuel_range_m(0);
180
181 // 7 acc_pedal
182 if (chassis_detail.has_vehicle_state_feedback_2_c4() &&
183 chassis_detail.vehicle_state_feedback_2_c4()
184 .has_driven_torque_feedback()) {
185 chassis_.set_throttle_percentage(static_cast<float>(
187 } else {
188 chassis_.set_throttle_percentage(0);
189 }
190 // 8 brake_pedal
191 if (chassis_detail.has_vehicle_state_feedback_c1() &&
192 chassis_detail.vehicle_state_feedback_c1().has_brake_torque_feedback()) {
193 chassis_.set_brake_percentage(static_cast<float>(
195 } else {
196 chassis_.set_brake_percentage(0);
197 }
198 // 9 gear position
199 if (chassis_detail.has_vehicle_state_feedback_c1() &&
200 chassis_detail.vehicle_state_feedback_c1().has_gear_state_actual()) {
201 switch (chassis_detail.vehicle_state_feedback_c1().gear_state_actual()) {
203 chassis_.set_gear_location(Chassis::GEAR_DRIVE);
204 } break;
206 chassis_.set_gear_location(Chassis::GEAR_NEUTRAL);
207 } break;
209 chassis_.set_gear_location(Chassis::GEAR_REVERSE);
210 } break;
212 chassis_.set_gear_location(Chassis::GEAR_PARKING);
213 } break;
214 default:
215 chassis_.set_gear_location(Chassis::GEAR_INVALID);
216 break;
217 }
218 } else {
219 chassis_.set_gear_location(Chassis::GEAR_NONE);
220 }
221 // 11 steering_percentage
222 if (chassis_detail.has_vehicle_state_feedback_c1() &&
223 chassis_detail.vehicle_state_feedback_c1().has_steering_actual()) {
224 chassis_.set_steering_percentage(static_cast<float>(
225 chassis_detail.vehicle_state_feedback_c1().steering_actual() * 100.0 /
226 vehicle_params_.max_steer_angle() * M_PI / 180));
227 } else {
228 chassis_.set_steering_percentage(0);
229 }
230 // 12 epb
231 if (chassis_detail.has_vehicle_state_feedback_c1() &&
232 chassis_detail.vehicle_state_feedback_c1().has_parking_actual()) {
233 chassis_.set_parking_brake(
234 chassis_detail.vehicle_state_feedback_c1().parking_actual() ==
236 } else {
237 chassis_.set_parking_brake(false);
238 }
239 // 13 error mask
240 if (chassis_error_mask_) {
241 chassis_.set_chassis_error_mask(chassis_error_mask_);
242 }
243 // Give engage_advice based on error_code and canbus feedback
244 if (!chassis_error_mask_ && !chassis_.parking_brake()) {
245 chassis_.mutable_engage_advice()->set_advice(
247 } else {
248 chassis_.mutable_engage_advice()->set_advice(
250 chassis_.mutable_engage_advice()->set_reason(
251 "CANBUS not ready, epb is not released or firmware error!");
252 }
253
254 // 14 add checkresponse signal
255 if (chassis_detail.has_enable_state_feedback_c3()) {
256 if (chassis_detail.enable_state_feedback_c3().has_brake_enable_state()) {
257 chassis_.mutable_check_response()->set_is_esp_online(
258 chassis_detail.enable_state_feedback_c3().brake_enable_state() == 1);
259 }
260 if (chassis_detail.enable_state_feedback_c3().has_driven_enable_state() &&
261 chassis_detail.enable_state_feedback_c3().has_gear_enable_actual()) {
262 chassis_.mutable_check_response()->set_is_vcu_online(
263 ((chassis_detail.enable_state_feedback_c3().driven_enable_state() ==
264 1) &&
265 (chassis_detail.enable_state_feedback_c3().gear_enable_actual() ==
266 1)) == 1);
267 }
268 if (chassis_detail.enable_state_feedback_c3().has_steering_enable_state()) {
269 chassis_.mutable_check_response()->set_is_eps_online(
271 1);
272 }
273 }
274
275 return chassis_;
276}
277
278bool ZhongyunController::VerifyID() { return true; }
279
280void ZhongyunController::Emergency() {
282 ResetProtocol();
283}
284
285ErrorCode ZhongyunController::EnableAutoMode() {
287 AINFO << "Already in COMPLETE_AUTO_DRIVE mode.";
288 return ErrorCode::OK;
289 }
290 steering_control_a2_->set_steering_enable_control(
292 gear_control_a1_->set_gear_enable_control(
294 torque_control_a3_->set_driven_enable_control(
296 brake_control_a4_->set_brake_enable_control(
298 parking_control_a5_->set_parking_enable_control(
300
301 can_sender_->Update();
302 const int32_t flag =
303 CHECK_RESPONSE_STEER_UNIT_FLAG | CHECK_RESPONSE_SPEED_UNIT_FLAG;
304 if (!CheckResponse(flag, true)) {
305 AERROR << "Failed to switch to COMPLETE_AUTO_DRIVE mode.";
306 Emergency();
307 set_chassis_error_code(Chassis::CHASSIS_ERROR);
308 return ErrorCode::CANBUS_ERROR;
309 }
311 AINFO << "Switch to COMPLETE_AUTO_DRIVE mode ok.";
312 return ErrorCode::OK;
313}
314
315ErrorCode ZhongyunController::DisableAutoMode() {
316 ResetProtocol();
317 can_sender_->Update();
319 set_chassis_error_code(Chassis::NO_ERROR);
320 AINFO << "Switch to COMPLETE_MANUAL mode ok.";
321 return ErrorCode::OK;
322}
323
324ErrorCode ZhongyunController::EnableSteeringOnlyMode() {
328 AINFO << "Already in AUTO_STEER_ONLY mode";
329 return ErrorCode::OK;
330 }
331 steering_control_a2_->set_steering_enable_control(
333 gear_control_a1_->set_gear_enable_control(
335 torque_control_a3_->set_driven_enable_control(
337 brake_control_a4_->set_brake_enable_control(
339 parking_control_a5_->set_parking_enable_control(
341
342 can_sender_->Update();
343 const int32_t flag =
344 CHECK_RESPONSE_STEER_UNIT_FLAG | CHECK_RESPONSE_SPEED_UNIT_FLAG;
345 if (!CheckResponse(flag, true)) {
346 AERROR << "Failed to switch to COMPLETE_AUTO_DRIVE mode. Please check the "
347 "emergency button or chassis.";
348 Emergency();
349 set_chassis_error_code(Chassis::CHASSIS_ERROR);
350 return ErrorCode::CANBUS_ERROR;
351 }
353 AINFO << "Switch to COMPLETE_AUTO_DRIVE mode ok.";
354 return ErrorCode::OK;
355}
356
357ErrorCode ZhongyunController::EnableSpeedOnlyMode() {
361 AINFO << "Already in AUTO_SPEED_ONLY mode";
362 return ErrorCode::OK;
363 }
364 steering_control_a2_->set_steering_enable_control(
366 gear_control_a1_->set_gear_enable_control(
368 torque_control_a3_->set_driven_enable_control(
370 brake_control_a4_->set_brake_enable_control(
372 parking_control_a5_->set_parking_enable_control(
374
375 can_sender_->Update();
376 if (CheckResponse(CHECK_RESPONSE_SPEED_UNIT_FLAG, true) == false) {
377 AERROR << "Failed to switch to AUTO_SPEED_ONLY mode.";
378 Emergency();
379 set_chassis_error_code(Chassis::CHASSIS_ERROR);
380 return ErrorCode::CANBUS_ERROR;
381 }
383 AINFO << "Switch to AUTO_SPEED_ONLY mode ok.";
384 return ErrorCode::OK;
385}
386
387// NEUTRAL, REVERSE, DRIVE, PARK
388void ZhongyunController::Gear(Chassis::GearPosition gear_position) {
391 AINFO << "This drive mode no need to set gear.";
392 return;
393 }
394
395 switch (gear_position) {
397 gear_control_a1_->set_gear_state_target(
399 break;
400 }
402 gear_control_a1_->set_gear_state_target(
404 break;
405 }
406 case Chassis::GEAR_DRIVE: {
407 gear_control_a1_->set_gear_state_target(
409 break;
410 }
412 gear_control_a1_->set_gear_state_target(
414 break;
415 }
416
418 AERROR << "Gear command is invalid!";
419 gear_control_a1_->set_gear_state_target(
421 break;
422 }
423 default: {
424 gear_control_a1_->set_gear_state_target(
426 break;
427 }
428 }
429}
430
431// brake with brake pedal
432// pedal:0.00~99.99, unit:percentage
433void ZhongyunController::Brake(double pedal) {
436 AINFO << "The current drive mode does not need to set brake pedal.";
437 return;
438 }
439 brake_control_a4_->set_brake_torque(pedal);
440}
441
442// drive with throttle pedal
443// pedal:0.00~99.99 unit:percentage
444void ZhongyunController::Throttle(double pedal) {
447 AINFO << "The current drive mode does not need to set throttle pedal.";
448 return;
449 }
450 torque_control_a3_->set_driven_torque(pedal);
451}
452
453// confirm the car is driven by acceleration command or throttle/brake pedal
454// drive with acceleration/deceleration
455// acc:-7.0 ~ 5.0, unit:m/s^2
456void ZhongyunController::Acceleration(double acc) {
459 AINFO << "The current drive mode does not need to set acceleration.";
460 return;
461 }
462 // None
463}
464
465// zhongyun default, -30% ~ 30%, left:+, right:-
466// need to be compatible with control module, so reverse
467// steering with old angle speed
468// angle:-99.99~0.00~99.99, unit:%, left:-, right:+
469void ZhongyunController::Steer(double angle) {
472 AINFO << "The current driving mode does not need to set steer.";
473 return;
474 }
475 const double real_angle =
476 vehicle_params_.max_steer_angle() / M_PI * 180 * angle / 100.0;
477 steering_control_a2_->set_steering_target(real_angle);
478}
479
480// steering with new angle speed
481// zhongyun has no angle_speed
482// angle:-30~30, unit:%, left:+, right:-
483void ZhongyunController::Steer(double angle, double angle_spd) {
486 AINFO << "The current driving mode does not need to set steer.";
487 return;
488 }
489 const double real_angle =
490 vehicle_params_.max_steer_angle() / M_PI * 180 * angle / 100.0;
491 steering_control_a2_->set_steering_target(real_angle);
492}
493
494void ZhongyunController::SetEpbBreak(const ControlCommand& command) {
495 if (command.parking_brake()) {
496 parking_control_a5_->set_parking_target(
498 } else {
499 parking_control_a5_->set_parking_target(
501 }
502}
503
504ErrorCode ZhongyunController::HandleCustomOperation(
505 const external_command::ChassisCommand& command) {
506 return ErrorCode::OK;
507}
508
509void ZhongyunController::SetBeam(const VehicleSignal& vehicle_signal) {
510 if (vehicle_signal.high_beam()) {
511 // None
512 } else if (vehicle_signal.low_beam()) {
513 // None
514 } else {
515 // None
516 }
517}
518
519void ZhongyunController::SetHorn(const VehicleSignal& vehicle_signal) {
520 if (vehicle_signal.horn()) {
521 // None
522 } else {
523 // None
524 }
525}
526
527void ZhongyunController::SetTurningSignal(const VehicleSignal& vehicle_signal) {
528 // Set Turn Signal
529 // None
530}
531
532void ZhongyunController::ResetProtocol() {
533 message_manager_->ResetSendMessages();
534}
535
536bool ZhongyunController::CheckChassisError() {
537 Zhongyun chassis_detail;
538 message_manager_->GetSensorData(&chassis_detail);
539 if (!chassis_.has_check_response()) {
540 AERROR_EVERY(100) << "ChassisDetail has NO zhongyun vehicle info.";
541 return false;
542 }
543
544 // check steer error
545 if (chassis_detail.has_error_state_e1() &&
546 chassis_detail.error_state_e1().has_steering_error_code()) {
547 if (chassis_detail.error_state_e1().steering_error_code() ==
549 return true;
550 }
551 }
552 // check ems error
553 if (chassis_detail.has_error_state_e1() &&
554 chassis_detail.error_state_e1().has_driven_error_code()) {
555 if (chassis_detail.error_state_e1().driven_error_code() ==
557 return true;
558 }
559 }
560 // check eps error
561 if (chassis_detail.has_error_state_e1() &&
562 chassis_detail.error_state_e1().has_brake_error_code()) {
563 if (chassis_detail.error_state_e1().brake_error_code() ==
565 return true;
566 }
567 }
568 // check gear error
569 if (chassis_detail.has_error_state_e1() &&
570 chassis_detail.error_state_e1().has_gear_error_msg()) {
571 if (chassis_detail.error_state_e1().gear_error_msg() ==
573 return true;
574 }
575 }
576 // check parking error
577 if (chassis_detail.has_error_state_e1() &&
578 chassis_detail.error_state_e1().has_parking_error_code()) {
579 if (chassis_detail.error_state_e1().parking_error_code() ==
581 return true;
582 }
583 }
584 return false;
585}
586
587void ZhongyunController::SecurityDogThreadFunc() {
588 int32_t vertical_ctrl_fail = 0;
589 int32_t horizontal_ctrl_fail = 0;
590
591 if (can_sender_ == nullptr) {
592 AERROR << "Failed to run SecurityDogThreadFunc() because can_sender_ is "
593 "nullptr.";
594 return;
595 }
596 while (!can_sender_->IsRunning()) {
597 std::this_thread::yield();
598 }
599
600 std::chrono::duration<double, std::micro> default_period{50000};
601 int64_t start = 0;
602 int64_t end = 0;
603 while (can_sender_->IsRunning()) {
605 const Chassis::DrivingMode mode = driving_mode();
606 bool emergency_mode = false;
607
608 // 1. horizontal control check
609 if ((mode == Chassis::COMPLETE_AUTO_DRIVE ||
610 mode == Chassis::AUTO_STEER_ONLY) &&
611 !CheckResponse(CHECK_RESPONSE_STEER_UNIT_FLAG, false)) {
612 ++horizontal_ctrl_fail;
613 if (horizontal_ctrl_fail >= kMaxFailAttempt) {
614 emergency_mode = true;
615 AINFO << "Driving_mode is into emergency by steer manual intervention";
616 set_chassis_error_code(Chassis::MANUAL_INTERVENTION);
617 }
618 } else {
619 horizontal_ctrl_fail = 0;
620 }
621
622 // 2. vertical control check
623 if ((mode == Chassis::COMPLETE_AUTO_DRIVE ||
624 mode == Chassis::AUTO_SPEED_ONLY) &&
625 !CheckResponse(CHECK_RESPONSE_SPEED_UNIT_FLAG, false)) {
626 ++vertical_ctrl_fail;
627 if (vertical_ctrl_fail >= kMaxFailAttempt) {
628 emergency_mode = true;
629 AINFO << "Driving_mode is into emergency by speed manual intervention";
630 set_chassis_error_code(Chassis::MANUAL_INTERVENTION);
631 }
632 } else {
633 vertical_ctrl_fail = 0;
634 }
635 if (CheckChassisError()) {
636 set_chassis_error_code(Chassis::CHASSIS_ERROR);
637 emergency_mode = true;
638 }
639
640 if (emergency_mode && mode != Chassis::EMERGENCY_MODE) {
642 message_manager_->ResetSendMessages();
643 can_sender_->Update();
644 }
646 std::chrono::duration<double, std::micro> elapsed{end - start};
647 if (elapsed < default_period) {
648 std::this_thread::sleep_for(default_period - elapsed);
649 } else {
650 AERROR
651 << "Too much time consumption in ZhongyunController looping process:"
652 << elapsed.count();
653 }
654 }
655}
656
657bool ZhongyunController::CheckResponse(const int32_t flags, bool need_wait) {
658 // for Zhongyun, CheckResponse commonly takes 300ms. We leave a 100ms buffer
659 // for it.
660 int32_t retry_num = 20;
661 Zhongyun chassis_detail;
662 bool is_eps_online = false;
663 bool is_vcu_online = false;
664 bool is_esp_online = false;
665
666 do {
667 if (message_manager_->GetSensorData(&chassis_detail) != ErrorCode::OK) {
668 AERROR_EVERY(100) << "get chassis detail failed.";
669 return false;
670 }
671 bool check_ok = true;
672 if (flags & CHECK_RESPONSE_STEER_UNIT_FLAG) {
673 is_eps_online = chassis_.has_check_response() &&
674 chassis_.check_response().has_is_eps_online() &&
675 chassis_.check_response().is_eps_online();
676 check_ok = check_ok && is_eps_online;
677 }
678
679 if (flags & CHECK_RESPONSE_SPEED_UNIT_FLAG) {
680 is_vcu_online = chassis_.has_check_response() &&
681 chassis_.check_response().has_is_vcu_online() &&
682 chassis_.check_response().is_vcu_online();
683 is_esp_online = chassis_.has_check_response() &&
684 chassis_.check_response().has_is_esp_online() &&
685 chassis_.check_response().is_esp_online();
686 check_ok = check_ok && is_vcu_online && is_esp_online;
687 }
688 if (need_wait) {
689 --retry_num;
690 std::this_thread::sleep_for(
691 std::chrono::duration<double, std::milli>(20));
692 }
693 if (check_ok) {
694 return true;
695 } else {
696 AINFO << "Need to check response again.";
697 }
698 } while (need_wait && retry_num);
699
700 AINFO << "check_response fail: is_eps_online:" << is_eps_online
701 << ", is_vcu_online:" << is_vcu_online
702 << ", is_esp_online:" << is_esp_online;
703 return false;
704}
705
706void ZhongyunController::set_chassis_error_mask(const int32_t mask) {
707 std::lock_guard<std::mutex> lock(chassis_mask_mutex_);
708 chassis_error_mask_ = mask;
709}
710
711int32_t ZhongyunController::chassis_error_mask() {
712 std::lock_guard<std::mutex> lock(chassis_mask_mutex_);
713 return chassis_error_mask_;
714}
715
716Chassis::ErrorCode ZhongyunController::chassis_error_code() {
717 std::lock_guard<std::mutex> lock(chassis_error_code_mutex_);
718 return chassis_error_code_;
719}
720
721void ZhongyunController::set_chassis_error_code(
722 const Chassis::ErrorCode& error_code) {
723 std::lock_guard<std::mutex> lock(chassis_error_code_mutex_);
724 chassis_error_code_ = error_code;
725}
726
727} // namespace zhongyun
728} // namespace canbus
729} // namespace apollo
Defines SenderMessage class and CanSender class.
virtual void set_driving_mode(const Chassis::DrivingMode &driving_mode)
MessageManager< ::apollo::canbus::Zhongyun > * message_manager_
Brakecontrola4 * set_brake_enable_control(Brake_control_a4::Brake_enable_controlType brake_enable_control)
Brakecontrola4 * set_brake_torque(double brake_torque)
Gearcontrola1 * set_gear_enable_control(Gear_control_a1::Gear_enable_controlType gear_enable_control)
Gearcontrola1 * set_gear_state_target(Gear_control_a1::Gear_state_targetType gear_state_target)
Parkingcontrola5 * set_parking_target(Parking_control_a5::Parking_targetType parking_target)
Parkingcontrola5 * set_parking_enable_control(Parking_control_a5::Parking_enable_controlType parking_enable_control)
Steeringcontrola2 * set_steering_target(double steering_target)
Steeringcontrola2 * set_steering_enable_control(Steering_control_a2::Steering_enable_controlType steering_enable_control)
Torquecontrola3 * set_driven_torque(double driven_torque)
Torquecontrola3 * set_driven_enable_control(Torque_control_a3::Driven_enable_controlType driven_enable_control)
bool Start() override
start the vehicle controller.
void Stop() override
stop the vehicle controller.
::apollo::common::ErrorCode Init(const VehicleParameter &params, CanSender<::apollo::canbus::Zhongyun > *const can_sender, MessageManager<::apollo::canbus::Zhongyun > *const message_manager) override
Chassis chassis() override
calculate and return the chassis.
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 Brake_enable_stateType brake_enable_state
optional Gear_enable_actualType gear_enable_actual
optional Steering_enable_stateType steering_enable_state
optional Driven_enable_stateType driven_enable_state
optional Parking_actualType parking_actual
optional Gear_state_actualType gear_state_actual
optional Enable_state_feedback_c3 enable_state_feedback_c3
optional Vehicle_state_feedback_2_c4 vehicle_state_feedback_2_c4
optional Vehicle_state_feedback_c1 vehicle_state_feedback_c1
The class of VehicleController