inc/TrcAccel.h
author Michael Tsang <mikets@hotmail.com>
Sat Mar 27 19:25:50 2010 -0700 (2010-03-27)
changeset 144 e44126e46aee
parent 125 b32f2f1c281e
permissions -rw-r--r--
Fixed compile warning on unused local variables
     1 #if 0
     2 /// Copyright (c) Titan Robotics Club. All rights reserved.
     3 ///
     4 /// <module name="TrcAccel.h" />
     5 ///
     6 /// <summary>
     7 ///     This module contains the definition and implementation of the TrcAccel
     8 ///     class.
     9 /// </summary>
    10 ///
    11 /// <remarks>
    12 ///     Environment: Wind River C++ for National Instrument cRIO based Robot.
    13 /// </remarks>
    14 #endif
    15 
    16 #ifndef _TRCACCEL_H
    17 #define _TRCACCEL_H
    18 
    19 #ifdef MOD_ID
    20     #undef MOD_ID
    21 #endif
    22 #define MOD_ID                  MOD_ACCEL
    23 #ifdef MOD_NAME
    24     #undef MOD_NAME
    25 #endif
    26 #define MOD_NAME                "TrcAccel"
    27 
    28 //
    29 // 50 calibration points at 20ms each will cost us a total of 1 second start
    30 // up time.
    31 //
    32 #ifndef ACCEL_NUM_CAL_PTS
    33     #define ACCEL_NUM_CAL_PTS           50
    34 #endif
    35 #ifndef ACCEL_CAL_INTERVAL
    36     #define ACCEL_CAL_INTERVAL          0.02    //20ms
    37 #endif
    38 #ifndef ACCEL_DEADBAND_THRESHOLD
    39     #define ACCEL_DEADBAND_THRESHOLD    0.01
    40 #endif
    41 
    42 /**
    43  * This class defines and implements the TrcAccel object. The TrcAccel object
    44  * inherits the ADXL345_I2C accelerometer object from the WPI library. This
    45  * object periodically sample the accelerometer value for the acceleration
    46  * value. It also integrates the acceleration value to calculate the velocity
    47  * and then integrates the velocity to calculate the distance value.
    48  */
    49 class TrcAccel: public ADXL345_I2C
    50 {
    51 private:
    52     SEM_ID      m_semaphore;
    53     Notifier   *m_notifier;
    54     AllAxes     m_accelData;
    55     AllAxes     m_offsetZeroG;
    56     double      m_velX;
    57     double      m_velY;
    58     double      m_velZ;
    59     double      m_distX;
    60     double      m_distY;
    61     double      m_distZ;
    62     bool        m_fEnabled;
    63     UINT32      m_timestamp;
    64     
    65     /**
    66      * This function is called periodically by the a timer callback to
    67      * process the accelerometer data. It integrates the data with time
    68      * to calculate the velocity, integrates it again to calculate
    69      * distance.
    70      */
    71     void
    72     Integrator(
    73         void
    74         )
    75     {
    76         TLevel(HIFREQ);
    77         TEnter();
    78 
    79         CRITICAL_REGION(m_semaphore)
    80         {
    81             if (m_fEnabled)
    82             {
    83                 UINT32 timeCurr = GetMsecTime();
    84                 float period = (float)(timeCurr - m_timestamp)/1000.0;
    85                 m_timestamp = timeCurr;
    86                 m_accelData = GetAccelerations();
    87                 m_accelData.XAxis -= m_offsetZeroG.XAxis;
    88                 m_accelData.YAxis -= m_offsetZeroG.YAxis;
    89                 m_accelData.ZAxis -= m_offsetZeroG.ZAxis;
    90                 m_accelData.XAxis = GRAVITY_CONSTANT*m_accelData.XAxis;
    91                 m_accelData.YAxis = GRAVITY_CONSTANT*m_accelData.YAxis;
    92                 m_accelData.ZAxis = GRAVITY_CONSTANT*m_accelData.ZAxis;
    93 #if 0
    94                 m_accelData.XAxis = GRAVITY_CONSTANT*
    95                                     DEADBAND(m_accelData.XAxis,
    96                                              ACCEL_DEADBAND_THRESHOLD);
    97                 m_accelData.YAxis = GRAVITY_CONSTANT*
    98                                     DEADBAND(m_accelData.YAxis,
    99                                              ACCEL_DEADBAND_THRESHOLD);
   100                 m_accelData.ZAxis = GRAVITY_CONSTANT*
   101                                     DEADBAND(m_accelData.ZAxis,
   102                                              ACCEL_DEADBAND_THRESHOLD);
   103 #endif
   104                 m_velX += m_accelData.XAxis*period;
   105                 m_velY += m_accelData.YAxis*period;
   106                 m_velZ += m_accelData.ZAxis*period;
   107                 m_distX += m_velX*period;
   108                 m_distY += m_velY*period;
   109                 m_distZ += m_velZ*period;
   110                 TSampling(("X(%f,%f,%f), Y(%f,%f,%f), Z(%f,%f,%f)",
   111                            m_accelData.XAxis*FEET_PER_METER,
   112                            m_velX*FEET_PER_METER,
   113                            m_distX*FEET_PER_METER,
   114                            m_accelData.YAxis*FEET_PER_METER,
   115                            m_velY*FEET_PER_METER,
   116                            m_distY*FEET_PER_METER,
   117                            m_accelData.ZAxis*FEET_PER_METER,
   118                            m_velZ*FEET_PER_METER,
   119                            m_distZ*FEET_PER_METER));
   120             }
   121         }
   122         END_REGION;
   123 
   124         TExit();
   125     }   //Integrator
   126 
   127     /**
   128      * This function is called when the timer expired. It will call the
   129      * non-static worker function.
   130      *
   131      * @param timer Points to the TrcAccel object to call the worker function.
   132      */
   133     static
   134     void
   135     CallIntegrator(
   136         __in void *accel
   137         )
   138     {
   139         TLevel(HIFREQ);
   140         TEnterMsg(("accel=%p", accel));
   141         ((TrcAccel *)accel)->Integrator();
   142         TExit();
   143     }   //CallIntegrator
   144 
   145 public:
   146     /**
   147      * Constructor: Create an instance of the TrcAccel object. It initializes
   148      * the object and starts the periodic timer.
   149      *
   150      * @param slot Specifies the slot of the digital module on which the I2C
   151      *        port is used for the accelerometer.
   152      * @param period Specifies the sampling time for doing calculations. This
   153      *        period is used to integrate acceleration into speed and distance
   154      *        travelled.
   155      */
   156     TrcAccel(
   157         __in UINT32 slot,
   158         __in float  period = 0.02
   159         ): ADXL345_I2C(slot)
   160     {
   161         TLevel(INIT);
   162         TEnterMsg(("slot=%d,period=%f", slot, period));
   163 
   164         m_semaphore = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
   165         m_notifier = new Notifier(TrcAccel::CallIntegrator, this);
   166         m_accelData.XAxis = 0.0;
   167         m_accelData.YAxis = 0.0;
   168         m_accelData.ZAxis = 0.0;
   169         m_offsetZeroG.XAxis = 0.0;
   170         m_offsetZeroG.YAxis = 0.0;
   171         m_offsetZeroG.ZAxis = 0.0;
   172         m_velX = 0.0;
   173         m_velY = 0.0;
   174         m_velZ = 0.0;
   175         m_distX = 0.0;
   176         m_distY = 0.0;
   177         m_distZ = 0.0;
   178         m_fEnabled = false;
   179         m_notifier->StartPeriodic(period);
   180 
   181         TExit();
   182     }   //TrcAccel
   183 
   184     /**
   185      * Destructor: Destroy an instance of the TrcAccel object.
   186      */
   187     ~TrcAccel(
   188         void
   189         )
   190     {
   191         TLevel(INIT);
   192         TEnter();
   193 
   194         semFlush(m_semaphore);
   195         SAFE_DELETE(m_notifier);
   196 
   197         TExit();
   198     }   //~TrcAccel
   199 
   200     /**
   201      * This function returns the current acceleration value of the X axis in
   202      * the unit of meters per second square.
   203      *
   204      * @return Returns the X acceleration value.
   205      */
   206     double
   207     GetMetricAccelX(
   208         void
   209         )
   210     {
   211         TLevel(HIFREQ);
   212         TEnter();
   213         TExitMsg(("=%f", m_accelData.XAxis));
   214         return m_accelData.XAxis;
   215     }   //GetMetricAccelX
   216 
   217     /**
   218      * This function returns the current acceleration value of the X axis in
   219      * the unit of feet per second square.
   220      *
   221      * @return Returns the X acceleration value.
   222      */
   223     double
   224     GetAccelX(
   225         void
   226         )
   227     {
   228         TLevel(HIFREQ);
   229         TEnter();
   230         double value = m_accelData.XAxis*FEET_PER_METER;
   231         TExitMsg(("=%f", value));
   232         return value;
   233     }   //GetAccelX
   234 
   235     /**
   236      * This function returns the current acceleration value of the Y axis in
   237      * the unit of meters per second square.
   238      *
   239      * @return Returns the Y acceleration value.
   240      */
   241     double
   242     GetMetricAccelY(
   243         void
   244         )
   245     {
   246         TLevel(HIFREQ);
   247         TEnter();
   248         TExitMsg(("=%f", m_accelData.YAxis));
   249         return m_accelData.YAxis;
   250     }   //GetMetricAccelY
   251 
   252     /**
   253      * This function returns the current acceleration value of the Y axis in
   254      * the unit of feet per second square.
   255      *
   256      * @return Returns the Y acceleration value.
   257      */
   258     double
   259     GetAccelY(
   260         void
   261         )
   262     {
   263         TLevel(HIFREQ);
   264         TEnter();
   265         double value = m_accelData.YAxis*FEET_PER_METER;
   266         TExitMsg(("=%f", value));
   267         return value;
   268     }   //GetAccelY
   269 
   270     /**
   271      * This function returns the current acceleration value of the Z axis in
   272      * the unit of meters per second square.
   273      *
   274      * @return Returns the Z acceleration value.
   275      */
   276     double
   277     GetMetricAccelZ(
   278         void
   279         )
   280     {
   281         TLevel(HIFREQ);
   282         TEnter();
   283         TExitMsg(("=%f", m_accelData.ZAxis));
   284         return m_accelData.ZAxis;
   285     }   //GetMetricAccelZ
   286 
   287     /**
   288      * This function returns the current acceleration value of the Z axis in
   289      * the unit of feet per second square.
   290      *
   291      * @return Returns the Z acceleration value.
   292      */
   293     double
   294     GetAccelZ(
   295         void
   296         )
   297     {
   298         TLevel(HIFREQ);
   299         TEnter();
   300         double value = m_accelData.ZAxis*FEET_PER_METER;
   301         TExitMsg(("=%f", value));
   302         return value;
   303     }   //GetAccelZ
   304 
   305     /**
   306      * This function returns the current velocity value of the X axis in
   307      * the unit of meters per second.
   308      *
   309      * @return Returns the X velocity value.
   310      */
   311     double
   312     GetMetricVelX(
   313         void
   314         )
   315     {
   316         TLevel(HIFREQ);
   317         TEnter();
   318         TExitMsg(("=%f", m_velX));
   319         return m_velX;
   320     }   //GetMetricVelX
   321 
   322     /**
   323      * This function returns the current velocity value of the X axis in
   324      * the unit of feet per second.
   325      *
   326      * @return Returns the X velocity value.
   327      */
   328     double
   329     GetVelX(
   330         void
   331         )
   332     {
   333         TLevel(HIFREQ);
   334         TEnter();
   335         double value = m_velX*FEET_PER_METER;
   336         TExitMsg(("=%f", value));
   337         return value;
   338     }   //GetVelX
   339 
   340     /**
   341      * This function returns the current velocity value of the Y axis in
   342      * the unit of meters per second.
   343      *
   344      * @return Returns the Y velocity value.
   345      */
   346     double
   347     GetMetricVelY(
   348         void
   349         )
   350     {
   351         TLevel(HIFREQ);
   352         TEnter();
   353         TExitMsg(("=%f", m_velY));
   354         return m_velY;
   355     }   //GetMetricVelY
   356 
   357     /**
   358      * This function returns the current velocity value of the Y axis in
   359      * the unit of feet per second.
   360      *
   361      * @return Returns the Y velocity value.
   362      */
   363     double
   364     GetVelY(
   365         void
   366         )
   367     {
   368         TLevel(HIFREQ);
   369         TEnter();
   370         double value = m_velY*FEET_PER_METER;
   371         TExitMsg(("=%f", value));
   372         return value;
   373     }   //GetVelY
   374 
   375     /**
   376      * This function returns the current velocity value of the Z axis in
   377      * the unit of meters per second.
   378      *
   379      * @return Returns the Z velocity value.
   380      */
   381     double
   382     GetMetricVelZ(
   383         void
   384         )
   385     {
   386         TLevel(HIFREQ);
   387         TEnter();
   388         TExitMsg(("=%f", m_velZ));
   389         return m_velZ;
   390     }   //GetMetricVelZ
   391 
   392     /**
   393      * This function returns the current velocity value of the Z axis in
   394      * the unit of feet per second.
   395      *
   396      * @return Returns the Z velocity value.
   397      */
   398     double
   399     GetVelZ(
   400         void
   401         )
   402     {
   403         TLevel(HIFREQ);
   404         TEnter();
   405         double value = m_velZ*FEET_PER_METER;
   406         TExitMsg(("=%f", value));
   407         return value;
   408     }   //GetVelZ
   409 
   410     /**
   411      * This function returns the current distance value of the X axis in
   412      * the unit of meters.
   413      *
   414      * @return Returns the X distance value.
   415      */
   416     double
   417     GetMetricDistX(
   418         void
   419         )
   420     {
   421         TLevel(HIFREQ);
   422         TEnter();
   423         TExitMsg(("=%f", m_distX));
   424         return m_distX;
   425     }   //GetMetricDistX
   426 
   427     /**
   428      * This function returns the current distance value of the X axis in
   429      * the unit of feet.
   430      *
   431      * @return Returns the X distance value.
   432      */
   433     double
   434     GetDistX(
   435         void
   436         )
   437     {
   438         TLevel(HIFREQ);
   439         TEnter();
   440         double value = m_distX*FEET_PER_METER;
   441         TExitMsg(("=%f", value));
   442         return value;
   443     }   //GetDistX
   444 
   445     /**
   446      * This function returns the current distance value of the Y axis in
   447      * the unit of meters.
   448      *
   449      * @return Returns the Y distance value.
   450      */
   451     double
   452     GetMetricDistY(
   453         void
   454         )
   455     {
   456         TLevel(HIFREQ);
   457         TEnter();
   458         TExitMsg(("=%f", m_distY));
   459         return m_distY;
   460     }   //GetMetricDistY
   461 
   462     /**
   463      * This function returns the current distance value of the Y axis in
   464      * the unit of feet.
   465      *
   466      * @return Returns the Y distance value.
   467      */
   468     double
   469     GetDistY(
   470         void
   471         )
   472     {
   473         TLevel(HIFREQ);
   474         TEnter();
   475         double value = m_distY*FEET_PER_METER;
   476         TExitMsg(("=%f", value));
   477         return value;
   478     }   //GetDistY
   479 
   480     /**
   481      * This function returns the current distance value of the Z axis in
   482      * the unit of meters.
   483      *
   484      * @return Returns the Z distance value.
   485      */
   486     double
   487     GetMetricDistZ(
   488         void
   489         )
   490     {
   491         TLevel(HIFREQ);
   492         TEnter();
   493         TExitMsg(("=%f", m_distZ));
   494         return m_distZ;
   495     }   //GetMetricDistZ
   496 
   497     /**
   498      * This function returns the current distance value of the Z axis in
   499      * the unit of feet.
   500      *
   501      * @return Returns the Z distance value.
   502      */
   503     double
   504     GetDistZ(
   505         void
   506         )
   507     {
   508         TLevel(HIFREQ);
   509         TEnter();
   510         double value = m_distZ*FEET_PER_METER;
   511         TExitMsg(("=%f", value));
   512         return value;
   513     }   //GetDistZ
   514 
   515     /**
   516      * This function resets the acceleration, velocity and distance values.
   517      */
   518     void
   519     Reset(
   520         void
   521         )
   522     {
   523         TLevel(API);
   524         TEnter();
   525 
   526         CRITICAL_REGION(m_semaphore)
   527         {
   528             m_accelData.XAxis = 0.0;
   529             m_accelData.YAxis = 0.0;
   530             m_accelData.ZAxis = 0.0;
   531             m_velX = 0.0;
   532             m_velY = 0.0;
   533             m_velZ = 0.0;
   534             m_distX = 0.0;
   535             m_distY = 0.0;
   536             m_distZ = 0.0;
   537         }
   538         END_REGION;
   539 
   540         TExit();
   541     }   //Reset
   542 
   543     /**
   544      * This function sets the accelerometer to enable or disable state.
   545      *
   546      * @param fEnabled If true, enables the accelerometer, false otherwise.
   547      */
   548     void
   549     SetEnabled(
   550         __in bool fEnabled
   551         )
   552     {
   553         TLevel(API);
   554         TEnter();
   555 
   556         m_fEnabled = fEnabled;
   557         if (fEnabled)
   558         {
   559             Reset();
   560             m_timestamp = GetMsecTime();
   561         }
   562 
   563         TExit();
   564     }   //SetEnabled
   565 
   566     /**
   567      * This function is called to calibrate the zero G point. It assumes the
   568      * accelerometer is sitting still at level ground during the calibration.
   569      * It samples a number of points on all axes and averages them to be the
   570      * zero G point for the axes. Note that the Z-axis is not really at zero G
   571      * when it is still. Z-axis should be 1G at level ground. But for the
   572      * purpose of measuring relative G's on all axes, we calibrate zero G for
   573      * all axes.
   574      */
   575     void
   576     CalibrateZeroG(
   577         void
   578         )
   579     {
   580         AllAxes data;
   581         AllAxes zeroG;
   582         TLevel(INIT);
   583         TEnter();
   584 
   585         zeroG.XAxis = 0.0;
   586         zeroG.YAxis = 0.0;
   587         zeroG.YAxis = 0.0;
   588         for (UINT32 i = 0; i < ACCEL_NUM_CAL_PTS; i++)
   589         {
   590             data = GetAccelerations();
   591             zeroG.XAxis += data.XAxis;
   592             zeroG.YAxis += data.YAxis;
   593             zeroG.ZAxis += data.ZAxis;
   594             Wait(ACCEL_CAL_INTERVAL);
   595         }
   596 
   597         CRITICAL_REGION(m_semaphore)
   598         {
   599             m_offsetZeroG.XAxis = zeroG.XAxis/ACCEL_NUM_CAL_PTS;
   600             m_offsetZeroG.YAxis = zeroG.YAxis/ACCEL_NUM_CAL_PTS;
   601             m_offsetZeroG.ZAxis = zeroG.ZAxis/ACCEL_NUM_CAL_PTS;
   602             TInfo(("AccelZeroG:x=%f,y=%f,z=%f",
   603                    m_offsetZeroG.XAxis, m_offsetZeroG.YAxis,
   604                    m_offsetZeroG.ZAxis));
   605         }
   606         END_REGION;
   607 
   608         Reset();
   609 
   610         TExit();
   611     }   //CalibrateZeroG
   612 };  //class TrcAccel
   613 
   614 #endif  //ifndef _TRCACCEL_H