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 static edu.wpi.first.util.ErrorMessages.requireNonNullParam; 008 009import edu.wpi.first.hal.FRCNetComm.tResourceType; 010import edu.wpi.first.hal.HAL; 011import edu.wpi.first.util.sendable.Sendable; 012import edu.wpi.first.util.sendable.SendableBuilder; 013import edu.wpi.first.util.sendable.SendableRegistry; 014 015/** 016 * Handle operation of an analog accelerometer. The accelerometer reads acceleration directly 017 * through the sensor. Many sensors have multiple axis and can be treated as multiple devices. Each 018 * is calibrated by finding the center value over a period of time. 019 */ 020public class AnalogAccelerometer implements Sendable, AutoCloseable { 021 private AnalogInput m_analogChannel; 022 private double m_voltsPerG = 1.0; 023 private double m_zeroGVoltage = 2.5; 024 private final boolean m_allocatedChannel; 025 026 /** Common initialization. */ 027 private void initAccelerometer() { 028 HAL.report(tResourceType.kResourceType_Accelerometer, m_analogChannel.getChannel() + 1); 029 SendableRegistry.addLW(this, "Accelerometer", m_analogChannel.getChannel()); 030 } 031 032 /** 033 * Create a new instance of an accelerometer. 034 * 035 * <p>The constructor allocates desired analog channel. 036 * 037 * @param channel The channel number for the analog input the accelerometer is connected to 038 */ 039 @SuppressWarnings("this-escape") 040 public AnalogAccelerometer(final int channel) { 041 this(new AnalogInput(channel), true); 042 SendableRegistry.addChild(this, m_analogChannel); 043 } 044 045 /** 046 * Create a new instance of Accelerometer from an existing AnalogChannel. Make a new instance of 047 * accelerometer given an AnalogChannel. This is particularly useful if the port is going to be 048 * read as an analog channel as well as through the Accelerometer class. 049 * 050 * @param channel The existing AnalogInput object for the analog input the accelerometer is 051 * connected to 052 */ 053 @SuppressWarnings("this-escape") 054 public AnalogAccelerometer(final AnalogInput channel) { 055 this(channel, false); 056 } 057 058 @SuppressWarnings("this-escape") 059 private AnalogAccelerometer(final AnalogInput channel, final boolean allocatedChannel) { 060 requireNonNullParam(channel, "channel", "AnalogAccelerometer"); 061 m_allocatedChannel = allocatedChannel; 062 m_analogChannel = channel; 063 initAccelerometer(); 064 } 065 066 /** Delete the analog components used for the accelerometer. */ 067 @Override 068 public void close() { 069 SendableRegistry.remove(this); 070 if (m_analogChannel != null && m_allocatedChannel) { 071 m_analogChannel.close(); 072 } 073 m_analogChannel = null; 074 } 075 076 /** 077 * Return the acceleration in Gs. 078 * 079 * <p>The acceleration is returned units of Gs. 080 * 081 * @return The current acceleration of the sensor in Gs. 082 */ 083 public double getAcceleration() { 084 if (m_analogChannel == null) { 085 return 0.0; 086 } 087 return (m_analogChannel.getAverageVoltage() - m_zeroGVoltage) / m_voltsPerG; 088 } 089 090 /** 091 * Set the accelerometer sensitivity. 092 * 093 * <p>This sets the sensitivity of the accelerometer used for calculating the acceleration. The 094 * sensitivity varies by accelerometer model. There are constants defined for various models. 095 * 096 * @param sensitivity The sensitivity of accelerometer in Volts per G. 097 */ 098 public void setSensitivity(double sensitivity) { 099 m_voltsPerG = sensitivity; 100 } 101 102 /** 103 * Set the voltage that corresponds to 0 G. 104 * 105 * <p>The zero G voltage varies by accelerometer model. There are constants defined for various 106 * models. 107 * 108 * @param zero The zero G voltage. 109 */ 110 public void setZero(double zero) { 111 m_zeroGVoltage = zero; 112 } 113 114 @Override 115 public void initSendable(SendableBuilder builder) { 116 builder.setSmartDashboardType("Accelerometer"); 117 builder.addDoubleProperty("Value", this::getAcceleration, null); 118 } 119}