001// Copyright (c) FIRST and other WPILib contributors.
002// Open Source Software; you can modify and/or share it under the terms of
003// the WPILib BSD license file in the root directory of this project.
004
005package edu.wpi.first.wpilibj;
006
007import edu.wpi.first.hal.AccelerometerJNI;
008import edu.wpi.first.hal.FRCNetComm.tResourceType;
009import edu.wpi.first.hal.HAL;
010import edu.wpi.first.util.sendable.Sendable;
011import edu.wpi.first.util.sendable.SendableBuilder;
012import edu.wpi.first.util.sendable.SendableRegistry;
013
014/**
015 * Built-in accelerometer.
016 *
017 * <p>This class allows access to the roboRIO's internal accelerometer.
018 */
019public class BuiltInAccelerometer implements Sendable, AutoCloseable {
020  public enum Range {
021    k2G,
022    k4G,
023    k8G
024  }
025
026  /**
027   * Constructor.
028   *
029   * @param range The range the accelerometer will measure
030   */
031  @SuppressWarnings("this-escape")
032  public BuiltInAccelerometer(Range range) {
033    setRange(range);
034    HAL.report(tResourceType.kResourceType_Accelerometer, 0, 0, "Built-in accelerometer");
035    SendableRegistry.addLW(this, "BuiltInAccel", 0);
036  }
037
038  /** Constructor. The accelerometer will measure +/-8 g-forces */
039  public BuiltInAccelerometer() {
040    this(Range.k8G);
041  }
042
043  @Override
044  public void close() {
045    SendableRegistry.remove(this);
046  }
047
048  /**
049   * Set the measuring range of the accelerometer.
050   *
051   * @param range The maximum acceleration, positive or negative, that the accelerometer will
052   *     measure.
053   */
054  public final void setRange(Range range) {
055    AccelerometerJNI.setAccelerometerActive(false);
056
057    switch (range) {
058      case k2G:
059        AccelerometerJNI.setAccelerometerRange(0);
060        break;
061      case k4G:
062        AccelerometerJNI.setAccelerometerRange(1);
063        break;
064      case k8G:
065        AccelerometerJNI.setAccelerometerRange(2);
066        break;
067      default:
068        throw new IllegalArgumentException("Missing case for range type " + range);
069    }
070
071    AccelerometerJNI.setAccelerometerActive(true);
072  }
073
074  /**
075   * The acceleration in the X axis.
076   *
077   * @return The acceleration of the roboRIO along the X axis in g-forces
078   */
079  public double getX() {
080    return AccelerometerJNI.getAccelerometerX();
081  }
082
083  /**
084   * The acceleration in the Y axis.
085   *
086   * @return The acceleration of the roboRIO along the Y axis in g-forces
087   */
088  public double getY() {
089    return AccelerometerJNI.getAccelerometerY();
090  }
091
092  /**
093   * The acceleration in the Z axis.
094   *
095   * @return The acceleration of the roboRIO along the Z axis in g-forces
096   */
097  public double getZ() {
098    return AccelerometerJNI.getAccelerometerZ();
099  }
100
101  @Override
102  public void initSendable(SendableBuilder builder) {
103    builder.setSmartDashboardType("3AxisAccelerometer");
104    builder.addDoubleProperty("X", this::getX, null);
105    builder.addDoubleProperty("Y", this::getY, null);
106    builder.addDoubleProperty("Z", this::getZ, null);
107  }
108}