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     values.sensors.addEntry(sensorName+"Heading",curHeading);
00150   }
00151   virtual void reclaimValues(DynamicRobotState& values) {
00152     values.sensors.removeEntry(sensorName+"X");
00153     values.sensors.removeEntry(sensorName+"Y");
00154     values.sensors.removeEntry(sensorName+"Z");
00155     values.sensors.removeEntry(sensorName+"Heading");
00156   }
00157   plist::Primitive<std::string> sensorName; //!< Name of the sensor instance, to match up with the a sensorNames[] in RobotInfo header.
00158   plist::Primitive<float> curX; //!< current displacement along the X axis
00159   plist::Primitive<float> curY; //!< current displacement along the Y axis
00160   plist::Primitive<float> curZ; //!< current displacement along the Z axis
00161   plist::Primitive<float> curHeading; //!< current orientation
00162   static const std::string autoRegister; //!< Provides registration with FamilyFactory<SensorInfo>
00163   PLIST_CLONE_DEF(GPSSensor,new GPSSensor(*this));
00164 protected:
00165   //! performs common initialization
00166   void init() {
00167     addEntry("SensorName",sensorName,"Name of the sensor instance, to match up with the a sensorNames[] in RobotInfo header.");
00168     setLoadSavePolicy(FIXED,SYNC);    
00169   }
00170 };
00171 
00172 //! Odometry is presently only used for the Create robot, which reports cumulative distances and angles. 
00173 struct OdometrySensor : public SensorInfo {
00174   //! constructor
00175   OdometrySensor()
00176     : SensorInfo(autoRegister), forwardSensorName(), leftSensorName(), upSensorName(), headingSensorName(),
00177       leftEncoderSensorName(), rightEncoderSensorName(),
00178       lastX(0), lastY(0), lastZ(0), lastHeading(0),
00179       deltaX(0), deltaY(0), deltaZ(0), deltaHeading(0), 
00180       cumX(0), cumY(0), cumZ(0), cumHeading(0),
00181       wheelCircumference(0), wheelBase(0), encoderTicksPerRev(0),
00182       leftEncoder(0), rightEncoder(0)
00183   { init(); }
00184 
00185   //! copy constructor for cloning
00186   OdometrySensor(const OdometrySensor& s)
00187     : SensorInfo(s), forwardSensorName(s.forwardSensorName), leftSensorName(s.leftSensorName), upSensorName(s.upSensorName), headingSensorName(s.headingSensorName), 
00188       leftEncoderSensorName(s.leftEncoderSensorName), rightEncoderSensorName(s.rightEncoderSensorName),
00189       lastX(s.lastX), lastY(s.lastY), lastZ(s.lastZ), lastHeading(s.lastHeading),
00190       deltaX(s.deltaX), deltaY(s.deltaY), deltaZ(s.deltaZ), deltaHeading(s.deltaHeading),
00191       cumX(s.cumX), cumY(s.cumY), cumZ(s.cumZ), cumHeading(s.cumHeading),
00192       wheelCircumference(s.wheelCircumference), wheelBase(s.wheelBase), 
00193       encoderTicksPerRev(s.encoderTicksPerRev), leftEncoder(s.leftEncoder), rightEncoder(s.rightEncoder)
00194   { init(); }
00195   
00196   virtual void declareValues(DynamicRobotState& values) {
00197     if (forwardSensorName.size() > 0)
00198       values.sensors.addEntry(forwardSensorName,cumX);
00199     if (leftSensorName.size() > 0)
00200       values.sensors.addEntry(leftSensorName,cumY);
00201     if (upSensorName.size() > 0)
00202       values.sensors.addEntry(upSensorName,cumZ);
00203     if (headingSensorName.size() > 0)
00204       values.sensors.addEntry(headingSensorName,cumHeading);
00205     if (leftEncoderSensorName.size() > 0)
00206       values.sensors.addEntry(leftEncoderSensorName,leftEncoder);
00207     if (rightEncoderSensorName.size() > 0)
00208       values.sensors.addEntry(rightEncoderSensorName,rightEncoder);
00209   }
00210 
00211   virtual void reclaimValues(DynamicRobotState& values) {
00212     if (forwardSensorName.size() > 0)
00213       values.sensors.removeEntry(forwardSensorName);
00214     if (leftSensorName.size() > 0)
00215       values.sensors.removeEntry(leftSensorName);
00216     if (upSensorName.size() > 0)
00217       values.sensors.removeEntry(upSensorName);
00218     if (headingSensorName.size() > 0)
00219       values.sensors.removeEntry(headingSensorName);
00220     if (leftEncoderSensorName.size() > 0)
00221       values.sensors.removeEntry(leftEncoderSensorName);
00222     if (rightEncoderSensorName.size() > 0)
00223       values.sensors.removeEntry(rightEncoderSensorName);
00224   }
00225 
00226   plist::Primitive<std::string> forwardSensorName; //!< Name of the sensor instance, to match up with the sensorNames[] in RobotInfo header.
00227   plist::Primitive<std::string> leftSensorName; //!< Name of the sensor instance, to match up with the sensorNames[] in RobotInfo header.
00228   plist::Primitive<std::string> upSensorName; //!< Name of the sensor instance, to match up with the sensorNames[] in RobotInfo header.
00229   plist::Primitive<std::string> headingSensorName; //!< Name of the sensor instance, to match up with the sensorNames[] in RobotInfo header.
00230   plist::Primitive<std::string> leftEncoderSensorName; //!< Name of the left encoder instance, to match up with the SensorNames[] in RobotInfo header.
00231   plist::Primitive<std::string> rightEncoderSensorName; //!< Name of the right encoder instance, to match up with the SensorNames[] in RobotInfo header.
00232   float lastX; //!< previous displacement along the X axis
00233   float lastY; //!< previous displacement along the Y axis
00234   float lastZ; //!< previous displacement along the Z axis
00235   float lastHeading; //!< previous heading
00236   float deltaX; //!< current displacement along the X axis
00237   float deltaY; //!< current displacement along the Y axis
00238   float deltaZ; //!< current displacement along the Z axis
00239   float deltaHeading; //!< current heading change
00240   plist::Primitive<float> cumX; //!< cumulative displacement along the X axis
00241   plist::Primitive<float> cumY; //!< cumulative displacement along the Y axis
00242   plist::Primitive<float> cumZ; //!< cumulative displacement along the Z axis
00243   plist::Primitive<float> cumHeading; //!< cumulative heading change
00244   plist::Primitive<float> wheelCircumference; //!< wheel circumference in mm (72.0 for Create2)
00245   plist::Primitive<float> wheelBase; //!< wheel base in mm (235.0 for Create2)
00246   plist::Primitive<float> encoderTicksPerRev; //!< number of encoder ticks per revolution (508.8 for Create2)
00247   plist::Primitive<float> leftEncoder; //!< left encoder value for Create-like robots
00248   plist::Primitive<float> rightEncoder; //!< rightencoder value for Create-like robots
00249   static const std::string autoRegister; //!< Provides registration with FamilyFactory<SensorInfo>
00250   PLIST_CLONE_DEF(OdometrySensor,new OdometrySensor(*this));
00251 protected:
00252   //! performs common initialization
00253   void init() {
00254     addEntry("ForwardSensorName",forwardSensorName,"Name of the sensor along X axis");
00255     addEntry("LeftSensorName",leftSensorName,"Name of the sensor along Y axis");
00256     addEntry("UpSensorName",upSensorName,"Name of the sensor along Z axis");
00257     addEntry("HeadingSensorName",headingSensorName,"Name of the sensor for orientation");   
00258     addEntry("WheelCircumference",wheelCircumference,"Wheel circumference in mm");
00259     addEntry("WheelBase",wheelBase,"Wheel base in mm");
00260     addEntry("EncoderTicksPerRev",encoderTicksPerRev,"Number of encoder ticks per revolution");
00261     addEntry("LeftEncoderSensorName",leftEncoderSensorName,"Name of the left wheel encoder");
00262     addEntry("RightEncoderSensorName",rightEncoderSensorName,"Name of the right wheel encoder");
00263     setLoadSavePolicy(FIXED,SYNC);    
00264   }
00265 };
00266 
00267 namespace plist {
00268   //! This specialization looks for the SensorInfo::sensorType, then has the factory construct the correct subtype before loading the @a node into and returning that.
00269   template<> SensorInfo* loadXML(xmlNode* node);
00270   //! SensorInfo::sensorType.set() could still lead to trouble, although with a little work we could probably find a way to support it...
00271   template<> inline SensorInfo* allocate() { throw std::runtime_error("cannot plist::allocate generic instances (SensorInfo)"); }
00272 }
00273 
00274 /*! @file
00275  * @brief 
00276  * @author Ethan Tira-Thompson (ejt) (Creator)
00277  */
00278 
00279 #endif

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:50 2016 by Doxygen 1.6.3