00001
00036 #ifndef _LibMultiSense_details_channel_hh
00037 #define _LibMultiSense_details_channel_hh
00038
00039 #include "MultiSenseChannel.hh"
00040
00041 #include "details/utility/Portability.hh"
00042 #include "details/utility/Thread.hh"
00043 #include "details/utility/BufferStream.hh"
00044 #include "details/utility/Units.hh"
00045 #include "details/listeners.hh"
00046 #include "details/signal.hh"
00047 #include "details/storage.hh"
00048 #include "details/wire/Protocol.h"
00049 #include "details/wire/ImageMetaMessage.h"
00050 #include "details/wire/VersionResponseMessage.h"
00051
00052 #ifndef WIN32
00053 #include <netinet/ip.h>
00054 #include <unistd.h>
00055 #endif
00056
00057 #include <vector>
00058 #include <list>
00059 #include <set>
00060 #include <map>
00061 #include <iostream>
00062 #include <fstream>
00063
00064 namespace crl {
00065 namespace multisense {
00066 namespace details {
00067
00068
00069
00070
00071 class impl : public Channel {
00072 public:
00073
00074
00075
00076
00077 impl(const std::string& address);
00078 ~impl();
00079
00080
00081
00082
00083 virtual Status addIsolatedCallback (image::Callback callback,
00084 DataSource imageSourceMask,
00085 void *userDataP);
00086 virtual Status addIsolatedCallback (lidar::Callback callback,
00087 void *userDataP);
00088 virtual Status addIsolatedCallback (pps::Callback callback,
00089 void *userDataP);
00090 virtual Status addIsolatedCallback (imu::Callback callback,
00091 void *userDataP);
00092
00093 virtual Status removeIsolatedCallback(image::Callback callback);
00094 virtual Status removeIsolatedCallback(lidar::Callback callback);
00095 virtual Status removeIsolatedCallback(pps::Callback callback);
00096 virtual Status removeIsolatedCallback(imu::Callback callback);
00097
00098 virtual void* reserveCallbackBuffer ();
00099 virtual Status releaseCallbackBuffer (void *referenceP);
00100
00101 virtual Status networkTimeSynchronization(bool enabled);
00102
00103 virtual Status startStreams (DataSource mask);
00104 virtual Status stopStreams (DataSource mask);
00105 virtual Status getEnabledStreams (DataSource& mask);
00106
00107 virtual Status startDirectedStream (const DirectedStream& stream);
00108 virtual Status startDirectedStreams (const std::vector<DirectedStream>& streams);
00109 virtual Status stopDirectedStream (const DirectedStream& stream);
00110 virtual Status getDirectedStreams (std::vector<DirectedStream>& streams);
00111 virtual Status maxDirectedStreams (uint32_t& maximum);
00112
00113 virtual Status setTriggerSource (TriggerSource s);
00114
00115 virtual Status setMotorSpeed (float rpm);
00116
00117 virtual Status getLightingConfig (lighting::Config& c);
00118 virtual Status setLightingConfig (const lighting::Config& c);
00119
00120 virtual Status getSensorVersion (VersionType& version);
00121 virtual Status getApiVersion (VersionType& version);
00122 virtual Status getVersionInfo (system::VersionInfo& v);
00123
00124 virtual Status getImageConfig (image::Config& c);
00125 virtual Status setImageConfig (const image::Config& c);
00126
00127 virtual Status getImageCalibration (image::Calibration& c);
00128 virtual Status setImageCalibration (const image::Calibration& c);
00129
00130 virtual Status getLidarCalibration (lidar::Calibration& c);
00131 virtual Status setLidarCalibration (const lidar::Calibration& c);
00132
00133 virtual Status getImageHistogram (int64_t frameId, image::Histogram& histogram);
00134
00135 virtual Status getDeviceModes (std::vector<system::DeviceMode>& modes);
00136
00137 virtual Status getMtu (int32_t& mtu);
00138 virtual Status setMtu (int32_t mtu);
00139
00140 virtual Status getNetworkConfig (system::NetworkConfig& c);
00141 virtual Status setNetworkConfig (const system::NetworkConfig& c);
00142
00143 virtual Status getDeviceInfo (system::DeviceInfo& info);
00144 virtual Status setDeviceInfo (const std::string& key,
00145 const system::DeviceInfo& i);
00146
00147 virtual Status flashBitstream (const std::string& file);
00148 virtual Status flashFirmware (const std::string& file);
00149
00150 virtual Status verifyBitstream (const std::string& file);
00151 virtual Status verifyFirmware (const std::string& file);
00152
00153 virtual Status getImuInfo (uint32_t& maxSamplesPerMessage,
00154 std::vector<imu::Info>& info);
00155 virtual Status getImuConfig (uint32_t& samplesPerMessage,
00156 std::vector<imu::Config>& c);
00157 virtual Status setImuConfig (bool storeSettingsInFlash,
00158 uint32_t samplesPerMessage,
00159 const std::vector<imu::Config>& c);
00160
00161 virtual Status getLargeBufferDetails (uint32_t& bufferCount,
00162 uint32_t& bufferSize);
00163 virtual Status setLargeBuffers (const std::vector<uint8_t*>& buffers,
00164 uint32_t bufferSize);
00165 virtual Status getLocalUdpPort (uint16_t& port);
00166
00167 private:
00168
00169
00170
00171
00172 typedef void (*UdpAssembler)(utility::BufferStreamWriter& stream,
00173 const uint8_t *dataP,
00174 uint32_t offset,
00175 uint32_t length);
00176
00177
00178
00179
00180 static CRL_CONSTEXPR VersionType API_VERSION = 0x0305;
00181
00182
00183
00184
00185 static CRL_CONSTEXPR uint32_t MAX_MTU_SIZE = 9000;
00186 static CRL_CONSTEXPR uint16_t DEFAULT_SENSOR_TX_PORT = 9001;
00187 static CRL_CONSTEXPR uint32_t RX_POOL_LARGE_BUFFER_SIZE = (10 * (1024 * 1024));
00188 static CRL_CONSTEXPR uint32_t RX_POOL_LARGE_BUFFER_COUNT = 50;
00189 static CRL_CONSTEXPR uint32_t RX_POOL_SMALL_BUFFER_SIZE = (10 * (1024));
00190 static CRL_CONSTEXPR uint32_t RX_POOL_SMALL_BUFFER_COUNT = 100;
00191
00192 static CRL_CONSTEXPR double DEFAULT_ACK_TIMEOUT () { return 0.2; }
00193 static CRL_CONSTEXPR uint32_t DEFAULT_ACK_ATTEMPTS = 5;
00194 static CRL_CONSTEXPR uint32_t IMAGE_META_CACHE_DEPTH = 20;
00195 static CRL_CONSTEXPR uint32_t UDP_TRACKER_CACHE_DEPTH = 10;
00196 static CRL_CONSTEXPR uint32_t TIME_SYNC_OFFSET_DECAY = 8;
00197
00198
00199
00200
00201
00202
00203
00204
00205 static CRL_CONSTEXPR uint32_t MAX_USER_IMAGE_QUEUE_SIZE = 5;
00206 static CRL_CONSTEXPR uint32_t MAX_USER_LASER_QUEUE_SIZE = 20;
00207
00208
00209
00210
00211
00212 static CRL_CONSTEXPR uint32_t MAX_USER_PPS_QUEUE_SIZE = 2;
00213 static CRL_CONSTEXPR uint32_t MAX_USER_IMU_QUEUE_SIZE = 50;
00214
00215
00216
00217
00218 static CRL_CONSTEXPR uint32_t MAX_DIRECTED_STREAMS = 8;
00219
00220
00221
00222
00223 class UdpTracker {
00224 public:
00225
00226 UdpTracker(uint32_t t,
00227 UdpAssembler a,
00228 utility::BufferStreamWriter& s) :
00229 m_totalBytesInMessage(t),
00230 m_bytesAssembled(0),
00231 m_packetsAssembled(0),
00232 m_lastByteOffset(-1),
00233 m_assembler(a),
00234 m_stream(s) {};
00235
00236 utility::BufferStreamWriter& stream() { return m_stream; };
00237 uint32_t packets() { return m_packetsAssembled; };
00238
00239 bool assemble(uint32_t bytes,
00240 uint32_t offset,
00241 const uint8_t *dataP) {
00242
00243 if (offset <= m_lastByteOffset)
00244 CRL_EXCEPTION("out-of-order or duplicate packet");
00245
00246 m_assembler(m_stream, dataP, offset, bytes);
00247
00248 m_bytesAssembled += bytes;
00249 m_lastByteOffset = offset;
00250 m_packetsAssembled ++;
00251
00252 if (m_bytesAssembled == m_totalBytesInMessage)
00253 return true;
00254 return false;
00255 }
00256
00257 private:
00258
00259 uint32_t m_totalBytesInMessage;
00260 uint32_t m_bytesAssembled;
00261 uint32_t m_packetsAssembled;
00262 int64_t m_lastByteOffset;
00263 UdpAssembler m_assembler;
00264 utility::BufferStreamWriter m_stream;
00265 };
00266
00267
00268
00269
00270 int32_t m_serverSocket;
00271 uint16_t m_serverSocketPort;
00272
00273
00274
00275
00276 struct sockaddr_in m_sensorAddress;
00277
00278
00279
00280
00281 int32_t m_sensorMtu;
00282
00283
00284
00285
00286 std::vector<uint8_t> m_incomingBuffer;
00287
00288
00289
00290
00291 uint16_t m_txSeqId;
00292 int32_t m_lastRxSeqId;
00293 int64_t m_unWrappedRxSeqId;
00294
00295
00296
00297
00298 DepthCache<int64_t, UdpTracker> m_udpTrackerCache;
00299
00300
00301
00302
00303 typedef std::vector<utility::BufferStreamWriter*> BufferPool;
00304
00305 BufferPool m_rxLargeBufferPool;
00306 BufferPool m_rxSmallBufferPool;
00307
00308
00309
00310
00311 DepthCache<int64_t, wire::ImageMeta> m_imageMetaCache;
00312
00313
00314
00315
00316 typedef std::map<wire::IdType, UdpAssembler> UdpAssemblerMap;
00317
00318 UdpAssemblerMap m_udpAssemblerMap;
00319
00320
00321
00322
00323 utility::Mutex m_dispatchLock;
00324
00325
00326
00327
00328 utility::Mutex m_streamLock;
00329
00330
00331
00332
00333 bool m_threadsRunning;
00334
00335
00336
00337
00338 utility::Thread *m_rxThreadP;
00339 utility::Mutex m_rxLock;
00340
00341
00342
00343
00344 utility::Thread *m_statusThreadP;
00345
00346
00347
00348
00349 std::list<ImageListener*> m_imageListeners;
00350 std::list<LidarListener*> m_lidarListeners;
00351 std::list<PpsListener*> m_ppsListeners;
00352 std::list<ImuListener*> m_imuListeners;
00353
00354
00355
00356
00357 MessageWatch m_watch;
00358
00359
00360
00361
00362 MessageMap m_messages;
00363
00364
00365
00366
00367 DataSource m_streamsEnabled;
00368
00369
00370
00371
00372 utility::Mutex m_timeLock;
00373 bool m_timeOffsetInit;
00374 double m_timeOffset;
00375 bool m_networkTimeSyncEnabled;
00376
00377
00378
00379
00380 wire::VersionResponse m_sensorVersion;
00381
00382
00383
00384
00385 template<class T, class U> Status waitData(const T& command,
00386 U& data,
00387 const double& timeout=DEFAULT_ACK_TIMEOUT(),
00388 int32_t attempts=DEFAULT_ACK_ATTEMPTS);
00389 #if defined (_MSC_VER)
00390 template<class T> Status waitAck (const T& msg,
00391 wire::IdType id,
00392 const double& timeout,
00393 int32_t attempts);
00394 template<class T> Status waitAck (const T& msg) {
00395 return waitAck (msg, MSG_ID(T::ID), double(DEFAULT_ACK_TIMEOUT()), DEFAULT_ACK_ATTEMPTS);
00396 }
00397 #else
00398 template<class T> Status waitAck (const T& msg,
00399 wire::IdType id=MSG_ID(T::ID),
00400 const double& timeout=DEFAULT_ACK_TIMEOUT(),
00401 int32_t attempts=DEFAULT_ACK_ATTEMPTS);
00402 #endif
00403
00404 template<class T> void publish (const T& message);
00405 void publish (const utility::BufferStreamWriter& stream);
00406 void dispatch (utility::BufferStreamWriter& buffer);
00407 void dispatchImage(utility::BufferStream& buffer,
00408 image::Header& header);
00409 void dispatchLidar(utility::BufferStream& buffer,
00410 lidar::Header& header);
00411 void dispatchPps (pps::Header& header);
00412 void dispatchImu (imu::Header& header);
00413
00414
00415 utility::BufferStreamWriter& findFreeBuffer (uint32_t messageLength);
00416 const int64_t& unwrapSequenceId(uint16_t id);
00417 UdpAssembler getUdpAssembler (const uint8_t *udpDatagramP,
00418 uint32_t length);
00419
00420 void eraseFlashRegion (uint32_t region);
00421 void programOrVerifyFlashRegion(std::ifstream& file,
00422 uint32_t operation,
00423 uint32_t region);
00424 Status doFlashOp (const std::string& filename,
00425 uint32_t operation,
00426 uint32_t region);
00427
00428 void applySensorTimeOffset(const double& offset);
00429 double sensorToLocalTime (const double& sensorTime);
00430 void sensorToLocalTime (const double& sensorTime,
00431 uint32_t& seconds,
00432 uint32_t& microseconds);
00433
00434 void cleanup();
00435 void bind ();
00436 void handle ();
00437
00438
00439
00440
00441 static wire::SourceType sourceApiToWire(DataSource mask);
00442 static DataSource sourceWireToApi(wire::SourceType mask);
00443 static uint32_t hardwareApiToWire(uint32_t h);
00444 static uint32_t hardwareWireToApi(uint32_t h);
00445 static uint32_t imagerApiToWire(uint32_t h);
00446 static uint32_t imagerWireToApi(uint32_t h);
00447 #if WIN32
00448 static DWORD WINAPI rxThread (void *userDataP);
00449 static DWORD WINAPI statusThread (void *userDataP);
00450 #else
00451 static void *rxThread (void *userDataP);
00452 static void *statusThread (void *userDataP);
00453 #endif
00454 };
00455
00456
00457 }}};
00458
00459 #endif // LibMultiSense_details_channel_hh