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