23#include <condition_variable>
41#include "modules/common_msgs/drivers_msgs/can_card_parameter.pb.h"
42#include "modules/drivers/canbus/proto/sensor_canbus_conf.pb.h"
69template <
typename SensorType>
75 : monitor_logger_buffer_(
87 void PublishSensorData();
90 bool OnError(
const std::string &error_msg);
91 void RegisterCanClients();
94 std::unique_ptr<CanClient> can_client_;
96 std::unique_ptr<canbus::MessageManager<SensorType>> sensor_message_manager_;
97 std::unique_ptr<std::thread> thread_;
99 int64_t last_timestamp_ = 0;
100 std::unique_ptr<cyber::Timer> timer_;
103 volatile bool data_trigger_running_ =
false;
104 std::shared_ptr<Writer<SensorType>> sensor_writer_;
109template <
typename SensorType>
113 return OnError(
"Unable to load canbus conf file: " + config_file_path_);
116 AINFO <<
"The canbus conf file is loaded: " << config_file_path_;
117 ADEBUG <<
"Canbus_conf:" << canbus_conf_.ShortDebugString();
120 auto *can_factory = CanClientFactory::Instance();
121 can_factory->RegisterCanClients();
122 can_client_ = can_factory->CreateCANClient(canbus_conf_.can_card_parameter());
124 return OnError(
"Failed to create can client.");
126 AINFO <<
"Can client is successfully created.";
129 if (sensor_message_manager_ ==
nullptr) {
130 return OnError(
"Failed to create message manager.");
132 AINFO <<
"Sensor message manager is successfully created.";
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.");
138 AINFO <<
"The can receiver is successfully initialized.";
139 sensor_writer_ = node_->CreateWriter<SensorType>(FLAGS_sensor_node_name);
143template <
typename SensorType>
146 if (can_client_->Start() != ErrorCode::OK) {
147 return OnError(
"Failed to start can client");
149 AINFO <<
"Can client is started.";
152 if (can_receiver_.Start() != ErrorCode::OK) {
153 return OnError(
"Failed to start can receiver.");
155 AINFO <<
"Can receiver is started.";
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));
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.");
175 monitor_logger_buffer_.INFO(
"Canbus is started.");
180template <
typename SensorType>
181void SensorCanbus<SensorType>::OnTimer() {
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_);
192 sensor_message_manager_->ClearSensorData();
196template <
typename SensorType>
198 if (FLAGS_sensor_freq > 0) {
202 can_receiver_.Stop();
205 if (data_trigger_running_) {
206 data_trigger_running_ =
false;
207 if (thread_ !=
nullptr && thread_->joinable()) {
208 sensor_message_manager_->GetMutableCVar()->notify_all();
213 AINFO <<
"Data trigger stopped [ok].";
217template <
typename SensorType>
219 monitor_logger_buffer_.ERROR(error_msg);
Defines the CanFrame struct and CanClient interface.
Defines the CanClientFactory class.
Defines CanReceiver class.
Cyber has builtin time type Time.
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.
message manager manages protocols.
The class of MessageManager
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,...