00001
00002
00003
00004
00005
00006
00007
00008
00009
00024 #include <unistd.h>
00025 #include <sys/socket.h>
00026 #include <arpa/inet.h>
00027 #include <poll.h>
00028 #include <errno.h>
00029
00030 #include <velodyne/input.h>
00031
00032 namespace velodyne
00033 {
00034 using namespace velodyne_common;
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 int Input::getPacket(velodyne_msgs::VelodynePacket *pkt)
00045 {
00046 double time = 0.0;
00047 int rc = getPackets(&pkt->data[0], 1, &time);
00048 pkt->stamp = ros::Time(time);
00049 return rc;
00050 }
00051
00052
00053
00054
00055
00056 int InputSocket::vopen(void)
00057 {
00058 sockfd_ = socket(PF_INET, SOCK_DGRAM, 0);
00059 if (sockfd_ == -1)
00060 {
00061 perror("socket");
00062 return -1;
00063 }
00064
00065 sockaddr_in my_addr;
00066 memset(&my_addr, 0, sizeof(my_addr));
00067 my_addr.sin_family = AF_INET;
00068 my_addr.sin_port = htons(udp_port_);
00069 my_addr.sin_addr.s_addr = INADDR_ANY;
00070
00071 if (bind(sockfd_, (sockaddr *)&my_addr, sizeof(sockaddr)) == -1)
00072 {
00073 perror("bind");
00074 return -1;
00075 }
00076
00077 ROS_DEBUG("Velodyne socket fd is %d\n", sockfd_);
00078
00079 return 0;
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 int InputSocket::getPackets(uint8_t *buffer, int npacks,
00092 double *data_time)
00093 {
00094 int result = npacks;
00095 double time1 = ros::Time::now().toSec();
00096
00097 struct pollfd fds[1];
00098 fds[0].fd = sockfd_;
00099 fds[0].events = POLLIN;
00100 static const int POLL_TIMEOUT = 1000;
00101
00102 for (int i = 0; i < npacks; ++i)
00103 {
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 do
00123 {
00124 int retval = poll(fds, 1, POLL_TIMEOUT);
00125 if (retval < 0)
00126 {
00127 if (errno != EINTR)
00128 ROS_ERROR("poll() error: %s", strerror(errno));
00129 return result;
00130 }
00131 if (retval == 0)
00132 {
00133 ROS_WARN("Velodyne poll() timeout");
00134 return result;
00135 }
00136 if ((fds[0].revents & POLLERR)
00137 || (fds[0].revents & POLLHUP)
00138 || (fds[0].revents & POLLNVAL))
00139 {
00140 ROS_ERROR("poll() reports Velodyne error");
00141 return result;
00142 }
00143 } while ((fds[0].revents & POLLIN) == 0);
00144
00145
00146 ssize_t nbytes = recvfrom(sockfd_,
00147 &buffer[i * RawScan::PACKET_SIZE],
00148 RawScan::PACKET_SIZE, 0, NULL, NULL);
00149 if ((uint32_t) nbytes == RawScan::PACKET_SIZE)
00150 --result;
00151 else
00152 {
00153 ROS_DEBUG_STREAM("incomplete Velodyne packet read: "
00154 << nbytes << " bytes");
00155 --i;
00156 }
00157 }
00158
00159 double time2 = ros::Time::now().toSec();
00160
00161
00162
00163 *data_time = (time2 + time1) / 2.0;
00164
00165 return result;
00166 }
00167
00168 int InputSocket::vclose(void)
00169 {
00170 int rc = close(sockfd_);
00171 return rc;
00172 }
00173
00174
00175 int InputPCAP::vopen(void)
00176 {
00177 ROS_INFO("Opening input file \"%s\"", filename_.c_str());
00178
00179
00180 if ((pcap_ = pcap_open_offline(filename_.c_str(), errbuf_) ) == NULL)
00181 {
00183 ROS_FATAL("Error opening Velodyne socket dump file.");
00184 return -1;
00185 }
00186 return 0;
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 int InputPCAP::getPackets(uint8_t *buffer,
00201 int npacks,
00202 double *data_time)
00203 {
00204 struct pcap_pkthdr *header;
00205 const u_char *pkt_data;
00206 int result = npacks;
00207
00208 for (int i = 0; i < npacks; ++i)
00209 {
00210 int res;
00211 if ((res = pcap_next_ex(pcap_, &header, &pkt_data)) >= 0)
00212 {
00213
00214
00215
00216 if (read_fast_ == false)
00217 delay_.sleep();
00218
00219 memcpy(&buffer[i * RawScan::PACKET_SIZE],
00220 pkt_data+42, RawScan::PACKET_SIZE);
00221 *data_time = ros::Time::now().toSec();
00222 empty_ = false;
00223 --result;
00224
00225 }
00226 else
00227 {
00228 if (empty_)
00229 {
00230 ROS_WARN("Error %d reading Velodyne packet: %s",
00231 res, pcap_geterr(pcap_));
00232 return result;
00233 }
00234
00235 if (read_once_)
00236 {
00237 ROS_INFO("end of file reached -- done reading.");
00238 return -1;
00239 }
00240
00241 if (repeat_delay_ > 0.0)
00242 {
00243 ROS_INFO("end of file reached -- delaying %.3f seconds.",
00244 repeat_delay_);
00245 usleep(rint(repeat_delay_ * 1000000.0));
00246 }
00247
00248 ROS_DEBUG("replaying Velodyne dump file");
00249
00250
00251
00252
00253 pcap_close(pcap_);
00254 pcap_ = pcap_open_offline(filename_.c_str(), errbuf_);
00255 empty_ = true;
00256 i = -1;
00257 result = npacks;
00258 }
00259 }
00260
00261 return result;
00262 }
00263
00264 int InputPCAP::vclose(void)
00265 {
00266 pcap_close(pcap_);
00267 return 0;
00268 }
00269
00270 }