Tekkotsu Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
DataSource.hGo to the documentation of this file.00001 //-*-c++-*- 00002 #ifndef INCLUDED_DataSource_h_ 00003 #define INCLUDED_DataSource_h_ 00004 00005 #include <string> 00006 #include <iostream> 00007 00008 /* Usage cases: 00009 00010 Pulled (on demand): 00011 block with timeout: save bandwidth, accept latency -- load only after last was read and framerate delay 00012 sleep: minimize latency, waste bandwidth -- send requests at framerate 00013 Pushed (sent by source): 00014 block (no timeout): when new data arrives, insert into queue (might overwrite last queue slot) 00015 sleep: can't block, have to poll at framerate 00016 */ 00017 00018 class LoadDataThread; 00019 00020 //! abstract base class for simulator data sources 00021 /*! Each subclass will implement loading data from some piece of hardware or network protocol. This class 00022 * is expected to be tied to a LoadDataThread (or subclass) which holds configuration settings which might 00023 * be shared by multiple data sources, in particular LoadDataThread::src. 00024 * 00025 * Ideally, getData() should return the most recent unprocessed data -- meaning that if you are pulling 00026 * from a realtime source like a network stream, if multiple frames have arrived since the last call to 00027 * getData(), you should return the most recent frame of the bunch. 00028 * 00029 * If your data source provides sensor data including current output values, you should call 00030 * providingOutput() for those outputs when you start being used by a LoadDataThread 00031 * (e.g. setDataSourceThread() is called), and ignoringOutput() when you are no longer active 00032 * (e.g. setDataSourceThread() is called with NULL). This prevents the Motion process from 00033 * clobbering your readings with its own feedback. 00034 */ 00035 class DataSource { 00036 public: 00037 DataSource() : frozen(true), framerate(-1), verbose(0), thread(NULL) {} //!< constructor 00038 DataSource(const DataSource& ds) : frozen(ds.frozen), framerate(ds.framerate), verbose(ds.verbose), thread(NULL) {} //!< copy constructor, just in case your subclass wants it 00039 DataSource& operator=(const DataSource&) { return *this; } //!< assignment operator, just in case your subclass wants it 00040 virtual ~DataSource() {} //!< destructor 00041 00042 //! returns the simulator time of the next data segment 00043 /*! should be in the future if nothing new since last data segment, otherwise should be the 00044 * timestamp of the most recent data segment (older segments are skipped), return -1U if there is no more data 00045 * @see timestamp argument of getData() */ 00046 virtual unsigned int nextTimestamp()=0; 00047 00048 //! returns a descriptive name of the next data segment for user feedback 00049 /*! @see name argument of getData() */ 00050 virtual const std::string& nextName()=0; 00051 00052 //! called to retrieve the most recent data segment, or blocking until new data is available 00053 /*! @param[out] payload on return, should point to beginning of data segment, or NULL if none available 00054 * @param[out] payloadSize on return, should indicate size in bytes of data segment as @a payload 00055 * @param[in] timestamp the suggested return time; if multiple samples may be taken in the interval, they should be skipped until this time 00056 * @param[out] timestamp on return, should contain the time at which the data arrived (real time stream) or was scheduled to be sent (log on disk) 00057 * @param[out] name on return, a human-readable name for the frame -- e.g. filename for a data file loaded from disk 00058 * @return frame serial number, used to tell when frames from the data source have been dropped (indicated by the return value incrementing by more than one) 00059 * 00060 * If no more data is available, set payload to NULL, and return the current frame (i.e. don't increment serial number). 00061 * 00062 * This call <b>should block</b> until data is available. Other functions may be called 00063 * asynchronously from other threads while in this function, see ThreadNS::Lock to implement 00064 * mutual exclusion locks if needed. 00065 * 00066 * The input value of @a timestamp is a suggestion from the user's requested framerate -- try 00067 * to return the frame closest to it. If it is already past (e.g. 0 on 'advance'), return the current data! 00068 * If you return a timestamp in the future, the LoadDataThread will sleep until the appropriate time. 00069 * 00070 * Note that this can be called when the source is frozen, which means you should unfreeze, 00071 * get the current (unread) data or block until the next data, freeze again, and return the data. */ 00072 virtual unsigned int getData(const char *& payload, unsigned int& payloadSize, unsigned int& timestamp, std::string& name)=0; 00073 00074 //! called by simulator when the data source's activity changes; calls doFreeze() or doUnfreeze() as appropriate 00075 /*! You probably don't want to override this function -- that's what doFreeze() doUnfreeze are for! */ 00076 virtual void setFrozen(bool fr) { if(fr==frozen) return; if((frozen=fr)) doFreeze(); else doUnfreeze(); } 00077 virtual bool getFrozen() const { return frozen; } //!< returns #frozen status 00078 00079 //! if called, indicates a request to restart/reinitialize the data source 00080 /*! For example, a FileSystemDataSource would go back to the beginning of its list, 00081 * and a network-based source would close and reopen the connection */ 00082 virtual void reset() {} 00083 00084 //! called by the LoadDataThread subclass, allows you to register for properties which your subclass may care about 00085 /*! a pointer to the LoadDataThread is passed when this is becoming the current data source; 00086 * NULL will be passed when the data source is no longer being used */ 00087 virtual void setDataSourceThread(LoadDataThread* th) { thread=th; } 00088 //! returns the LoadDataThread using this data source 00089 virtual LoadDataThread* getDataSourceThread() const { return thread; } 00090 00091 virtual void setDataSourceFramerate(float fr) { framerate=fr; } //!< called by LoadDataThread whenever the expected framerate changes (LoadDataThread::framerate) 00092 virtual void setDataSourceVerbose(int v) { verbose=v; } //!< called by LoadDataThread whenever the requested verbosity level changes (LoadDataThread::verbosity) 00093 00094 //! Called by simulator during initialization to tell DataSources where the array of output reference counts are stored (see #providedOutputs) 00095 /*! This would need to point into a shared memory region if using multi-process model, hence we can't just 00096 * use process-local static allocation. */ 00097 static void setOutputTracker(unsigned int outputs[]) { providedOutputs=outputs; } 00098 00099 //! will be called by initialization code prior to first getData() if client code is going to block on getting the first sensor reading 00100 static void setNeedsSensor(bool waiting) { requiresFirstSensor=waiting; } 00101 00102 protected: 00103 //! subclasses should call this if they provide sensor updates which will contain a measurement of the current position of output @a i. 00104 /* A DataSource should consider itself providing an output if it will be sending some kind of measurement of 00105 * the current value of an output, and has been assigned to a LoadDataThread 00106 * (i.e. setDataSourceThread() has been called and #thread is non-NULL).\n 00107 * This prevents the motion process from clobbering your readings with its own feedback. */ 00108 static void providingOutput(unsigned int i) { 00109 if(providedOutputs==NULL) { 00110 std::cerr << "Warning: unable to access DataSource::providedOutputs (NULL) +" << i << std::endl; 00111 return; 00112 } 00113 providedOutputs[i]++; 00114 } 00115 //! subclasses should call this if they used to, but will no longer, provide sensor updates containing the current position of output @a i. 00116 /*! You don't need to call this if you didn't previously call providingOutput(). */ 00117 static void ignoringOutput(unsigned int i) { 00118 if(providedOutputs==NULL) { 00119 std::cerr << "Warning: unable to access DataSource::providedOutputs (NULL) -" << i << std::endl; 00120 return; 00121 } 00122 if(providedOutputs[i]==0) { 00123 std::cerr << "ERROR: DataSource output tracking underflow (" << __FILE__ << ":" << __LINE__ << ")" << std::endl; 00124 return; 00125 } 00126 providedOutputs[i]--; 00127 } 00128 00129 virtual void doFreeze() {} //!< user hook for when #frozen is set to true 00130 virtual void doUnfreeze() {} //!< user hook for when #frozen is set to false 00131 00132 bool frozen; //!< indicates that data is going to be requested "sparsely"; logged data sources should not increment with time 00133 float framerate; 00134 int verbose; 00135 LoadDataThread* thread; //!< stores last call to setParent() 00136 00137 //! if true, indicates that client code is going to wait for sensor readings returned by getData before executing 00138 /*! Allocation defined in LoadDataThread.cc */ 00139 static bool requiresFirstSensor; 00140 00141 private: 00142 //! The counts of which outputs are being provided are used so the motion process can tell if it needs to provide feedback. 00143 /*! Subclasses should call providingOutput() and ignoringOutput() when they start and stop providing an output. 00144 * A DataSource should consider itself providing an output if it will be sending some kind of measurement of 00145 * the current value of an output, and has been assigned to a LoadDataThread 00146 * (i.e. setDataSourceThread() has been called and #thread is non-NULL). 00147 * 00148 * Allocation is found in LoadDataThread.cc to avoid file clutter (no other need for a DataSource.cc) */ 00149 static unsigned int * providedOutputs; 00150 }; 00151 00152 /*! @file 00153 * @brief Defines DataSource, an abstract base class for simulator data sources 00154 * @author Ethan Tira-Thompson (ejt) (Creator) 00155 * 00156 * $Author: ejt $ 00157 * $Name: tekkotsu-4_0 $ 00158 * $Revision: 1.8 $ 00159 * $State: Exp $ 00160 * $Date: 2007/07/24 03:46:35 $ 00161 */ 00162 00163 #endif |
Tekkotsu Hardware Abstraction Layer 4.0 |
Generated Thu Nov 22 01:00:53 2007 by Doxygen 1.5.4 |