Apollo 10.0
自动驾驶开放平台
can_receiver.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
22#pragma once
23
24#include <atomic>
25#include <cmath>
26#include <future>
27#include <iostream>
28#include <memory>
29#include <sstream>
30#include <thread>
31#include <vector>
32
33#include "modules/common_msgs/basic_msgs/error_code.pb.h"
34
35#include "cyber/common/macros.h"
36#include "cyber/cyber.h"
40
45namespace apollo {
46namespace drivers {
47namespace canbus {
48
53template <typename SensorType>
55 public:
59 CanReceiver() = default;
60
64 virtual ~CanReceiver() = default;
65
76 bool enable_log);
77
83 bool IsRunning() const;
84
90 bool IsFinishRecvOnce() const;
91
97
101 void Stop();
102
103 private:
104 void RecvThreadFunc();
105
106 int32_t Start(bool is_blocked);
107
108 private:
109 std::atomic<bool> is_running_ = {false};
110 std::atomic<bool> is_finish_recv_once_ = {false};
111 // CanClient, MessageManager pointer life is managed by outer program
112 CanClient *can_client_ = nullptr;
113 MessageManager<SensorType> *pt_manager_ = nullptr;
114 bool enable_log_ = false;
115 bool is_init_ = false;
116 std::future<void> async_result_;
117
119};
120
121template <typename SensorType>
123 CanClient *can_client, MessageManager<SensorType> *pt_manager,
124 bool enable_log) {
125 can_client_ = can_client;
126 pt_manager_ = pt_manager;
127 enable_log_ = enable_log;
128 if (can_client_ == nullptr) {
129 AERROR << "Invalid can client.";
130 return ::apollo::common::ErrorCode::CANBUS_ERROR;
131 }
132 if (pt_manager_ == nullptr) {
133 AERROR << "Invalid protocol manager.";
134 return ::apollo::common::ErrorCode::CANBUS_ERROR;
135 }
136 is_init_ = true;
137 return ::apollo::common::ErrorCode::OK;
138}
139
140template <typename SensorType>
142 AINFO << "Can client receiver thread starts.";
143 CHECK_NOTNULL(can_client_);
144 CHECK_NOTNULL(pt_manager_);
145
146 int32_t receive_error_count = 0;
147 int32_t receive_none_count = 0;
148 const int32_t ERROR_COUNT_MAX = 10;
149 auto default_period = 10 * 1000;
150
151 while (IsRunning()) {
152 is_finish_recv_once_.exchange(false);
153 ADEBUG << "is_finish_recv_once_ 1 is " << is_finish_recv_once_.load();
154 std::vector<CanFrame> buf;
155 int32_t frame_num = MAX_CAN_RECV_FRAME_LEN;
156 if (can_client_->Receive(&buf, &frame_num) !=
158 LOG_IF_EVERY_N(ERROR, receive_error_count++ > ERROR_COUNT_MAX,
159 ERROR_COUNT_MAX)
160 << "Received " << receive_error_count << " error messages.";
161 cyber::USleep(default_period);
162 continue;
163 }
164 receive_error_count = 0;
165
166 if (buf.size() != static_cast<size_t>(frame_num)) {
167 AERROR_EVERY(100) << "Receiver buf size [" << buf.size()
168 << "] does not match can_client returned length["
169 << frame_num << "].";
170 }
171
172 if (frame_num == 0) {
173 LOG_IF_EVERY_N(ERROR, receive_none_count++ > ERROR_COUNT_MAX,
174 ERROR_COUNT_MAX)
175 << "Received " << receive_none_count << " empty messages.";
176 cyber::USleep(default_period);
177 continue;
178 }
179 receive_none_count = 0;
180
181 for (const auto &frame : buf) {
182 uint8_t len = frame.len;
183 uint32_t uid = frame.id;
184 const uint8_t *data = frame.data;
185 pt_manager_->Parse(uid, data, len);
186 if (enable_log_) {
187 AINFO << "recv_can_frame#" << frame.CanFrameString();
188 }
189 }
190 is_finish_recv_once_.exchange(true);
191 ADEBUG << "is_finish_recv_once_ 2 is " << is_finish_recv_once_.load();
192 cyber::Yield();
193 }
194 AINFO << "Can client receiver thread stopped.";
195}
196
197template <typename SensorType>
199 return is_running_.load();
200}
201
202template <typename SensorType>
204 ADEBUG << "is_finish_recv_once_ state is " << is_finish_recv_once_.load();
205 return is_finish_recv_once_.load();
206}
207
208template <typename SensorType>
210 if (is_init_ == false) {
211 return ::apollo::common::ErrorCode::CANBUS_ERROR;
212 }
213 is_running_.exchange(true);
214
215 async_result_ = cyber::Async(&CanReceiver<SensorType>::RecvThreadFunc, this);
216 return ::apollo::common::ErrorCode::OK;
217}
218
219template <typename SensorType>
221 if (IsRunning()) {
222 AINFO << "Stopping can client receiver ...";
223 is_running_.exchange(false);
224 async_result_.wait();
225 } else {
226 AINFO << "Can client receiver is not running.";
227 }
228 AINFO << "Can client receiver stopped [ok].";
229}
230
231} // namespace canbus
232} // namespace drivers
233} // namespace apollo
Defines the CanFrame struct and CanClient interface.
The class which defines the CAN client to send and receive message.
Definition can_client.h:92
::apollo::common::ErrorCode Start()
Start the CAN receiver.
virtual ~CanReceiver()=default
Destructor.
bool IsRunning() const
Get the working status of this CAN receiver.
void Stop()
Stop the CAN receiver.
common::ErrorCode Init(CanClient *can_client, MessageManager< SensorType > *pt_manager, bool enable_log)
Initialize by a CAN client, message manager.
CanReceiver()=default
Constructor.
bool IsFinishRecvOnce() const
Get the receive status in once receive buf.
message manager manages protocols.
#define DISALLOW_COPY_AND_ASSIGN(classname)
Definition macros.h:48
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AERROR_EVERY(freq)
Definition log.h:86
#define AINFO
Definition log.h:42
The class of MessageManager
const int32_t MAX_CAN_RECV_FRAME_LEN
class register implement
Definition arena_queue.h:37