41 : monitor_logger_buffer_(
42 apollo::common::monitor::MonitorMessageItem::CANBUS) {}
44bool CanbusComponent::Init() {
49 AINFO <<
"The canbus conf file is loaded: " << FLAGS_canbus_conf_file;
50 ADEBUG <<
"Canbus_conf:" << canbus_conf_.ShortDebugString();
52 std::string vehicle_library_path;
55 &vehicle_library_path)) {
56 AERROR << FLAGS_load_vehicle_library <<
" No such vehicle library";
59 AINFO <<
"Load the vehicle factory library: " << FLAGS_load_vehicle_library
60 <<
"(" << vehicle_library_path <<
")";
63 auto vehicle_object = loader.CreateClassObj<AbstractVehicleFactory>(
64 FLAGS_load_vehicle_class_name);
65 if (!vehicle_object) {
66 AERROR <<
"Failed to create the vehicle factory: "
67 << FLAGS_load_vehicle_class_name;
70 AINFO <<
"Successfully create vehicle factory: "
71 << FLAGS_load_vehicle_class_name;
73 vehicle_object_ = vehicle_object;
74 if (!vehicle_object_->Init(&canbus_conf_)) {
75 AERROR <<
"Fail to init vehicle factory.";
78 AINFO <<
"Vehicle factory is successfully initialized.";
80 cyber::ReaderConfig guardian_cmd_reader_config;
81 guardian_cmd_reader_config.channel_name = FLAGS_guardian_topic;
82 guardian_cmd_reader_config.pending_queue_size =
83 FLAGS_guardian_cmd_pending_queue_size;
85 cyber::ReaderConfig control_cmd_reader_config;
86 control_cmd_reader_config.channel_name = FLAGS_control_command_topic;
87 control_cmd_reader_config.pending_queue_size =
88 FLAGS_control_cmd_pending_queue_size;
90 cyber::ReaderConfig chassis_cmd_reader_config;
91 chassis_cmd_reader_config.channel_name = FLAGS_chassis_command_topic;
92 chassis_cmd_reader_config.pending_queue_size =
93 FLAGS_control_cmd_pending_queue_size;
96 if (FLAGS_receive_guardian) {
98 guardian_cmd_reader_config,
99 [
this](
const std::shared_ptr<GuardianCommand> &cmd) {
100 ADEBUG <<
"Received guardian data: run canbus callback.";
102 OnGuardianCommand(*cmd);
104 if ((end_time - start_time) * 1e-6 > FLAGS_guardian_period) {
105 AWARN <<
"Guardian callback time: "
106 << (end_time - start_time) * 1e-3 <<
" ms.";
111 control_cmd_reader_config,
112 [
this](
const std::shared_ptr<ControlCommand> &cmd) {
113 ADEBUG <<
"Received control data: run canbus callback.";
115 OnControlCommand(*cmd);
117 if ((end_time - start_time) * 1e-6 > FLAGS_control_period) {
118 AWARN <<
"Control callback time: " << (end_time - start_time) * 1e-3
126 chassis_cmd_reader_config,
127 [
this](
const std::shared_ptr<ChassisCommand> &cmd) {
128 ADEBUG <<
"Received control data: run canbus callback.";
129 OnChassisCommand(*cmd);
133 chassis_writer_ =
node_->CreateWriter<Chassis>(FLAGS_chassis_topic);
136 if (!vehicle_object_->Start()) {
137 AERROR <<
"Fail to start canclient, cansender, canreceiver, canclient, "
138 "vehicle controller.";
142 AINFO <<
"Start canclient cansender, canreceiver, canclient, vehicle "
143 "controller successfully.";
145 monitor_logger_buffer_.INFO(
"Canbus is started.");
150void CanbusComponent::Clear() {
151 vehicle_object_->Stop();
152 AINFO <<
"Cleanup Canbus component";
155void CanbusComponent::PublishChassis() {
156 Chassis chassis = vehicle_object_->publish_chassis();
157 common::util::FillHeader(
node_->Name(), &chassis);
158 chassis_writer_->Write(chassis);
159 ADEBUG << chassis.ShortDebugString();
162bool CanbusComponent::Proc() {
165 if (FLAGS_receive_guardian) {
166 guardian_cmd_reader_->Observe();
167 const auto &guardian_cmd_msg = guardian_cmd_reader_->GetLatestObserved();
168 if (guardian_cmd_msg ==
nullptr) {
169 AERROR <<
"guardian cmd msg is not ready!";
171 OnGuardianCommandCheck(*guardian_cmd_msg);
174 control_command_reader_->Observe();
175 const auto &control_cmd_msg = control_command_reader_->GetLatestObserved();
176 if (control_cmd_msg ==
nullptr) {
177 AERROR <<
"control cmd msg is not ready!";
179 OnControlCommandCheck(*control_cmd_msg);
184 if (vehicle_object_->CheckChassisCommunicationFault()) {
185 AERROR <<
"Can not get the chassis info, please check the chassis "
193 if (FLAGS_enable_chassis_detail_pub) {
194 vehicle_object_->PublishChassisDetail();
198 if (FLAGS_enable_chassis_detail_sender_pub) {
199 vehicle_object_->PublishChassisDetailSender();
203 vehicle_object_->UpdateHeartbeat();
206 const double time_diff_ms = (end_time - start_time) * 1e-3;
207 if (time_diff_ms > (1 / FLAGS_chassis_freq * 1e3)) {
208 AWARN <<
"CanbusComponent::Proc() takes too much time: " << time_diff_ms
215void CanbusComponent::OnControlCommand(
const ControlCommand &control_command) {
220 if (current_timestamp - last_timestamp_controlcmd_ <
221 FLAGS_min_cmd_interval * 1000) {
222 ADEBUG <<
"Control command comes too soon. Ignore. Required "
223 "FLAGS_min_cmd_interval["
224 << FLAGS_min_cmd_interval <<
"] ms, actual time interval["
225 << (current_timestamp - last_timestamp_controlcmd_) * 1e-3
229 last_timestamp_controlcmd_ = current_timestamp;
231 if (!is_control_cmd_time_delay_) {
232 vehicle_object_->UpdateCommand(&control_command);
236void CanbusComponent::OnControlCommandCheck(
241 double cmd_time_diff =
243 if (FLAGS_use_control_cmd_check &&
244 (cmd_time_diff > (FLAGS_max_control_miss_num * FLAGS_control_period))) {
245 AERROR <<
"Control cmd timeout, sequence_number:"
247 <<
", Time_of_delay:" << cmd_time_diff <<
" s"
248 <<
", time delay threshold: "
249 << (FLAGS_max_control_miss_num * FLAGS_control_period) <<
" s";
254 is_control_cmd_time_delay_ =
true;
256 new_guardian_command.mutable_control_command()->CopyFrom(control_command);
257 ProcessGuardianCmdTimeout(&new_guardian_command);
258 ADEBUG <<
"new_guardian_command is "
259 << new_guardian_command.ShortDebugString();
260 vehicle_object_->UpdateCommand(&new_guardian_command.
control_command());
263 is_control_cmd_time_delay_ =
false;
267void CanbusComponent::OnGuardianCommand(
269 if (!is_control_cmd_time_delay_) {
274void CanbusComponent::OnGuardianCommandCheck(
279 double guardian_cmd_time_diff =
281 if (FLAGS_use_guardian_cmd_check &&
282 (guardian_cmd_time_diff >
283 (FLAGS_max_guardian_miss_num * FLAGS_guardian_period))) {
284 AERROR <<
"Guardain cmd timeout, sequence_number:"
286 <<
", Time_of_delay:" << guardian_cmd_time_diff <<
" s"
287 <<
", time delay threshold: "
288 << (FLAGS_max_guardian_miss_num * FLAGS_guardian_period) <<
" s";
293 is_control_cmd_time_delay_ =
true;
295 new_guardian_command.CopyFrom(guardian_command);
296 ProcessGuardianCmdTimeout(&new_guardian_command);
297 ADEBUG <<
"new_guardian_command is "
298 << new_guardian_command.ShortDebugString();
299 vehicle_object_->UpdateCommand(&new_guardian_command.
control_command());
302 is_control_cmd_time_delay_ =
false;
306void CanbusComponent::OnChassisCommand(
const ChassisCommand &chassis_command) {
311 if (current_timestamp - last_timestamp_chassiscmd_ <
312 FLAGS_min_cmd_interval * 1000) {
313 ADEBUG <<
"Control command comes too soon. Ignore.\n Required "
314 "FLAGS_min_cmd_interval["
315 << FLAGS_min_cmd_interval <<
"], actual time interval["
316 << current_timestamp - last_timestamp_chassiscmd_ <<
"].";
319 last_timestamp_chassiscmd_ = current_timestamp;
321 ADEBUG <<
"Control_sequence_number:"
323 << current_timestamp -
328 vehicle_object_->UpdateCommand(&chassis_command);
331common::Status CanbusComponent::OnError(
const std::string &error_msg) {
332 monitor_logger_buffer_.ERROR(error_msg);
333 return ::apollo::common::Status(ErrorCode::CANBUS_ERROR, error_msg);
336void CanbusComponent::ProcessTimeoutByClearCanSender() {
340 !FLAGS_chassis_debug_mode) {
341 ADEBUG <<
"The current driving mode does not need to check cmd timeout.";
342 if (vehicle_object_->IsSendProtocolClear()) {
343 AINFO <<
"send protocol is clear, ignore driving mode, need to recover "
345 vehicle_object_->AddSendProtocol();
350 if (!is_control_cmd_time_delay_previous_ && is_control_cmd_time_delay_) {
351 AINFO <<
"control cmd time latency delay, clear send protocol.";
352 vehicle_object_->ClearSendProtocol();
353 }
else if (is_control_cmd_time_delay_previous_ &&
354 !is_control_cmd_time_delay_) {
355 AINFO <<
"control cmd time latency reover, add send protocol.";
356 if (vehicle_object_->IsSendProtocolClear()) {
357 vehicle_object_->AddSendProtocol();
360 is_control_cmd_time_delay_previous_ = is_control_cmd_time_delay_;
363void CanbusComponent::ProcessGuardianCmdTimeout(
365 AINFO <<
"Into cmd timeout process, set estop.";
366 guardian_command->mutable_control_command()->set_throttle(0.0);
367 guardian_command->mutable_control_command()->set_steering_target(0.0);
368 guardian_command->mutable_control_command()->set_steering_rate(25.0);
369 guardian_command->mutable_control_command()->set_brake(FLAGS_estop_brake);