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. Save a reference to 062 * this object so GC doesn't cancel the callback. 063 */ 064 public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) { 065 int uid = EncoderDataJNI.registerInitializedCallback(m_index, callback, initialNotify); 066 return new CallbackStore(m_index, uid, EncoderDataJNI::cancelInitializedCallback); 067 } 068 069 /** 070 * Read the Initialized value of the encoder. 071 * 072 * @return true if initialized 073 */ 074 public boolean getInitialized() { 075 return EncoderDataJNI.getInitialized(m_index); 076 } 077 078 /** 079 * Change the Initialized value of the encoder. 080 * 081 * @param initialized the new value 082 */ 083 public void setInitialized(boolean initialized) { 084 EncoderDataJNI.setInitialized(m_index, initialized); 085 } 086 087 /** 088 * Register a callback on the count property of the encoder. 089 * 090 * @param callback the callback that will be called whenever the count property is changed 091 * @param initialNotify if true, the callback will be run on the initial value 092 * @return the {@link CallbackStore} object associated with this callback. Save a reference to 093 * this object so GC doesn't cancel the callback. 094 */ 095 public CallbackStore registerCountCallback(NotifyCallback callback, boolean initialNotify) { 096 int uid = EncoderDataJNI.registerCountCallback(m_index, callback, initialNotify); 097 return new CallbackStore(m_index, uid, EncoderDataJNI::cancelCountCallback); 098 } 099 100 /** 101 * Read the count of the encoder. 102 * 103 * @return the count 104 */ 105 public int getCount() { 106 return EncoderDataJNI.getCount(m_index); 107 } 108 109 /** 110 * Change the count of the encoder. 111 * 112 * @param count the new count 113 */ 114 public void setCount(int count) { 115 EncoderDataJNI.setCount(m_index, count); 116 } 117 118 /** 119 * Register a callback on the period of the encoder. 120 * 121 * @param callback the callback that will be called whenever the period is changed 122 * @param initialNotify if true, the callback will be run on the initial value 123 * @return the {@link CallbackStore} object associated with this callback. Save a reference to 124 * this object so GC doesn't cancel the callback. 125 */ 126 public CallbackStore registerPeriodCallback(NotifyCallback callback, boolean initialNotify) { 127 int uid = EncoderDataJNI.registerPeriodCallback(m_index, callback, initialNotify); 128 return new CallbackStore(m_index, uid, EncoderDataJNI::cancelPeriodCallback); 129 } 130 131 /** 132 * Read the period of the encoder. 133 * 134 * @return the encoder period 135 */ 136 public double getPeriod() { 137 return EncoderDataJNI.getPeriod(m_index); 138 } 139 140 /** 141 * Change the encoder period. 142 * 143 * @param period the new period 144 */ 145 public void setPeriod(double period) { 146 EncoderDataJNI.setPeriod(m_index, period); 147 } 148 149 /** 150 * Register a callback to be called whenever the encoder is reset. 151 * 152 * @param callback the callback 153 * @param initialNotify whether to run the callback on the initial value 154 * @return the {@link CallbackStore} object associated with this callback. Save a reference to 155 * this object so GC doesn't cancel the callback. 156 */ 157 public CallbackStore registerResetCallback(NotifyCallback callback, boolean initialNotify) { 158 int uid = EncoderDataJNI.registerResetCallback(m_index, callback, initialNotify); 159 return new CallbackStore(m_index, uid, EncoderDataJNI::cancelResetCallback); 160 } 161 162 /** 163 * Check if the encoder has been reset. 164 * 165 * @return true if reset 166 */ 167 public boolean getReset() { 168 return EncoderDataJNI.getReset(m_index); 169 } 170 171 /** 172 * Change the reset property of the encoder. 173 * 174 * @param reset the new value 175 */ 176 public void setReset(boolean reset) { 177 EncoderDataJNI.setReset(m_index, reset); 178 } 179 180 /** 181 * Register a callback to be run whenever the max period of the encoder is changed. 182 * 183 * @param callback the callback 184 * @param initialNotify whether to run the callback on the initial value 185 * @return the {@link CallbackStore} object associated with this callback. Save a reference to 186 * this object so GC doesn't cancel the callback. 187 */ 188 public CallbackStore registerMaxPeriodCallback(NotifyCallback callback, boolean initialNotify) { 189 int uid = EncoderDataJNI.registerMaxPeriodCallback(m_index, callback, initialNotify); 190 return new CallbackStore(m_index, uid, EncoderDataJNI::cancelMaxPeriodCallback); 191 } 192 193 /** 194 * Get the max period of the encoder. 195 * 196 * @return the max period of the encoder 197 */ 198 public double getMaxPeriod() { 199 return EncoderDataJNI.getMaxPeriod(m_index); 200 } 201 202 /** 203 * Change the max period of the encoder. 204 * 205 * @param maxPeriod the new value 206 */ 207 public void setMaxPeriod(double maxPeriod) { 208 EncoderDataJNI.setMaxPeriod(m_index, maxPeriod); 209 } 210 211 /** 212 * Register a callback on the direction of the encoder. 213 * 214 * @param callback the callback that will be called whenever the direction is changed 215 * @param initialNotify if true, the callback will be run on the initial value 216 * @return the {@link CallbackStore} object associated with this callback. Save a reference to 217 * this object so GC doesn't cancel the callback. 218 */ 219 public CallbackStore registerDirectionCallback(NotifyCallback callback, boolean initialNotify) { 220 int uid = EncoderDataJNI.registerDirectionCallback(m_index, callback, initialNotify); 221 return new CallbackStore(m_index, uid, EncoderDataJNI::cancelDirectionCallback); 222 } 223 224 /** 225 * Get the direction of the encoder. 226 * 227 * @return the direction of the encoder 228 */ 229 public boolean getDirection() { 230 return EncoderDataJNI.getDirection(m_index); 231 } 232 233 /** 234 * Set the direction of the encoder. 235 * 236 * @param direction the new direction 237 */ 238 public void setDirection(boolean direction) { 239 EncoderDataJNI.setDirection(m_index, direction); 240 } 241 242 /** 243 * Register a callback on the reverse direction. 244 * 245 * @param callback the callback that will be called whenever the reverse direction is changed 246 * @param initialNotify if true, the callback will be run on the initial value 247 * @return the {@link CallbackStore} object associated with this callback. Save a reference to 248 * this object so GC doesn't cancel the callback. 249 */ 250 public CallbackStore registerReverseDirectionCallback( 251 NotifyCallback callback, boolean initialNotify) { 252 int uid = EncoderDataJNI.registerReverseDirectionCallback(m_index, callback, initialNotify); 253 return new CallbackStore(m_index, uid, EncoderDataJNI::cancelReverseDirectionCallback); 254 } 255 256 /** 257 * Get the reverse direction of the encoder. 258 * 259 * @return the reverse direction of the encoder 260 */ 261 public boolean getReverseDirection() { 262 return EncoderDataJNI.getReverseDirection(m_index); 263 } 264 265 /** 266 * Set the reverse direction. 267 * 268 * @param reverseDirection the new value 269 */ 270 public void setReverseDirection(boolean reverseDirection) { 271 EncoderDataJNI.setReverseDirection(m_index, reverseDirection); 272 } 273 274 /** 275 * Register a callback on the samples-to-average value of this encoder. 276 * 277 * @param callback the callback that will be called whenever the samples-to-average is changed 278 * @param initialNotify if true, the callback will be run on the initial value 279 * @return the {@link CallbackStore} object associated with this callback. Save a reference to 280 * this object so GC doesn't cancel the callback. 281 */ 282 public CallbackStore registerSamplesToAverageCallback( 283 NotifyCallback callback, boolean initialNotify) { 284 int uid = EncoderDataJNI.registerSamplesToAverageCallback(m_index, callback, initialNotify); 285 return new CallbackStore(m_index, uid, EncoderDataJNI::cancelSamplesToAverageCallback); 286 } 287 288 /** 289 * Get the samples-to-average value. 290 * 291 * @return the samples-to-average value 292 */ 293 public int getSamplesToAverage() { 294 return EncoderDataJNI.getSamplesToAverage(m_index); 295 } 296 297 /** 298 * Set the samples-to-average value. 299 * 300 * @param samplesToAverage the new value 301 */ 302 public void setSamplesToAverage(int samplesToAverage) { 303 EncoderDataJNI.setSamplesToAverage(m_index, samplesToAverage); 304 } 305 306 /** 307 * Change the encoder distance. 308 * 309 * @param distance the new distance 310 */ 311 public void setDistance(double distance) { 312 EncoderDataJNI.setDistance(m_index, distance); 313 } 314 315 /** 316 * Read the distance of the encoder. 317 * 318 * @return the encoder distance 319 */ 320 public double getDistance() { 321 return EncoderDataJNI.getDistance(m_index); 322 } 323 324 /** 325 * Change the rate of the encoder. 326 * 327 * @param rate the new rate 328 */ 329 public void setRate(double rate) { 330 EncoderDataJNI.setRate(m_index, rate); 331 } 332 333 /** 334 * Get the rate of the encoder. 335 * 336 * @return the rate of change 337 */ 338 public double getRate() { 339 return EncoderDataJNI.getRate(m_index); 340 } 341 342 /** Resets all simulation data for this encoder. */ 343 public void resetData() { 344 EncoderDataJNI.resetData(m_index); 345 } 346}