Apollo 10.0
自动驾驶开放平台
input.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2020 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
18
19#include <arpa/inet.h>
20#include <fcntl.h>
21#include <poll.h>
22#include <sys/file.h>
23#include <sys/socket.h>
24
25#include <cerrno>
26#include <cstdint>
27#include <cstring>
28#include <memory>
29
30namespace apollo {
31namespace drivers {
32namespace lslidar {
33namespace driver {
34
35Input::Input(uint16_t port, std::string lidar_ip, int packet_size) {
36 packet_size_ = packet_size;
37 inet_aton(lidar_ip.c_str(), &devip_);
38}
39
41 return 0;
42}
43
45 (void)close(sockfd_);
46}
47
48InputSocket::InputSocket(uint16_t port, std::string lidar_ip, int packet_size) :
49 Input(port, lidar_ip, packet_size) {
50 port_ = port;
51 sockfd_ = -1;
52 sockfd_ = socket(PF_INET, SOCK_DGRAM, 0);
53 if (-1 == sockfd_) {
54 AERROR << "socket open error";
55 return;
56 }
57
58 inet_aton(lidar_ip.c_str(), &devip_);
59 sockaddr_in myAddress; // my address information
60 memset(&myAddress, 0, sizeof(myAddress)); // initialize to zeros
61 myAddress.sin_family = AF_INET; // host byte order
62 myAddress.sin_port = htons(port); // port in network byte order
63 myAddress.sin_addr.s_addr = INADDR_ANY; // automatically fill in my IP
64
65 if (bind(sockfd_,
66 reinterpret_cast<sockaddr *>(&myAddress),
67 sizeof(sockaddr))
68 == -1) {
69 AERROR << "bind error, port:" << port;
70 return;
71 }
72
73 if (fcntl(sockfd_, F_SETFL, O_NONBLOCK | FASYNC) < 0) {
74 AERROR << "fcntl error";
75 return;
76 }
77}
78
80 (void)close(sockfd_);
81}
82
84 double time1 = apollo::cyber::Time().Now().ToSecond();
85 struct pollfd fds[1];
86 fds[0].fd = sockfd_;
87 fds[0].events = POLLIN;
88 static const int POLL_TIMEOUT = 3000; // one second (in msec)
89
90 sockaddr_in sender_address;
91 socklen_t sender_address_len = sizeof(sender_address);
92
93 while (true) {
94 // Receive packets that should now be available from the
95 // socket using a blocking read.
96 // poll() until input available
97 do {
98 int retval = poll(fds, 1, POLL_TIMEOUT);
99 if (retval < 0) {
100 if (errno != EINTR)
101 AERROR << "poll() error: " << strerror(errno);
102
103 return 1;
104 }
105 if (retval == 0) {
106 AERROR << "lslidar poll() timeout, port: " << port_;
107 return 1;
108 }
109 if ((fds[0].revents & POLLERR) || (fds[0].revents & POLLHUP)
110 || (fds[0].revents & POLLNVAL)) {
111 AWARN << "poll() reports lslidar error";
112 return 1;
113 }
114 } while ((fds[0].revents & POLLIN) == 0);
115 uint8_t bytes[1212];
116 ssize_t nbytes = recvfrom(
117 sockfd_,
118 bytes,
120 0,
121 reinterpret_cast<sockaddr *>(&sender_address),
122 &sender_address_len);
123 if (nbytes < 0) {
124 if (errno != EWOULDBLOCK) {
125 AERROR << "recvfail";
126 return 1;
127 }
128 } else if ((size_t)nbytes == size_t(packet_size_)) {
129 if (sender_address.sin_addr.s_addr != devip_.s_addr) {
130 AERROR << "lidar IP parameter set error,please reset in config "
131 "file";
132 continue;
133 } else {
134 pkt->set_data(bytes, packet_size_);
135 break;
136 }
137 }
138 AERROR << "incomplete lslidar packet read: " << nbytes << " bytes";
139 }
140
141 // Average the times at which we begin and end reading. Use that to
142 // estimate when the scan occurred.
143 double time2 = apollo::cyber::Time().Now().ToSecond();
144 AINFO << apollo::cyber::Time((time2 + time1) / 2.0).ToNanosecond();
145 return 0;
146}
147
149 uint16_t port,
150 std::string lidar_ip,
151 int packet_size,
152 double packet_rate,
153 std::string filename,
154 bool read_once,
155 bool read_fast,
156 double repeat_delay) :
157 Input(port, lidar_ip, packet_size),
158 packet_rate_(packet_rate),
159 filename_(filename) {
160 pcap_ = NULL;
161 empty_ = true;
162 packet_rate_ = packet_rate;
163 lidar_ip_ = lidar_ip;
164 // get parameters using private node handle
165 read_once_ = read_once;
166 read_fast_ = read_fast;
167 repeat_delay_ = repeat_delay;
168
169 if (read_once_)
170 AINFO << "Read input file only once.";
171 if (read_fast_)
172 AINFO << "Read input file as quickly as possible.";
173 if (repeat_delay_ > 0.0)
174 AINFO << "Delay %.3f seconds before repeating input file."
175 << repeat_delay_;
176
177 // Open the PCAP dump file
178 AERROR << "Opening PCAP file " << filename_;
179 if ((pcap_ = pcap_open_offline(filename_.c_str(), errbuf_)) == NULL) {
180 AERROR << "Error opening lslidar socket dump file.";
181 return;
182 }
183
184 std::stringstream filter;
185 if (lidar_ip != "") {
186 filter << "src host " << lidar_ip << " && ";
187 }
188 filter << "udp dst port " << port;
189 pcap_compile(
190 pcap_,
191 &pcap_packet_filter_,
192 filter.str().c_str(),
193 1,
194 PCAP_NETMASK_UNKNOWN);
195}
196
199 pcap_close(pcap_);
200}
201
204 struct pcap_pkthdr *header;
205 const u_char *pkt_data;
206
207 // while (flag == 1)
208 while (!apollo::cyber::IsShutdown()) {
209 int res;
210 if ((res = pcap_next_ex(pcap_, &header, &pkt_data)) >= 0) {
211 // Skip packets not for the correct port and from the
212 // selected IP address.
213 if (!lidar_ip_.empty()
214 && (0
215 == pcap_offline_filter(
216 &pcap_packet_filter_, header, pkt_data)))
217 continue;
218
219 // Keep the reader from blowing through the file.
220 if (read_fast_ == false)
221 usleep(static_cast<int>(1000 * 1000 / packet_rate_ / 1.1));
222 if (1206 == packet_size_) {
223 uint8_t bytes[1206];
224 memcpy(bytes, pkt_data + 42, packet_size_);
225 pkt->set_data(bytes, packet_size_);
226 } else if (1212 == packet_size_) {
227 uint8_t bytes[1212];
228 memcpy(bytes, pkt_data + 42, packet_size_);
229 pkt->set_data(bytes, packet_size_);
230 }
231
232 empty_ = false;
233 return 0; // success
234 }
235
236 if (empty_) {
237 AINFO << "Error " << res
238 << " reading lslidar packet: " << pcap_geterr(pcap_);
239 return -1;
240 }
241
242 if (read_once_) {
243 AINFO << "end of file reached -- done reading.";
244 return -1;
245 }
246
247 if (repeat_delay_ > 0.0) {
248 AINFO << "end of file reached -- delaying" << repeat_delay_
249 << "seconds.";
250 usleep(rint(repeat_delay_ * 1000000.0));
251 }
252
253 AINFO << "replaying lslidar dump file";
254
255 // I can't figure out how to rewind the file, because it
256 // starts with some kind of header. So, close the file
257 // and reopen it with pcap.
258 pcap_close(pcap_);
259 pcap_ = pcap_open_offline(filename_.c_str(), errbuf_);
260 empty_ = true; // maybe the file disappeared?
261 } // loop back and try again
262 return 0;
263}
264
265} // namespace driver
266} // namespace lslidar
267} // namespace drivers
268} // namespace apollo
Cyber has builtin time type Time.
Definition time.h:31
uint64_t ToNanosecond() const
convert time to nanosecond.
Definition time.cc:83
static Time Now()
get the current time.
Definition time.cc:57
double ToSecond() const
convert time to second.
Definition time.cc:77
InputPCAP(uint16_t port=MSOP_DATA_PORT_NUMBER, std::string lidar_ip="192.168.1.200", int packet_size=1212, double packet_rate=0.0, std::string filename="", bool read_once=false, bool read_fast=false, double repeat_delay=0.0)
Definition input.cc:148
virtual int GetPacket(LslidarPacket *pkt)
Get one lslidar packet.
Definition input.cc:203
virtual int GetPacket(LslidarPacket *pkt)
Definition input.cc:83
InputSocket(uint16_t port=MSOP_DATA_PORT_NUMBER, std::string lidar_ip="192.168.1.200", int packet_size=1212)
Definition input.cc:48
virtual int GetPacket(LslidarPacket *pkt)
Definition input.cc:40
Input(uint16_t portport=MSOP_DATA_PORT_NUMBER, std::string lidar_ip="192.168.1.200", int packet_size=1212)
Definition input.cc:35
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
#define AWARN
Definition log.h:43
bool IsShutdown()
Definition state.h:46
class register implement
Definition arena_queue.h:37
@ POLL_TIMEOUT