Apollo  6.0
Open source self driving car software
sensor_canbus.h
Go to the documentation of this file.
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 
21 #pragma once
22 
23 #include <condition_variable>
24 #include <memory>
25 #include <mutex>
26 #include <string>
27 #include <thread>
28 #include <utility>
29 #include <vector>
30 
31 #include "cyber/common/file.h"
33 
34 #include "cyber/time/time.h"
41 #include "modules/drivers/canbus/proto/can_card_parameter.pb.h"
42 #include "modules/drivers/canbus/proto/sensor_canbus_conf.pb.h"
44 
49 namespace apollo {
50 namespace drivers {
51 
58 using apollo::common::ErrorCode;
59 // using apollo::common::Status;
60 using apollo::common::monitor::MonitorMessageItem;
65 using apollo::drivers::canbus::SensorCanbusConf;
66 template <typename T>
68 
69 template <typename SensorType>
71  public:
72  // TODO(lizh): check whether we need a new msg item, say
73  // MonitorMessageItem::SENSORCANBUS
75  : monitor_logger_buffer_(
76  apollo::common::monitor::MonitorMessageItem::CANBUS) {}
77  ~SensorCanbus();
78 
83  bool Init() override;
84 
85  private:
86  bool Start();
87  void PublishSensorData();
88  void OnTimer();
89  void DataTrigger();
90  bool OnError(const std::string &error_msg);
91  void RegisterCanClients();
92 
93  SensorCanbusConf canbus_conf_;
94  std::unique_ptr<CanClient> can_client_;
95  CanReceiver<SensorType> can_receiver_;
96  std::unique_ptr<canbus::MessageManager<SensorType>> sensor_message_manager_;
97  std::unique_ptr<std::thread> thread_;
98 
99  int64_t last_timestamp_ = 0;
100  std::unique_ptr<cyber::Timer> timer_;
101  common::monitor::MonitorLogBuffer monitor_logger_buffer_;
102  std::mutex mutex_;
103  volatile bool data_trigger_running_ = false;
104  std::shared_ptr<Writer<SensorType>> sensor_writer_;
105 };
106 
107 // method implementations
108 
109 template <typename SensorType>
111  // load conf
112  if (!cyber::common::GetProtoFromFile(config_file_path_, &canbus_conf_)) {
113  return OnError("Unable to load canbus conf file: " + config_file_path_);
114  }
115 
116  AINFO << "The canbus conf file is loaded: " << config_file_path_;
117  ADEBUG << "Canbus_conf:" << canbus_conf_.ShortDebugString();
118 
119  // Init can client
120  auto *can_factory = CanClientFactory::Instance();
121  can_factory->RegisterCanClients();
122  can_client_ = can_factory->CreateCANClient(canbus_conf_.can_card_parameter());
123  if (!can_client_) {
124  return OnError("Failed to create can client.");
125  }
126  AINFO << "Can client is successfully created.";
127 
128  sensor_message_manager_.reset(new canbus::MessageManager<SensorType>());
129  if (sensor_message_manager_ == nullptr) {
130  return OnError("Failed to create message manager.");
131  }
132  AINFO << "Sensor message manager is successfully created.";
133 
134  if (can_receiver_.Init(can_client_.get(), sensor_message_manager_.get(),
135  canbus_conf_.enable_receiver_log()) != ErrorCode::OK) {
136  return OnError("Failed to init can receiver.");
137  }
138  AINFO << "The can receiver is successfully initialized.";
139  sensor_writer_ = node_->CreateWriter<SensorType>(FLAGS_sensor_node_name);
140  return Start();
141 }
142 
143 template <typename SensorType>
145  // 1. init and start the can card hardware
146  if (can_client_->Start() != ErrorCode::OK) {
147  return OnError("Failed to start can client");
148  }
149  AINFO << "Can client is started.";
150 
151  // 2. start receive first then send
152  if (can_receiver_.Start() != ErrorCode::OK) {
153  return OnError("Failed to start can receiver.");
154  }
155  AINFO << "Can receiver is started.";
156 
157  // 3. set timer to trigger publish info periodically
158  // if sensor_freq == 0, then it is event-triggered publishment.
159  // no need for timer.
160  if (FLAGS_sensor_freq > 0) {
161  double duration_ms = 1000.0 / FLAGS_sensor_freq;
162  timer_.reset(new cyber::Timer(static_cast<uint32_t>(duration_ms),
163  [this]() { this->OnTimer(); }, false));
164  timer_->Start();
165  } else {
166  data_trigger_running_ = true;
167  thread_.reset(new std::thread([this] { DataTrigger(); }));
168  if (thread_ == nullptr) {
169  AERROR << "Unable to create data trigger thread.";
170  return OnError("Failed to start data trigger thread.");
171  }
172  }
173 
174  // last step: publish monitor messages
175  monitor_logger_buffer_.INFO("Canbus is started.");
176 
177  return true;
178 }
179 
180 template <typename SensorType>
182  PublishSensorData();
183 }
184 
185 template <typename SensorType>
187  std::condition_variable *cvar = sensor_message_manager_->GetMutableCVar();
188  while (data_trigger_running_) {
189  std::unique_lock<std::mutex> lock(mutex_);
190  cvar->wait(lock);
191  PublishSensorData();
192  sensor_message_manager_->ClearSensorData();
193  }
194 }
195 
196 template <typename SensorType>
198  if (FLAGS_sensor_freq > 0) {
199  timer_->Stop();
200  }
201 
202  can_receiver_.Stop();
203  can_client_->Stop();
204 
205  if (data_trigger_running_) {
206  data_trigger_running_ = false;
207  if (thread_ != nullptr && thread_->joinable()) {
208  sensor_message_manager_->GetMutableCVar()->notify_all();
209  thread_->join();
210  }
211  thread_.reset();
212  }
213  AINFO << "Data trigger stopped [ok].";
214 }
215 
216 // Send the error to monitor and return it
217 template <typename SensorType>
218 bool SensorCanbus<SensorType>::OnError(const std::string &error_msg) {
219  monitor_logger_buffer_.ERROR(error_msg);
220  return false;
221 }
222 
223 } // namespace drivers
224 } // namespace apollo
::apollo::cyber::Time Time
Definition: racobit_radar_message_manager.h:41
CanClientFactory inherites apollo::common::util::Factory.
Definition: can_client_factory.h:44
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
Defines the CanFrame struct and CanClient interface.
The class which defines the CAN client to send and receive message.
Definition: can_client.h:92
The class of MessageManager.
Definition: writer.h:42
#define ADEBUG
Definition: log.h:41
Used to perform oneshot or periodic timing tasks.
Definition: timer.h:71
SensorCanbus()
Definition: sensor_canbus.h:74
~SensorCanbus()
Definition: sensor_canbus.h:197
bool GetProtoFromFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as a representation of protobufs, and merges the parsed content to the proto.
std::string config_file_path_
Definition: component_base.h:114
Defines CanReceiver class.
std::shared_ptr< Node > node_
Definition: component_base.h:113
The class of MonitorLogBuffer.
#define AERROR
Definition: log.h:44
template of canbus-based sensor module main class (e.g., mobileye).
Definition: sensor_canbus.h:70
message manager manages protocols. It supports parse and can get protocol data by message id...
Definition: message_manager.h:68
SensorType
Sensor types are set in the order of lidar, radar, camera, ultrasonic Please make sure SensorType has...
Definition: sensor_meta.h:29
bool OK()
Definition: state.h:44
Defines the CanClientFactory class.
This class help collect MonitorMessage pb to monitor topic. The messages can be published automatical...
Definition: monitor_log_buffer.h:60
bool Init() override
module initialization function
Definition: sensor_canbus.h:110
#define AINFO
Definition: log.h:42
CAN receiver.
Definition: can_receiver.h:55
Some util functions.
The Component can process up to four channels of messages. The message type is specified when the com...
Definition: component.h:58