channel.hh
Go to the documentation of this file.
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 // The implementation details
00070 
00071 class impl : public Channel {
00072 public:
00073 
00074     //
00075     // Construction
00076 
00077     impl(const std::string& address);
00078     ~impl();
00079 
00080     //
00081     // Public API
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     // A handler prototype for custom UDP datagram reassembly
00171 
00172     typedef void (*UdpAssembler)(utility::BufferStreamWriter& stream,
00173                                  const uint8_t               *dataP,
00174                                  uint32_t                     offset,
00175                                  uint32_t                     length);
00176 
00177     //
00178     // The version of this API
00179 
00180     static CRL_CONSTEXPR VersionType API_VERSION = 0x0305; // 3.5
00181 
00182     //
00183     // Misc. internal constants
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     // We must protect ourselves from user callbacks misbehaving
00200     // and gobbling up all of our RX buffers
00201     //
00202     // These define the maximum number of datums that we will
00203     // queue up in a user dispatch thread.
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     // PPS and IMU callbacks do not reserve an RX buffer, so queue
00210     // depths are limited by RAM (via heap.)
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     // The maximum number of directed streams
00217 
00218     static CRL_CONSTEXPR uint32_t MAX_DIRECTED_STREAMS = 8;
00219 
00220     //
00221     // A re-assembler for multi-packet messages
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     // The socket identifier and local port
00269 
00270     int32_t  m_serverSocket;
00271     uint16_t m_serverSocketPort;
00272 
00273     //
00274     // The address of the sensor
00275 
00276     struct sockaddr_in m_sensorAddress;
00277 
00278     //
00279     // The operating MTU of the sensor
00280 
00281     int32_t m_sensorMtu;
00282 
00283     //
00284     // A buffer to receive incoming UDP packets
00285 
00286     std::vector<uint8_t> m_incomingBuffer;
00287 
00288     //
00289     // Sequence ID for multi-packet message reassembly
00290 
00291     uint16_t m_txSeqId;
00292     int32_t  m_lastRxSeqId;
00293     int64_t  m_unWrappedRxSeqId;
00294 
00295     //
00296     // A cache to track incoming messages by sequence ID
00297 
00298     DepthCache<int64_t, UdpTracker> m_udpTrackerCache;
00299 
00300     //
00301     // A pool of RX buffers, to reduce the amount of internal copying
00302 
00303     typedef std::vector<utility::BufferStreamWriter*> BufferPool;
00304 
00305     BufferPool m_rxLargeBufferPool;
00306     BufferPool m_rxSmallBufferPool;
00307 
00308     //
00309     // A cache of image meta data
00310 
00311     DepthCache<int64_t, wire::ImageMeta> m_imageMetaCache;
00312 
00313     //
00314     // A map of custom UDP assemblers
00315 
00316     typedef std::map<wire::IdType, UdpAssembler> UdpAssemblerMap;
00317 
00318     UdpAssemblerMap m_udpAssemblerMap;
00319 
00320     //
00321     // Mutex for callback registration and dispatching
00322 
00323     utility::Mutex m_dispatchLock;
00324 
00325     //
00326     // Mutex for stream control
00327 
00328     utility::Mutex m_streamLock;
00329 
00330     //
00331     // A flag to shut down the internal threads
00332 
00333     bool m_threadsRunning;
00334 
00335     //
00336     // Internal UDP reception thread
00337 
00338     utility::Thread *m_rxThreadP;
00339     utility::Mutex   m_rxLock;
00340 
00341     //
00342     // Internal status thread
00343 
00344     utility::Thread *m_statusThreadP;
00345 
00346     //
00347     // The lists of user callbacks
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     // A message signal interface
00356 
00357     MessageWatch m_watch;
00358 
00359     //
00360     // A message storage interface
00361 
00362     MessageMap m_messages;
00363 
00364     //
00365     // The mask of currently enabled streams (desired)
00366 
00367     DataSource m_streamsEnabled;
00368 
00369     //
00370     // The current sensor time offset
00371 
00372     utility::Mutex m_timeLock;
00373     bool           m_timeOffsetInit;
00374     double         m_timeOffset;
00375     bool           m_networkTimeSyncEnabled;
00376 
00377     //
00378     // Cached version info from the device
00379 
00380     wire::VersionResponse m_sensorVersion;
00381 
00382     //
00383     // Private procedures
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     // Static members
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 }}}; // namespaces
00458 
00459 #endif // LibMultiSense_details_channel_hh


multisense_lib
Author(s):
autogenerated on Thu Aug 27 2015 14:01:11