trclib/TrcGyro.h
author Michael Tsang
Sat Feb 05 16:24:20 2011 -0800 (2011-02-05)
changeset 40 ea68beef9fd9
permissions -rw-r--r--
Cleaned up
     1 #if 0
     2 /// Copyright (c) Titan Robotics Club. All rights reserved.
     3 ///
     4 /// <module name="TrcGyro.h" />
     5 ///
     6 /// <summary>
     7 ///     This module contains the definition and implementation of the TrcGyro
     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 _TRCGYRO_H
    17 #define _TRCGYRO_H
    18 
    19 #ifdef MOD_ID
    20     #undef MOD_ID
    21 #endif
    22 #define MOD_ID                  MOD_GYRO
    23 #ifdef MOD_NAME
    24     #undef MOD_NAME
    25 #endif
    26 #define MOD_NAME                "TrcGyro"
    27 
    28 #define PIDMODE_ANGLE           0
    29 #define PIDMODE_VELOCITY        1
    30 #define PIDMODE_ACCELERATION    2
    31 
    32 /**
    33  * This class defines and implements the TrcGyro object. This object inherits
    34  * the Gyro object from the WPI library. It added the support of providing
    35  * angular velocity as well as angular acceleration information which is
    36  * missing from the Gyro class in the WPI library.
    37  */
    38 class TrcGyro: public Gyro
    39 {
    40 private:
    41     float       m_period;
    42     SEM_ID      m_semaphore;
    43     Notifier   *m_notifier;
    44     float       m_angle;
    45     float       m_angularVelocity;
    46     float       m_angularAcceleration;
    47     UINT32      m_modePID;
    48 
    49     /**
    50      * This function is called periodically by the a timer callback to process
    51      * the gyro data. It differentiate the angle with time to calculate the
    52      * angular velocity, differentiates it again to calculate angular
    53      * acceleration.
    54      */
    55     void
    56     Differentiator(
    57         void
    58         )
    59     {
    60         TLevel(HIFREQ);
    61         TEnter();
    62 
    63         CRITICAL_REGION(m_semaphore)
    64         {
    65             float prevAngle = m_angle;
    66             float prevVelocity = m_angularVelocity;
    67             m_angle = GetAngle();
    68             m_angularVelocity = (m_angle - prevAngle)/m_period;
    69             m_angularAcceleration = (m_angularVelocity - prevVelocity)/
    70                                     m_period;
    71             TSampling(("angle=%f,anglevel=%f,angleaccel=%f",
    72                        m_angle, m_angularVelocity, m_angularAcceleration));
    73         }
    74         END_REGION;
    75 
    76         TExit();
    77     }   //Differentiator
    78 
    79     /**
    80      * This function is called when the timer expired. It will call the
    81      * non-static worker function.
    82      *
    83      * @param timer Points to the TrcGyro object to call the worker function.
    84      */
    85     static
    86     void
    87     CallDifferentiator(
    88         __in void *gyro
    89         )
    90     {
    91         TLevel(HIFREQ);
    92         TEnterMsg(("gyro=%p", gyro));
    93         ((TrcGyro *)gyro)->Differentiator();
    94         TExit();
    95     }   //CallDifferentiator
    96 
    97     /**
    98      * This function does the common initialization of the TrcGyro object.
    99      */
   100     void
   101     GyroInit(
   102         void
   103         )
   104     {
   105         TLevel(INIT);
   106         TEnter();
   107 
   108         m_semaphore = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
   109         m_notifier = new Notifier(TrcGyro::CallDifferentiator, this);
   110         m_angle = GetAngle();
   111         m_angularVelocity = 0.0;
   112         m_angularAcceleration = 0.0;
   113         m_modePID = PIDMODE_ANGLE;
   114         m_notifier->StartPeriodic(m_period);
   115 
   116         TExit();
   117     }   //GyroInit
   118 
   119 public:
   120     /**
   121      * Constructor: Create an instance of the TrcGyro object. It initializes
   122      * the object and starts the periodic timer.
   123      *
   124      * @param slot Specifies the slot of the analog module.
   125      * @param channel Specifies the analog channel.
   126      * @param period Specifies the sampling time for doing calculations. This
   127      *        period is used to differentiate angle into velocity and
   128      *        acceleration.
   129      */
   130     TrcGyro(
   131         __in UINT32 slot,
   132         __in UINT32 channel,
   133         __in float  period = 0.05
   134         ): Gyro(slot, channel),
   135            m_period(period)
   136     {
   137         TLevel(INIT);
   138         TEnterMsg(("slot=%d,channel=%d,period=%f", slot, channel, period));
   139         GyroInit();
   140         TExit();
   141     }   //TrcGyro
   142 
   143     /**
   144      * Constructor: Create an instance of the TrcGyro object. It initializes
   145      * the object and starts the periodic timer.
   146      *
   147      * @param channel Specifies the analog channel.
   148      * @param period Specifies the sampling time for doing calculations. This
   149      *        period is used to differentiate angle into velocity and
   150      *        acceleration.
   151      */
   152     TrcGyro(
   153         __in UINT32 channel,
   154         __in float  period = 0.05
   155         ): Gyro(channel),
   156            m_period(period)
   157     {
   158         TLevel(INIT);
   159         TEnterMsg(("channel=%d,period=%f", channel, period));
   160         GyroInit();
   161         TExit();
   162     }   //TrcGyro
   163 
   164     /**
   165      * Destructor: Destroy an instance of the TrcGyro object.
   166      */
   167     ~TrcGyro(
   168         void
   169         )
   170     {
   171         TLevel(INIT);
   172         TEnter();
   173 
   174         semFlush(m_semaphore);
   175         SAFE_DELETE(m_notifier);
   176 
   177         TExit();
   178     }   //~TrcGyro
   179 
   180     /**
   181      * This function gets the current angle in degrees.
   182      */
   183     float
   184     GetAngle(
   185         void
   186         )
   187     {
   188         float value;
   189         TLevel(API);
   190         TEnter();
   191 
   192         CRITICAL_REGION(m_semaphore)
   193         {
   194             value = m_angle;
   195         }
   196         END_REGION;
   197 
   198         TExitMsg(("=%f", value));
   199         return value;
   200     }   //GetAngle
   201 
   202     /**
   203      * This function gets the current angular velocity in degrees per second.
   204      */
   205     float
   206     GetAngularVelocity(
   207         void
   208         )
   209     {
   210         float value;
   211         TLevel(API);
   212         TEnter();
   213 
   214         CRITICAL_REGION(m_semaphore)
   215         {
   216             value = m_angularVelocity;
   217         }
   218         END_REGION;
   219 
   220         TExitMsg(("=%f", value));
   221         return value;
   222     }   //GetAngularVelocity
   223 
   224     /**
   225      * This function gets the current angular acceleration in degrees per
   226      * second square.
   227      */
   228     float
   229     GetAngularAcceleration(
   230         void
   231         )
   232     {
   233         float value;
   234         TLevel(API);
   235         TEnter();
   236 
   237         CRITICAL_REGION(m_semaphore)
   238         {
   239             value = m_angularAcceleration;
   240         }
   241         END_REGION;
   242 
   243         TExitMsg(("=%f", value));
   244         return value;
   245     }   //GetAngularAcceleration
   246 
   247     /**
   248      * This function sets the PID mode so that PIDGet will return
   249      * the desired value.
   250      */
   251     void
   252     SetPIDMode(
   253         __in UINT32 mode
   254         )
   255     {
   256         TLevel(API);
   257         TEnterMsg(("mode=%d", mode));
   258 
   259         CRITICAL_REGION(m_semaphore)
   260         {
   261             m_modePID = mode;
   262         }
   263         END_REGION;
   264 
   265         TExit();
   266     }   //SetPIDMode
   267 
   268     /**
   269      * This function is called by the PID controller to get the sensor
   270      * data.
   271      */
   272     double
   273     PIDGet(
   274         void
   275         )
   276     {
   277         double value = 0.0;
   278         TLevel(HIFREQ);
   279         TEnter();
   280 
   281         CRITICAL_REGION(m_semaphore)
   282         {
   283             switch (m_modePID)
   284             {
   285             case PIDMODE_ANGLE:
   286                 value = m_angle;
   287                 break;
   288 
   289             case PIDMODE_VELOCITY:
   290                 value = m_angularVelocity;
   291                 break;
   292 
   293             case PIDMODE_ACCELERATION:
   294                 value = m_angularAcceleration;
   295                 break;
   296             }
   297         }
   298         END_REGION;
   299 
   300         TExitMsg(("=%f", value));
   301         return value;
   302     }   //PIDGet
   303 };  //class TrcGyro
   304 
   305 #endif  //ifndef _TRCGYRO_H