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 a 42° by 31.5° camera, like Logitech Communicate STX, note that these specifications indicate either a mistake or non-square pixels...
00035 namespace CameraSTX {
00036   const float CameraHorizFOV = 0.7330382858f; //!< horizontal field of view (radians)
00037   const float CameraVertFOV = 0.5497787144f; //!< 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 namespace RobotInfo {
00045   
00046   //! 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)
00047   enum MinMaxRange_t { MinRange,MaxRange };
00048   
00049   //! 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)
00050   /*! This function should return the actual RobotInfo::TargetName and not a hard coded string.
00051    *  This way, we can rely on testing equality with a direct pointer comparison instead of strcmp().
00052    *  (Also eliminates chance of typo or missing refactorization if renamed!).
00053    *
00054    *  The result of this function is stored in #RobotName, so you don't need to call
00055    *  this function -- the only reason it's declared in the header is so you can call
00056    *  it during static initialization, when you can't rely on RobotName having been
00057    *  initialized yet. */
00058   const char* const detectModel();
00059   
00060   //! Name of the robot which is actually running
00061   /*! This is usually set to the TargetName, but if the target model is a "compatability" target,
00062    *  where the actual host hardware may be a different (more restrictive) configuration,
00063    *  then RobotName will be set to the TargetName of that configuration.
00064    *
00065    *  Note that you should be able to rely on doing pointer comparisons
00066    *  between RobotName and various TargetNames to test for different robot models,
00067    *  instead of using strcmp() for each. 
00068    *
00069    *  However, a std::string is used on Aperios to transparently trigger the strcmp because
00070    *  of the way the process model is handled there screws up the pointer comparison
00071    *  (a different process does the static initialization, so we get a pointer relative to its
00072    *  memory space instead of the one we're executing in.  Unix-based platforms don't
00073    *  have this problem by using a "real" fork() operation.) */
00074 #ifndef PLATFORM_APERIOS
00075   extern const char* const RobotName;
00076 #else // have to use a string because aperios is annoying like that
00077   extern const std::string RobotName;
00078 #endif
00079   
00080   //! Allows behaviors to lookup output/button/sensor names from other models to support basic cross-model portability
00081   /*! Use the getCapabilities() function to look up the Capabalities instance for a given model based on its string robot name */
00082   class Capabilities {
00083     friend const Capabilities* getCapabilities(const std::string& robName);
00084   public:
00085     //! constructor, pass the robot name this is regarding, and outputs, buttons, and sensor names
00086     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);
00087     //! shallow copy (explicit to satisfy warning)
00088     Capabilities(const Capabilities& cap)
00089       : name(cap.name),
00090       frames(cap.frames), buttons(cap.buttons), sensors(cap.sensors),
00091       frameToIndex(cap.frameToIndex), buttonToIndex(cap.buttonToIndex), sensorToIndex(cap.sensorToIndex),
00092       pidJointOffset(cap.pidJointOffset), numPIDJoints(cap.numPIDJoints), ledOffset(cap.ledOffset), numLEDs(cap.numLEDs), numOutputs(cap.numOutputs),
00093       fakeOutputs() {}
00094     //! shallow assign (explicit to satisfy warning)
00095     Capabilities& operator=(const Capabilities& cap) {
00096       name=cap.name;
00097       frames=cap.frames; buttons=cap.buttons; sensors=cap.sensors;
00098       frameToIndex=cap.frameToIndex; buttonToIndex=cap.buttonToIndex; sensorToIndex=cap.sensorToIndex;
00099       pidJointOffset=cap.pidJointOffset; numPIDJoints=cap.numPIDJoints; ledOffset=cap.ledOffset; numLEDs=cap.numLEDs; numOutputs=cap.numOutputs;
00100       fakeOutputs=cap.fakeOutputs;
00101       return *this;
00102     }
00103     //! destructor, explicit just to avoid warning when used as base class
00104     virtual ~Capabilities() {}
00105     
00106     //! returns the name of the robot this corresponds to
00107     inline const char * getRobotName() const { return name; }
00108     
00109     //! returns the number of unique outputs (i.e. not counting aliases and non-actuated reference frames)
00110     inline unsigned int getNumOutputs() const { return numOutputs; }
00111     //! returns the number of unique reference frames (includes all outputs, plus unactuated points of interest, like cameras or end effector tips
00112     inline unsigned int getNumFrames() const { return frames.size(); }
00113     //! returns the number of unique buttons (i.e. not counting aliases)
00114     inline unsigned int getNumButtons() const { return buttons.size(); }
00115     //! returns the number of unique sensors (i.e. not counting aliases)
00116     inline unsigned int getNumSensors() const { return sensors.size(); }
00117     
00118     inline unsigned int getPIDJointOffset() const { return pidJointOffset; } //!< returns the offset of the block of 'PID' joints in an output array
00119     inline unsigned int getNumPIDJoints() const { return numPIDJoints; } //!< returns the number of 'PID' joints
00120     inline unsigned int getLEDOffset() const { return ledOffset; } //!< returns the offset of the block of LEDs in an output array
00121     inline unsigned int getNumLEDs() const { return numLEDs; } //!< returns the number of LEDs
00122     
00123     //! look up the name corresponding to an offset, returns NULL if not found/available
00124     inline const char * getOutputName(unsigned int i) const { return i<numOutputs ? frames[i].c_str() : NULL; }
00125     //! look up the name corresponding to an offset, returns NULL if not found/available
00126     inline const char * getFrameName(unsigned int i) const { return i<frames.size() ? frames[i].c_str() : NULL; }
00127     //! look up the name corresponding to an offset, returns NULL if not found/available
00128     inline const char * getButtonName(unsigned int i) const { return i<buttons.size() ? buttons[i].c_str() : NULL; }
00129     //! look up the name corresponding to an offset, returns NULL if not found/available
00130     inline const char * getSensorName(unsigned int i) const { return i<sensors.size() ? sensors[i].c_str() : NULL; }
00131     
00132     //! Look up the offset corresponding to a output name, throws std::invalid_argument if not found
00133     /*! Identical to findOutputOffset(), except throws an exception instead of returning an invalid value.
00134      *  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?) */
00135     inline unsigned int getOutputOffset(const std::string& out) const {
00136       unsigned int i = lookupT("output",frameToIndex,out);
00137       if(i>=numOutputs) {
00138         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)");
00139         throw std::invalid_argument(str);
00140       }
00141       return i;
00142     }
00143     //! Look up the offset corresponding to a reference frame name, throws std::invalid_argument if not found
00144     /*! Identical to findFrameOffset(), except throws an exception instead of returning an invalid value.
00145      *  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?) */
00146     inline unsigned int getFrameOffset(const std::string& frame) const { return lookupT("frame",frameToIndex,frame); }
00147     //! look up the offset corresponding to a button name, throws std::invalid_argument if not found
00148     /*! Identical to findButtonOffset(), except throws an exception instead of returning an invalid value.
00149      *  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?) */
00150     inline unsigned int getButtonOffset(const std::string& but) const { return lookupT("button",buttonToIndex,but); }
00151     //! look up the offset corresponding to a sensor name, throws std::invalid_argument if not found
00152     /*! Identical to findSensorOffset(), except throws an exception instead of returning an invalid value.
00153      *  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?) */
00154     inline unsigned int getSensorOffset(const std::string& sen) const { return lookupT("sensor",sensorToIndex,sen); }
00155     
00156     //! look up the offset corresponding to a output name, returns -1U if not found/available
00157     /*! Identical to getOutputOffset(), except returns an invalid value instead of throwing an exception.
00158      *  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) */ 
00159     inline unsigned int findOutputOffset(const std::string& out) const {
00160       unsigned int i = lookup(frameToIndex,out);
00161       return (i>=numOutputs) ? -1U : i;
00162     }
00163     //! look up the offset corresponding to a reference frame name, returns -1U if not found/available
00164     /*! Identical to getFrameOffset(), except returns an invalid value instead of throwing an exception.
00165      *  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) */ 
00166     inline unsigned int findFrameOffset(const std::string& frame) const { return lookup(frameToIndex,frame); }
00167     //! look up the offset corresponding to a button name, returns -1U if not found/available
00168     /*! Identical to getButtonOffset(), except returns an invalid value instead of throwing an exception.
00169      *  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) */ 
00170     inline unsigned int findButtonOffset(const std::string& but) const { return lookup(buttonToIndex,but); }
00171     //! look up the offset corresponding to a sensor name, returns -1U if not found/available
00172     /*! Identical to getSensorOffset(), except returns an invalid value instead of throwing an exception.
00173      *  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) */ 
00174     inline unsigned int findSensorOffset(const std::string& sen) const { return lookup(sensorToIndex,sen); }
00175     
00176     //! returns the offsets of "fake" outputs, see #fakeOutputs
00177     inline const std::set<unsigned int>& getFakeOutputs() const { return fakeOutputs; }
00178     
00179   protected:
00180     //! helper function, does the work of the get..Offset functions
00181     inline unsigned int lookupT(const char * errStr, const std::map<std::string,unsigned int>& nameToIndex, const std::string& capname) const {
00182       std::map<std::string,unsigned int>::const_iterator it=nameToIndex.find(capname);
00183       if(it==nameToIndex.end()) {
00184         std::string str; str.append(name).append("::capabilities could not find ").append(errStr).append(" named ").append(capname);
00185         throw std::invalid_argument(str);
00186       }
00187       return it->second;
00188     }
00189     //! helper function, does the work of the find..Offset functions
00190     inline unsigned int lookup(const std::map<std::string,unsigned int>& nameToIndex, const std::string& capname) const {
00191       std::map<std::string,unsigned int>::const_iterator it=nameToIndex.find(capname);
00192       return it==nameToIndex.end() ? -1U : it->second;
00193     }
00194     
00195     const char* name; //!< name of robot model
00196     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
00197     std::vector<std::string> buttons; //!< array of names for buttons -- this is the "primary" name for each button, #buttonToIndex may contain additional aliases
00198     std::vector<std::string> sensors; //!< array of names for sensors -- this is the "primary" name for each sensor, #sensorToIndex may contain additional aliases
00199     std::map<std::string,unsigned int> frameToIndex; //!< maps output names to offset values
00200     std::map<std::string,unsigned int> buttonToIndex; //!< maps button names to offset values
00201     std::map<std::string,unsigned int> sensorToIndex; //!< maps sensor names to offset values
00202     
00203     size_t pidJointOffset; //!< the offset of the PID joints
00204     size_t numPIDJoints; //!< the number of PID joints
00205     size_t ledOffset; //!< the offset of the LEDs
00206     size_t numLEDs; //!< the number of LEDs
00207     size_t numOutputs; //!< the total number of outputs (e.g. the reference frames which are actuated)
00208     
00209     //! Offsets of "fake" outputs, which don't correspond to any physical device on the robot
00210     /*! This is used in compatability modes, where some outputs may not be available on the
00211      *  host hardware, or for meta-outputs, which control the interpretation of other outputs.
00212      *  (such as the A/B LED mode setting for the ERS-7, where a "virtual" LED switches
00213      *  the system's intepretation of the face panel LEDs).
00214      *
00215      *  Most robots can probably just leave this empty -- on Aperios the "fake" outputs are
00216      *  skipped when interfacing with the system and their values receive feedback from
00217      *  the motion process.  When using the tekkotsu executable under unix-based systems,
00218      *  the HAL layer handles this functionality via its own configuration settings, and these
00219      *  values are ignored. */
00220     std::set<unsigned int> fakeOutputs;
00221     
00222     //! returns a static map from robot names to capability instances, which are externally allocated
00223     /*! The Capabilties base class will automatically insert entries into this collection. */
00224     static std::map<std::string, const Capabilities*>& getCaps();
00225   };
00226 
00227 }
00228 
00229 /*! @file
00230  * @brief Defines items shared between robot models, like camera specifications
00231  * @author ejt (Creator)
00232  */
00233 
00234 #endif

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