2 /// Copyright (c) Titan Robotics Club. All rights reserved.
4 /// <module name="TrcAccel.h" />
7 /// This module contains the definition and implementation of the TrcAccel
12 /// Environment: Wind River C++ for National Instrument cRIO based Robot.
22 #define MOD_ID MOD_ACCEL
26 #define MOD_NAME "TrcAccel"
29 // 50 calibration points at 20ms each will cost us a total of 1 second start
32 #ifndef ACCEL_NUM_CAL_PTS
33 #define ACCEL_NUM_CAL_PTS 50
35 #ifndef ACCEL_CAL_INTERVAL
36 #define ACCEL_CAL_INTERVAL 0.02 //20ms
38 #ifndef ACCEL_DEADBAND_THRESHOLD
39 #define ACCEL_DEADBAND_THRESHOLD 0.01
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.
49 class TrcAccel: public ADXL345_I2C
55 AllAxes m_offsetZeroG;
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
79 CRITICAL_REGION(m_semaphore)
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;
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);
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));
128 * This function is called when the timer expired. It will call the
129 * non-static worker function.
131 * @param timer Points to the TrcAccel object to call the worker function.
140 TEnterMsg(("accel=%p", accel));
141 ((TrcAccel *)accel)->Integrator();
147 * Constructor: Create an instance of the TrcAccel object. It initializes
148 * the object and starts the periodic timer.
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
158 __in float period = 0.02
162 TEnterMsg(("slot=%d,period=%f", slot, period));
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;
179 m_notifier->StartPeriodic(period);
185 * Destructor: Destroy an instance of the TrcAccel object.
194 semFlush(m_semaphore);
195 SAFE_DELETE(m_notifier);
201 * This function returns the current acceleration value of the X axis in
202 * the unit of meters per second square.
204 * @return Returns the X acceleration value.
213 TExitMsg(("=%f", m_accelData.XAxis));
214 return m_accelData.XAxis;
218 * This function returns the current acceleration value of the X axis in
219 * the unit of feet per second square.
221 * @return Returns the X acceleration value.
230 double value = m_accelData.XAxis*FEET_PER_METER;
231 TExitMsg(("=%f", value));
236 * This function returns the current acceleration value of the Y axis in
237 * the unit of meters per second square.
239 * @return Returns the Y acceleration value.
248 TExitMsg(("=%f", m_accelData.YAxis));
249 return m_accelData.YAxis;
253 * This function returns the current acceleration value of the Y axis in
254 * the unit of feet per second square.
256 * @return Returns the Y acceleration value.
265 double value = m_accelData.YAxis*FEET_PER_METER;
266 TExitMsg(("=%f", value));
271 * This function returns the current acceleration value of the Z axis in
272 * the unit of meters per second square.
274 * @return Returns the Z acceleration value.
283 TExitMsg(("=%f", m_accelData.ZAxis));
284 return m_accelData.ZAxis;
288 * This function returns the current acceleration value of the Z axis in
289 * the unit of feet per second square.
291 * @return Returns the Z acceleration value.
300 double value = m_accelData.ZAxis*FEET_PER_METER;
301 TExitMsg(("=%f", value));
306 * This function returns the current velocity value of the X axis in
307 * the unit of meters per second.
309 * @return Returns the X velocity value.
318 TExitMsg(("=%f", m_velX));
323 * This function returns the current velocity value of the X axis in
324 * the unit of feet per second.
326 * @return Returns the X velocity value.
335 double value = m_velX*FEET_PER_METER;
336 TExitMsg(("=%f", value));
341 * This function returns the current velocity value of the Y axis in
342 * the unit of meters per second.
344 * @return Returns the Y velocity value.
353 TExitMsg(("=%f", m_velY));
358 * This function returns the current velocity value of the Y axis in
359 * the unit of feet per second.
361 * @return Returns the Y velocity value.
370 double value = m_velY*FEET_PER_METER;
371 TExitMsg(("=%f", value));
376 * This function returns the current velocity value of the Z axis in
377 * the unit of meters per second.
379 * @return Returns the Z velocity value.
388 TExitMsg(("=%f", m_velZ));
393 * This function returns the current velocity value of the Z axis in
394 * the unit of feet per second.
396 * @return Returns the Z velocity value.
405 double value = m_velZ*FEET_PER_METER;
406 TExitMsg(("=%f", value));
411 * This function returns the current distance value of the X axis in
412 * the unit of meters.
414 * @return Returns the X distance value.
423 TExitMsg(("=%f", m_distX));
428 * This function returns the current distance value of the X axis in
431 * @return Returns the X distance value.
440 double value = m_distX*FEET_PER_METER;
441 TExitMsg(("=%f", value));
446 * This function returns the current distance value of the Y axis in
447 * the unit of meters.
449 * @return Returns the Y distance value.
458 TExitMsg(("=%f", m_distY));
463 * This function returns the current distance value of the Y axis in
466 * @return Returns the Y distance value.
475 double value = m_distY*FEET_PER_METER;
476 TExitMsg(("=%f", value));
481 * This function returns the current distance value of the Z axis in
482 * the unit of meters.
484 * @return Returns the Z distance value.
493 TExitMsg(("=%f", m_distZ));
498 * This function returns the current distance value of the Z axis in
501 * @return Returns the Z distance value.
510 double value = m_distZ*FEET_PER_METER;
511 TExitMsg(("=%f", value));
516 * This function resets the acceleration, velocity and distance values.
526 CRITICAL_REGION(m_semaphore)
528 m_accelData.XAxis = 0.0;
529 m_accelData.YAxis = 0.0;
530 m_accelData.ZAxis = 0.0;
544 * This function sets the accelerometer to enable or disable state.
546 * @param fEnabled If true, enables the accelerometer, false otherwise.
556 m_fEnabled = fEnabled;
560 m_timestamp = GetMsecTime();
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
588 for (UINT32 i = 0; i < ACCEL_NUM_CAL_PTS; i++)
590 data = GetAccelerations();
591 zeroG.XAxis += data.XAxis;
592 zeroG.YAxis += data.YAxis;
593 zeroG.ZAxis += data.ZAxis;
594 Wait(ACCEL_CAL_INTERVAL);
597 CRITICAL_REGION(m_semaphore)
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));
614 #endif //ifndef _TRCACCEL_H