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 }