Tekkotsu Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
CommonInfo.hGo to the documentation of this file.00001 //-*-c++-*- 00002 #ifndef INCLUDED_CommonInfo_h_ 00003 #define INCLUDED_CommonInfo_h_ 00004 00005 #include <map> 00006 #include <set> 00007 #include <string> 00008 #include <stdexcept> 00009 00010 namespace RobotInfo { 00011 00012 //! 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) 00013 enum MinMaxRange_t { MinRange,MaxRange }; 00014 00015 //! 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) 00016 /*! This function should return the actual RobotInfo::TargetName and not a hard coded string. 00017 * This way, we can rely on testing equality with a direct pointer comparison instead of strcmp(). 00018 * (Also eliminates chance of typo or missing refactorization if renamed!). 00019 * 00020 * The result of this function is stored in #RobotName, so you don't need to call 00021 * this function -- the only reason it's declared in the header is so you can call 00022 * it during static initialization, when you can't rely on RobotName having been 00023 * initialized yet. */ 00024 const char* const detectModel(); 00025 00026 //! Name of the robot which is actually running 00027 /*! This is usually set to the TargetName, but if the target model is a "compatability" target, 00028 * where the actual host hardware may be a different (more restrictive) configuration, 00029 * then RobotName will be set to the TargetName of that configuration. 00030 * 00031 * Note that you should be able to rely on doing pointer comparisons 00032 * between RobotName and various TargetNames to test for different robot models, 00033 * instead of using strcmp() for each. 00034 * 00035 * However, a std::string is used on Aperios to transparently trigger the strcmp because 00036 * of the way the process model is handled there screws up the pointer comparison 00037 * (a different process does the static initialization, so we get a pointer relative to its 00038 * memory space instead of the one we're executing in. Unix-based platforms don't 00039 * have this problem by using a "real" fork() operation.) */ 00040 #ifndef PLATFORM_APERIOS 00041 extern const char* const RobotName; 00042 #else // have to use a string because aperios is annoying like that 00043 extern const std::string RobotName; 00044 #endif 00045 00046 //! Allows behaviors to lookup output/button/sensor names from other models to support basic cross-model portability 00047 /*! Use the getCapabilities() function to look up the Capabalities instance for a given model based on its string robot name */ 00048 class Capabilities { 00049 friend Capabilities* getCapabilities(const std::string& robName); 00050 public: 00051 //! constructor, pass the robot name this is regarding, and outputs, buttons, and sensor names 00052 Capabilities(const char* robName, size_t numOut, const char * const outNames[], 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); 00053 //! shallow copy (explicit to satisfy warning) 00054 Capabilities(const Capabilities& cap) 00055 : name(cap.name), numOutputs(cap.numOutputs), numButtons(cap.numButtons), numSensors(cap.numSensors), 00056 outputs(cap.outputs), buttons(cap.buttons), sensors(cap.sensors), 00057 outputToIndex(cap.outputToIndex), buttonToIndex(cap.buttonToIndex), sensorToIndex(cap.sensorToIndex), 00058 pidJointOffset(cap.pidJointOffset), numPIDJoints(cap.numPIDJoints), ledOffset(cap.ledOffset), numLEDs(cap.numLEDs), 00059 fakeOutputs() {} 00060 //! shallow assign (explicit to satisfy warning) 00061 Capabilities& operator=(const Capabilities& cap) { 00062 name=cap.name; 00063 numOutputs=cap.numOutputs; numButtons=cap.numButtons; numSensors=cap.numSensors; 00064 outputs=cap.outputs; buttons=cap.buttons; sensors=cap.sensors; 00065 outputToIndex=cap.outputToIndex; buttonToIndex=cap.buttonToIndex; sensorToIndex=cap.sensorToIndex; 00066 pidJointOffset=cap.pidJointOffset; numPIDJoints=cap.numPIDJoints; ledOffset=cap.ledOffset; numLEDs=cap.numLEDs; 00067 fakeOutputs=cap.fakeOutputs; 00068 return *this; 00069 } 00070 //! destructor, explicit just to avoid warning when used as base class 00071 virtual ~Capabilities() {} 00072 00073 //! returns the name of the robot this corresponds to 00074 inline const char * getRobotName() const { return name; } 00075 00076 //! returns the number of unique outputs (i.e. not counting aliases) 00077 inline unsigned int getNumOutputs() const { return numOutputs; } 00078 //! returns the number of unique buttons (i.e. not counting aliases) 00079 inline unsigned int getNumButtons() const { return numButtons; } 00080 //! returns the number of unique sensors (i.e. not counting aliases) 00081 inline unsigned int getNumSensors() const { return numSensors; } 00082 00083 //! look up the name corresponding to an offset, returns NULL if not found/available 00084 inline const char * getOutputName(unsigned int i) const { return i<numOutputs ? outputs[i] : NULL; } 00085 //! look up the name corresponding to an offset, returns NULL if not found/available 00086 inline const char * getButtonName(unsigned int i) const { return i<numButtons ? buttons[i] : NULL; } 00087 //! look up the name corresponding to an offset, returns NULL if not found/available 00088 inline const char * getSensorName(unsigned int i) const { return i<numSensors ? sensors[i] : NULL; } 00089 00090 //! Look up the offset corresponding to a output name, throws std::invalid_argument if not found 00091 /*! Identical to findOutputOffset(), except throws an exception instead of returning an invalid value. 00092 * 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?) */ 00093 inline unsigned int getOutputOffset(const char* out) const { return lookupT("output",outputToIndex,out); } 00094 //! look up the offset corresponding to a button name, throws std::invalid_argument if not found 00095 /*! Identical to findButtonOffset(), except throws an exception instead of returning an invalid value. 00096 * 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?) */ 00097 inline unsigned int getButtonOffset(const char* but) const { return lookupT("button",buttonToIndex,but); } 00098 //! look up the offset corresponding to a sensor name, throws std::invalid_argument if not found 00099 /*! Identical to findSensorOffset(), except throws an exception instead of returning an invalid value. 00100 * 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?) */ 00101 inline unsigned int getSensorOffset(const char* sen) const { return lookupT("sensor",sensorToIndex,sen); } 00102 00103 //! look up the offset corresponding to a output name, returns -1U if not found/available 00104 /*! Identical to getOutputOffset(), except returns an invalid value instead of throwing an exception. 00105 * 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) */ 00106 inline unsigned int findOutputOffset(const char* out) const { return lookup(outputToIndex,out); } 00107 //! look up the offset corresponding to a button name, returns -1U if not found/available 00108 /*! Identical to getButtonOffset(), except returns an invalid value instead of throwing an exception. 00109 * 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) */ 00110 inline unsigned int findButtonOffset(const char* but) const { return lookup(buttonToIndex,but); } 00111 //! look up the offset corresponding to a sensor name, returns -1U if not found/available 00112 /*! Identical to getSensorOffset(), except returns an invalid value instead of throwing an exception. 00113 * 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) */ 00114 inline unsigned int findSensorOffset(const char* sen) const { return lookup(sensorToIndex,sen); } 00115 00116 inline unsigned int getPIDJointOffset() const { return pidJointOffset; } //!< returns the offset of the block of 'PID' joints in an output array 00117 inline unsigned int getNumPIDJoints() const { return numPIDJoints; } //!< returns the number of 'PID' joints 00118 inline unsigned int getLEDOffset() const { return ledOffset; } //!< returns the offset of the block of LEDs in an output array 00119 inline unsigned int getNumLEDs() const { return numLEDs; } //!< returns the number of LEDs 00120 00121 //! returns the offsets of "fake" outputs, see #fakeOutputs 00122 inline const std::set<unsigned int>& getFakeOutputs() const { return fakeOutputs; } 00123 00124 protected: 00125 //! helper function, does the work of the get..Offset functions 00126 inline unsigned int lookupT(const char * errStr, const std::map<std::string,unsigned int>& nameToIndex, const char * capname) const { 00127 std::map<std::string,unsigned int>::const_iterator it=nameToIndex.find(capname); 00128 if(it==nameToIndex.end()) { 00129 std::string str; str.append(name).append("::capabilities could not find ").append(errStr).append(" named ").append(capname); 00130 throw std::invalid_argument(str); 00131 } 00132 return it->second; 00133 } 00134 //! helper function, does the work of the find..Offset functions 00135 inline unsigned int lookup(const std::map<std::string,unsigned int>& nameToIndex, const char * capname) const { 00136 std::map<std::string,unsigned int>::const_iterator it=nameToIndex.find(capname); 00137 return it==nameToIndex.end() ? -1U : it->second; 00138 } 00139 00140 const char* name; //!< name of robot model 00141 size_t numOutputs; //!< length of #outputs 00142 size_t numButtons; //!< length of #buttons 00143 size_t numSensors; //!< length of #sensors 00144 const char * const * outputs; //!< array of names for outputs -- this is the "primary" name for each output, #outputToIndex may contain additional aliases 00145 const char * const * buttons; //!< array of names for buttons -- this is the "primary" name for each button, #buttonToIndex may contain additional aliases 00146 const char * const * sensors; //!< array of names for sensors -- this is the "primary" name for each sensor, #sensorToIndex may contain additional aliases 00147 std::map<std::string,unsigned int> outputToIndex; //!< maps output names to offset values 00148 std::map<std::string,unsigned int> buttonToIndex; //!< maps button names to offset values 00149 std::map<std::string,unsigned int> sensorToIndex; //!< maps sensor names to offset values 00150 00151 size_t pidJointOffset; //!< the offset of the PID joints 00152 size_t numPIDJoints; //!< the number of PID joints 00153 size_t ledOffset; //!< the offset of the LEDs 00154 size_t numLEDs; //!< the number of LEDs 00155 00156 //! Offsets of "fake" outputs, which don't correspond to any physical device on the robot 00157 /*! This is used in compatability modes, where some outputs may not be available on the 00158 * host hardware, or for meta-outputs, which control the interpretation of other outputs. 00159 * (such as the A/B LED mode setting for the ERS-7, where a "virtual" LED switches 00160 * the system's intepretation of the face panel LEDs). 00161 * 00162 * Most robots can probably just leave this empty -- on Aperios the "fake" outputs are 00163 * skipped when interfacing with the system and their values receive feedback from 00164 * the motion process. When using the tekkotsu executable under unix-based systems, 00165 * the HAL layer handles this functionality via its own configuration settings, and these 00166 * values are ignored. */ 00167 std::set<unsigned int> fakeOutputs; 00168 00169 //! returns a static map from robot names to capability instances, which are externally allocated 00170 /*! The Capabilties base class will automatically insert entries into this collection. */ 00171 static std::map<std::string, class Capabilities*>& getCaps(); 00172 }; 00173 00174 } 00175 00176 /*! @file 00177 * @brief 00178 * @author ejt (Creator) 00179 * 00180 * $Author: ejt $ 00181 * $Name: tekkotsu-4_0 $ 00182 * $Revision: 1.7 $ 00183 * $State: Exp $ 00184 * $Date: 2007/11/09 19:01:13 $ 00185 */ 00186 00187 #endif |
Tekkotsu v4.0 |
Generated Thu Nov 22 00:54:51 2007 by Doxygen 1.5.4 |