roboRIO Accelerometer

➠ General Overview

One of the many features that comes with the RoboRIO is the built-in 3-axis accelerometer, which has the potential to replace the ADXL345 accelerometer that also comes in the 2015 Kit of Parts. The purpose of this device is to determine the proper acceleration of an object, which is its acceleration relative to freefall. This can be used to determine how much the robot is tilted or a way to monitor motion.

➠ Specifications

  • Axes: 3 (x, y, and z)
  • Sample Rate: 800 Samples per second
  • Resolution: 12 bits
  • Range: ±8g (gravity)
  • Noise: 3.9 mgms typical at 25° C

➠ The Code

This is the code we used to determine the direction of each axis as well as the stability of the returned values.

#include "WPILib.h"

class Robot: public SampleRobot {
    BuiltInAccelerometer accelerometer;

    const double kUpdatePeriod = 0.005; // 5milliseconds / 0.005 seconds.
public:
    //sets the range of the accelerometer to be + or - 8G (units of gravity)
    Robot() : accelerometer(Accelerometer::Range::kRange_8G) {

    }

    void OperatorControl() {
        double xAcceleration;    //acceleration on the x-axis
        double yAcceleration;    //acceleration on the y-axis    
        double zAcceleration;    //acceleration on the z-axis
        double previousX = 0;    //Previous recursive average on x-axis
        double previousY = 0;    //Previous recursive average on y-axis
        double previousZ = 1;    //Previous recursive average on z-axis

        while (IsOperatorControl() && IsEnabled()) {
            xAcceleration = accelerometer.GetX(); //returns x-axis accel
            yAcceleration = accelerometer.GetY(); //returns y-axis accel
            zAcceleration = accelerometer.GetZ(); //returns z-axis accel

            SmartDashboard::PutNumber("X-Axis G:", xAcceleration);
            SmartDashboard::PutNumber("Y-Axis G:", yAcceleration);
            SmartDashboard::PutNumber("Z-Axis G:", zAcceleration);

            SmartDashboard::PutNumber("Recrusive X-Axis Average:", ((xAcceleration*0.1) + (0.9*previousX)));
            //returns a recursive average for the x-axis
            SmartDashboard::PutNumber(“Recursive Y-Axis Average:", ((yAcceleration*0.1) + (0.9*previousY)));
            //returns a recursive average for the y-axis
            SmartDashboard::PutNumber(“Recursive Z-Axis Average:”, ((zAcceleration*0.1) + (0.9*previousZ)));
            //returns a recursive average for the z-axis
            previousX = (xAcceleration*0.1) + (0.9*previousX);
            previousY = (yAcceleration*0.1) + (0.9*previousY);
            previousZ = (zAcceleration*0.1) + (0.9*previousZ);
            Wait(kUpdatePeriod); // Wait a short bit before updating again
        }
    }
};

START_ROBOT_CLASS(Robot);

➠ The Explanation

BuiltInAccelerometer accelerometer;

Declare the RoboRIO accelerometer as BuiltInAccelerometer; declared between public SampleRobot and public : RobotDemo

public:
    //sets the range of the accelerometer to be + or - 8G (units of gravity)
    Robot() : accelerometer(Accelerometer::Range::kRange_8G) {

    }

Initializes the roboRIO accelerometer with a range of +/- 8Gs, which is the acceleration in units of gravity (9.81m/s). This is the maximum range that the device is capable of. There is no need to input pwm ports as the accelerometer is built in.

void OperatorControl() {
        double xAcceleration;    //acceleration on the x-axis
        double yAcceleration;    //acceleration on the y-axis    
        double zAcceleration;    //acceleration on the z-axis
        double previousX = 0;    //Previous recursive average on x-axis
        double previousY = 0;    //Previous recursive average on y-axis
        double previousZ = 1;    //Previous recursive average on z-axis

In this section we initialize the variables that we will be using for output on the SmartDashboard. Since the accelerometer has 3 axes, we need a variable for each one (x, y, and z). The previous axis variables are used to determine a recursive average that is explained later in this document. They are meant to store the value of the recursive average of all previously returned values. previousX and previousY are equal to 0 because that is the expected value when the roboRIO is at rest and on a perfectly horizontal surface. previousZ is equal to 1 because the roboRIO is not in freefall, which is what an accelerometer measures acceleration in reference to.

    while (IsOperatorControl() && IsEnabled()) {
        xAcceleration = accelerometer.GetX(); //returns x-axis accel
        yAcceleration = accelerometer.GetY(); //returns y-axis accel
        zAcceleration = accelerometer.GetZ(); //returns z-axis accel

        SmartDashboard::PutNumber("X-Axis G:", xAcceleration);
        SmartDashboard::PutNumber("Y-Axis G:", yAcceleration);
        SmartDashboard::PutNumber("Z-Axis G:", zAcceleration);

Here, the variables xAcceleration, yAcceleration, and zAcceleration are being set to the current values of the accelerometer pertaining to the x, y, and z axis. After updating these values, they are then sent to the SmartDashboard to be read in the form of a running value or a table.

            SmartDashboard::PutNumber("Recrusive X-Axis Average:", ((xAcceleration*0.1) + (0.9*previousX)));
            //returns a recursive average for the x-axis
            SmartDashboard::PutNumber(“Recursive Y-Axis Average:", ((yAcceleration*0.1) + (0.9*previousY)));
            //returns a recursive average for the y-axis
            SmartDashboard::PutNumber(“Recursive Z-Axis Average:”, ((zAcceleration*0.1) + (0.9*previousZ)));
            //returns a recursive average for the z-axis
            previousX = (xAcceleration*0.1) + (0.9*previousX);
            previousY = (yAcceleration*0.1) + (0.9*previousY);
            previousZ = (zAcceleration*0.1) + (0.9*previousZ);
            Wait(kUpdatePeriod); // Wait a short bit before updating again
        }
    }
};
START_ROBOT_CLASS(Robot);

Here we calculate the recursive average for each axis which can be useful during testing. The purpose of having this recursive average is to effectively reduce the sensitivity of the returned values to fluctuations. This allows you to get a more accurate and stable reading for each axis of the accelerometer, and could be used to test for varying angles that the accelerometer is tilted.

This simple recursive average algorithm is done by taking .1 of the current value for an axis and adding it to .9 of the previous average. This essentially means that we have a constantly changing average. Note that the sensitivity of this algorithm can be adjusted by changing the “0.1” and “0.9” values. However, remember that the two multipliers must add to a value of 1, because the average will tend to continue increasing or decreasing depending on how the multipliers are adjusted. If you have a multipliers of .01 and .99, the current average will be much less sensitive to change as the weight of each new number is drastically decreased.