Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

MirageDriver.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_MirageDriver_h_
00003 #define INCLUDED_MirageDriver_h_
00004 
00005 #include "local/DeviceDriver.h"
00006 #include "local/MotionHook.h"
00007 #include "local/DeviceDrivers/ImageStreamDriver.h"
00008 #include "local/DeviceDrivers/PListSensorDriver.h"
00009 #include "local/CommPorts/NetworkCommPort.h"
00010 #include "Wireless/netstream.h"
00011 #include "IPC/CallbackThread.h"
00012 #include "Shared/MarkScope.h"
00013 #include "IPC/DriverMessaging.h"
00014 
00015 //! description of MirageDriver
00016 class MirageDriver : public virtual DeviceDriver, public MotionHook, public virtual plist::PrimitiveListener, public virtual DriverMessaging::Listener {
00017 public:
00018   static const unsigned int DEFAULT_PORT = 19785;
00019   static const unsigned int DEFAULT_FPS = 25;
00020   
00021   enum Encoding { ENCODE_YUV, ENCODE_PNG, ENCODE_JPG }; //!< must be kept in sync with tools/mirage/CommThread.h
00022   static const char* encodingNames[]; //!< must be kept in sync with tools/mirage/CommThread.h
00023 
00024   explicit MirageDriver(const std::string& name)
00025     : DeviceDriver(autoRegisterDriver,name), MotionHook(), persist(false), highres(false), initLocation(), initOrientation(), physicsWalk(false), physicsWheels(true),
00026     commLock(), comm(), bufferedMsg(), opener(&MirageDriver::openConnection,*this), opening(false), positions(), sensrc(name), imgsrc(name), depthsrc(name)
00027   {
00028     addEntry("Host",imgsrc.host,"Specifies the hostname running the Mirage client");
00029     addEntry("Port",imgsrc.port,"Specifies the port number of the Mirage client");
00030     addEntry("Persist",persist,"If true, the robot model will not be removed when the Tekkotsu executable disconnects.");
00031     addEntry("Encoding",imgsrc.encoding,"Indicates whether to request JPG or PNG images from the simulated camera input");
00032     addEntry("PNGLevel",imgsrc.pngCompressionLevel,"The compression level to pass to libpng, and thus zlib.  0 for no compression (fastest), 9 for maximum (slowest).  Image quality is constant as this is lossless.");
00033     addEntry("JPGQuality",imgsrc.jpgQualityLevel,"The compression level to pass to libjpeg, 0 for very poor quality and small file size, 100 for best quality but larger files.");
00034     addEntry("HighRes",highres,"If true, will render simulated camera input at 'double' resolution instead of 'full'");
00035     addEntry("InitialLocation",initLocation,"The x, y, and z coordinates the robot will start out at if Persist is false.");
00036     addEntry("InitialOrientation",initOrientation,"The axis component of a quaternion representing robot orientation to use if Persist is false.");
00037     addEntry("PhysicsWalk",physicsWalk,"If true (and the kinematics configuration specifies mass for the robot), Mirage will use friction and physics to model the effects of walking; if false, Mirage will use a \"perfect\" model based on hints from the WalkMC itself.");
00038     addEntry("PhysicsWheels",physicsWheels,"If true (and the kinematics configuration specifies mass for the robot), then Mirage wheel use friction and physics to model robot motion; if false, Mirage will try to directly compute and move the robot.");
00039     highres.addPrimitiveListener(this);
00040     imgsrc.encoding.addPrimitiveListener(this);
00041     setLoadSavePolicy(FIXED,SYNC);
00042   }
00043 
00044   virtual std::string getClassName() const { return autoRegisterDriver; }
00045   
00046   virtual MotionHook* getMotionSink() { return dynamic_cast<MotionHook*>(this); }
00047   virtual void getSensorSources(std::map<std::string,DataSource*>& sources) {
00048     sources.clear();
00049     sources["Sensors"]=&sensrc;
00050   }
00051   virtual void getImageSources(std::map<std::string,DataSource*>& sources) {
00052     sources.clear();
00053     sources["Camera"]=&imgsrc;
00054     sources["Depth"] = &depthsrc;
00055   }
00056   
00057   virtual void motionStarting();
00058   virtual void updateAllOutputs();
00059   virtual bool isConnected();
00060   virtual void motionStopping();
00061   virtual void motionUpdated(const std::vector<size_t>& changedIndices, const float outputs[][NumOutputs]);
00062   
00063   virtual void plistValueChanged(const plist::PrimitiveBase& pl);
00064   
00065   plist::Primitive<bool> persist;
00066   
00067   plist::Primitive<bool> highres; //!< If true, will render simulated camera input at "double" resolution instead of "full"
00068   
00069   plist::Point initLocation;
00070   plist::Point initOrientation;
00071   plist::Primitive<bool> physicsWalk; //!< If true (and the kinematics configuration specifies mass for the robot), Mirage will use friction and physics to model the effects of walking; if false, Mirage will use a "perfect" model based on hints from the WalkMC itself.
00072   plist::Primitive<bool> physicsWheels; //!< If true (and the kinematics configuration specifies mass for the robot), then Mirage wheel use friction and physics to model robot motion; if false, Mirage will try to directly compute and move the robot.
00073   
00074 protected:
00075   Thread::Lock commLock;
00076   ionetstream comm;
00077   std::string bufferedMsg;
00078   CallbackThread opener;
00079   bool opening;
00080   plist::Primitive<float> positions[NumOutputs];
00081   
00082   template<class T>
00083   class Subscription : public T, public NetworkCommPort {
00084   public:
00085     Subscription(const std::string& name) : DeviceDriver("MirageDriver::Subscription",name+"::Subscription"), T(name), NetworkCommPort(name) {
00086       host="localhost";
00087       port=DEFAULT_PORT;
00088       T::srcFrameRate = DEFAULT_FPS;
00089     }
00090     virtual const std::string& nextName() { return T::instanceName; }
00091     virtual void doFreeze();
00092     virtual void doUnfreeze();
00093   protected:
00094     virtual CommPort * getComm(const std::string& name) { return this; }
00095     virtual bool requestFrame(CommPort& comm);
00096     virtual void opened()=0;
00097     virtual void closing();
00098     virtual void plistValueChanged(const plist::PrimitiveBase& pl) {
00099       if(&pl==&host || &pl==&port)
00100         NetworkCommPort::plistValueChanged(pl);
00101       else
00102         T::plistValueChanged(pl);
00103     }
00104   };
00105   
00106   class SensorSubscription : public Subscription<PListSensorDriver> {
00107   public:
00108     SensorSubscription(const std::string& name)
00109     : DeviceDriver("MirageDriver::ImageSubscription",name+"::SensorSubscription"), Subscription<PListSensorDriver>(name+"::SensorSubscription") {}
00110   protected:
00111     virtual void opened();
00112   } sensrc;
00113   
00114   class ImageSubscription : public Subscription<ImageStreamDriver> {
00115   public:
00116     ImageSubscription(const std::string& name)
00117       : DeviceDriver("MirageDriver::ImageSubscription",name+"::ImageSubscription"), Subscription<ImageStreamDriver>(name+"::ImageSubscription"),
00118       encoding(ENCODE_PNG,encodingNames), pngCompressionLevel(1), jpgQualityLevel(85)
00119     {
00120       encoding.addNameForVal("jpeg",ENCODE_JPG);
00121       encoding.addPrimitiveListener(this);
00122       pngCompressionLevel.addPrimitiveListener(this);
00123       jpgQualityLevel.addPrimitiveListener(this);
00124       format.set(encoding.get()); // pass as string to select appropriate enum
00125     }
00126     
00127     virtual void registerSource();
00128     virtual void deregisterSource();
00129     
00130     plist::NamedEnumeration<Encoding> encoding; //!< indicates whether to stream JPG or PNG images as simulated camera input
00131     plist::Primitive<unsigned int> pngCompressionLevel; //!< the compression level to pass to libpng, and thus zlib.  0 for no compression (fastest), 9 for maximum compression (slowest), image quality is constant as this is lossless
00132     plist::Primitive<unsigned int> jpgQualityLevel; //!< the compression level to pass to libjpeg, 0 for very poor quality and small file size, 100 for best quality but larger files
00133   protected:
00134     virtual void opened();
00135     virtual void plistValueChanged(const plist::PrimitiveBase& pl);
00136   } imgsrc;
00137 
00138   class DepthSubscription : public Subscription<ImageStreamDriver> {
00139   public:
00140     DepthSubscription(const std::string& name)
00141     : DeviceDriver("MirageDriver::DepthSubscription", name + "::DepthSubscription"),
00142       Subscription<ImageStreamDriver> (name + "::DepthSubscription"),
00143       encoding(ENCODE_PNG, encodingNames), pngCompressionLevel(1), jpgQualityLevel(85)
00144     {
00145       encoding.addNameForVal("jpeg", ENCODE_JPG);
00146       encoding.addPrimitiveListener(this);
00147       pngCompressionLevel.addPrimitiveListener(this);
00148       jpgQualityLevel.addPrimitiveListener(this);
00149       format.set(encoding.get());
00150       setSID(ProjectInterface::visRawDepthSID);
00151     }
00152 
00153     virtual void registerSource();
00154     virtual void deregisterSource();
00155 
00156     plist::NamedEnumeration<Encoding> encoding;
00157     plist::Primitive<unsigned int> pngCompressionLevel;
00158     plist::Primitive<unsigned int> jpgQualityLevel;
00159   protected:
00160     virtual void opened();
00161     virtual void plistValueChanged(const plist::PrimitiveBase& pl);
00162   } depthsrc;
00163 
00164   void openConnection();
00165   void sendUpdate(plist::Dictionary& msg);
00166   
00167   void processDriverMessage(const DriverMessaging::Message& dmsg);
00168 
00169 private:
00170   //! holds the class name, set via registration with the DeviceDriver registry
00171   static const std::string autoRegisterDriver;
00172 };
00173 
00174 template<class T>
00175 void MirageDriver::Subscription<T>::doUnfreeze() {
00176   T::doUnfreeze();
00177   if(!isWriteable())
00178     return;
00179   plist::Dictionary d;
00180   plist::Primitive<bool> singleFrame(false);
00181   d.addEntry("SingleFrame",singleFrame);
00182   //MarkScope autolock(*this); // not a query-response, don't need lock
00183   std::ostream os(&getWriteStreambuf());
00184   d.saveStream(os,true);
00185   os.flush();
00186 }
00187 
00188 template<class T>
00189 void MirageDriver::Subscription<T>::doFreeze() {
00190   T::doFreeze();
00191   requestFrame(*this);
00192 }
00193 
00194 template<class T>
00195 bool MirageDriver::Subscription<T>::requestFrame(CommPort& comm) {
00196   if(!isWriteable() || T::realtime)
00197     return false;
00198   plist::Dictionary d;
00199   plist::Primitive<bool> singleFrame(true);
00200   d.addEntry("SingleFrame",singleFrame);
00201   MarkScope autolock(*this);
00202   std::ostream os(&getWriteStreambuf());
00203   d.saveStream(os,true);
00204   os.flush();
00205 
00206   return true;
00207 }
00208 
00209 template<class T>
00210 void MirageDriver::Subscription<T>::closing() {
00211   MarkScope autolock(*this);
00212   std::ostream os(&getWriteStreambuf());
00213   os << "</subscription>" << std::flush;
00214   NetworkCommPort::closing();
00215 }
00216 
00217 /*! @file
00218  * @brief 
00219  * @author Ethan Tira-Thompson (ejt) (Creator)
00220  */
00221 
00222 #endif

Tekkotsu Hardware Abstraction Layer 5.1CVS
Generated Mon May 9 05:01:39 2016 by Doxygen 1.6.3