Apollo 10.0
自动驾驶开放平台
sensor_canbus.h
浏览该文件的文档.
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/common_msgs/drivers_msgs/can_card_parameter.pb.h"
42#include "modules/drivers/canbus/proto/sensor_canbus_conf.pb.h"
44
49namespace apollo {
50namespace drivers {
51
59// using apollo::common::Status;
66template <typename T>
68
69template <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) {}
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
109template <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
143template <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
180template <typename SensorType>
181void SensorCanbus<SensorType>::OnTimer() {
182 PublishSensorData();
183}
184
185template <typename SensorType>
186void SensorCanbus<SensorType>::DataTrigger() {
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
196template <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
217template <typename SensorType>
218bool 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
Defines the CanFrame struct and CanClient interface.
Defines the CanClientFactory class.
Defines CanReceiver class.
Cyber has builtin time type Time.
Definition time.h:31
template of canbus-based sensor module main class (e.g., mobileye).
bool Init() override
module initialization function
CanClientFactory inherites apollo::common::util::Factory.
The class which defines the CAN client to send and receive message.
Definition can_client.h:92
message manager manages protocols.
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
The class of MessageManager
Some util functions.
The class of MonitorLogBuffer
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,...
Definition file.cc:132
class register implement
Definition arena_queue.h:37