Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages | Examples

triadObserver.cpp

Go to the documentation of this file.
00001 //////////////////////////////////////////////////////////////////////////////////////////////////
00002 /*! \file triadObserver.cpp
00003 *  \brief Observes attitute with the triad algorithm
00004 *  \author $Author: jayhawk_hokie $
00005 *  \version $Revision: 1.6 $
00006 *  \date    $Date: 2007/08/31 16:08:01 $
00007 *//////////////////////////////////////////////////////////////////////////////////////////////////
00008 /*!
00009 */
00010 //////////////////////////////////////////////////////////////////////////////////////////////////
00011 
00012 
00013 #include "triadObserver.h"
00014 
00015 using namespace std;
00016 
00017 /*! \brief Default Constructor */
00018 triadObserver::triadObserver( )
00019 { 
00020         Initialize( );
00021 }
00022 
00023 /*! \brief Create a triad observer from XML handle and whorl object
00024  *  @param handle XML handle with current whorl as starting node
00025  *  @param ptr_whorl Pointer to a whorl object
00026  */
00027 triadObserver::triadObserver( TiXmlHandle handle, Whorl* ptr_whorl )
00028 {
00029         m_whorl = ptr_whorl;
00030         
00031         Initialize( );
00032 
00033         // call parse function to get inertial measurement vectors
00034         Parse( handle );
00035 }
00036 
00037 /*! \brief DeConstructor for triadObserver object */
00038 triadObserver::~triadObserver( )
00039 { }
00040 
00041 /*! \brief Initialize triad observer
00042 */
00043 int triadObserver::Initialize( )
00044 {
00045         m_magBody.initialize(3);
00046 
00047         m_2magBodyPrevious.initialize(3);
00048 
00049         m_accelBody.initialize(3);
00050         m_accelInertial.initialize(3);
00051         m_magInertial.initialize(3);
00052         m_ratesBody.initialize(3);
00053         m_AngularAccel.initialize(3);
00054 
00055         m_rsensor.initialize(3);
00056         
00057         return( 0 );
00058 }
00059 
00060 /*! \brief Parse inertial measurement vectors from configuration file
00061         * @param handle XML handle with current whorl as starting node
00062         */
00063 void triadObserver::Parse( TiXmlHandle handle ) 
00064 {
00065         int response;
00066 
00067         // create handles with magnetometer and accelerometer nodes as starting points
00068         TiXmlHandle accelElement =  handle.FirstChild( m_whorl->GetSimulatorName( ) ).FirstChild("HARDWARE_PROPERTIES").FirstChild("DMU_ACCELEROMETER");
00069         TiXmlHandle magElement = handle.FirstChild( m_whorl->GetSimulatorName( ) ).FirstChild("HARDWARE_PROPERTIES").FirstChild("MAGNETOMETER");        
00070 
00071 
00072         // get magnetometer inertial vector and normalize
00073         response = magElement.Child("INERTIAL_VECTOR", 0).Element() ->  QueryDoubleAttribute( "valueX", &(m_magInertial)(1) );
00074         checkResponse(response);
00075         response = magElement.Child("INERTIAL_VECTOR", 0).Element() ->  QueryDoubleAttribute( "valueY", &(m_magInertial)(2) );
00076         checkResponse(response);
00077         response = magElement.Child("INERTIAL_VECTOR", 0).Element() ->  QueryDoubleAttribute( "valueZ", &(m_magInertial)(3) );
00078         checkResponse(response);
00079 
00080         // Normalize magnetmeter inertial vector
00081         normalize( m_magInertial );
00082 
00083         // get accelerometer inertial vector and normalize
00084         response = accelElement.Child("INERTIAL_VECTOR", 0).Element() -> QueryDoubleAttribute( "valueX", &(m_accelInertial)(1) );
00085         checkResponse(response);
00086         response = accelElement.Child("INERTIAL_VECTOR", 0).Element() -> QueryDoubleAttribute( "valueY", &(m_accelInertial)(2) );
00087         checkResponse(response);
00088         response = accelElement.Child("INERTIAL_VECTOR", 0).Element() -> QueryDoubleAttribute( "valueZ", &(m_accelInertial)(3) );
00089         checkResponse(response);
00090 
00091         // Normalize accelerometer inertial vector
00092         normalize( m_accelInertial ); // [rad/s^2] 
00093 
00094         // get motion pak sensor radius
00095         for (int i=0;i<3;i++)
00096         {
00097                 response = handle.FirstChild( m_whorl->GetSimulatorName( ) ).FirstChild("PHYSICAL_PROPERTIES").FirstChild("SENSOR_RADIUS").Child("VECTOR",i)
00098                         .Element() -> QueryDoubleAttribute("value",&(m_rsensor)(i+1));  
00099                 checkResponse(response);
00100         }
00101 }
00102         
00103 /*! \brief Take measurements and update state vector in whorl object */
00104 int triadObserver::Run( )
00105 {
00106         //static double XaccelCorr, YaccelCorr, ZaccelCorr; // acceleration correction variables
00107         //static double rX = -14.25; // distance from center of rotation to motionpak sensors in inches (x-direction)
00108         DirectionCosineMatrix Rbi;
00109         Quaternion attitude;
00110         Vector correction(3);
00111         Vector state(7);  // state = [q_bar; q4; rates]
00112 
00113         /* since the magnetometer, accelerometers and rate gyros are all we're using for now, this function assumes their use
00114          and ONLY their use*/
00115 
00116         // get accelerometer reading
00117 
00118         (m_accelBody)(1) = m_whorl->GetAccelerometer("ACC_X")->GetMeasurement().GetAsDouble();
00119         (m_accelBody)(2) = m_whorl->GetAccelerometer("ACC_Y")->GetMeasurement().GetAsDouble();
00120         (m_accelBody)(3) = m_whorl->GetAccelerometer("ACC_Z")->GetMeasurement().GetAsDouble();
00121 
00122         // get magnetomter reading
00123 
00124         m_magBody = m_whorl->GetMagnetometer()->GetVectorMeasurement();
00125 
00126         if( fabs( norm2(m_magBody) - norm2(m_2magBodyPrevious) ) > 70 )
00127         {
00128                 m_magBody = m_whorl->GetMagnetometer()->GetVectorMeasurement();
00129                 m_2magBodyPrevious = m_magBody;
00130         }
00131         else
00132         {
00133                 m_2magBodyPrevious = m_magBody;
00134         }       
00135 
00136 
00137         // get rate gyro reading
00138 
00139         (m_ratesBody)(1) = m_whorl->GetRateGyro("RATE_GYRO_X")->GetMeasurement().GetAsDouble();
00140         (m_ratesBody)(2) = m_whorl->GetRateGyro("RATE_GYRO_Y")->GetMeasurement().GetAsDouble();
00141         (m_ratesBody)(3) = m_whorl->GetRateGyro("RATE_GYRO_Z")->GetMeasurement().GetAsDouble();
00142         
00143         // Have no sensor for determing angular acceleration. Need to Address this issue.
00144         Vector angularAcceleration(3);
00145 
00146         // Correct Acceleration vector due to rotation
00147         AccelerationCorrection( angularAcceleration, m_ratesBody, m_accelBody, m_rsensor );
00148 
00149         // perfrorm triad algorithm on measurements and extract quaternion
00150         Rbi = GetAttitude( );
00151 
00152         attitude = Rbi.GetQuaternion();
00153 
00154         // set state vector
00155         state(_(1,4)) = attitude;
00156         state(_(5,7)) = m_ratesBody;
00157 
00158         m_whorl->SetState( state );
00159 
00160         return 0;
00161 }
00162 
00163 /*! \brief Triad algorithm implementation (called from run function)
00164         * @return Rbi 3x3 Attitude matrix 
00165         */
00166 Matrix triadObserver::GetAttitude( )
00167 {
00168         
00169         Vector t1b(3), t2b(3), t3b(3), t1i(3), t2i(3), t3i(3); // triad vectors
00170         Matrix Rbt(3,3), Rti(3,3); //triad rotation matrices
00171         Matrix Rbi;     
00172         
00173         // normalize measurement vectors
00174         
00175         normalize( m_magBody );
00176         normalize( m_accelBody );
00177 
00178         // create triad vectors
00179 
00180         t1b = m_accelBody;
00181         t2b = crossP(t1b,m_magBody);    
00182         normalize(t2b);
00183         t3b = crossP(t1b,t2b); // does not need to be normalized since theta=90 deg
00184 
00185         
00186         t1i = m_accelInertial;
00187         t2i = crossP( t1i, m_magInertial );     
00188         normalize(t2i);
00189         t3i = crossP(t1i,t2i);
00190 
00191         // set triad rotation matrices
00192                 
00193         Rbt(_(1,3),_(1,1)) = t1b;
00194         Rbt(_(1,3),_(2,2)) = t2b;
00195         Rbt(_(1,3),_(3,3)) = t3b;
00196                 
00197         
00198         Rti(_(1,1),_(1,3)) = ~t1i;
00199         Rti(_(2,2),_(1,3)) = ~t2i;
00200         Rti(_(3,3),_(1,3)) = ~t3i;
00201         
00202         // set final Rbi matrix
00203          
00204         Rbi = Rbt*Rti;  
00205 
00206         return Rbi;
00207 }
00208 
00209 void triadObserver::SetMagnetometerBodyVector( Vector _magnetometer )
00210 {
00211         m_magBody = _magnetometer;
00212 }
00213 
00214 void triadObserver::SetMagnetometerInertialVector( Vector _magnetometer )
00215 {
00216         m_magInertial = _magnetometer;
00217 }
00218 
00219 void triadObserver::SetAccelerometerBodyVector( Vector _accelerometer )
00220 {
00221         m_accelBody = _accelerometer;
00222 }
00223 
00224 void triadObserver::SetAccelerometerInertialVector( Vector _accelerometer )
00225 {
00226         m_accelInertial = _accelerometer;
00227 }
00228 
00229 
00230 
00231 // Do not change the comments below - they will be added automatically by CVS
00232 /*****************************************************************************
00233 *       $Log: triadObserver.cpp,v $
00234 *       Revision 1.6  2007/08/31 16:08:01  jayhawk_hokie
00235 *       Modified.
00236 *
00237 *       Revision 1.5  2007/07/24 08:45:27  jayhawk_hokie
00238 *       Replaced matrix pointers.
00239 *
00240 *       Revision 1.4  2007/05/29 19:02:15  jayhawk_hokie
00241 *       *** empty log message ***
00242 *
00243 *       Revision 1.3  2007/03/27 19:15:44  jayhawk_hokie
00244 *       Updated Class.
00245 *
00246 *       Revision 1.2  2007/03/21 20:12:28  jayhawk_hokie
00247 *       Update of the Triad Observer Class
00248 *
00249 *       Revision 1.1  2007/01/12 22:11:57  bwilliam
00250 *       Initial submission.
00251 *
00252 ******************************************************************************/
00253 

Generated on Wed Sep 5 12:54:27 2007 for DSACSS Operational Code by  doxygen 1.3.9.1