Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

CommonInfo.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_CommonInfo_h_
00003 #define INCLUDED_CommonInfo_h_
00004 
00005 #include <vector>
00006 #include <map>
00007 #include <set>
00008 #include <string>
00009 #include <stdexcept>
00010 #include "Shared/fmat.h"
00011 
00012 //! parameters for a 60° horizontal field of view, 4:3 aspect ratio camera
00013 namespace CameraGeneric60 {
00014   const float CameraHorizFOV=60*(float)M_PI/180; //!< horizontal field of view (radians)
00015   const float CameraVertFOV=0.8172757101952f; //!< vertical field of view (radians): 2*atan( tan(60°/2) * 3/4 ) = 46.83°
00016   const float CameraFOV=CameraHorizFOV; //!< should be set to maximum of #CameraHorizFOV or #CameraVertFOV
00017   const unsigned int CameraResolutionX=640; //!< the number of pixels available in the 'full' layer
00018   const unsigned int CameraResolutionY=480; //!< the number of pixels available in the 'full' layer
00019   extern const char CameraModelName[]; //!< specifies a name of the camera to load calibration parameters into RobotInfo::CameraHomography
00020 }
00021 
00022 //! parameters for a 75° diagonal field of view, 4:3 aspect ratio camera, like Logitech QuickCam Pro 9000 or Communicate Deluxe
00023 namespace Camera75DOF {
00024   // 2*atan( tan(75/2) * 4/5 ) = 63.09° (horizontal)
00025   // 2*atan( tan(75/2) * 3/5 ) = 49.44° (vertical)
00026   const float CameraHorizFOV = 1.1010990963f; //!< horizontal field of view (radians)
00027   const float CameraVertFOV = 0.8629313824f; //!< vertical field of view (radians)
00028   const float CameraFOV=CameraHorizFOV; //!< should be set to maximum of #CameraHorizFOV or #CameraVertFOV
00029     const unsigned int CameraResolutionX=640; //!< the number of pixels available in the 'full' layer
00030     const unsigned int CameraResolutionY=480; //!< the number of pixels available in the 'full' layer
00031   extern const char CameraModelName[]; //!< specifies a name of the camera to load calibration parameters into RobotInfo::CameraHomography
00032 }
00033 
00034 //! parameters for Microsoft Kinect
00035 namespace CameraKinect {
00036   const float CameraHorizFOV = 1.01229097f; //!< horizontal field of view (radians)
00037   const float CameraVertFOV = 0.785398163f; //!< vertical field of view (radians)
00038   const float CameraFOV=CameraHorizFOV; //!< should be set to maximum of #CameraHorizFOV or #CameraVertFOV
00039   const unsigned int CameraResolutionX=640; //!< the number of pixels available in the 'full' layer
00040   const unsigned int CameraResolutionY=480; //!< the number of pixels available in the 'full' layer
00041   extern const char CameraModelName[]; //!< specifies a name of the camera to load calibration parameters into RobotInfo::CameraHomography
00042 }
00043 
00044 //! parameters for a 42° by 31.5° camera, like Logitech Communicate STX, note that these specifications indicate either a mistake or non-square pixels...
00045 namespace CameraSTX {
00046   const float CameraHorizFOV = 0.7330382858f; //!< horizontal field of view (radians)
00047   const float CameraVertFOV = 0.5497787144f; //!< vertical field of view (radians)
00048   const float CameraFOV=CameraHorizFOV; //!< should be set to maximum of #CameraHorizFOV or #CameraVertFOV
00049   const unsigned int CameraResolutionX=640; //!< the number of pixels available in the 'full' layer
00050   const unsigned int CameraResolutionY=480; //!< the number of pixels available in the 'full' layer
00051   extern const char CameraModelName[]; //!< specifies a name of the camera to load calibration parameters into RobotInfo::CameraHomography
00052 }
00053 
00054 //! parameters for a 66° camera, like the Microsoft LifeCam, with a 16:9 aspect ratio
00055 namespace CameraLifeCam {
00056   const float CameraHorizFOV = 1.03010024717f; //!< horizontal field of view (radians)
00057   const float CameraVertFOV = 0.61646432538f; //!< vertical field of view (radians)
00058   const float CameraFOV=CameraHorizFOV; //!< should be set to maximum of #CameraHorizFOV or #CameraVertFOV
00059   const unsigned int CameraResolutionX=1280; //!< the number of pixels available in the 'full' layer
00060   const unsigned int CameraResolutionY=720; //!< the number of pixels available in the 'full' layer
00061   extern const char CameraModelName[]; //!< specifies a name of the camera to load calibration parameters into RobotInfo::CameraHomography
00062 }
00063 namespace RobotInfo {
00064   
00065   //! Defines the indexes to use as indices to access the min and max entries of joint limit specifications (e.g. ERS7Info::outputRanges and ERS7Info::mechanicalLimits)
00066   enum MinMaxRange_t { MinRange,MaxRange };
00067   
00068   //! Some target models, such as ERS2xxInfo, may be dual-booting compatability modes.  This function returns the actual robot name (e.g. ERS210Info::TargetName or ERS220Info::TargetName)
00069   /*! This function should return the actual RobotInfo::TargetName and not a hard coded string.
00070    *  This way, we can rely on testing equality with a direct pointer comparison instead of strcmp().
00071    *  (Also eliminates chance of typo or missing refactorization if renamed!).
00072    *
00073    *  The result of this function is stored in #RobotName, so you don't need to call
00074    *  this function -- the only reason it's declared in the header is so you can call
00075    *  it during static initialization, when you can't rely on RobotName having been
00076    *  initialized yet. */
00077   const char* const detectModel();
00078   
00079   //! Name of the robot which is actually running
00080   /*! This is usually set to the TargetName, but if the target model is a "compatability" target,
00081    *  where the actual host hardware may be a different (more restrictive) configuration,
00082    *  then RobotName will be set to the TargetName of that configuration.
00083    *
00084    *  Note that you should be able to rely on doing pointer comparisons
00085    *  between RobotName and various TargetNames to test for different robot models,
00086    *  instead of using strcmp() for each. 
00087    *
00088    *  However, a std::string is used on Aperios to transparently trigger the strcmp because
00089    *  of the way the process model is handled there screws up the pointer comparison
00090    *  (a different process does the static initialization, so we get a pointer relative to its
00091    *  memory space instead of the one we're executing in.  Unix-based platforms don't
00092    *  have this problem by using a "real" fork() operation.) */
00093 #ifndef PLATFORM_APERIOS
00094   extern const char* const RobotName;
00095 #else // have to use a string because aperios is annoying like that
00096   extern const std::string RobotName;
00097 #endif
00098   
00099   //! Allows behaviors to lookup output/button/sensor names from other models to support basic cross-model portability
00100   /*! Use the getCapabilities() function to look up the Capabalities instance for a given model based on its string robot name */
00101   class Capabilities {
00102     friend const Capabilities* getCapabilities(const std::string& robName);
00103   public:
00104     //! constructor, pass the robot name this is regarding, and outputs, buttons, and sensor names
00105     Capabilities(const char* robName, size_t numFrame, const char * const frameNames[], size_t numBut, const char * const butNames[], size_t numSen, const char * const senNames[], size_t pidOff, size_t numPID, size_t ledOff, size_t numLED, size_t numTotalOut);
00106     //! shallow copy (explicit to satisfy warning)
00107     Capabilities(const Capabilities& cap)
00108       : name(cap.name),
00109       frames(cap.frames), buttons(cap.buttons), sensors(cap.sensors),
00110       frameToIndex(cap.frameToIndex), buttonToIndex(cap.buttonToIndex), sensorToIndex(cap.sensorToIndex),
00111       pidJointOffset(cap.pidJointOffset), numPIDJoints(cap.numPIDJoints), ledOffset(cap.ledOffset), numLEDs(cap.numLEDs), numOutputs(cap.numOutputs),
00112       fakeOutputs() {}
00113     //! shallow assign (explicit to satisfy warning)
00114     Capabilities& operator=(const Capabilities& cap) {
00115       name=cap.name;
00116       frames=cap.frames; buttons=cap.buttons; sensors=cap.sensors;
00117       frameToIndex=cap.frameToIndex; buttonToIndex=cap.buttonToIndex; sensorToIndex=cap.sensorToIndex;
00118       pidJointOffset=cap.pidJointOffset; numPIDJoints=cap.numPIDJoints; ledOffset=cap.ledOffset; numLEDs=cap.numLEDs; numOutputs=cap.numOutputs;
00119       fakeOutputs=cap.fakeOutputs;
00120       return *this;
00121     }
00122     //! destructor, explicit just to avoid warning when used as base class
00123     virtual ~Capabilities() {}
00124     
00125     //! returns the name of the robot this corresponds to
00126     inline const char * getRobotName() const { return name; }
00127     
00128     //! returns the number of unique outputs (i.e. not counting aliases and non-actuated reference frames)
00129     inline unsigned int getNumOutputs() const { return numOutputs; }
00130     //! returns the number of unique reference frames (includes all outputs, plus unactuated points of interest, like cameras or end effector tips
00131     inline unsigned int getNumFrames() const { return frames.size(); }
00132     //! returns the number of unique buttons (i.e. not counting aliases)
00133     inline unsigned int getNumButtons() const { return buttons.size(); }
00134     //! returns the number of unique sensors (i.e. not counting aliases)
00135     inline unsigned int getNumSensors() const { return sensors.size(); }
00136     
00137     inline unsigned int getPIDJointOffset() const { return pidJointOffset; } //!< returns the offset of the block of 'PID' joints in an output array
00138     inline unsigned int getNumPIDJoints() const { return numPIDJoints; } //!< returns the number of 'PID' joints
00139     inline unsigned int getLEDOffset() const { return ledOffset; } //!< returns the offset of the block of LEDs in an output array
00140     inline unsigned int getNumLEDs() const { return numLEDs; } //!< returns the number of LEDs
00141     
00142     //! look up the name corresponding to an offset, returns NULL if not found/available
00143     inline const char * getOutputName(unsigned int i) const { return i<numOutputs ? frames[i].c_str() : NULL; }
00144     //! look up the name corresponding to an offset, returns NULL if not found/available
00145     inline const char * getFrameName(unsigned int i) const { return i<frames.size() ? frames[i].c_str() : NULL; }
00146     //! look up the name corresponding to an offset, returns NULL if not found/available
00147     inline const char * getButtonName(unsigned int i) const { return i<buttons.size() ? buttons[i].c_str() : NULL; }
00148     //! look up the name corresponding to an offset, returns NULL if not found/available
00149     inline const char * getSensorName(unsigned int i) const { return i<sensors.size() ? sensors[i].c_str() : NULL; }
00150     
00151     //! Look up the offset corresponding to a output name, throws std::invalid_argument if not found
00152     /*! Identical to findOutputOffset(), except throws an exception instead of returning an invalid value.
00153      *  Use this if you expect that the output is available, and want a noisy fail-fast if something's wrong (e.g. typo in name?) */
00154     inline unsigned int getOutputOffset(const std::string& out) const {
00155       unsigned int i = lookupT("output",frameToIndex,out);
00156       if(i>=numOutputs) {
00157         std::string str; str.append(name).append("::capabilities could not find output named ").append(out).append(" (but there is an immobile reference frame by that name)");
00158         throw std::invalid_argument(str);
00159       }
00160       return i;
00161     }
00162     //! Look up the offset corresponding to a reference frame name, throws std::invalid_argument if not found
00163     /*! Identical to findFrameOffset(), except throws an exception instead of returning an invalid value.
00164      *  Use this if you expect that the frame is available, and want a noisy fail-fast if something's wrong (e.g. typo in name?) */
00165     inline unsigned int getFrameOffset(const std::string& frame) const { return lookupT("frame",frameToIndex,frame); }
00166     //! look up the offset corresponding to a button name, throws std::invalid_argument if not found
00167     /*! Identical to findButtonOffset(), except throws an exception instead of returning an invalid value.
00168      *  Use this if you expect that the button is available, and want a noisy fail-fast if something's wrong (e.g. typo in name?) */
00169     inline unsigned int getButtonOffset(const std::string& but) const { return lookupT("button",buttonToIndex,but); }
00170     //! look up the offset corresponding to a sensor name, throws std::invalid_argument if not found
00171     /*! Identical to findSensorOffset(), except throws an exception instead of returning an invalid value.
00172      *  Use this if you expect that the sensor is available, and want a noisy fail-fast if something's wrong (e.g. typo in name?) */
00173     inline unsigned int getSensorOffset(const std::string& sen) const { return lookupT("sensor",sensorToIndex,sen); }
00174     
00175     //! look up the offset corresponding to a output name, returns -1U if not found/available
00176     /*! Identical to getOutputOffset(), except returns an invalid value instead of throwing an exception.
00177      *  Use this if you are testing to see if a capability exists, and don't want to incur exception handling if it isn't (say you're doing a lot of testing) */ 
00178     inline unsigned int findOutputOffset(const std::string& out) const {
00179       unsigned int i = lookup(frameToIndex,out);
00180       return (i>=numOutputs) ? -1U : i;
00181     }
00182     //! look up the offset corresponding to a reference frame name, returns -1U if not found/available
00183     /*! Identical to getFrameOffset(), except returns an invalid value instead of throwing an exception.
00184      *  Use this if you are testing to see if a capability exists, and don't want to incur exception handling if it isn't (say you're doing a lot of testing) */ 
00185     inline unsigned int findFrameOffset(const std::string& frame) const { return lookup(frameToIndex,frame); }
00186     //! look up the offset corresponding to a button name, returns -1U if not found/available
00187     /*! Identical to getButtonOffset(), except returns an invalid value instead of throwing an exception.
00188      *  Use this if you are testing to see if a capability exists, and don't want to incur exception handling if it isn't (say you're doing a lot of testing) */ 
00189     inline unsigned int findButtonOffset(const std::string& but) const { return lookup(buttonToIndex,but); }
00190     //! look up the offset corresponding to a sensor name, returns -1U if not found/available
00191     /*! Identical to getSensorOffset(), except returns an invalid value instead of throwing an exception.
00192      *  Use this if you are testing to see if a capability exists, and don't want to incur exception handling if it isn't (say you're doing a lot of testing) */ 
00193     inline unsigned int findSensorOffset(const std::string& sen) const { return lookup(sensorToIndex,sen); }
00194     
00195     //! returns the offsets of "fake" outputs, see #fakeOutputs
00196     inline const std::set<unsigned int>& getFakeOutputs() const { return fakeOutputs; }
00197     
00198   protected:
00199     //! helper function, does the work of the get..Offset functions
00200     inline unsigned int lookupT(const char * errStr, const std::map<std::string,unsigned int>& nameToIndex, const std::string& capname) const {
00201       std::map<std::string,unsigned int>::const_iterator it=nameToIndex.find(capname);
00202       if(it==nameToIndex.end()) {
00203         std::string str; str.append(name).append("::capabilities could not find ").append(errStr).append(" named ").append(capname);
00204         throw std::invalid_argument(str);
00205       }
00206       return it->second;
00207     }
00208     //! helper function, does the work of the find..Offset functions
00209     inline unsigned int lookup(const std::map<std::string,unsigned int>& nameToIndex, const std::string& capname) const {
00210       std::map<std::string,unsigned int>::const_iterator it=nameToIndex.find(capname);
00211       return it==nameToIndex.end() ? -1U : it->second;
00212     }
00213     
00214     const char* name; //!< name of robot model
00215     std::vector<std::string> frames; //!< array of names for reference frames -- this is the "primary" name for each output/frame, #frameToIndex may contain additional aliases
00216     std::vector<std::string> buttons; //!< array of names for buttons -- this is the "primary" name for each button, #buttonToIndex may contain additional aliases
00217     std::vector<std::string> sensors; //!< array of names for sensors -- this is the "primary" name for each sensor, #sensorToIndex may contain additional aliases
00218     std::map<std::string,unsigned int> frameToIndex; //!< maps output names to offset values
00219     std::map<std::string,unsigned int> buttonToIndex; //!< maps button names to offset values
00220     std::map<std::string,unsigned int> sensorToIndex; //!< maps sensor names to offset values
00221     
00222     size_t pidJointOffset; //!< the offset of the PID joints
00223     size_t numPIDJoints; //!< the number of PID joints
00224     size_t ledOffset; //!< the offset of the LEDs
00225     size_t numLEDs; //!< the number of LEDs
00226     size_t numOutputs; //!< the total number of outputs (e.g. the reference frames which are actuated)
00227     
00228     //! Offsets of "fake" outputs, which don't correspond to any physical device on the robot
00229     /*! This is used in compatability modes, where some outputs may not be available on the
00230      *  host hardware, or for meta-outputs, which control the interpretation of other outputs.
00231      *  (such as the A/B LED mode setting for the ERS-7, where a "virtual" LED switches
00232      *  the system's intepretation of the face panel LEDs).
00233      *
00234      *  Most robots can probably just leave this empty -- on Aperios the "fake" outputs are
00235      *  skipped when interfacing with the system and their values receive feedback from
00236      *  the motion process.  When using the tekkotsu executable under unix-based systems,
00237      *  the HAL layer handles this functionality via its own configuration settings, and these
00238      *  values are ignored. */
00239     std::set<unsigned int> fakeOutputs;
00240     
00241     //! returns a static map from robot names to capability instances, which are externally allocated
00242     /*! The Capabilties base class will automatically insert entries into this collection. */
00243     static std::map<std::string, const Capabilities*>& getCaps();
00244   };
00245 
00246 }
00247 
00248 /*! @file
00249  * @brief Defines items shared between robot models, like camera specifications
00250  * @author ejt (Creator)
00251  */
00252 
00253 #endif

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