001/*----------------------------------------------------------------------------*/
002/* Copyright (c) FIRST 2008-2012. All Rights Reserved.                        */
003/* Open Source Software - may be modified and shared by FRC teams. The code   */
004/* must be accompanied by the FIRST BSD license file in the root directory of */
005/* the project.                                                               */
006/*----------------------------------------------------------------------------*/
007
008package edu.wpi.first.wpilibj;
009
010import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
011import edu.wpi.first.wpilibj.communication.UsageReporting;
012import edu.wpi.first.wpilibj.livewindow.LiveWindow;
013import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
014import edu.wpi.first.wpilibj.tables.ITable;
015
016
017/**
018 * Handle operation of an analog accelerometer.
019 * The accelerometer reads acceleration directly through the sensor. Many sensors have
020 * multiple axis and can be treated as multiple devices. Each is calibrated by finding
021 * the center value over a period of time.
022 */
023public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWindowSendable {
024
025    private AnalogInput m_analogChannel;
026    private double m_voltsPerG = 1.0;
027    private double m_zeroGVoltage = 2.5;
028    private boolean m_allocatedChannel;
029
030    /**
031     * Common initialization
032     */
033    private void initAccelerometer() {
034        UsageReporting.report(tResourceType.kResourceType_Accelerometer, m_analogChannel.getChannel());
035        LiveWindow.addSensor("Accelerometer", m_analogChannel.getChannel(), this);
036    }
037
038    /**
039     * Create a new instance of an accelerometer.
040     *
041     * The constructor allocates desired analog channel.
042     * @param channel The channel number for the analog input the accelerometer is connected to
043     */
044    public AnalogAccelerometer(final int channel) {
045        m_allocatedChannel = true;
046        m_analogChannel = new AnalogInput(channel);
047        initAccelerometer();
048    }
049
050    /**
051     * Create a new instance of Accelerometer from an existing AnalogChannel.
052     * Make a new instance of accelerometer given an AnalogChannel. This is particularly
053     * useful if the port is going to be read as an analog channel as well as through
054     * the Accelerometer class.
055     * @param channel The existing AnalogInput object for the analog input the accelerometer is connected to
056     */
057    public AnalogAccelerometer(AnalogInput channel) {
058        m_allocatedChannel = false;
059        if (channel == null)
060            throw new NullPointerException("Analog Channel given was null");
061        m_analogChannel = channel;
062        initAccelerometer();
063    }
064
065    /**
066     * Delete the analog components used for the accelerometer.
067     */
068    public void free() {
069        if (m_analogChannel != null && m_allocatedChannel) {
070            m_analogChannel.free();
071        }
072        m_analogChannel = null;
073    }
074
075    /**
076     * Return the acceleration in Gs.
077     *
078     * The acceleration is returned units of Gs.
079     *
080     * @return The current acceleration of the sensor in Gs.
081     */
082    public double getAcceleration() {
083        return (m_analogChannel.getAverageVoltage() - m_zeroGVoltage) / m_voltsPerG;
084    }
085
086    /**
087     * Set the accelerometer sensitivity.
088     *
089     * This sets the sensitivity of the accelerometer used for calculating the acceleration.
090     * The sensitivity varies by accelerometer model. There are constants defined for various models.
091     *
092     * @param sensitivity The sensitivity of accelerometer in Volts per G.
093     */
094    public void setSensitivity(double sensitivity) {
095        m_voltsPerG = sensitivity;
096    }
097
098    /**
099     * Set the voltage that corresponds to 0 G.
100     *
101     * The zero G voltage varies by accelerometer model. There are constants defined for various models.
102     *
103     * @param zero The zero G voltage.
104     */
105    public void setZero(double zero) {
106        m_zeroGVoltage = zero;
107    }
108
109    /**
110     * Get the Acceleration for the PID Source parent.
111     *
112     * @return The current acceleration in Gs.
113     */
114    public double pidGet() {
115        return getAcceleration();
116    }
117
118    public String getSmartDashboardType() {
119        return "Accelerometer";
120    }
121    /*
122     * Live Window code, only does anything if live window is activated.
123     */
124    private ITable m_table;
125
126    /**
127     * {@inheritDoc}
128     */
129    public void initTable(ITable subtable) {
130        m_table = subtable;
131        updateTable();
132    }
133
134    /**
135     * {@inheritDoc}
136     */
137    public ITable getTable() {
138        return m_table;
139    }
140
141    /**
142     * {@inheritDoc}
143     */
144    public void updateTable() {
145        if (m_table != null) {
146            m_table.putNumber("Value", getAcceleration());
147        }
148    }
149
150    /**
151     * Analog Channels don't have to do anything special when entering the LiveWindow.
152     * {@inheritDoc}
153     */
154    public void startLiveWindowMode() {}
155
156    /**
157     * Analog Channels don't have to do anything special when exiting the LiveWindow.
158     * {@inheritDoc}
159     */
160    public void stopLiveWindowMode() {}
161}