29 #include <unordered_map> 32 #include "gtest/gtest_prod.h" 38 #include "modules/common/proto/error_code.pb.h" 54 template <
typename SensorType>
115 uint32_t message_id_ = 0;
119 int32_t curr_period_ = 0;
122 static std::mutex mutex_;
123 struct CanFrame can_frame_to_send_;
124 struct CanFrame can_frame_to_update_;
131 template <
typename SensorType>
150 common::ErrorCode
Init(
CanClient *can_client,
bool enable_log);
161 bool init_with_one =
false);
167 apollo::common::ErrorCode Start();
184 bool IsRunning()
const;
185 bool enable_log()
const;
187 FRIEND_TEST(CanSenderTest, OneRunCase);
190 void PowerSendThreadFunc();
193 const int32_t delta_period);
194 bool is_init_ =
false;
195 bool is_running_ =
false;
198 std::vector<SenderMessage<SensorType>> send_messages_;
199 std::unique_ptr<std::thread> thread_;
200 bool enable_log_ =
false;
207 template <
typename SensorType>
210 template <
typename SensorType>
215 template <
typename SensorType>
219 : message_id_(message_id), protocol_data_(protocol_data) {
221 for (int32_t i = 0; i < protocol_data->
GetLength(); ++i) {
222 can_frame_to_update_.
data[i] = 0xFF;
225 int32_t len = protocol_data_->GetLength();
227 can_frame_to_update_.
id = message_id_;
228 can_frame_to_update_.
len =
static_cast<uint8_t
>(len);
230 period_ = protocol_data_->GetPeriod();
231 curr_period_ = period_;
236 template <
typename SensorType>
238 curr_period_ -= period_delta;
239 if (curr_period_ <= 0) {
240 curr_period_ = period_;
244 template <
typename SensorType>
246 if (protocol_data_ ==
nullptr) {
247 AERROR <<
"Attention: ProtocolData is nullptr!";
250 protocol_data_->UpdateData(can_frame_to_update_.
data);
252 std::lock_guard<std::mutex> lock(mutex_);
253 can_frame_to_send_ = can_frame_to_update_;
256 template <
typename SensorType>
261 template <
typename SensorType>
263 std::lock_guard<std::mutex> lock(mutex_);
264 return can_frame_to_send_;
267 template <
typename SensorType>
272 template <
typename SensorType>
274 CHECK_NOTNULL(can_client_);
276 sch.sched_priority = 99;
277 pthread_setschedparam(pthread_self(), SCHED_FIFO, &sch);
279 const int32_t INIT_PERIOD = 5000;
280 int32_t delta_period = INIT_PERIOD;
281 int32_t new_delta_period = INIT_PERIOD;
283 int64_t tm_start = 0;
285 int64_t sleep_interval = 0;
287 AINFO <<
"Can client sender thread starts.";
289 while (is_running_) {
291 new_delta_period = INIT_PERIOD;
293 for (
auto &message : send_messages_) {
294 bool need_send = NeedSend(message, delta_period);
295 message.UpdateCurrPeriod(delta_period);
296 new_delta_period = std::min(new_delta_period, message.curr_period());
301 std::vector<CanFrame> can_frames;
303 can_frames.push_back(can_frame);
311 delta_period = new_delta_period;
313 sleep_interval = delta_period - (tm_end - tm_start);
315 if (sleep_interval > 0) {
316 std::this_thread::sleep_for(std::chrono::microseconds(sleep_interval));
319 AWARN <<
"Too much time for calculation: " << tm_end - tm_start
320 <<
"us is more than minimum period: " << delta_period <<
"us";
323 AINFO <<
"Can client sender thread stopped!";
326 template <
typename SensorType>
330 AERROR <<
"Duplicated Init request.";
331 return common::ErrorCode::CANBUS_ERROR;
333 if (can_client ==
nullptr) {
334 AERROR <<
"Invalid can client.";
335 return common::ErrorCode::CANBUS_ERROR;
338 can_client_ = can_client;
339 enable_log_ = enable_log;
343 template <
typename SensorType>
346 bool init_with_one) {
347 if (protocol_data ==
nullptr) {
348 AERROR <<
"invalid protocol data.";
351 send_messages_.emplace_back(
356 template <
typename SensorType>
359 AERROR <<
"Cansender has already started.";
360 return common::ErrorCode::CANBUS_ERROR;
363 thread_.reset(
new std::thread([
this] { PowerSendThreadFunc(); }));
368 template <
typename SensorType>
370 for (
auto &message : send_messages_) {
375 template <
typename SensorType>
378 AINFO <<
"Stopping can sender ...";
380 if (thread_ !=
nullptr && thread_->joinable()) {
385 AERROR <<
"CanSender is not running.";
388 AINFO <<
"Can client sender stopped [ok].";
391 template <
typename SensorType>
396 template <
typename SensorType>
401 template <
typename SensorType>
403 const int32_t delta_period) {
const uint32_t kSenderInterval
Definition: can_sender.h:205
virtual ~SenderMessage()=default
Destructor.
std::string CanFrameString() const
CanFrame string including essential information about the message.
Definition: can_client.h:69
uint8_t data[8]
Message content.
Definition: can_client.h:54
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
uint32_t id
Message id.
Definition: can_client.h:50
This is the base class of protocol data.
Definition: protocol_data.h:44
SenderMessage(const uint32_t message_id, ProtocolData< SensorType > *protocol_data)
Constructor which takes message ID and protocol data.
Definition: can_sender.h:211
Defines the CanFrame struct and CanClient interface.
The class which defines the CAN client to send and receive message.
Definition: can_client.h:92
#define DISALLOW_COPY_AND_ASSIGN(classname)
Definition: macros.h:48
virtual int32_t GetLength() const
Definition: protocol_data.h:134
common::ErrorCode Init(CanClient *can_client, bool enable_log)
Initialize by a CAN client based on its brand.
Definition: can_sender.h:327
bool enable_log() const
Definition: can_sender.h:397
The class which defines the information to send and receive.
Definition: can_client.h:48
apollo::common::ErrorCode Start()
Start the CAN sender.
Definition: can_sender.h:357
uint8_t len
Message length.
Definition: can_client.h:52
void UpdateCurrPeriod(const int32_t delta_period)
Update the current period for sending messages by a difference.
Definition: can_sender.h:237
CAN sender.
Definition: can_sender.h:132
CanFrame()
Constructor.
Definition: can_client.h:61
#define ADEBUG
Definition: log.h:41
void Update()
Update the protocol data. But the updating process depends on the real type of protocol data which in...
Definition: can_sender.h:245
bool IsRunning() const
Get the working status of this CAN sender. To check if it is running.
Definition: can_sender.h:392
bool Init(const char *binary_name)
uint32_t message_id() const
Get the message ID.
Definition: can_sender.h:257
void AddMessage(uint32_t message_id, ProtocolData< SensorType > *protocol_data, bool init_with_one=false)
Add a message with its ID, protocol data.
Definition: can_sender.h:344
The class of ProtocolData.
This class defines the message to send.
Definition: can_sender.h:55
#define AERROR
Definition: log.h:44
void Update()
Definition: can_sender.h:369
#define AWARN
Definition: log.h:43
SensorType
Sensor types are set in the order of lidar, radar, camera, ultrasonic Please make sure SensorType has...
Definition: sensor_meta.h:29
uint64_t ToNanosecond() const
convert time to nanosecond.
bool OK()
Definition: state.h:44
static Time Now()
get the current time.
void Stop()
Stop the CAN sender.
Definition: can_sender.h:376
#define AINFO
Definition: log.h:42
int32_t curr_period() const
Get the current period to send messages. It may be different from the period from protocol data by up...
Definition: can_sender.h:268