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  /** Accelerometer range. */
021  public enum Range {
022    /** 2 Gs max. */
023    k2G,
024    /** 4 Gs max. */
025    k4G,
026    /** 8 Gs max. */
027    k8G
028  }
029
030  /**
031   * Constructor.
032   *
033   * @param range The range the accelerometer will measure
034   */
035  @SuppressWarnings("this-escape")
036  public BuiltInAccelerometer(Range range) {
037    setRange(range);
038    HAL.report(tResourceType.kResourceType_Accelerometer, 0, 0, "Built-in accelerometer");
039    SendableRegistry.addLW(this, "BuiltInAccel", 0);
040  }
041
042  /** Constructor. The accelerometer will measure +/-8 g-forces */
043  public BuiltInAccelerometer() {
044    this(Range.k8G);
045  }
046
047  @Override
048  public void close() {
049    SendableRegistry.remove(this);
050  }
051
052  /**
053   * Set the measuring range of the accelerometer.
054   *
055   * @param range The maximum acceleration, positive or negative, that the accelerometer will
056   *     measure.
057   */
058  public final void setRange(Range range) {
059    AccelerometerJNI.setAccelerometerActive(false);
060
061    switch (range) {
062      case k2G:
063        AccelerometerJNI.setAccelerometerRange(0);
064        break;
065      case k4G:
066        AccelerometerJNI.setAccelerometerRange(1);
067        break;
068      case k8G:
069        AccelerometerJNI.setAccelerometerRange(2);
070        break;
071      default:
072        throw new IllegalArgumentException("Missing case for range type " + range);
073    }
074
075    AccelerometerJNI.setAccelerometerActive(true);
076  }
077
078  /**
079   * The acceleration in the X axis.
080   *
081   * @return The acceleration of the roboRIO along the X axis in g-forces
082   */
083  public double getX() {
084    return AccelerometerJNI.getAccelerometerX();
085  }
086
087  /**
088   * The acceleration in the Y axis.
089   *
090   * @return The acceleration of the roboRIO along the Y axis in g-forces
091   */
092  public double getY() {
093    return AccelerometerJNI.getAccelerometerY();
094  }
095
096  /**
097   * The acceleration in the Z axis.
098   *
099   * @return The acceleration of the roboRIO along the Z axis in g-forces
100   */
101  public double getZ() {
102    return AccelerometerJNI.getAccelerometerZ();
103  }
104
105  @Override
106  public void initSendable(SendableBuilder builder) {
107    builder.setSmartDashboardType("3AxisAccelerometer");
108    builder.addDoubleProperty("X", this::getX, null);
109    builder.addDoubleProperty("Y", this::getY, null);
110    builder.addDoubleProperty("Z", this::getZ, null);
111  }
112}