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.simulation;
006
007import edu.wpi.first.hal.simulation.EncoderDataJNI;
008import edu.wpi.first.hal.simulation.NotifyCallback;
009import edu.wpi.first.wpilibj.Encoder;
010import java.util.NoSuchElementException;
011
012/** Class to control a simulated encoder. */
013public class EncoderSim {
014  private final int m_index;
015
016  /**
017   * Constructs from an Encoder object.
018   *
019   * @param encoder Encoder to simulate
020   */
021  public EncoderSim(Encoder encoder) {
022    m_index = encoder.getFPGAIndex();
023  }
024
025  private EncoderSim(int index) {
026    m_index = index;
027  }
028
029  /**
030   * Creates an EncoderSim for a digital input channel. Encoders take two channels, so either one
031   * may be specified.
032   *
033   * @param channel digital input channel
034   * @return Simulated object
035   * @throws NoSuchElementException if no Encoder is configured for that channel
036   */
037  public static EncoderSim createForChannel(int channel) {
038    int index = EncoderDataJNI.findForChannel(channel);
039    if (index < 0) {
040      throw new NoSuchElementException("no encoder found for channel " + channel);
041    }
042    return new EncoderSim(index);
043  }
044
045  /**
046   * Creates an EncoderSim for a simulated index. The index is incremented for each simulated
047   * Encoder.
048   *
049   * @param index simulator index
050   * @return Simulated object
051   */
052  public static EncoderSim createForIndex(int index) {
053    return new EncoderSim(index);
054  }
055
056  /**
057   * Register a callback on the Initialized property of the encoder.
058   *
059   * @param callback the callback that will be called whenever the Initialized property is changed
060   * @param initialNotify if true, the callback will be run on the initial value
061   * @return the {@link CallbackStore} object associated with this callback.
062   */
063  public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) {
064    int uid = EncoderDataJNI.registerInitializedCallback(m_index, callback, initialNotify);
065    return new CallbackStore(m_index, uid, EncoderDataJNI::cancelInitializedCallback);
066  }
067
068  /**
069   * Read the Initialized value of the encoder.
070   *
071   * @return true if initialized
072   */
073  public boolean getInitialized() {
074    return EncoderDataJNI.getInitialized(m_index);
075  }
076
077  /**
078   * Change the Initialized value of the encoder.
079   *
080   * @param initialized the new value
081   */
082  public void setInitialized(boolean initialized) {
083    EncoderDataJNI.setInitialized(m_index, initialized);
084  }
085
086  /**
087   * Register a callback on the count property of the encoder.
088   *
089   * @param callback the callback that will be called whenever the count property is changed
090   * @param initialNotify if true, the callback will be run on the initial value
091   * @return the {@link CallbackStore} object associated with this callback.
092   */
093  public CallbackStore registerCountCallback(NotifyCallback callback, boolean initialNotify) {
094    int uid = EncoderDataJNI.registerCountCallback(m_index, callback, initialNotify);
095    return new CallbackStore(m_index, uid, EncoderDataJNI::cancelCountCallback);
096  }
097
098  /**
099   * Read the count of the encoder.
100   *
101   * @return the count
102   */
103  public int getCount() {
104    return EncoderDataJNI.getCount(m_index);
105  }
106
107  /**
108   * Change the count of the encoder.
109   *
110   * @param count the new count
111   */
112  public void setCount(int count) {
113    EncoderDataJNI.setCount(m_index, count);
114  }
115
116  /**
117   * Register a callback on the period of the encoder.
118   *
119   * @param callback the callback that will be called whenever the period is changed
120   * @param initialNotify if true, the callback will be run on the initial value
121   * @return the {@link CallbackStore} object associated with this callback.
122   */
123  public CallbackStore registerPeriodCallback(NotifyCallback callback, boolean initialNotify) {
124    int uid = EncoderDataJNI.registerPeriodCallback(m_index, callback, initialNotify);
125    return new CallbackStore(m_index, uid, EncoderDataJNI::cancelPeriodCallback);
126  }
127
128  /**
129   * Read the period of the encoder.
130   *
131   * @return the encoder period
132   */
133  public double getPeriod() {
134    return EncoderDataJNI.getPeriod(m_index);
135  }
136
137  /**
138   * Change the encoder period.
139   *
140   * @param period the new period
141   */
142  public void setPeriod(double period) {
143    EncoderDataJNI.setPeriod(m_index, period);
144  }
145
146  /**
147   * Register a callback to be called whenever the encoder is reset.
148   *
149   * @param callback the callback
150   * @param initialNotify whether to run the callback on the initial value
151   * @return the {@link CallbackStore} object associated with this callback.
152   */
153  public CallbackStore registerResetCallback(NotifyCallback callback, boolean initialNotify) {
154    int uid = EncoderDataJNI.registerResetCallback(m_index, callback, initialNotify);
155    return new CallbackStore(m_index, uid, EncoderDataJNI::cancelResetCallback);
156  }
157
158  /**
159   * Check if the encoder has been reset.
160   *
161   * @return true if reset
162   */
163  public boolean getReset() {
164    return EncoderDataJNI.getReset(m_index);
165  }
166
167  /**
168   * Change the reset property of the encoder.
169   *
170   * @param reset the new value
171   */
172  public void setReset(boolean reset) {
173    EncoderDataJNI.setReset(m_index, reset);
174  }
175
176  /**
177   * Register a callback to be run whenever the max period of the encoder is changed.
178   *
179   * @param callback the callback
180   * @param initialNotify whether to run the callback on the initial value
181   * @return the {@link CallbackStore} object associated with this callback.
182   */
183  public CallbackStore registerMaxPeriodCallback(NotifyCallback callback, boolean initialNotify) {
184    int uid = EncoderDataJNI.registerMaxPeriodCallback(m_index, callback, initialNotify);
185    return new CallbackStore(m_index, uid, EncoderDataJNI::cancelMaxPeriodCallback);
186  }
187
188  /**
189   * Get the max period of the encoder.
190   *
191   * @return the max period of the encoder
192   */
193  public double getMaxPeriod() {
194    return EncoderDataJNI.getMaxPeriod(m_index);
195  }
196
197  /**
198   * Change the max period of the encoder.
199   *
200   * @param maxPeriod the new value
201   */
202  public void setMaxPeriod(double maxPeriod) {
203    EncoderDataJNI.setMaxPeriod(m_index, maxPeriod);
204  }
205
206  /**
207   * Register a callback on the direction of the encoder.
208   *
209   * @param callback the callback that will be called whenever the direction is changed
210   * @param initialNotify if true, the callback will be run on the initial value
211   * @return the {@link CallbackStore} object associated with this callback.
212   */
213  public CallbackStore registerDirectionCallback(NotifyCallback callback, boolean initialNotify) {
214    int uid = EncoderDataJNI.registerDirectionCallback(m_index, callback, initialNotify);
215    return new CallbackStore(m_index, uid, EncoderDataJNI::cancelDirectionCallback);
216  }
217
218  /**
219   * Get the direction of the encoder.
220   *
221   * @return the direction of the encoder
222   */
223  public boolean getDirection() {
224    return EncoderDataJNI.getDirection(m_index);
225  }
226
227  /**
228   * Set the direction of the encoder.
229   *
230   * @param direction the new direction
231   */
232  public void setDirection(boolean direction) {
233    EncoderDataJNI.setDirection(m_index, direction);
234  }
235
236  /**
237   * Register a callback on the reverse direction.
238   *
239   * @param callback the callback that will be called whenever the reverse direction is changed
240   * @param initialNotify if true, the callback will be run on the initial value
241   * @return the {@link CallbackStore} object associated with this callback.
242   */
243  public CallbackStore registerReverseDirectionCallback(
244      NotifyCallback callback, boolean initialNotify) {
245    int uid = EncoderDataJNI.registerReverseDirectionCallback(m_index, callback, initialNotify);
246    return new CallbackStore(m_index, uid, EncoderDataJNI::cancelReverseDirectionCallback);
247  }
248
249  /**
250   * Get the reverse direction of the encoder.
251   *
252   * @return the reverse direction of the encoder
253   */
254  public boolean getReverseDirection() {
255    return EncoderDataJNI.getReverseDirection(m_index);
256  }
257
258  /**
259   * Set the reverse direction.
260   *
261   * @param reverseDirection the new value
262   */
263  public void setReverseDirection(boolean reverseDirection) {
264    EncoderDataJNI.setReverseDirection(m_index, reverseDirection);
265  }
266
267  /**
268   * Register a callback on the samples-to-average value of this encoder.
269   *
270   * @param callback the callback that will be called whenever the samples-to-average is changed
271   * @param initialNotify if true, the callback will be run on the initial value
272   * @return the {@link CallbackStore} object associated with this callback.
273   */
274  public CallbackStore registerSamplesToAverageCallback(
275      NotifyCallback callback, boolean initialNotify) {
276    int uid = EncoderDataJNI.registerSamplesToAverageCallback(m_index, callback, initialNotify);
277    return new CallbackStore(m_index, uid, EncoderDataJNI::cancelSamplesToAverageCallback);
278  }
279
280  /**
281   * Get the samples-to-average value.
282   *
283   * @return the samples-to-average value
284   */
285  public int getSamplesToAverage() {
286    return EncoderDataJNI.getSamplesToAverage(m_index);
287  }
288
289  /**
290   * Set the samples-to-average value.
291   *
292   * @param samplesToAverage the new value
293   */
294  public void setSamplesToAverage(int samplesToAverage) {
295    EncoderDataJNI.setSamplesToAverage(m_index, samplesToAverage);
296  }
297
298  /**
299   * Register a callback on the distance per pulse value of this encoder.
300   *
301   * @param callback the callback that will be called whenever the distance per pulse is changed
302   * @param initialNotify if true, the callback will be run on the initial value
303   * @return the {@link CallbackStore} object associated with this callback.
304   */
305  public CallbackStore registerDistancePerPulseCallback(
306      NotifyCallback callback, boolean initialNotify) {
307    int uid = EncoderDataJNI.registerDistancePerPulseCallback(m_index, callback, initialNotify);
308    return new CallbackStore(m_index, uid, EncoderDataJNI::cancelDistancePerPulseCallback);
309  }
310
311  /**
312   * Get the distance per pulse value.
313   *
314   * @return the distance per pulse value
315   */
316  public double getDistancePerPulse() {
317    return EncoderDataJNI.getDistancePerPulse(m_index);
318  }
319
320  /**
321   * Set the distance per pulse value.
322   *
323   * @param distancePerPulse the new distancePerPulse
324   */
325  public void setDistancePerPulse(double distancePerPulse) {
326    EncoderDataJNI.setDistancePerPulse(m_index, distancePerPulse);
327  }
328
329  /**
330   * Change the encoder distance.
331   *
332   * @param distance the new distance
333   */
334  public void setDistance(double distance) {
335    EncoderDataJNI.setDistance(m_index, distance);
336  }
337
338  /**
339   * Read the distance of the encoder.
340   *
341   * @return the encoder distance
342   */
343  public double getDistance() {
344    return EncoderDataJNI.getDistance(m_index);
345  }
346
347  /**
348   * Change the rate of the encoder.
349   *
350   * @param rate the new rate
351   */
352  public void setRate(double rate) {
353    EncoderDataJNI.setRate(m_index, rate);
354  }
355
356  /**
357   * Get the rate of the encoder.
358   *
359   * @return the rate of change
360   */
361  public double getRate() {
362    return EncoderDataJNI.getRate(m_index);
363  }
364
365  /** Resets all simulation data for this encoder. */
366  public void resetData() {
367    EncoderDataJNI.resetData(m_index);
368  }
369}