001/*
002 * Copyright (c) 2018-2022 REV Robotics
003 *
004 * Redistribution and use in source and binary forms, with or without
005 * modification, are permitted provided that the following conditions are met:
006 *
007 * 1. Redistributions of source code must retain the above copyright notice,
008 *    this list of conditions and the following disclaimer.
009 * 2. Redistributions in binary form must reproduce the above copyright
010 *    notice, this list of conditions and the following disclaimer in the
011 *    documentation and/or other materials provided with the distribution.
012 * 3. Neither the name of REV Robotics nor the names of its
013 *    contributors may be used to endorse or promote products derived from
014 *    this software without specific prior written permission.
015 *
016 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
017 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
018 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
019 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
020 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
021 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
022 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
023 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
024 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
025 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
026 * POSSIBILITY OF SUCH DAMAGE.
027 */
028
029package com.revrobotics;
030
031import com.revrobotics.jni.CANSparkMaxJNI;
032
033/** Get an instance of this class by using {@link CANSparkMax#getAnalog(Mode)}. */
034public class SparkMaxAnalogSensor implements AnalogInput, CANAnalog {
035  public enum Mode {
036    /**
037     * In absolute mode, the reported position directly corresponds to the actual voltage of the
038     * analog sensor
039     */
040    kAbsolute(0),
041    /**
042     * In relative mode, the reported position of the analog sensor is relative to its position at
043     * startup
044     */
045    kRelative(1);
046
047    public final int value;
048
049    Mode(int value) {
050      this.value = value;
051    }
052  }
053
054  // package-private to the revrobotics package
055  final Mode mode;
056  final CANSparkMax sparkMax;
057
058  // package-private (can only be used by other classes in this package)
059  SparkMaxAnalogSensor(CANSparkMax sparkMax, Mode mode) {
060    this.sparkMax = sparkMax;
061    this.mode = mode;
062
063    if (mode == null) {
064      throw new IllegalArgumentException("mode must not be null");
065    }
066
067    CANSparkMaxJNI.c_SparkMax_SetAnalogMode(sparkMax.sparkMaxHandle, mode.value);
068  }
069
070  /**
071   * Get the voltage of the analog sensor.
072   *
073   * @return Voltage of the sensor.
074   */
075  @Override
076  public double getVoltage() {
077    sparkMax.throwIfClosed();
078    return CANSparkMaxJNI.c_SparkMax_GetAnalogVoltage(sparkMax.sparkMaxHandle);
079  }
080
081  /**
082   * Get the position of the sensor. Returns value in the native unit of 'volt' by default, and can
083   * be changed by a scale factor using setPositionConversionFactor().
084   *
085   * @return Position of the sensor
086   */
087  @Override
088  public double getPosition() {
089    sparkMax.throwIfClosed();
090    return CANSparkMaxJNI.c_SparkMax_GetAnalogPosition(sparkMax.sparkMaxHandle);
091  }
092
093  /**
094   * Get the velocity of the sensor. Returns value in the native units of 'volts per second' by
095   * default, and can be changed by a scale factor using setVelocityConversionFactor().
096   *
097   * @return Velocity of the sensor in volts per second
098   */
099  @Override
100  public double getVelocity() {
101    sparkMax.throwIfClosed();
102    return CANSparkMaxJNI.c_SparkMax_GetAnalogVelocity(sparkMax.sparkMaxHandle);
103  }
104
105  /**
106   * Set the voltage of the sensor in simulation. /note This function is only to be used for
107   * simulation purposes
108   */
109  void setSimVoltage(float voltage) {
110    sparkMax.throwIfClosed();
111    CANSparkMaxJNI.c_SparkMax_SetSimAnalogVoltage(sparkMax.sparkMaxHandle, voltage);
112  }
113
114  /**
115   * Set the position of the sensor in simulation. /note This function is only to be used for
116   * simulation purposes
117   */
118  void setSimPosition(float position) {
119    sparkMax.throwIfClosed();
120    CANSparkMaxJNI.c_SparkMax_SetSimAnalogPosition(sparkMax.sparkMaxHandle, position);
121  }
122
123  /**
124   * Set the velocity of the sensor in simulation. /note This function is only to be used for
125   * simulation purposes
126   */
127  void setSimVelocity(float velocity) {
128    sparkMax.throwIfClosed();
129    CANSparkMaxJNI.c_SparkMax_SetSimAnalogVelocity(sparkMax.sparkMaxHandle, velocity);
130  }
131
132  /**
133   * Set the conversion factor for the position of the analog sensor. By default, revolutions per
134   * volt is 1. Changing the position conversion factor will also change the position units.
135   *
136   * @param factor The conversion factor which will be multiplied by volts
137   * @return {@link REVLibError#kOk} if successful
138   */
139  @Override
140  public REVLibError setPositionConversionFactor(double factor) {
141    sparkMax.throwIfClosed();
142    return REVLibError.fromInt(
143        CANSparkMaxJNI.c_SparkMax_SetAnalogPositionConversionFactor(
144            sparkMax.sparkMaxHandle, (float) factor));
145  }
146
147  /**
148   * Set the conversion factor for the velocity of the analog sensor. By default, revolutions per
149   * volt second is 1. Changing the velocity conversion factor will also change the velocity units.
150   *
151   * @param factor The conversion factor which will be multiplied by volts per second
152   * @return {@link REVLibError#kOk} if successful
153   */
154  @Override
155  public REVLibError setVelocityConversionFactor(double factor) {
156    sparkMax.throwIfClosed();
157    return REVLibError.fromInt(
158        CANSparkMaxJNI.c_SparkMax_SetAnalogVelocityConversionFactor(
159            sparkMax.sparkMaxHandle, (float) factor));
160  }
161
162  /**
163   * Get the current conversion factor for the position of the analog sensor.
164   *
165   * @return Analog position conversion factor
166   */
167  @Override
168  public double getPositionConversionFactor() {
169    sparkMax.throwIfClosed();
170    return CANSparkMaxJNI.c_SparkMax_GetAnalogPositionConversionFactor(sparkMax.sparkMaxHandle);
171  }
172
173  /**
174   * Get the current conversion factor for the velocity of the analog sensor.
175   *
176   * @return Analog velocity conversion factor
177   */
178  @Override
179  public double getVelocityConversionFactor() {
180    sparkMax.throwIfClosed();
181    return CANSparkMaxJNI.c_SparkMax_GetAnalogVelocityConversionFactor(sparkMax.sparkMaxHandle);
182  }
183
184  /**
185   * Set the phase of the anlog sensor so that it is set to be in phase with the motor itself
186   *
187   * @param inverted The phase of the sensor
188   * @return {@link REVLibError#kOk} if successful
189   */
190  @Override
191  public REVLibError setInverted(boolean inverted) {
192    sparkMax.throwIfClosed();
193    return REVLibError.fromInt(
194        CANSparkMaxJNI.c_SparkMax_SetAnalogInverted(sparkMax.sparkMaxHandle, inverted));
195  }
196
197  /**
198   * Get the phase of the analog sensor
199   *
200   * @return The phase of the sensor
201   */
202  @Override
203  public boolean getInverted() {
204    sparkMax.throwIfClosed();
205    return CANSparkMaxJNI.c_SparkMax_GetAnalogInverted(sparkMax.sparkMaxHandle);
206  }
207
208  // package-private to the revrobotics package
209  int getSparkMaxFeedbackDeviceId() {
210    return CANSparkMaxLowLevel.FeedbackSensorType.kAnalog.value;
211  }
212}