Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

SensorInfo.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_SensorInfo_h_
00003 #define INCLUDED_SensorInfo_h_
00004 
00005 #include "Shared/plist.h"
00006 #include "Shared/plistSpecialty.h"
00007 #include "Shared/DynamicRobotState.h"
00008 
00009 //! Base class for sensor descriptions, actual subclass name stored in #sensorType
00010 struct SensorInfo : virtual public plist::Dictionary {
00011   //! Subclass should add name/value pairs to the dictionary to allow variable number of values per Sensor, as well as fast filtering and serialization to subscribers.
00012   /*! A reference to a permanent plist::Primitive<float> instance should be added, this is how values are extracted from the sensor via this shared value. */
00013   virtual void declareValues(DynamicRobotState& values)=0;
00014   
00015   //! Subclass should remove values added via previous declareValues()
00016   virtual void reclaimValues(DynamicRobotState& values)=0;
00017   
00018   //! Name of sensor class, with "Sensor" prefix removed; see KinematicJoint::SensorInfo subclasses
00019   plist::Primitive<std::string> sensorType;
00020   
00021   PLIST_CLONE_ABS(SensorInfo);
00022   
00023 protected:
00024   //! Constructor, pass the name of the subclass, minus the "Sensor" prefix — this is used to recreate the subtype via a factory (so you should also do the autoRegister thing and pass that here)
00025   explicit SensorInfo(const std::string& type) : plist::Dictionary(), sensorType(type) { init(); }
00026   //! Copy constructor for cloning
00027   SensorInfo(const SensorInfo& si) : plist::Dictionary(), sensorType(si.sensorType) { init(); }
00028   //! performs common initialization
00029   void init() {
00030     addEntry("SensorType",sensorType,"Name of sensor class, with \"Sensor\" prefix removed; see KinematicJoint::SensorInfo subclasses");
00031     setLoadSavePolicy(SYNC,SYNC); // should override to FIXED,SYNC from subclasses
00032   }
00033 };
00034 
00035 //! Configures a sensor to take range measurements
00036 /*! Will test for a collision shape between min and max range.
00037  *  If a hit is found at a distance less than saturationRange, it will be clamped at that value.
00038  *  If no hit is found within the specified min/max range, the maximum value will be reported. */
00039 struct SensorRangeFinder : public SensorInfo {
00040   //! constructor
00041   SensorRangeFinder() : SensorInfo(autoRegister), value(0), sensorName(), minRange(0), saturationRange(0),maxRange(0) { init(); }
00042   //! copy constructor for cloning
00043   SensorRangeFinder(const SensorRangeFinder& s)
00044     : SensorInfo(s), value(s.value), sensorName(s.sensorName), minRange(s.minRange),
00045     saturationRange(s.saturationRange), maxRange(s.maxRange) { init(); }
00046   
00047   virtual void declareValues(DynamicRobotState& values) {
00048     values.sensors.addEntry(sensorName,value);
00049   }
00050   virtual void reclaimValues(DynamicRobotState& values) {
00051     values.sensors.removeEntry(sensorName);
00052   }
00053   plist::Primitive<float> value; //!< current sensor value
00054   plist::Primitive<std::string> sensorName; //!< Name of the sensor instance, to match up with the a sensorNames[] in RobotInfo header.
00055   plist::Primitive<float> minRange; //!< Minimum range for hit testing, obstacles closer than this won't be detected (will report max range)
00056   plist::Primitive<float> saturationRange; //!< Minimum range of sensitivity, obstacles closer than this (but further than min range) will be reported at this value
00057   plist::Primitive<float> maxRange; //!< Maximum range for hit testing, obstacles further than this won't be detected (and thus will report this value)
00058   static const std::string autoRegister; //!< Provides registration with FamilyFactory<SensorInfo>
00059   PLIST_CLONE_DEF(SensorRangeFinder,new SensorRangeFinder(*this));
00060 protected:
00061   //! performs common initialization
00062   void init() {
00063     addEntry("SensorName",sensorName,"Name of the sensor instance, to match up with the a sensorNames[] in RobotInfo header.");
00064     addEntry("MinRange",minRange,"Minimum range for hit testing, obstacles closer than this won't be detected (will report max range)");
00065     addEntry("SaturationRange",saturationRange,"Minimum range of sensitivity, obstacles closer than this (but further than min range) will be reported at this value");
00066     addEntry("MaxRange",maxRange,"Maximum range for hit testing, obstacles further than this won't be detected (and thus will report this value)");
00067     setLoadSavePolicy(FIXED,SYNC);
00068   }
00069 };
00070 
00071 //! Sets value to 1 if there are any contact constraints within the specified region of the associated body; 0 otherwise
00072 /*! The min/max values can be used to limit which contact positions can toggle the sensor.
00073  *  Only axes where min≠max are considered for filtering.  Thus all 0's for min and max values indicate no filtering. */
00074 struct SensorContact : public SensorInfo {
00075   //! constructor
00076   SensorContact() : SensorInfo(autoRegister), value(0), sensorName(),
00077   lx(2,0,false), ly(2,0,false), lz(2,0,false), ax(2,0,false), ay(2,0,false), az(2,0,false) { init(); }
00078   //! copy constructor for cloning
00079   SensorContact(const SensorContact& s) : SensorInfo(s), value(s.value), sensorName(s.sensorName),
00080   lx(s.lx), ly(s.ly), lz(s.lz), ax(s.ax), ay(s.ay), az(s.az) { init(); }
00081   
00082   virtual void declareValues(DynamicRobotState& values) {
00083     values.buttons.addEntry(sensorName,value);
00084   }
00085   virtual void reclaimValues(DynamicRobotState& values) {
00086     values.buttons.removeEntry(sensorName);
00087   }
00088   bool testPoint(float x, float y, float z);
00089   plist::Primitive<float> value; //!< current sensor value: 1 if there are any contact constraints within the specified region of the associated body; 0 otherwise
00090   plist::Primitive<std::string> sensorName; //!< Name of the sensor instance, to match up with the a sensorNames[] in RobotInfo header.
00091   plist::ArrayOf<plist::Primitive<float> > lx; //!< Minimum and maximum cartesian x
00092   plist::ArrayOf<plist::Primitive<float> > ly; //!< Minimum and maximum cartesian y
00093   plist::ArrayOf<plist::Primitive<float> > lz; //!< Minimum and maximum cartesian z
00094   plist::ArrayOf<plist::Angle> ax; //!< Minimum and maximum angle about joint origin x axis (y axis is 0°)
00095   plist::ArrayOf<plist::Angle> ay; //!< Minimum and maximum angle about joint origin y axis (z axis is 0°)
00096   plist::ArrayOf<plist::Angle> az; //!< Minimum and maximum angle about joint origin z axis (x axis is 0°)
00097   static const std::string autoRegister; //!< Provides registration with FamilyFactory<SensorInfo>
00098   PLIST_CLONE_DEF(SensorContact,new SensorContact(*this));
00099 protected:
00100   //! performs common initialization
00101   void init() {
00102     addEntry("SensorName",sensorName,"Name of the sensor instance, to match up with the a sensorNames[] in RobotInfo header.");
00103     addEntry("LinX",lx,"Minimum and maximum cartesian x");
00104     addEntry("LinY",ly,"Minimum and maximum cartesian y");
00105     addEntry("LinZ",lz,"Minimum and maximum cartesian z");
00106     addEntry("AngX",ax,"Minimum and maximum angle about joint origin x axis");
00107     addEntry("AngY",ay,"Minimum and maximum angle about joint origin y axis");
00108     addEntry("AngZ",az,"Minimum and maximum angle about joint origin z axis");
00109     lx.setSaveInlineStyle(true); ly.setSaveInlineStyle(true); lz.setSaveInlineStyle(true);
00110     ax.setSaveInlineStyle(true); ay.setSaveInlineStyle(true); az.setSaveInlineStyle(true);
00111     setLoadSavePolicy(FIXED,SYNC);
00112   }
00113 };
00114 
00115 //! Sets value to the current joint position.  This is created automatically by Mirage for named joints where min≠max, so typically you don't need to explicitly request this sensor
00116 struct SensorFeedback : public SensorInfo {
00117   //! constructor
00118   SensorFeedback() : SensorInfo(autoRegister), value(0), sensorName() { init(); }
00119   //! copy constructor for cloning
00120   SensorFeedback(const SensorFeedback& s) : SensorInfo(s), value(s.value), sensorName(s.sensorName) { init(); }
00121   
00122   virtual void declareValues(DynamicRobotState& values) {
00123     values.outputs.addEntry(sensorName,value);
00124   }
00125   virtual void reclaimValues(DynamicRobotState& values) {
00126     values.outputs.removeEntry(sensorName);
00127   }
00128   plist::Primitive<float> value; //!< current sensor value: 1 if there are any contact constraints within the specified region of the associated body; 0 otherwise
00129   std::string sensorName; //!< will be set by Client during loading to ensure synchronization with KinematicJoint name
00130   static const std::string autoRegister; //!< Provides registration with FamilyFactory<SensorInfo>
00131   PLIST_CLONE_DEF(SensorFeedback,new SensorFeedback(*this));
00132 protected:
00133   //! performs common initialization
00134   void init() {
00135     setLoadSavePolicy(FIXED,SYNC);
00136   }
00137 };
00138 
00139 struct GPSSensor : public SensorInfo {
00140   //! constructor
00141   GPSSensor() : SensorInfo(autoRegister), sensorName(), curX(0), curY(0), curZ(0), curHeading(0) { init(); }
00142   //! copy constructor for cloning
00143   GPSSensor(const GPSSensor& s) : SensorInfo(s), sensorName(s.sensorName), curX(s.curX), curY(s.curY), curZ(s.curZ), curHeading(s.curHeading) { init(); }
00144   
00145   virtual void declareValues(DynamicRobotState& values) {
00146     values.sensors.addEntry(sensorName+"X",curX);
00147     values.sensors.addEntry(sensorName+"Y",curY);
00148     values.sensors.addEntry(sensorName+"Z",curZ);
00149   }
00150   virtual void reclaimValues(DynamicRobotState& values) {
00151     values.sensors.removeEntry(sensorName+"X");
00152     values.sensors.removeEntry(sensorName+"Y");
00153     values.sensors.removeEntry(sensorName+"Z");
00154   }
00155   plist::Primitive<std::string> sensorName; //!< Name of the sensor instance, to match up with the a sensorNames[] in RobotInfo header.
00156   plist::Primitive<float> curX; //!< current displacement along the X axis
00157   plist::Primitive<float> curY; //!< current displacement along the Y axis
00158   plist::Primitive<float> curZ; //!< current displacement along the Z axis
00159   plist::Angle curHeading; //!< current orientation
00160   static const std::string autoRegister; //!< Provides registration with FamilyFactory<SensorInfo>
00161   PLIST_CLONE_DEF(GPSSensor,new GPSSensor(*this));
00162 protected:
00163   //! performs common initialization
00164   void init() {
00165     addEntry("SensorName",sensorName,"Name of the sensor instance, to match up with the a sensorNames[] in RobotInfo header.");
00166     addEntry("CurX",curX,"Current displacement along the X axis");
00167     addEntry("CurY",curY,"Current displacement along the Y axis");
00168     addEntry("CurZ",curZ,"Current displacement along the Z axis");
00169     addEntry("CurHeading",curHeading,"Current orientation");
00170     setLoadSavePolicy(FIXED,SYNC);    
00171   }
00172 };
00173 
00174 //! Odometry is presently only used for the Create robot, which reports cumulative distances and angles. 
00175 struct OdometrySensor : public SensorInfo {
00176   //! constructor
00177   OdometrySensor()
00178     : SensorInfo(autoRegister), forwardSensorName(), leftSensorName(), upSensorName(), headingSensorName(), 
00179       lastX(0), lastY(0), lastZ(0), lastHeading(0),
00180       deltaX(0), deltaY(0), deltaZ(0), deltaHeading(0), 
00181       cumX(0), cumY(0), cumZ(0), cumHeading(0) { init(); }
00182   //! copy constructor for cloning
00183   OdometrySensor(const OdometrySensor& s)
00184     : SensorInfo(s), forwardSensorName(s.forwardSensorName), leftSensorName(s.leftSensorName), upSensorName(s.upSensorName), headingSensorName(s.headingSensorName), 
00185       lastX(s.lastX), lastY(s.lastY), lastZ(s.lastZ), lastHeading(s.lastHeading),
00186       deltaX(s.deltaX), deltaY(s.deltaY), deltaZ(s.deltaZ), deltaHeading(s.deltaHeading),
00187       cumX(s.cumX), cumY(s.cumY), cumZ(s.cumZ), cumHeading(s.cumHeading) { init(); }
00188   
00189   virtual void declareValues(DynamicRobotState& values) {
00190     if (forwardSensorName.size() > 0)
00191       values.sensors.addEntry(forwardSensorName,cumX);
00192     if (leftSensorName.size() > 0)
00193       values.sensors.addEntry(leftSensorName,cumY);
00194     if (upSensorName.size() > 0)
00195       values.sensors.addEntry(upSensorName,cumZ);
00196     if (headingSensorName.size() > 0)
00197       values.sensors.addEntry(headingSensorName,cumHeading);
00198   }
00199   virtual void reclaimValues(DynamicRobotState& values) {
00200     if (forwardSensorName.size() > 0)
00201       values.sensors.removeEntry(forwardSensorName);
00202     if (leftSensorName.size() > 0)
00203       values.sensors.removeEntry(leftSensorName);
00204     if (upSensorName.size() > 0)
00205       values.sensors.removeEntry(upSensorName);
00206     if (headingSensorName.size() > 0)
00207       values.sensors.removeEntry(headingSensorName);
00208   }
00209   plist::Primitive<std::string> forwardSensorName; //!< Name of the sensor instance, to match up with the a sensorNames[] in RobotInfo header.
00210   plist::Primitive<std::string> leftSensorName; //!< Name of the sensor instance, to match up with the a sensorNames[] in RobotInfo header.
00211   plist::Primitive<std::string> upSensorName; //!< Name of the sensor instance, to match up with the a sensorNames[] in RobotInfo header.
00212   plist::Primitive<std::string> headingSensorName; //!< Name of the sensor instance, to match up with the a sensorNames[] in RobotInfo header.
00213   float lastX; //!< previous displacement along the X axis
00214   float lastY; //!< previous displacement along the Y axis
00215   float lastZ; //!< previous displacement along the Z axis
00216   float lastHeading; //!< previous heading
00217   float deltaX; //!< current displacement along the X axis
00218   float deltaY; //!< current displacement along the Y axis
00219   float deltaZ; //!< current displacement along the Z axis
00220   float deltaHeading; //!< current heading change
00221   plist::Primitive<float> cumX; //!< cumulative displacement along the X axis
00222   plist::Primitive<float> cumY; //!< cumulative displacement along the Y axis
00223   plist::Primitive<float> cumZ; //!< cumulative displacement along the Z axis
00224   plist::Primitive<float> cumHeading; //!< cumulative heading change
00225   static const std::string autoRegister; //!< Provides registration with FamilyFactory<SensorInfo>
00226   PLIST_CLONE_DEF(OdometrySensor,new OdometrySensor(*this));
00227 protected:
00228   //! performs common initialization
00229   void init() {
00230     addEntry("ForwardSensorName",forwardSensorName,"Name of the sensor along X axis");
00231     addEntry("LeftSensorName",leftSensorName,"Name of the sensor along Y axis");
00232     addEntry("UpSensorName",upSensorName,"Name of the sensor along Z axis");
00233     addEntry("HeadingSensorName",headingSensorName,"Name of the sensor for orientation");   
00234     setLoadSavePolicy(FIXED,SYNC);    
00235   }
00236 };
00237 
00238 namespace plist {
00239   //! This specialization looks for the SensorInfo::sensorType, then has the factory construct the correct subtype before loading the @a node into and returning that.
00240   template<> SensorInfo* loadXML(xmlNode* node);
00241   //! SensorInfo::sensorType.set() could still lead to trouble, although with a little work we could probably find a way to support it...
00242   template<> inline SensorInfo* allocate() { throw std::runtime_error("cannot plist::allocate generic instances (SensorInfo)"); }
00243 }
00244 
00245 /*! @file
00246  * @brief 
00247  * @author Ethan Tira-Thompson (ejt) (Creator)
00248  */
00249 
00250 #endif

Tekkotsu v5.1CVS
Generated Fri Mar 16 05:26:51 2012 by Doxygen 1.6.3