Changeset 20891

Show
Ignore:
Timestamp:
11/06/07 07:23:41 (1 year ago)
Author:
dshipton
Message:

MFT r20886: Intersense API Fixes
- Fixes a configuration error where we send the configuration to the tracker

without it being opened yet.

- Fixes problems where other softwares would put the IS-900 in a different state

than our driver expected. (boresight fix)

- Fixes and uses Quaternions by default. If quaternions are not available

then Euler angles are used.

- Increased sample rate and added code for getting rid of the

control thread sleep.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • juggler/branches/2.2/modules/gadgeteer/drivers/Intersense/IntersenseAPI/IntersenseAPI.cpp

    r20429 r20891  
    127127void IntersenseAPI::controlLoop() 
    128128{ 
    129    // Loop through and keep sampling until stopSampleing is called. 
     129   // Loop through and keep sampling until stopSampling is called. 
    130130   while(!mDone) 
    131131   { 
    132132      this->sample(); 
    133       //TODO: Find a way to eliminate this sleep. If I rememeber correctly it 
    134       //      was added because the CPU was getting pegged too fast with samples 
    135       //      since there was no I/O wait because we are simply querying the 
    136       //      ISense library. 
    137       vpr::System::msleep(50); 
     133      //TODO: Find a way to eliminate this sleep. Currently, the CPU is 
     134      //      pegged aquiring samples since there was no I/O wait because 
     135      //      we are simply querying the ISense library. 
     136      //      Note: This sleep was 50ms but 10ms is more reasonable given 
     137      //      the records/sec IS-900 can return. 
     138      vpr::System::msleep(10); 
    138139   } 
    139140} 
     
    141142bool IntersenseAPI::startSampling() 
    142143{ 
    143    // Configure the stations used by the configuration 
    144    for( unsigned int i = 0; i < mStations.size(); ++i ) 
    145    { 
    146       int station_index = mStations[i].stationIndex; 
    147  
    148       // Load the config state from the physical tracker 
    149       mTracker.loadConfigState(station_index); 
    150       mTracker.setState(station_index, mStations[i].enabled); 
    151       mTracker.setAngleFormat(station_index, ISD_EULER); 
    152       mTracker.setInputs(station_index, 
    153                          mStations[i].useDigital || mStations[i].useAnalog); 
    154       // Save the config state to the physical tracker. 
    155       mTracker.saveConfigState(station_index); 
    156    } 
    157  
    158144   // Ensure that we have not already started sampling. 
    159145   if (this->isActive() == true) 
     
    184170         << "failed to connect to tracker.\n" << vprDEBUG_FLUSH; 
    185171      return false; 
     172   } 
     173 
     174   // Configure the stations used by the configuration 
     175   for( unsigned int i = 0; i < mStations.size(); ++i ) 
     176   { 
     177      int station_index = mStations[i].stationIndex; 
     178      // Reset any boresight being used by trackd or ICIDO 
     179      // This makes a call to the tracker and is not simply setting 
     180      // state on a var to configure the tracker with as done below. 
     181      mTracker.resetStationBoresight(station_index); 
     182      // Load the config state from the physical tracker 
     183      mTracker.loadConfigState(station_index); 
     184      mTracker.setState(station_index, mStations[i].enabled); 
     185      mTracker.setInputs(station_index, 
     186                         mStations[i].useDigital || mStations[i].useAnalog); 
     187      mTracker.setTimeStamped( station_index, false ); 
     188      mTracker.setDefaultCoordFrame( station_index ); 
     189 
     190      // Save the config state to the physical tracker. 
     191      if ( ! mTracker.saveConfigState(station_index) ) 
     192      { 
     193         vprDEBUG(vprDBG_ERROR,vprDBG_CRITICAL_LVL) 
     194            << clrOutNORM(clrRED,"ERROR:") 
     195            << " [gadget::IntersenseAPI::startSampling()] mTracker.saveConfigState() " 
     196            << "failed to save config state to station " << i << ".\n" 
     197            << vprDEBUG_FLUSH; 
     198 
     199         mTracker.close(); 
     200         return false; 
     201      } 
     202 
     203      //Try to get output in quat form otherwise fallback on euler angles 
     204      mTracker.setAngleFormat(station_index, ISD_QUATERNION); 
     205      if ( ! mTracker.saveConfigState(station_index) ) 
     206      { 
     207         // Failed to set quaternion format which means it is set for euler 
     208         mTracker.setAngleFormat(station_index, ISD_EULER); 
     209      } 
    186210   } 
    187211 
     
    219243   } 
    220244 
     245   // Check to see if we have new data to pull 
     246   if ( ! mTracker.updateData() ) 
     247   { 
     248       vprDEBUG(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL) 
     249         << clrOutBOLD(clrRED, "[gadget::IntersenseAPI::sample()]") 
     250         << ": Could not read data from InterSense API driver!\n" 
     251         << vprDEBUG_FLUSH; 
     252      return false; 
     253   } 
     254 
     255 
     256// This is the some code for the beginnings of trying to eliminate  
     257// the sleep in the control loop. Needs more testing. 
     258/* 
     259   bool has_new_data(false); 
     260   for ( unsigned int i = 0 ; i < mStations.size() ; ++i ) 
     261   { 
     262      // Make sure station is enabled and tracker has updated data. 
     263      if( mStations[i].enabled && mTracker.hasData(mStations[i].stationIndex) ) 
     264      { 
     265         has_new_data = true; 
     266         break; 
     267      } 
     268   } 
     269 
     270   // If there wasn't any new data then reliquish control to the cpu and return 
     271   if( ! has_new_data ) 
     272   { 
     273      vpr::Thread::yield(); 
     274      vpr::System::msleep(10); 
     275   } 
     276*/ 
     277 
    221278   // Create the data buffers to put the new data into. 
    222279   std::vector<gadget::PositionData> cur_pos_samples(mStations.size()); 
     
    224281   std::vector<gadget::AnalogData>   cur_analog_samples; 
    225282 
    226  
    227283   // get an initial timestamp for this entire sample. we'll copy it into 
    228284   // each PositionData for this sample. 
     
    232288   } 
    233289 
    234    mTracker.updateData(); 
    235  
    236    vpr::Thread::yield(); 
    237  
    238290   for ( unsigned int i = 0 ; i < mStations.size() ; ++i ) 
    239291   { 
     
    241293      int stationIndex = mStations[i].stationIndex; 
    242294 
     295 
    243296      // Set the time of each PositionData to match the first. 
    244297      cur_pos_samples[i].setTime( cur_pos_samples[0].getTime() ); 
    245298 
     299      // Don't process data from disabled stations 
     300      if( ! mStations[i].enabled ) 
     301      { 
     302         continue; 
     303      } 
     304 
     305      gmtl::identity(cur_pos_samples[i].mPosData); 
    246306      // If the Intersense is returning data in Euler format. Otherwise we 
    247307      // assume that it is returning data in quaternion format. 
    248308      if ( mTracker.getAngleFormat(stationIndex) == ISD_EULER ) 
    249309      { 
    250          gmtl::identity(cur_pos_samples[i].mPosData); 
    251310         gmtl::EulerAngleZYXf euler( gmtl::Math::deg2Rad( mTracker.zRot( stationIndex ) ), 
    252311                                     gmtl::Math::deg2Rad( mTracker.yRot( stationIndex ) ), 
    253312                                     gmtl::Math::deg2Rad( mTracker.xRot( stationIndex ) ) ); 
    254313         gmtl::setRot( cur_pos_samples[i].mPosData, euler ); 
    255          gmtl::setTrans( cur_pos_samples[i].mPosData, 
    256                          gmtl::Vec3f(mTracker.xPos( stationIndex ), 
    257                                      mTracker.yPos( stationIndex ), 
    258                                      mTracker.zPos( stationIndex )) ); 
    259314      } 
    260315      else 
     
    264319                               mTracker.zQuat( stationIndex ), 
    265320                               mTracker.wQuat( stationIndex )); 
    266          gmtl::set( cur_pos_samples[i].mPosData, quatValue ); 
    267       } 
     321         gmtl::setRot( cur_pos_samples[i].mPosData, quatValue ); 
     322      } 
     323 
     324      gmtl::setTrans( cur_pos_samples[i].mPosData, 
     325                      gmtl::Vec3f(mTracker.xPos( stationIndex ), 
     326                                  mTracker.yPos( stationIndex ), 
     327                                  mTracker.zPos( stationIndex )) ); 
    268328 
    269329      // We start at the index of the first digital item (set in the config 
     
    299359   addDigitalSample(cur_digital_samples); 
    300360   addPositionSample(cur_pos_samples); 
    301  
    302361   return true; 
    303362} 
  • juggler/branches/2.2/modules/gadgeteer/drivers/Intersense/IntersenseAPI/IntersenseAPIStandalone.h

    r19894 r20891  
    116116   /** 
    117117    * Returns the format of the angles.  
    118     * (0 == ISD_EULER; 1 == ISD_QUATERNION) 
     118    * (1 == ISD_EULER; 2 == ISD_QUATERNION) 
    119119    */ 
    120120   int getAngleFormat(const unsigned int currentStation) const  
     
    140140   } 
    141141 
    142    ///////////// 
    143    // 
    144     
    145142   /** 
    146143    * Return if the Station is ON or OFF. 
     
    148145   void setState(const unsigned int currentStation, const bool state) 
    149146   { 
    150       mConfigData[currentStation].State = state
     147      mConfigData[currentStation].State = (state ? TRUE : FALSE)
    151148   } 
    152149 
     
    187184 
    188185   /** 
    189     * Returns the format of the angles.  
    190     * (0 == ISD_EULER; 1 == ISD_QUATERNION) 
     186    * Sets the format of the angles.  
     187    * (1 == ISD_EULER; 2 == ISD_QUATERNION) 
    191188    */ 
    192189   void setAngleFormat(const unsigned int currentStation, 
     
    197194 
    198195   /** 
    199     * Return whether the station should send time stamps or not. 
     196    * Sets whether the station should send time stamps or not. 
    200197    */ 
    201198   void setTimeStamped(const unsigned int currentStation, 
    202199                       const bool timeStamped) 
    203200   { 
    204       mConfigData[currentStation].TimeStamped = timeStamped
     201      mConfigData[currentStation].TimeStamped = (timeStamped ? TRUE : FALSE)
    205202   } 
    206203 
     
    211208   void setInputs(const unsigned int currentStation, const bool hasInputs) 
    212209   { 
    213       mConfigData[currentStation].GetInputs = hasInputs
     210      mConfigData[currentStation].GetInputs = (hasInputs ? TRUE : FALSE)
    214211   } 
    215212 
     
    270267    * Save the current configuration state to the physical tracker device. 
    271268    */ 
    272    void saveConfigState(const int d) 
    273    { 
    274       ISD_SetStationConfig( mHandle, &mConfigData[d], d+1, mVerbose ); 
     269   bool saveConfigState(const int d) 
     270   { 
     271      if( ISD_SetStationConfig( mHandle, &mConfigData[d], d+1, (mVerbose ? TRUE : FALSE) ) ) 
     272      { 
     273         return true; 
     274      } 
     275      return false; 
     276   } 
     277 
     278   /** 
     279    * Reset the tracking station's boresight. 
     280    */ 
     281   bool resetStationBoresight(const int d) 
     282   { 
     283      if ( ISD_Boresight( mHandle, d+1, FALSE ) ) 
     284      { 
     285         return true; 
     286      } 
     287      return false; 
     288   } 
     289 
     290   /** 
     291    * Sets the default coordinate system for the respective station. 
     292    */ 
     293   void setDefaultCoordFrame(const unsigned int currentStation) 
     294   { 
     295       /* set frame to default */ 
     296       mConfigData[currentStation].CoordFrame = ISD_DEFAULT_FRAME; 
     297   } 
     298 
     299   /** 
     300    * Check to see if we have new data for the i'th receiver. 
     301    */ 
     302   bool hasData(const unsigned int i) const 
     303   { 
     304     if ( mData.Station[i].NewData ) 
     305     { 
     306        return true; 
     307     } 
     308     return false; 
    275309   } 
    276310 
     
    328362   float xQuat(const unsigned int i) const 
    329363   { 
     364      return mData.Station[i].Orientation[1]; 
     365   } 
     366 
     367   /** 
     368    * Gets the y quaternion value of the i'th receiver.  
     369    */ 
     370   float yQuat(const unsigned int i) const 
     371   { 
     372      return mData.Station[i].Orientation[2]; 
     373   } 
     374 
     375   /** 
     376    * Gets the z quaternion value of the i'th receiver.  
     377    */ 
     378   float zQuat(const unsigned int i) const 
     379   { 
     380      return mData.Station[i].Orientation[3]; 
     381   } 
     382 
     383   /** 
     384    * Gets the w quaternion value of the i'th receiver.  
     385    */ 
     386   float wQuat(const unsigned int i) const 
     387   { 
    330388      return mData.Station[i].Orientation[0]; 
    331    } 
    332  
    333    /** 
    334     * Gets the y quaternion value of the i'th receiver.  
    335     */ 
    336    float yQuat(const unsigned int i) const 
    337    { 
    338       return mData.Station[i].Orientation[1]; 
    339    } 
    340  
    341    /** 
    342     * Gets the z quaternion value of the i'th receiver.  
    343     */ 
    344    float zQuat(const unsigned int i) const 
    345    { 
    346       return mData.Station[i].Orientation[2]; 
    347    } 
    348  
    349    /** 
    350     * Gets the w quaternion value of the i'th receiver.  
    351     */ 
    352    float wQuat(const unsigned int i) const 
    353    { 
    354       return mData.Station[i].Orientation[3]; 
    355389   } 
    356390