25 std::cout <<
"Connecting to TCP data channel at " << hostname <<
":" << tcp_port <<
" ... ";
29 boost::asio::ip::tcp::resolver resolver(
io_service_);
30 boost::asio::ip::tcp::resolver::query query(hostname, std::to_string(tcp_port));
31 boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
32 boost::asio::ip::tcp::resolver::iterator end;
35 boost::system::error_code error = boost::asio::error::host_not_found;
38 while (error && endpoint_iterator != end)
44 throw boost::system::system_error(error);
51 catch (std::exception& e)
53 std::cerr <<
"Exception: " << e.what() << std::endl;
69 udp_socket_->bind(boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0));
74 boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
78 catch (std::exception& e)
80 std::cerr <<
"Exception: " << e.what() << std::endl;
82 std::cout <<
"Receiving scanner data at local UDP port " <<
udp_port_ <<
" ... ";
117 if( error.value() != 995 )
118 std::cerr <<
"ERROR: " <<
"data connection error: " << error.message() <<
"(" << error.value() <<
")" << std::endl;
138 boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
142 if( error.value() != 995 )
143 std::cerr <<
"ERROR: " <<
"data connection error: " << error.message() <<
"(" << error.value() <<
")" << std::endl;
173 std::cerr <<
"Too many scans in receiver queue: Dropping scans!" << std::endl;
183 for(
int i=0; i<num_scan_points; i++ )
185 unsigned int data = p_scan_data[i];
186 unsigned int distance = (data & 0x000FFFFF);
187 unsigned int amplitude = (data & 0xFFFFF000) >> 20;
226 char* pp = (
char*) p;
255 catch (std::exception& e)
257 std::cerr <<
"Exception: " << e.what() << std::endl;
312 throw std::exception();
315 std::size_t pone_size =
ring_buffer_.array_one().second;
317 std::size_t ptwo_size =
ring_buffer_.array_two().second;
319 if( ptwo_size >= numbytes )
321 std::memcpy(ptwo+ptwo_size-numbytes, src, numbytes);
325 std::memcpy(pone+pone_size+ptwo_size-numbytes,
327 numbytes-ptwo_size );
329 src+numbytes-ptwo_size,
338 throw std::exception();
340 std::size_t pone_size =
ring_buffer_.array_one().second;
344 if( pone_size >= numbytes )
346 std::memcpy( dst, pone, numbytes );
350 std::memcpy( dst, pone, pone_size );
351 std::memcpy( dst+pone_size, ptwo, numbytes-pone_size);
boost::thread io_service_thread_
Event handler thread.
boost::asio::ip::tcp::socket * tcp_socket_
Receiving socket.
void disconnect()
Disconnect and cleanup.
~ScanDataReceiver()
Disconnect cleanly.
std::size_t getFullScansAvailable() const
Get the total number of fully received laserscans available.
double last_data_time_
time in seconds since epoch, when last data was received
void handleSocketRead(const boost::system::error_code &error)
Asynchronous callback function, called if data has been reveived by the TCP socket.
boost::asio::streambuf inbuf_
Boost::Asio streambuffer.
boost::asio::ip::udp::socket * udp_socket_
Receiving socket.
Normally contains one complete laserscan (a full rotation of the scanner head)
std::mutex data_mutex_
Protection against data races between ROS and IO threads.
boost::asio::ip::udp::endpoint udp_endpoint_
Endpoint in case of UDP receiver.
std::condition_variable data_notifier_
Data notification condition variable.
std::vector< std::uint32_t > distance_data
Distance data in polar form in millimeter.
bool retrievePacket(std::size_t start, PacketTypeC *p)
boost::circular_buffer< char > ring_buffer_
Internal ringbuffer for temporarily storing reveived data.
ScanDataReceiver()
Open an UDP port and listen on it.
std::vector< std::uint32_t > amplitude_data
Amplitude data in the range 32-4095, values lower than 32 indicate an error or undefined values...
std::vector< PacketHeader > headers
Header received with the distance and amplitude data.
boost::asio::io_service io_service_
Structure of a UDP or TCP data packet from the laserscanner.
bool isConnected() const
Return connection status.
std::array< char, 65536 > udp_buffer_
Buffer in case of UDP receiver.
void readBufferFront(char *dst, std::size_t numbytes)
void writeBufferBack(char *src, std::size_t numbytes)
int udp_port_
Data (UDP) port at local side.
std::deque< ScanData > scan_data_
Double ended queue with sucessfully received and parsed data, organized as single complete scans...
bool is_connected_
Internal connection state.
std::istream instream_
Input stream.