Changeset 20970

Show
Ignore:
Timestamp:
12/30/07 14:09:06 (8 months ago)
Author:
patrick
Message:

Refactored data normalization for analog devices so that user-level code can
now get access to the raw, non-normalized data. Instead of having every analog
device driver performing normalization for every sample that is collected, the
normalization is now performed in gadget::AnalogProxy::updateData(). This
means that only the sample returned by gadget::AnalogProxy::getData() is
normalized. The new method gadget::AnalogProxy::getRawData() provides the
access to the non-normalized sample. The analog sample buffers returned by
calling gadget::Analog::getAnalogDataBuffer() are not normalized.

The device drivers supporting analog data have been updated so that they no
longer do any normalization themselves (at least via the method
gadget::Analog::normalizeMinToMax()). Driver authors can still choose to
normalize data, but it is not necessary.

The protected method gadget::Analog::normalizeMinToMax() has been simplified,
renamed to gadget::Analog::normalize(), and made public. I decided to do it
this way instead of moving the method to gadget::AnalogProxy? so that
user-level code calling gadget::Analog::getAnalogDataBuffer() would have an
easy way to normalize individual samples if so desired. Another way of doing
it would be to add a method gadget::Analog::getNormalizedAnalogDataBuffer().

This new behavior for analog data normalization was discussed on
vrjuggler-devel several weeks ago.

Bumped the Gadgeteer version to 1.3.18.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • juggler/trunk/modules/gadgeteer/ChangeLog

    r20968 r20970  
    11DATE        AUTHOR      CHANGE 
    22----------- ----------- ------------------------------------------------------- 
     3Dec-30-2007 patrick     Moved analog data normalization to gadget::AnalogProxy 
     4                        so that analog device drivers need not perform any 
     5                        normalization of data read from the hardware. The raw, 
     6                        unormalized analog data can now be queried using 
     7                        gadget::AnalogProxy::getRawData(). The data returned by 
     8                        gadget::Analog::getAnalogDataBuffer() is no longer 
     9                        normalized. 
     10                        NEW VERSION: 1.3.18 
    311Dec-30-2007 patrick     Improved const correctness for most input-related 
    412                        classes. This should not break any existing code, but 
  • juggler/trunk/modules/gadgeteer/VERSION

    r20968 r20970  
     11.3.18-0 @12/30/2007 20:10:00 UTC@ 
    121.3.17-0 @12/30/2007 15:30:00 UTC@ 
    231.3.16-0 @11/18/2007 19:35:00 UTC@ 
  • juggler/trunk/modules/gadgeteer/drivers/3Dconnexion/SpaceBall/puck_device.cpp

    r19373 r20970  
    166166        for (unsigned int i = 0; i < _axes.size(); i++) 
    167167        { 
    168             float normalize; 
    169             float value = _axes[i].getAnalog(); 
    170             gadget::Analog::normalizeMinToMax(value, normalize); 
    171             submit[i] = normalize; 
     168            submit[i] = _axes[i].getAnalog(); 
    172169        } 
    173170        gadget::Analog::addAnalogSample(submit); 
     
    198195    for (unsigned int i = 0; i < _axes.size(); i++) 
    199196    { 
    200         float normalize; 
    201         float value = 0; 
    202         gadget::Analog::normalizeMinToMax(value, normalize); 
    203         _axes[i] = normalize; 
     197        _axes[i] = 0.0f; 
    204198    } 
    205199    for (unsigned int i = 0; i < _buttons.size(); i++) 
  • juggler/trunk/modules/gadgeteer/drivers/ART/DTrack/DTrack.cpp

    r20359 r20970  
    414414{ 
    415415        int nsize = (int )curAnalog.size(); 
    416         float fn; 
    417416 
    418417        if(n > nsize){ 
     
    420419 
    421420                for(int i=nsize; i<n; i++){  // set default for new elements 
    422                         this->normalizeMinToMax(0, fn); 
    423                         curAnalog[i] = fn; 
     421                        curAnalog[i] = 0.0f; 
    424422                        curAnalog[i].setTime(); 
    425423                } 
  • juggler/trunk/modules/gadgeteer/drivers/Ascension/Wanda/Wanda.cpp

    r19729 r20970  
    174174      // each sample buffer later. 
    175175      analog_samples[0].setTime(); 
    176  
    177       float x_axis, y_axis; 
    178       normalizeMinToMax(mWanda.getXAxis(), x_axis); 
    179       normalizeMinToMax(mWanda.getYAxis(), y_axis); 
    180  
    181       analog_samples[0].setAnalog(x_axis); 
    182       analog_samples[1].setAnalog(y_axis); 
     176      analog_samples[0].setAnalog(mWanda.getXAxis()); 
     177      analog_samples[1].setAnalog(mWanda.getYAxis()); 
    183178      analog_samples[1].setTime(analog_samples[0].getTime()); 
    184179 
  • juggler/trunk/modules/gadgeteer/drivers/Immersion/IBox/IBox.cpp

    r19729 r20970  
    203203      mButton[3] = mIBox->getButtonData(3); 
    204204 
    205       // we really need to do normalization here instead of in getData. 
    206       // need this so we return consistent AnalogData. -cj 
    207       float f; 
    208       this->normalizeMinToMax( mIBox->getAnalogData(0), f ); 
    209       mAnalog[0] = f; 
    210       this->normalizeMinToMax( mIBox->getAnalogData(1), f ); 
    211       mAnalog[1] = f; 
    212       this->normalizeMinToMax( mIBox->getAnalogData(2), f ); 
    213       mAnalog[2] = f; 
    214       this->normalizeMinToMax( mIBox->getAnalogData(3), f ); 
    215       mAnalog[3] = f; 
     205      mAnalog[0] = mIBox->getAnalogData(0); 
     206      mAnalog[1] = mIBox->getAnalogData(1); 
     207      mAnalog[2] = mIBox->getAnalogData(2); 
     208      mAnalog[3] = mIBox->getAnalogData(3); 
    216209 
    217210      mButton[0].setTime(); 
  • juggler/trunk/modules/gadgeteer/drivers/Intersense/IS900/Intersense.cpp

    r19729 r20970  
    330330      if ( stations[i].useAnalog ) 
    331331      { 
    332          float f; 
    333332         for ( int j = 0, k = min; 
    334333               j < MAX_ANALOG_CHANNELS && k < IS_ANALOG_NUM && k < num; 
    335334               ++j, ++k ) 
    336335         { 
    337             Analog::normalizeMinToMax(mTracker.analogData(stationIndex, j), f); 
    338             //mInput[progress].analog[k] = f; 
    339             cur_sample.analog[k] = f; 
     336            //mInput[progress].analog[k] = mTracker.analogData(stationIndex, j); 
     337            cur_sample.analog[k] = mTracker.analogData(stationIndex, j); 
    340338         } 
    341339      } 
  • juggler/trunk/modules/gadgeteer/drivers/Intersense/IntersenseAPI/IntersenseAPI.cpp

    r20886 r20970  
    344344      if (mStations[i].useAnalog) 
    345345      { 
    346          float f; 
    347346         for ( int j = 0; j < mStations[i].ana_num; ++j ) 
    348347         { 
    349             Analog::normalizeMinToMax(mTracker.analogData(stationIndex, j), f); 
    350             AnalogData new_analog(f); 
     348            AnalogData new_analog(mTracker.analogData(stationIndex, j)); 
    351349            new_analog.setTime(); 
    352350            cur_analog_samples.push_back(new_analog); 
  • juggler/trunk/modules/gadgeteer/drivers/Microsoft/DirectXJoystick/DirectXJoystick.cpp

    r19729 r20970  
    206206      { 
    207207         mCurAxes[i].setTime(); 
    208  
    209          float norm_value; 
    210          normalizeMinToMax(mInputDrv.getAxisValue(i), norm_value); 
    211          mCurAxes[i].setAnalog(norm_value); 
     208         mCurAxes[i].setAnalog(mInputDrv.getAxisValue(i)); 
    212209 
    213210         // Check for axis buttons. If we have a mapping for axis #i, then we 
  • juggler/trunk/modules/gadgeteer/drivers/Open/LinuxJoydev/LinuxJoydev.cpp

    r19729 r20970  
    248248         vprASSERT(axis_number < mCurAxesRanges.size() && "Axis out of range"); 
    249249 
    250          float norm_value(0.0f); 
    251          normalizeMinToMax(cur_event.value, norm_value); 
    252          mCurAxes[axis_number] = norm_value; 
     250         mCurAxes[axis_number] = cur_event.value; 
    253251         mCurAxes[axis_number].setTime(); 
    254252 
  • juggler/trunk/modules/gadgeteer/drivers/Open/Trackd/TrackdController.cpp

    r19729 r20970  
    131131   for (int j=0;j<mTrackdController->numValuators();j++) 
    132132   { 
    133        // TrackdController doesn't have a sample, so we do 
    134        // normalization here... 
    135        float f; 
    136        this->normalizeMinToMax (mTrackdController->getValuator(j), f); 
    137        mCurValuators[j] = f; 
     133       mCurValuators[j] = mTrackdController->getValuator(j); 
    138134       mCurValuators[j].setTime(); 
    139135   } 
  • juggler/trunk/modules/gadgeteer/drivers/Open/Trackd/TrackdController.h

    r20356 r20970  
    115115    * 
    116116    * @pre give the device number you wish to access. 
    117     * @post returns a value that ranges from 0.0f to 1.0f 
    118     * 
    119     * @note for example, if you are sampling a potentiometer, and it returns reading from 
    120     *       0, 255 - this function will normalize those values (using Analog::normalizeMinToMax()) 
    121     *       for another example, if your potentiometer's turn radius is limited mechanically to return 
    122     *       say, the values 176 to 200 (yes this is really low res), this function will still return 
    123     *       0.0f to 1.0f. 
    124     * 
    125     * @note to specify these min/max values, you must set in your Analog (or analog device) config 
    126     *       file the field "min" and "max".  By default (if these values do not appear), 
    127     *       "min" and "max" are set to 0.0f and 1.0f respectivly. 
    128     * 
    129     * @note TO ALL ANALOG DEVICE DRIVER WRITERS, you *must* normalize your data using 
    130     *       Analog::normalizeMinToMax() 
    131117    */ 
    132118   virtual AnalogData* getAnalogData(int devNum=0) 
     
    134120      vprASSERT(devNum < (int)mCurValuators.size() && "Analog index out of range");    // Make sure we have enough space 
    135121      return &(mCurValuators[devNum]); 
    136 //        float normalized; 
    137 //        this->normalizeMinToMax( mCurValuators[devNum], normalized ); 
    138 //        return normalized; 
    139122   } 
    140123 
  • juggler/trunk/modules/gadgeteer/drivers/Open/VRPN/Vrpn.cpp

    r19729 r20970  
    614614         << vprDEBUG_FLUSH; 
    615615 
    616       float value(0.0f); 
    617       normalizeMinToMax(b.channel[i], value); 
    618       mAnalogs[i] = value; 
     616      mAnalogs[i] = b.channel[i]; 
    619617   } 
    620618} 
  • juggler/trunk/modules/gadgeteer/drivers/VRCO/TrackdAPI/TrackdAPIController.cpp

    r19729 r20970  
    135135   for (int j=0;j<mControllerReader->trackdGetNumberOfValuators();j++) 
    136136   { 
    137        // TrackdController doesn't have a sample, so we do 
    138        // normalization here... 
    139        float f; 
    140        this->normalizeMinToMax (mControllerReader->trackdGetValuator(j), f); 
    141        mCurValuators[j] = f; 
     137       mCurValuators[j] = mControllerReader->trackdGetValuator(j); 
    142138       mCurValuators[j].setTime(); 
    143139   } 
  • juggler/trunk/modules/gadgeteer/drivers/VRCO/TrackdAPI/TrackdAPIController.h

    r20356 r20970  
    119119    * 
    120120    * @pre give the device number you wish to access. 
    121     * @post returns a value that ranges from 0.0f to 1.0f 
    122     * @note for example, if you are sampling a potentiometer, and it returns reading from 
    123     *        0, 255 - this function will normalize those values (using Analog::normalizeMinToMax()) 
    124     *        for another example, if your potentiometer's turn radius is limited mechanically to return 
    125     *        say, the values 176 to 200 (yes this is really low res), this function will still return 
    126     *        0.0f to 1.0f. 
    127     * @note to specify these min/max values, you must set in your Analog (or analog device) config 
    128     *        file the field "min" and "max".  By default (if these values do not appear), 
    129     *        "min" and "max" are set to 0.0f and 1.0f respectivly. 
    130     * @note TO ALL ANALOG DEVICE DRIVER WRITERS, you *must* normalize your data using 
    131     *        Analog::normalizeMinToMax() 
    132121    */ 
    133122   virtual AnalogData* getAnalogData(int devNum=0) 
  • juggler/trunk/modules/gadgeteer/drivers/configure.ac

    r20794 r20970  
    170170 
    171171VPR_PATH([1.1.42], , [AC_MSG_ERROR([*** VPR required for Device Drivers ***])]) 
    172 GADGETEER_PATH([1.3.11], , 
     172GADGETEER_PATH([1.3.18], , 
    173173               [AC_MSG_ERROR(*** Gadgeteer required for Device Drivers ***)]) 
    174174JCCL_PATH_CXX([1.1.5], , 
  • juggler/trunk/modules/gadgeteer/gadget/Devices/Sim/SimAnalog.cpp

    r19729 r20970  
    9696   //vprDEBUG(vprDBG_ALL, vprDBG_VERB_LVL)<<"*** SimAnalog::updateData()\n"<< vprDEBUG_FLUSH; 
    9797 
    98    // Make an list of the data that will be normalized 
    99    std::vector<AnalogData> norm_data(mAnaData.size()); 
    100  
    10198   // -- Update analog data --- // 
    10299   for (unsigned int i = 0; i < mSimKeysUp.size(); ++i) 
     
    111108      mAnaData[i].setAnalog(gmtl::Math::clamp(mAnaData[i].getAnalog(), 
    112109                                              getMin(), getMax())); 
    113  
    114       float normalized_value; 
    115       normalizeMinToMax(mAnaData[i].getAnalog(), normalized_value); 
    116  
    117       // Set the normalized data 
    118       norm_data[i] = normalized_value; 
    119       norm_data[i].setTime(mKeyboardMouse->getTimeStamp()); 
    120110   } 
    121111 
    122112   // Locks and then swaps the indices. 
    123    addAnalogSample(norm_data); 
     113   addAnalogSample(mAnaData); 
    124114   swapAnalogBuffers(); 
    125115} 
  • juggler/trunk/modules/gadgeteer/gadget/Type/Analog.cpp

    r20322 r20970  
    2828 
    2929#include <boost/concept_check.hpp> 
     30 
     31#include <gmtl/Math.h> 
     32 
    3033#include <vpr/IO/ObjectWriter.h> 
    3134#include <vpr/IO/ObjectReader.h> 
    3235#include <vpr/Util/Debug.h> 
     36 
     37#include <gadget/Util/DeviceSerializationTokens.h> 
    3338#include <gadget/Type/Analog.h> 
    34 #include <gadget/Util/DeviceSerializationTokens.h> 
    3539 
    3640 
     
    229233// This returns a value that is normalized to [0,1] 
    230234// if n < mMin or n > mMax, then result = mMin or mMax respectively. 
    231 void Analog::normalizeMinToMax(const float& plainJaneValue, 
    232                                float& normedFromMinToMax) 
    233 
    234    float value = plainJaneValue; 
    235  
    236    // first clamp the value so that min<=value<=max 
    237    if ( value < mMin ) value = mMin; 
    238    if ( value > mMax ) value = mMax; 
    239  
    240    // slide everything to 0.0 (subtract all by mMin) 
    241    // Then divide by max to get normalized value 
    242    float tmax( mMax - mMin), 
    243          tvalue(value - mMin); 
    244  
    245    // since [tmin/tmax...tmax/tmax] == [0.0f...1.0f], the normalized value will be value/tmax 
    246    normedFromMinToMax = tvalue / tmax; 
    247 
    248  
    249 float Analog::getMin() const 
    250 
    251    return mMin; 
    252 
    253  
    254 float Analog::getMax() const 
    255 
    256    return mMax; 
    257 
    258  
    259 void Analog::setMin(float mIn) 
    260 
    261    mMin = mIn; 
    262 
    263  
    264 void Analog::setMax(float mAx) 
    265 
    266    mMax = mAx; 
     235float Analog::normalize(const float rawData) const 
     236
     237   float value(rawData); 
     238 
     239   // First, clamp the value so that min <= value <= max. 
     240   const float min_value(getMin()); 
     241   const float max_value(getMax()); 
     242   gmtl::Math::clamp(value, min_value, max_value); 
     243 
     244   // Slide everything to 0.0 (subtract all by min_value), and then divide 
     245   // by max to get normalized value. 
     246   const float tmax(max_value - min_value); 
     247   const float tvalue(value - min_value); 
     248 
     249   // since [tmin/tmax...tmax/tmax] == [0.0f...1.0f], the normalized value 
     250   // will be value/tmax 
     251   return tvalue / tmax; 
     252
     253 
     254void Analog::setMin(const float minValue) 
     255
     256   mMin = minValue; 
     257
     258 
     259void Analog::setMax(const float maxValue) 
     260
     261   mMax = maxValue; 
    267262} 
    268263 
  • juggler/trunk/modules/gadgeteer/gadget/Type/Analog.h

    r20603 r20970  
    5656 * received analog data.  This is similar to the additions made by 
    5757 * gadget::Position and gadget::Digital. 
     58 * 
     59 * @note To specify the min/max values for an anlog device, the required "min" 
     60 *       and "max" properties of a config elment type derived from "analog" 
     61 *       must be set. By default (i.e., if these values do not appear), "min" 
     62 *       and "max" are set to 0.0f and 1.0f respectively. 
     63 * 
     64 * @note For version 1.3.18 and newer, data normalization is performed in 
     65 *       gadget::AnalogProxy::updateData(). Analog device driver authors no 
     66 *       longer need to perform data normalization. 
    5867 * 
    5968 * @see Input, InputMixer 
     
    122131    * 
    123132    * @param devNum Device unit number to access. 
    124     * 
    125     * @note For example, if you are sampling a potentiometer, and it returns 
    126     *       reading from 0, 255.  This function will normalize those values 
    127     *       (using Analog::normalizeMinToMax()).  For another example, if 
    128     *       your potentiometer's turn radius is limited mechanically to return, 
    129     *       say, the values 176 to 200 (yes this is really low res), this 
    130     *       function will still return 0.0f to 1.0f. 
    131     * @note To specify these min/max values, you must set in your Analog (or 
    132     *       analog device) config file the field "min" and "max".  By default 
    133     *       (if these values do not appear), "min" and "max" are set to 0.0f 
    134     *       and 1.0f respectivly. 
    135     * @note TO ALL ANALOG DEVICE DRIVER WRITERS, you *must* normalize your 
    136     *       data using Analog::normalizeMinToMax(). 
    137133    */ 
    138134   AnalogData getAnalogData(int devNum = 0); 
     
    170166   } 
    171167 
     168   /** 
     169    * Given a value that will range from [min() <= n <= max()], this returns 
     170    * a value that is normalized to the range [0,1]. 
     171    * 
     172    * @param rawData A non-normalized data value read from this analog device. 
     173    * 
     174    * @return The normalized form of \p rawData in the range [0,1]. 
     175    * 
     176    * @note This method was renamed from normalizeMinToMax() (a protected 
     177    *       method) in version 1.3.18. Analog device drivers are no longer 
     178    *       responsible for normalizing data. Instead, that operation is 
     179    *       performed "on demand" either by a method such as 
     180    *       gadget::AnalogProxy::updateData() or as desired by user-level code 
     181    *       that retrieves the full analog sample buffer collection. 
     182    * 
     183    * @since 1.3.18 
     184    * 
     185    * @see getMin() 
     186    * @see setMin() 
     187    * @see getMax() 
     188    * @see setMax() 
     189    * @see getAnalogDataBuffer() 
     190    */ 
     191   float normalize(const float rawData) const; 
     192 
     193   /** 
     194    * @name Data Bounds Interface 
     195    * 
     196    * These methods can be used for data normalization. 
     197    */ 
     198   //@{ 
     199   float getMin() const 
     200   { 
     201      return mMin; 
     202   } 
     203 
     204   float getMax() const 
     205   { 
     206      return mMax; 
     207   } 
     208   //@} 
     209 
    172210protected: 
    173    /** 
    174     * Given a value that will range from [min() <= n <= max()]. 
    175     * This returns a value that is normalized to [0,1] 
    176     */ 
    177    void normalizeMinToMax(const float& plainJaneValue, 
    178                           float& normedFromMinToMax); 
    179  
    180 protected: 
    181    /** 
    182     * Gets the minimum "real" data value (real == from hardware). 
    183     * This value is used to normalize the return value of getAnalogData. 
    184     * @note this function is not needed by an application author. 
    185     */ 
    186    float getMin() const; 
    187    float getMax() const; 
    188    void setMin(float mIn); 
    189    void setMax(float mAx); 
     211   void setMin(const float minValue); 
     212   void setMax(const float maxValue); 
    190213 
    191214private: 
    192    float mMin, mMax
    193  
    194 private: 
     215   float mMin
     216   float mMax; 
     217 
    195218   SampleBuffer_t    mAnalogSamples;  /**< Position samples */ 
    196219   AnalogData        mDefaultValue;   /**< Default analog value to return */ 
  • juggler/trunk/modules/gadgeteer/gadget/Type/AnalogProxy.cpp

    r20966 r20970  
    3636   : TypedProxy<Analog>(deviceName) 
    3737   , mUnitNum(unitNum) 
    38    , mData(-1.0f) 
     38   , mRawData(-1.0f) 
     39   , mData(0.0f) 
    3940{ 
    4041   /* Do nothing. */ ; 
     
    5859      // Make sure dependencies are updated. 
    5960      getProxiedInputDevice()->updateDataIfNeeded(); 
    60       mData = mTypedDevice->getAnalogData(mUnitNum); 
     61 
     62      mRawData = mTypedDevice->getAnalogData(mUnitNum); 
     63      mData    = mTypedDevice->normalize(mRawData.getAnalog()); 
    6164   } 
    6265} 
     
    6972vpr::Interval AnalogProxy::getTimeStamp() const 
    7073{ 
    71    return mData.getTime(); 
     74   return mRawData.getTime(); 
    7275} 
    7376 
  • juggler/trunk/modules/gadgeteer/gadget/Type/AnalogProxy.h

    r20968 r20970  
    6767   virtual ~AnalogProxy(); 
    6868 
    69    /** Updates the cached data copy from the device. */ 
     69   /** 
     70    * Updates the cached data copy from the device and the normalized form of 
     71    * that data. 
     72    * 
     73    * @post \c mRawData holds the current raw data sample from the proxied 
     74    *       analog device. \c mData holds the current normalized data sample 
     75    *       from the proxied analog device. 
     76    */ 
    7077   virtual void updateData(); 
    7178 
     
    7481 
    7582   /** 
    76     * Gets the current analog data value. 
    77     * @return The analog data from the device. 
     83    * Gets the current normalized analog data value. This value will be in 
     84    * the range [0.0,1.0]. 
     85    * 
     86    * @return The normalized analog data from the device. 
    7887    */ 
    7988   float getData() const 
     89   { 
     90      return isStupefied() ? 0.0f : mData; 
     91   } 
     92 
     93   /** 
     94    * Gets the current raw analog data value. This is the value read direcctly 
     95    * from the device without perfomring any normalization. 
     96    * 
     97    * @return The raw analog data from the device. 
     98    * 
     99    * @since 1.3.18 
     100    */ 
     101   float getRawData() const 
    80102   { 
    81103      const float analogDefault(0.0f); 
     
    86108      else 
    87109      { 
    88          return mData.getAnalog(); 
     110         return mRawData.getAnalog(); 
    89111      } 
    90112   } 
     
    118140private: 
    119141   int         mUnitNum; 
    120    AnalogData  mData; 
     142   AnalogData  mRawData; 
     143   float       mData; 
    121144}; 
    122145