Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <pcl/io/robot_eye_grabber.h>
00039 #include <pcl/console/print.h>
00040
00042 pcl::RobotEyeGrabber::RobotEyeGrabber ()
00043 : terminate_thread_ (false)
00044 , signal_point_cloud_size_ (1000)
00045 , data_port_ (443)
00046 , sensor_address_ (boost::asio::ip::address_v4::any ())
00047 {
00048 point_cloud_signal_ = createSignal<sig_cb_robot_eye_point_cloud_xyzi> ();
00049 resetPointCloud ();
00050 }
00051
00053 pcl::RobotEyeGrabber::RobotEyeGrabber (const boost::asio::ip::address& ipAddress, unsigned short port)
00054 : terminate_thread_ (false)
00055 , signal_point_cloud_size_ (1000)
00056 , data_port_ (port)
00057 , sensor_address_ (ipAddress)
00058 {
00059 point_cloud_signal_ = createSignal<sig_cb_robot_eye_point_cloud_xyzi> ();
00060 resetPointCloud ();
00061 }
00062
00064 pcl::RobotEyeGrabber::~RobotEyeGrabber () throw ()
00065 {
00066 stop ();
00067 disconnect_all_slots<sig_cb_robot_eye_point_cloud_xyzi> ();
00068 }
00069
00071 std::string
00072 pcl::RobotEyeGrabber::getName () const
00073 {
00074 return (std::string ("Ocular Robotics RobotEye Grabber"));
00075 }
00076
00078 float
00079 pcl::RobotEyeGrabber::getFramesPerSecond () const
00080 {
00081 return (0.0f);
00082 }
00083
00085 bool
00086 pcl::RobotEyeGrabber::isRunning () const
00087 {
00088 return (socket_thread_ != NULL);
00089 }
00090
00092 unsigned short
00093 pcl::RobotEyeGrabber::getDataPort () const
00094 {
00095 return (data_port_);
00096 }
00097
00099 void
00100 pcl::RobotEyeGrabber::setDataPort (const unsigned short port)
00101 {
00102 data_port_ = port;
00103 }
00104
00106 const boost::asio::ip::address&
00107 pcl::RobotEyeGrabber::getSensorAddress () const
00108 {
00109 return (sensor_address_);
00110 }
00111
00113 void
00114 pcl::RobotEyeGrabber::setSensorAddress (const boost::asio::ip::address& ipAddress)
00115 {
00116 sensor_address_ = ipAddress;
00117 }
00118
00120 std::size_t
00121 pcl::RobotEyeGrabber::getSignalPointCloudSize () const
00122 {
00123 return (signal_point_cloud_size_);
00124 }
00125
00127 void
00128 pcl::RobotEyeGrabber::setSignalPointCloudSize (std::size_t numberOfPoints)
00129 {
00130 signal_point_cloud_size_ = numberOfPoints;
00131 }
00132
00134 boost::shared_ptr<pcl::PointCloud<pcl::PointXYZI> >
00135 pcl::RobotEyeGrabber::getPointCloud () const
00136 {
00137 return point_cloud_xyzi_;
00138 }
00139
00141 void
00142 pcl::RobotEyeGrabber::resetPointCloud ()
00143 {
00144 point_cloud_xyzi_.reset (new pcl::PointCloud<pcl::PointXYZI>);
00145 point_cloud_xyzi_->is_dense = true;
00146 }
00147
00149 void
00150 pcl::RobotEyeGrabber::consumerThreadLoop ()
00151 {
00152 while (true)
00153 {
00154 boost::shared_array<unsigned char> data;
00155 if (!packet_queue_.dequeue (data))
00156 return;
00157
00158 convertPacketData (data.get(), 464);
00159 }
00160 }
00161
00163 void
00164 pcl::RobotEyeGrabber::convertPacketData (unsigned char *dataPacket, size_t length)
00165 {
00166 const size_t bytesPerPoint = 8;
00167 const size_t totalPoints = length / bytesPerPoint;
00168
00169 for (int i = 0; i < totalPoints; ++i)
00170 {
00171 PointXYZI xyzi;
00172 computeXYZI (xyzi, dataPacket + i*bytesPerPoint);
00173
00174 if (pcl::isFinite(xyzi))
00175 {
00176 point_cloud_xyzi_->push_back (xyzi);
00177 }
00178 }
00179
00180
00181 if (point_cloud_xyzi_->size () > signal_point_cloud_size_)
00182 {
00183 if (point_cloud_signal_->num_slots () > 0)
00184 point_cloud_signal_->operator() (point_cloud_xyzi_);
00185
00186 resetPointCloud ();
00187 }
00188 }
00189
00191 void
00192 pcl::RobotEyeGrabber::computeXYZI (pcl::PointXYZI& point, unsigned char* pointData)
00193 {
00194 uint16_t buffer = 0;
00195 double az = 0.0;
00196 double el = 0.0;
00197 double range = 0.0;
00198 uint16_t intensity = 0;
00199
00200 buffer = 0x00;
00201 buffer = pointData[0] << 8;
00202 buffer |= pointData[1];
00203 az = (buffer / 100.0);
00204
00205 buffer = 0x00;
00206 buffer = pointData[2] << 8;
00207 buffer |= pointData[3];
00208 el = (signed short int)buffer / 100.0;
00209
00210 buffer = 0x00;
00211 buffer = pointData[4] << 8;
00212 buffer |= pointData[5];
00213 range = (signed short int)buffer / 100.0;
00214
00215 buffer = 0x00;
00216 buffer = pointData[6] << 8;
00217 buffer |= pointData[7];
00218 intensity = buffer;
00219
00220 point.x = range * std::cos (el * M_PI/180) * std::sin (az * M_PI/180);
00221 point.y = range * std::cos (el * M_PI/180) * std::cos (az * M_PI/180);
00222 point.z = range * std::sin (el * M_PI/180);
00223 point.intensity = intensity;
00224 }
00225
00227 void
00228 pcl::RobotEyeGrabber::socketThreadLoop()
00229 {
00230 asyncSocketReceive();
00231 io_service_.reset();
00232 io_service_.run();
00233 }
00234
00236 void
00237 pcl::RobotEyeGrabber::asyncSocketReceive()
00238 {
00239
00240
00241 socket_->async_receive_from(boost::asio::buffer(receive_buffer_, 500), sender_endpoint_,
00242 boost::bind(&RobotEyeGrabber::socketCallback, this,
00243 boost::asio::placeholders::error,
00244 boost::asio::placeholders::bytes_transferred));
00245 }
00246
00248 void
00249 pcl::RobotEyeGrabber::socketCallback(const boost::system::error_code&, std::size_t numberOfBytes)
00250 {
00251 if (terminate_thread_)
00252 return;
00253
00254 if (sensor_address_ == boost::asio::ip::address_v4::any ()
00255 || sensor_address_ == sender_endpoint_.address ())
00256 {
00257 if (numberOfBytes == 464)
00258 {
00259 unsigned char *dup = new unsigned char[numberOfBytes];
00260 memcpy (dup, receive_buffer_, numberOfBytes);
00261 packet_queue_.enqueue (boost::shared_array<unsigned char>(dup));
00262 }
00263 }
00264
00265 asyncSocketReceive ();
00266 }
00267
00269 void
00270 pcl::RobotEyeGrabber::start ()
00271 {
00272 if (isRunning ())
00273 return;
00274
00275 boost::asio::ip::udp::endpoint destinationEndpoint (boost::asio::ip::address_v4::any (), data_port_);
00276
00277 try
00278 {
00279 socket_.reset (new boost::asio::ip::udp::socket (io_service_, destinationEndpoint));
00280 }
00281 catch (std::exception &e)
00282 {
00283 PCL_ERROR ("[pcl::RobotEyeGrabber::start] Unable to bind to socket! %s\n", e.what ());
00284 return;
00285 }
00286
00287 terminate_thread_ = false;
00288 resetPointCloud ();
00289 consumer_thread_.reset(new boost::thread (boost::bind (&RobotEyeGrabber::consumerThreadLoop, this)));
00290 socket_thread_.reset(new boost::thread (boost::bind (&RobotEyeGrabber::socketThreadLoop, this)));
00291 }
00292
00294 void
00295 pcl::RobotEyeGrabber::stop ()
00296 {
00297 if (!isRunning ())
00298 return;
00299
00300 terminate_thread_ = true;
00301
00302
00303 socket_->close ();
00304 io_service_.stop ();
00305 socket_thread_->join ();
00306 socket_thread_.reset ();
00307 socket_.reset();
00308
00309 packet_queue_.stopQueue ();
00310 consumer_thread_->join ();
00311 consumer_thread_.reset ();
00312 }