001/*
002 * Copyright (c) 2018-2021 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;
032import java.util.Locale;
033
034// package-private to the revrobotics package
035public class SparkMaxAlternateEncoder implements RelativeEncoder {
036  public enum Type {
037    kQuadrature(0);
038
039    @SuppressWarnings("MemberName")
040    public final int value;
041
042    Type(int value) {
043      this.value = value;
044    }
045
046    public static Type fromId(int id) {
047      return kQuadrature;
048    }
049  }
050
051  // package-private to the revrobotics package
052  final CANSparkMax sparkMax;
053  final Type type;
054  final int countsPerRev;
055
056  // package-private to the revrobotics package
057  SparkMaxAlternateEncoder(CANSparkMax sparkMax, Type type, int countsPerRev) {
058    this.sparkMax = sparkMax;
059    this.type = type;
060    this.countsPerRev = countsPerRev;
061
062    if (type == null) {
063      throw new IllegalArgumentException("encoderType must not be null");
064    }
065
066    if (countsPerRev == 0) {
067      throw new IllegalArgumentException("countsPerRev must not be zero");
068    }
069
070    REVLibError error =
071        REVLibError.fromInt(
072            CANSparkMaxJNI.c_SparkMax_AttemptToSetDataPortConfig(
073                sparkMax.sparkMaxHandle, CANSparkMax.DataPortConfig.kAltEncoder.m_value));
074    if (error == REVLibError.kSparkMaxDataPortAlreadyConfiguredDifferently) {
075      CANSparkMax.DataPortConfig currentConfig =
076          CANSparkMax.DataPortConfig.fromInt(
077              CANSparkMaxJNI.c_SparkMax_GetDataPortConfig(sparkMax.sparkMaxHandle));
078      throw new IllegalStateException(
079          String.format(
080              Locale.ENGLISH,
081              "An alternate encoder cannot be used while %s is active",
082              currentConfig.m_name));
083    }
084
085    CANSparkMaxJNI.c_SparkMax_SetAltEncoderCountsPerRevolution(
086        sparkMax.sparkMaxHandle, countsPerRev);
087
088    // If we ever add additional entries to the AlternateEncoderType enum, we need to use the
089    // encoderType param.
090  }
091
092  public double getPosition() {
093    sparkMax.throwIfClosed();
094    return CANSparkMaxJNI.c_SparkMax_GetAltEncoderPosition(sparkMax.sparkMaxHandle);
095  }
096
097  public double getVelocity() {
098    sparkMax.throwIfClosed();
099    return CANSparkMaxJNI.c_SparkMax_GetAltEncoderVelocity(sparkMax.sparkMaxHandle);
100  }
101
102  public REVLibError setPosition(double position) {
103    sparkMax.throwIfClosed();
104    return REVLibError.fromInt(
105        CANSparkMaxJNI.c_SparkMax_SetAltEncoderPosition(sparkMax.sparkMaxHandle, (float) position));
106  }
107
108  public REVLibError setPositionConversionFactor(double factor) {
109    sparkMax.throwIfClosed();
110    return REVLibError.fromInt(
111        CANSparkMaxJNI.c_SparkMax_SetAltEncoderPositionFactor(
112            sparkMax.sparkMaxHandle, (float) factor));
113  }
114
115  public REVLibError setVelocityConversionFactor(double factor) {
116    sparkMax.throwIfClosed();
117    return REVLibError.fromInt(
118        CANSparkMaxJNI.c_SparkMax_SetAltEncoderVelocityFactor(
119            sparkMax.sparkMaxHandle, (float) factor));
120  }
121
122  public double getPositionConversionFactor() {
123    sparkMax.throwIfClosed();
124    return CANSparkMaxJNI.c_SparkMax_GetAltEncoderPositionFactor(sparkMax.sparkMaxHandle);
125  }
126
127  public double getVelocityConversionFactor() {
128    sparkMax.throwIfClosed();
129    return CANSparkMaxJNI.c_SparkMax_GetAltEncoderVelocityFactor(sparkMax.sparkMaxHandle);
130  }
131
132  public REVLibError setAverageDepth(int depth) {
133    sparkMax.throwIfClosed();
134    return REVLibError.fromInt(
135        CANSparkMaxJNI.c_SparkMax_SetAltEncoderAverageDepth(sparkMax.sparkMaxHandle, depth));
136  }
137
138  public int getAverageDepth() {
139    sparkMax.throwIfClosed();
140    return CANSparkMaxJNI.c_SparkMax_GetAltEncoderAverageDepth(sparkMax.sparkMaxHandle);
141  }
142
143  public REVLibError setMeasurementPeriod(int period_us) {
144    sparkMax.throwIfClosed();
145    return REVLibError.fromInt(
146        CANSparkMaxJNI.c_SparkMax_SetAltEncoderMeasurementPeriod(
147            sparkMax.sparkMaxHandle, period_us));
148  }
149
150  public int getMeasurementPeriod() {
151    sparkMax.throwIfClosed();
152    return CANSparkMaxJNI.c_SparkMax_GetAltEncoderMeasurementPeriod(sparkMax.sparkMaxHandle);
153  }
154
155  public int getCountsPerRevolution() {
156    sparkMax.throwIfClosed();
157    return CANSparkMaxJNI.c_SparkMax_GetAltEncoderCountsPerRevolution(sparkMax.sparkMaxHandle);
158  }
159
160  @Override
161  public REVLibError setInverted(boolean inverted) {
162    sparkMax.throwIfClosed();
163    return REVLibError.fromInt(
164        CANSparkMaxJNI.c_SparkMax_SetAltEncoderInverted(sparkMax.sparkMaxHandle, inverted));
165  }
166
167  @Override
168  public boolean getInverted() {
169    sparkMax.throwIfClosed();
170    return CANSparkMaxJNI.c_SparkMax_GetAltEncoderInverted(sparkMax.sparkMaxHandle);
171  }
172
173  // package-private to the revrobotics package
174  int getSparkMaxFeedbackDeviceId() {
175    return CANSparkMaxLowLevel.FeedbackSensorType.kAlternateQuadrature.value;
176  }
177}