Squashed 'third_party/Phoenix-frc-lib/' content from commit 666d176
Change-Id: Ibaca2fc8ffb1177e786576cc1e4cc9f7a8c98f13
git-subtree-dir: third_party/Phoenix-frc-lib
git-subtree-split: 666d176a08151793044ab74e0005f13d3732ed96
diff --git a/java/src/com/ctre/CANTalon.java b/java/src/com/ctre/CANTalon.java
new file mode 100644
index 0000000..860c627
--- /dev/null
+++ b/java/src/com/ctre/CANTalon.java
@@ -0,0 +1,12 @@
+package com.ctre;
+
+/**
+* @deprecated Use TalonSRX instead. This deprecated class will be removed in 2019.
+* @see <a href="https://github.com/CrossTheRoadElec/Phoenix-Documentation/blob/master/Migration%20Guide.md">Phoenix 2018 Migration Guide</a>
+*/
+@Deprecated
+public class CANTalon extends com.ctre.phoenix.motorcontrol.can.TalonSRX {
+ public CANTalon(int deviceNumber) {
+ super(deviceNumber);
+ }
+}
diff --git a/java/src/com/ctre/phoenix/ButtonMonitor.java b/java/src/com/ctre/phoenix/ButtonMonitor.java
new file mode 100644
index 0000000..936fb7a
--- /dev/null
+++ b/java/src/com/ctre/phoenix/ButtonMonitor.java
@@ -0,0 +1,43 @@
+package com.ctre.phoenix;
+
+import edu.wpi.first.wpilibj.GenericHID;
+
+public class ButtonMonitor implements ILoopable
+{
+ GenericHID _gameCntrlr;
+ int _btnIdx;
+ IButtonPressEventHandler _handler;
+ boolean _isDown = false;
+
+ public interface IButtonPressEventHandler {
+ void OnButtonPress(int idx, boolean isDown);
+ };
+
+ public ButtonMonitor(GenericHID controller, int buttonIndex,
+ IButtonPressEventHandler ButtonPressEventHandler) {
+ _gameCntrlr = controller;
+ _btnIdx = buttonIndex;
+ _handler = ButtonPressEventHandler;
+ }
+
+ public void process() {
+ boolean down = _gameCntrlr.getRawButton(_btnIdx);
+
+ if (!_isDown && down){
+ _handler.OnButtonPress(_btnIdx, down);
+ }
+
+ _isDown = down;
+ }
+
+ public void onStart() {
+ }
+ public void onLoop() {
+ process();
+ }
+ public boolean isDone() {
+ return false;
+ }
+ public void onStop() {
+ }
+}
diff --git a/java/src/com/ctre/phoenix/CANifier.java b/java/src/com/ctre/phoenix/CANifier.java
new file mode 100644
index 0000000..31d33ce
--- /dev/null
+++ b/java/src/com/ctre/phoenix/CANifier.java
@@ -0,0 +1,616 @@
+/*
+ * Software License Agreement
+ *
+ * Copyright (C) Cross The Road Electronics. All rights
+ * reserved.
+ *
+ * Cross The Road Electronics (CTRE) licenses to you the right to
+ * use, publish, and distribute copies of CRF (Cross The Road) firmware files (*.crf) and Software
+ * API Libraries ONLY when in use with Cross The Road Electronics hardware products.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * CROSS THE ROAD ELECTRONICS BE LIABLE FOR ANY INCIDENTAL, SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE
+ */
+
+package com.ctre.phoenix;
+
+import edu.wpi.first.wpilibj.hal.HAL;
+
+/**
+ * CTRE CANifier
+ *
+ * Device for interfacing common devices to the CAN bus.
+ */
+public class CANifier {
+ private long m_handle;
+
+ /**
+ * Enum for velocity periods
+ */
+ public enum VelocityPeriod {
+ Period_1Ms(1),
+ Period_2Ms(2),
+ Period_5Ms(5),
+ Period_10Ms(10),
+ Period_20Ms(20),
+ Period_25Ms(25),
+ Period_50Ms(50),
+ Period_100Ms(100);
+ public static VelocityPeriod valueOf(int value) {
+ for(VelocityPeriod period : values()) {
+ if(period.value == value) {
+ return period;
+ }
+ }
+ return null;
+ }
+ public final int value;
+ VelocityPeriod(int initValue) {
+ this.value = initValue;
+ }
+ }
+
+ /**
+ * Enum for the LED Output Channels
+ */
+ public enum LEDChannel {
+ LEDChannelA(0), LEDChannelB(1), LEDChannelC(2);
+ public static LEDChannel valueOf(int value) {
+ for (LEDChannel mode : values()) {
+ if (mode.value == value) {
+ return mode;
+ }
+ }
+ return null;
+ }
+
+ public final int value;
+
+ LEDChannel(int initValue) {
+ this.value = initValue;
+ }
+ }
+
+ /**
+ * Enum for the PWM Input Channels
+ */
+ public enum PWMChannel {
+ PWMChannel0(0), PWMChannel1(1), PWMChannel2(2), PWMChannel3(3);
+ public static PWMChannel valueOf(int value) {
+ for (PWMChannel mode : values()) {
+ if (mode.value == value) {
+ return mode;
+ }
+ }
+ return null;
+ }
+
+ public final int value;
+
+ PWMChannel(int initValue) {
+ this.value = initValue;
+ }
+ }
+
+ public final int PWMChannelCount = 4;
+
+ /**
+ * General IO Pins on the CANifier
+ */
+ public enum GeneralPin {
+ QUAD_IDX (CANifierJNI.GeneralPin.QUAD_IDX.value),
+ QUAD_B (CANifierJNI.GeneralPin.QUAD_B.value),
+ QUAD_A (CANifierJNI.GeneralPin.QUAD_A.value),
+ LIMR (CANifierJNI.GeneralPin.LIMR.value),
+ LIMF (CANifierJNI.GeneralPin.LIMF.value),
+ SDA (CANifierJNI.GeneralPin.SDA.value),
+ SCL (CANifierJNI.GeneralPin.SCL.value),
+ SPI_CS (CANifierJNI.GeneralPin.SPI_CS.value),
+ SPI_MISO_PWM2P (CANifierJNI.GeneralPin.SPI_MISO_PWM2P.value),
+ SPI_MOSI_PWM1P (CANifierJNI.GeneralPin.SPI_MOSI_PWM1P.value),
+ SPI_CLK_PWM0P (CANifierJNI.GeneralPin.SPI_CLK_PWM0P.value);
+ public static GeneralPin valueOf(int value) {
+ for (GeneralPin mode : values()) {
+ if (mode.value == value) {
+ return mode;
+ }
+ }
+ return null;
+ }
+
+ public final int value;
+
+ GeneralPin(int initValue) {
+ this.value = initValue;
+ }
+ }
+
+ /**
+ * Class to hold the pin values.
+ */
+ public static class PinValues {
+ public boolean QUAD_IDX;
+ public boolean QUAD_B;
+ public boolean QUAD_A;
+ public boolean LIMR;
+ public boolean LIMF;
+ public boolean SDA;
+ public boolean SCL;
+ public boolean SPI_CS_PWM3;
+ public boolean SPI_MISO_PWM2;
+ public boolean SPI_MOSI_PWM1;
+ public boolean SPI_CLK_PWM0;
+ }
+
+ private boolean[] _tempPins = new boolean[11];
+
+ private int m_deviceNumber;
+ /**
+ * Constructor.
+ * @param deviceId The CAN Device ID of the CANifier.
+ */
+ public CANifier(int deviceId) {
+ m_handle = CANifierJNI.JNI_new_CANifier(deviceId);
+ m_deviceNumber = deviceId;
+ HAL.report(63, deviceId + 1);
+ }
+
+ /**
+ * Sets the LED Output
+ * @param percentOutput Output duty cycle expressed as percentage.
+ * @param ledChannel Channel to set the output of.
+ */
+ public void setLEDOutput(double percentOutput, LEDChannel ledChannel) {
+ /* convert float to integral fixed pt */
+ if (percentOutput > 1) {
+ percentOutput = 1;
+ }
+ if (percentOutput < 0) {
+ percentOutput = 0;
+ }
+ int dutyCycle = (int) (percentOutput * 1023); // [0,1023]
+
+ CANifierJNI.JNI_SetLEDOutput(m_handle, dutyCycle, ledChannel.value);
+ }
+
+ /**
+ * Sets the output of a General Pin
+ * @param outputPin The pin to use as output.
+ * @param outputValue The desired output state.
+ * @param outputEnable Whether this pin is an output. "True" enables output.
+ */
+ public void setGeneralOutput(GeneralPin outputPin, boolean outputValue, boolean outputEnable) {
+ CANifierJNI.JNI_SetGeneralOutput(m_handle, outputPin.value, outputValue, outputEnable);
+ }
+
+ /**
+ * Sets the output of all General Pins
+ * @param outputBits A bit mask of all the output states. LSB->MSB is in the order of the #GeneralPin enum.
+ * @param isOutputBits A boolean bit mask that sets the pins to be outputs or inputs. A bit of 1 enables output.
+ */
+ public void setGeneralOutputs(int outputBits, int isOutputBits) {
+ CANifierJNI.JNI_SetGeneralOutputs(m_handle, outputBits, isOutputBits);
+ }
+
+ /**
+ * Gets the state of all General Pins
+ * @param allPins A structure to fill with the current state of all pins.
+ */
+ public void getGeneralInputs(PinValues allPins) {
+ CANifierJNI.JNI_GetGeneralInputs(m_handle, _tempPins);
+ allPins.LIMF = _tempPins[GeneralPin.LIMF.value];
+ allPins.LIMR = _tempPins[GeneralPin.LIMR.value];
+ allPins.QUAD_A = _tempPins[GeneralPin.QUAD_A.value];
+ allPins.QUAD_B = _tempPins[GeneralPin.QUAD_B.value];
+ allPins.QUAD_IDX = _tempPins[GeneralPin.QUAD_IDX.value];
+ allPins.SCL = _tempPins[GeneralPin.SCL.value];
+ allPins.SDA = _tempPins[GeneralPin.SDA.value];
+ allPins.SPI_CLK_PWM0 = _tempPins[GeneralPin.SPI_CLK_PWM0P.value];
+ allPins.SPI_MOSI_PWM1 = _tempPins[GeneralPin.SPI_MOSI_PWM1P.value];
+ allPins.SPI_MISO_PWM2 = _tempPins[GeneralPin.SPI_MISO_PWM2P.value];
+ allPins.SPI_CS_PWM3 = _tempPins[GeneralPin.SPI_CS.value];
+ }
+
+ /**
+ * Gets the state of the specified pin
+ * @param inputPin The index of the pin.
+ * @return The state of the pin.
+ */
+ public boolean getGeneralInput(GeneralPin inputPin) {
+ return CANifierJNI.JNI_GetGeneralInput(m_handle, inputPin.value);
+ }
+
+ /**
+ * Call GetLastError() generated by this object.
+ * Not all functions return an error code but can
+ * potentially report errors.
+ *
+ * This function can be used to retrieve those error codes.
+ *
+ * @return The last ErrorCode generated.
+ */
+ public ErrorCode getLastError() {
+ int retval = CANifierJNI.JNI_GetLastError(m_handle);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the PWM Output
+ * Currently supports PWM 0, PWM 1, and PWM 2
+ * @param pwmChannel Index of the PWM channel to output.
+ * @param dutyCycle Duty Cycle (0 to 1) to output. Default period of the signal is 4.2 ms.
+ */
+ public void setPWMOutput(int pwmChannel, double dutyCycle) {
+ if (dutyCycle < 0) {
+ dutyCycle = 0;
+ } else if (dutyCycle > 1) {
+ dutyCycle = 1;
+ }
+ if (pwmChannel < 0) {
+ pwmChannel = 0;
+ }
+
+ int dutyCyc10bit = (int) (1023 * dutyCycle);
+
+ CANifierJNI.JNI_SetPWMOutput(m_handle, (int) pwmChannel, dutyCyc10bit);
+ }
+
+ /**
+ * Enables PWM Outputs
+ * Currently supports PWM 0, PWM 1, and PWM 2
+ * @param pwmChannel Index of the PWM channel to enable.
+ * @param bEnable "True" enables output on the pwm channel.
+ */
+ public void enablePWMOutput(int pwmChannel, boolean bEnable) {
+ if (pwmChannel < 0) {
+ pwmChannel = 0;
+ }
+
+ CANifierJNI.JNI_EnablePWMOutput(m_handle, (int) pwmChannel, bEnable);
+ }
+
+ /**
+ * Gets the PWM Input
+ * @param pwmChannel PWM channel to get.
+ * @param dutyCycleAndPeriod Double array to hold Duty Cycle [0] and Period [1].
+ */
+ public void getPWMInput(PWMChannel pwmChannel, double[] dutyCycleAndPeriod) {
+ CANifierJNI.JNI_GetPWMInput(m_handle, pwmChannel.value, dutyCycleAndPeriod);
+ }
+
+ /**
+ * Gets the quadrature encoder's position
+ * @return Position of encoder
+ */
+ public int getQuadraturePosition() {
+ return CANifierJNI.JNI_GetQuadraturePosition(m_handle);
+ }
+
+ /**
+ * Sets the quadrature encoder's position
+ * @param newPosition Position to set
+ * @param timeoutMs
+ Timeout value in ms. If nonzero, function will wait for
+ config success and report an error if it times out.
+ If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setQuadraturePosition(int newPosition, int timeoutMs) {
+ return ErrorCode.valueOf(CANifierJNI.JNI_SetQuadraturePosition(m_handle, newPosition, timeoutMs));
+ }
+
+ /**
+ * Gets the quadrature encoder's velocity
+ * @return Velocity of encoder
+ */
+ public int getQuadratureVelocity() {
+ return CANifierJNI.JNI_GetQuadratureVelocity(m_handle);
+ }
+
+ /**
+ * Configures the period of each velocity sample.
+ * Every 1ms a position value is sampled, and the delta between that sample
+ * and the position sampled kPeriod ms ago is inserted into a filter.
+ * kPeriod is configured with this function.
+ *
+ * @param period
+ * Desired period for the velocity measurement. @see
+ * #VelocityMeasPeriod
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configVelocityMeasurementPeriod(VelocityPeriod period, int timeoutMs) {
+ int retval = CANifierJNI.JNI_ConfigVelocityMeasurementPeriod(m_handle, period.value, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the number of velocity samples used in the rolling average velocity
+ * measurement.
+ *
+ * @param windowSize
+ * Number of samples in the rolling average of velocity
+ * measurement. Valid values are 1,2,4,8,16,32. If another
+ * value is specified, it will truncate to nearest support value.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configVelocityMeasurementWindow(int windowSize, int timeoutMs) {
+ int retval = CANifierJNI.JNI_ConfigVelocityMeasurementWindow(m_handle, windowSize, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the value of a custom parameter. This is for arbitrary use.
+ *
+ * Sometimes it is necessary to save calibration/duty cycle/output
+ * information in the device. Particularly if the
+ * device is part of a subsystem that can be replaced.
+ *
+ * @param newValue
+ * Value for custom parameter.
+ * @param paramIndex
+ * Index of custom parameter. [0-1]
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configSetCustomParam(int newValue, int paramIndex, int timeoutMs) {
+ int retval = CANifierJNI.JNI_ConfigSetCustomParam(m_handle, newValue, paramIndex, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Gets the value of a custom parameter. This is for arbitrary use.
+ *
+ * Sometimes it is necessary to save calibration/duty cycle/output
+ * information in the device. Particularly if the
+ * device is part of a subsystem that can be replaced.
+ *
+ * @param paramIndex
+ * Index of custom parameter. [0-1]
+ * @param timoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Value of the custom param.
+ */
+ public int configGetCustomParam(int paramIndex, int timoutMs) {
+ int retval = CANifierJNI.JNI_ConfigGetCustomParam(m_handle, paramIndex, timoutMs);
+ return retval;
+ }
+
+ /**
+ * Sets a parameter. Generally this is not used.
+ * This can be utilized in
+ * - Using new features without updating API installation.
+ * - Errata workarounds to circumvent API implementation.
+ * - Allows for rapid testing / unit testing of firmware.
+ *
+ * @param param
+ * Parameter enumeration.
+ * @param value
+ * Value of parameter.
+ * @param subValue
+ * Subvalue for parameter. Maximum value of 255.
+ * @param ordinal
+ * Ordinal of parameter.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configSetParameter(ParamEnum param, double value, int subValue, int ordinal, int timeoutMs) {
+ return configSetParameter(param.value, value, subValue, ordinal, timeoutMs);
+ }
+
+ /**
+ * Sets a parameter. Generally this is not used.
+ * This can be utilized in
+ * - Using new features without updating API installation.
+ * - Errata workarounds to circumvent API implementation.
+ * - Allows for rapid testing / unit testing of firmware.
+ *
+ * @param param
+ * Parameter enumeration.
+ * @param value
+ * Value of parameter.
+ * @param subValue
+ * Subvalue for parameter. Maximum value of 255.
+ * @param ordinal
+ * Ordinal of parameter.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configSetParameter(int param, double value, int subValue, int ordinal, int timeoutMs) {
+ int retval = CANifierJNI.JNI_ConfigSetParameter(m_handle, param, value, subValue, ordinal,
+ timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Gets a parameter. Generally this is not used.
+ * This can be utilized in
+ * - Using new features without updating API installation.
+ * - Errata workarounds to circumvent API implementation.
+ * - Allows for rapid testing / unit testing of firmware.
+ *
+ * @param param
+ * Parameter enumeration.
+ * @param ordinal
+ * Ordinal of parameter.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Value of parameter.
+ */
+ public double configGetParameter(ParamEnum param, int ordinal, int timeoutMs) {
+ return CANifierJNI.JNI_ConfigGetParameter(m_handle, param.value, ordinal, timeoutMs);
+ }
+ /**
+ * Sets the period of the given status frame.
+ *
+ * @param statusFrame
+ * Frame whose period is to be changed.
+ * @param periodMs
+ * Period in ms for the given frame.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setStatusFramePeriod(CANifierStatusFrame statusFrame, int periodMs, int timeoutMs) {
+ int retval = CANifierJNI.JNI_SetStatusFramePeriod(m_handle, statusFrame.value, periodMs, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Sets the period of the given status frame.
+ *
+ * @param statusFrame
+ * Frame whose period is to be changed.
+ * @param periodMs
+ * Period in ms for the given frame.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setStatusFramePeriod(int statusFrame, int periodMs, int timeoutMs) {
+ int retval = CANifierJNI.JNI_SetStatusFramePeriod(m_handle, statusFrame, periodMs, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Gets the period of the given status frame.
+ *
+ * @param frame
+ * Frame to get the period of.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Period of the given status frame.
+ */
+ public int getStatusFramePeriod(CANifierStatusFrame frame, int timeoutMs) {
+ return CANifierJNI.JNI_GetStatusFramePeriod(m_handle, frame.value, timeoutMs);
+ }
+
+ /**
+ * Sets the period of the given control frame.
+ *
+ * @param frame
+ * Frame whose period is to be changed.
+ * @param periodMs
+ * Period in ms for the given frame.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setControlFramePeriod(CANifierControlFrame frame, int periodMs) {
+ int retval = CANifierJNI.JNI_SetControlFramePeriod(m_handle, frame.value, periodMs);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Sets the period of the given control frame.
+ *
+ * @param frame
+ * Frame whose period is to be changed.
+ * @param periodMs
+ * Period in ms for the given frame.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setControlFramePeriod(int frame, int periodMs) {
+ int retval = CANifierJNI.JNI_SetControlFramePeriod(m_handle, frame, periodMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Gets the firmware version of the device.
+ *
+ * @return Firmware version of device.
+ */
+ public int getFirmwareVersion() {
+ return CANifierJNI.JNI_GetFirmwareVersion(m_handle);
+ }
+
+ /**
+ * Returns true if the device has reset since last call.
+ *
+ * @return Has a Device Reset Occurred?
+ */
+ public boolean hasResetOccurred() {
+ return CANifierJNI.JNI_HasResetOccurred(m_handle);
+ }
+
+ // ------ Faults ----------//
+ /**
+ * Gets the CANifier fault status
+ *
+ * @param toFill
+ * Container for fault statuses.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode getFaults(CANifierFaults toFill) {
+ int bits = CANifierJNI.JNI_GetFaults(m_handle);
+ toFill.update(bits);
+ return getLastError();
+ }
+ /**
+ * Gets the CANifier sticky fault status
+ *
+ * @param toFill
+ * Container for sticky fault statuses.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode getStickyFaults(CANifierStickyFaults toFill) {
+ int bits = CANifierJNI.JNI_GetStickyFaults(m_handle);
+ toFill.update(bits);
+ return getLastError();
+ }
+ /**
+ * Clears the Sticky Faults
+ *
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode clearStickyFaults(int timeoutMs) {
+ int retval = CANifierJNI.JNI_ClearStickyFaults(m_handle, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Gets the bus voltage seen by the device.
+ *
+ * @return The bus voltage value (in volts).
+ */
+ public double getBusVoltage() {
+ return CANifierJNI.JNI_GetBusVoltage(m_handle);
+ }
+
+ /**
+ * @return The Device Number
+ */
+ public int getDeviceID(){
+ return m_deviceNumber;
+ }
+}
diff --git a/java/src/com/ctre/phoenix/CANifierControlFrame.java b/java/src/com/ctre/phoenix/CANifierControlFrame.java
new file mode 100644
index 0000000..c7ce0f0
--- /dev/null
+++ b/java/src/com/ctre/phoenix/CANifierControlFrame.java
@@ -0,0 +1,21 @@
+package com.ctre.phoenix;
+
+public enum CANifierControlFrame {
+ Control_1_General(0x040000),
+ Control_2_PwmOutput(0x040040);
+
+ public static CANifierControlFrame valueOf(int value) {
+ for (CANifierControlFrame frame : values()) {
+ if (frame.value == value) {
+ return frame;
+ }
+ }
+ return null;
+ }
+
+ public final int value;
+
+ CANifierControlFrame(int initValue) {
+ this.value = initValue;
+ }
+}
diff --git a/java/src/com/ctre/phoenix/CANifierFaults.java b/java/src/com/ctre/phoenix/CANifierFaults.java
new file mode 100644
index 0000000..99a47b9
--- /dev/null
+++ b/java/src/com/ctre/phoenix/CANifierFaults.java
@@ -0,0 +1,16 @@
+package com.ctre.phoenix;
+
+public class CANifierFaults {
+ //!< True iff any of the above flags are true.
+ public boolean hasAnyFault() {
+ return false;
+ }
+ public int toBitfield() {
+ int retval = 0;
+ return retval;
+ }
+ public void update(int bits) {
+ }
+ public CANifierFaults() {
+ }
+};
diff --git a/java/src/com/ctre/phoenix/CANifierJNI.java b/java/src/com/ctre/phoenix/CANifierJNI.java
new file mode 100644
index 0000000..086397d
--- /dev/null
+++ b/java/src/com/ctre/phoenix/CANifierJNI.java
@@ -0,0 +1,107 @@
+/*
+ * Software License Agreement
+ *
+ * Copyright (C) Cross The Road Electronics. All rights
+ * reserved.
+ *
+ * Cross The Road Electronics (CTRE) licenses to you the right to
+ * use, publish, and distribute copies of CRF (Cross The Road) firmware files (*.crf) and Software
+ * API Libraries ONLY when in use with Cross The Road Electronics hardware products.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * CROSS THE ROAD ELECTRONICS BE LIABLE FOR ANY INCIDENTAL, SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE
+ */
+ package com.ctre.phoenix;
+
+ public class CANifierJNI extends CTREJNIWrapper {
+
+ public enum GeneralPin
+ {
+ QUAD_IDX(0),
+ QUAD_B (1),
+ QUAD_A (2),
+ LIMR (3),
+ LIMF (4),
+ SDA (5),
+ SCL (6),
+ SPI_CS (7),
+ SPI_MISO_PWM2P (8),
+ SPI_MOSI_PWM1P (9),
+ SPI_CLK_PWM0P (10);
+
+ final public int value;
+
+ GeneralPin(int value) {
+ this.value = value;
+ }
+ }
+
+ public static native long JNI_new_CANifier(int deviceNumber);
+
+ public static native void JNI_SetLEDOutput(long handle, int dutyCycle, int ledChannel);
+
+ public static native void JNI_SetGeneralOutputs(long handle, int outputBits, int isOutputBits);
+
+ public static native void JNI_SetGeneralOutput(long handle, int outputPin, boolean outputValue,
+ boolean outputEnable);
+
+ public static native void JNI_SetPWMOutput(long handle, int pwmChannel, int dutyCycle);
+
+ public static native void JNI_EnablePWMOutput(long handle, int pwmChannel, boolean bEnable);
+
+ public static native void JNI_GetGeneralInputs(long handle, boolean[] allPins);
+
+ public static native boolean JNI_GetGeneralInput(long handl, int inputPin);
+
+ public static native void JNI_GetPWMInput(long handle, int pwmChannel, double dutyCycleAndPeriod[]);
+
+ public static native int JNI_GetLastError(long handle);
+
+ public static native double JNI_GetBatteryVoltage(long handle);
+
+ public static native int JNI_GetQuadraturePosition(long handle);
+
+ public static native int JNI_SetQuadraturePosition(long handle, int newPosition, int timeoutMs);
+
+ public static native int JNI_GetQuadratureVelocity(long handle);
+
+ public static native int JNI_ConfigVelocityMeasurementPeriod(long handle, int period, int timeoutMs);
+
+ public static native int JNI_ConfigVelocityMeasurementWindow(long handle, int windowSize, int timeoutMs);
+
+ public static native int JNI_ConfigSetCustomParam(long handle, int newValue, int paramIndex, int timeoutMs);
+
+ public static native int JNI_ConfigGetCustomParam(long handle, int paramIndex, int timoutMs);
+
+ public static native int JNI_ConfigSetParameter(long handle, int param, double value, int subValue, int ordinal,
+ int timeoutMs);
+
+ public static native double JNI_ConfigGetParameter(long handle, int param, int ordinal, int timeoutMs);
+
+ public static native int JNI_SetStatusFramePeriod(long handle, int statusFrame, int periodMs, int timeoutMs);
+
+ public static native int JNI_GetStatusFramePeriod(long handle, int frame, int timeoutMs);
+
+ public static native int JNI_SetControlFramePeriod(long handle, int frame, int periodMs);
+
+ public static native int JNI_GetFirmwareVersion(long handle);
+
+ public static native boolean JNI_HasResetOccurred(long handle);
+
+ public static native int JNI_GetFaults(long handle);
+
+ public static native int JNI_GetStickyFaults(long handle);
+
+ public static native int JNI_ClearStickyFaults(long handle, int timeoutMs);
+
+ public static native double JNI_GetBusVoltage(long handle);
+ }
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/CANifierStatusFrame.java b/java/src/com/ctre/phoenix/CANifierStatusFrame.java
new file mode 100644
index 0000000..904b9be
--- /dev/null
+++ b/java/src/com/ctre/phoenix/CANifierStatusFrame.java
@@ -0,0 +1,26 @@
+package com.ctre.phoenix;
+
+public enum CANifierStatusFrame {
+ Status_1_General(0x041400),
+ Status_2_General(0x041440),
+ Status_3_PwmInputs0(0x041480),
+ Status_4_PwmInputs1(0x0414C0),
+ Status_5_PwmInputs2(0x041500),
+ Status_6_PwmInputs3(0x041540),
+ Status_8_Misc(0x0415C0);
+
+ public static CANifierStatusFrame valueOf(int value) {
+ for (CANifierStatusFrame frame : values()) {
+ if (frame.value == value) {
+ return frame;
+ }
+ }
+ return null;
+ }
+
+ public final int value;
+
+ CANifierStatusFrame(int initValue) {
+ this.value = initValue;
+ }
+}
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/CANifierStickyFaults.java b/java/src/com/ctre/phoenix/CANifierStickyFaults.java
new file mode 100644
index 0000000..2cb8dac
--- /dev/null
+++ b/java/src/com/ctre/phoenix/CANifierStickyFaults.java
@@ -0,0 +1,16 @@
+package com.ctre.phoenix;
+
+public class CANifierStickyFaults {
+ //!< True iff any of the above flags are true.
+ public boolean hasAnyFault() {
+ return false;
+ }
+ public int toBitfield() {
+ int retval = 0;
+ return retval;
+ }
+ public void update(int bits) {
+ }
+ public CANifierStickyFaults() {
+ }
+};
diff --git a/java/src/com/ctre/phoenix/CTREJNIWrapper.java b/java/src/com/ctre/phoenix/CTREJNIWrapper.java
new file mode 100644
index 0000000..8556ea5
--- /dev/null
+++ b/java/src/com/ctre/phoenix/CTREJNIWrapper.java
@@ -0,0 +1,21 @@
+package com.ctre.phoenix;
+
+public class CTREJNIWrapper {
+ static boolean libraryLoaded = false;
+
+ static {
+ if (!libraryLoaded) {
+ try {
+ System.loadLibrary("CTRE_PhoenixCCI");
+ } catch (UnsatisfiedLinkError e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ libraryLoaded = true;
+ }
+ }
+
+ public static native int getPortWithModule(byte module, byte channel);
+
+ public static native int getPort(byte channel);
+}
diff --git a/java/src/com/ctre/phoenix/CTRLoggerJNI.java b/java/src/com/ctre/phoenix/CTRLoggerJNI.java
new file mode 100644
index 0000000..059494a
--- /dev/null
+++ b/java/src/com/ctre/phoenix/CTRLoggerJNI.java
@@ -0,0 +1,12 @@
+package com.ctre.phoenix;
+
+import com.ctre.phoenix.CTREJNIWrapper;
+
+/* package */ class CTRLoggerJNI extends CTREJNIWrapper {
+ /* package */ static native int JNI_Logger_Log(int code, String origin, String stackTrace);
+
+ // public static native void JNI_Logger_Close();
+ // public static native void JNI_Logger_Open(int language);
+ // public static native String JNI_Logger_GetShort(int code);
+ // public static native String JNI_Logger_GetLong(int code);
+}
diff --git a/java/src/com/ctre/phoenix/ErrorCode.java b/java/src/com/ctre/phoenix/ErrorCode.java
new file mode 100644
index 0000000..97a47c2
--- /dev/null
+++ b/java/src/com/ctre/phoenix/ErrorCode.java
@@ -0,0 +1,123 @@
+package com.ctre.phoenix;
+
+import java.util.HashMap;
+
+public enum ErrorCode {
+ OK(0), //!< No Error - Function executed as expected
+
+ //CAN-Related
+ CAN_MSG_STALE(1),
+ CAN_TX_FULL(-1),
+ TxFailed(-1), //!< Could not transmit the CAN frame.
+ InvalidParamValue(-2), //!< Caller passed an invalid param
+ CAN_INVALID_PARAM(-2),
+ RxTimeout(-3), //!< CAN frame has not been received within specified period of time.
+ CAN_MSG_NOT_FOUND(-3),
+ TxTimeout(-4), //!< Not used.
+ CAN_NO_MORE_TX_JOBS(-4),
+ UnexpectedArbId(-5), //!< Specified CAN Id is invalid.
+ CAN_NO_SESSIONS_AVAIL(-5),
+ BufferFull(+6), //!< Caller attempted to insert data into a buffer that is full.
+ CAN_OVERFLOW(-6),
+ SensorNotPresent(-7), //!< Sensor is not present
+ FirmwareTooOld (-8),
+
+
+ //General
+ GeneralError(-100), //!< User Specified General Error
+ GENERAL_ERROR(-100),
+
+ //Signal
+ SIG_NOT_UPDATED(-200),
+ SigNotUpdated(-200), //!< Have not received an value response for signal.
+ NotAllPIDValuesUpdated(-201),
+
+ //Gadgeteer Port Error Codes
+ //These include errors between ports and modules
+ GEN_PORT_ERROR(-300),
+ PORT_MODULE_TYPE_MISMATCH(-301),
+ //Gadgeteer Module Error Codes
+ //These apply only to the module units themselves
+ GEN_MODULE_ERROR(-400),
+ MODULE_NOT_INIT_SET_ERROR(-401),
+ MODULE_NOT_INIT_GET_ERROR(-402),
+
+
+ //API
+ WheelRadiusTooSmall(-500),
+ TicksPerRevZero(-501),
+ DistanceBetweenWheelsTooSmall(-502),
+ GainsAreNotSet(-503),
+
+ //Higher Level
+ IncompatibleMode(-600),
+ InvalidHandle(-601), //!< Handle does not match stored map of handles
+
+
+ //CAN Related
+ PulseWidthSensorNotPresent (10), //!< Special Code for "isSensorPresent"
+
+ //General
+ GeneralWarning(100),
+ FeatureNotSupported(101),
+ NotImplemented(102),
+ FirmVersionCouldNotBeRetrieved (103),
+ FeaturesNotAvailableYet(104),
+ ControlModeNotValid(105),
+
+ ControlModeNotSupportedYet(106),
+ CascadedPIDNotSupportedYet(107),
+ AuxiliaryPIDNotSupportedYet(107),
+ RemoteSensorsNotSupportedYet(108),
+ MotProfFirmThreshold(109),
+ MotProfFirmThreshold2(110);
+
+ //---------------------- Integral To Enum operators -----------//
+ public final int value; //!< Hold the integral value of an enum instance.
+ /** Keep singleton map to quickly lookup enum via int */
+ private static HashMap<Integer, ErrorCode> _map = null;
+ /** private c'tor for above declarations */
+ private ErrorCode(int initValue) {this.value = initValue; }
+ /** static c'tor, prepare the map */
+ static {
+ _map = new HashMap<Integer, ErrorCode>();
+ for (ErrorCode type : ErrorCode.values()) {
+ _map.put(type.value, type);
+ }
+ }
+ /** public lookup to convert int to enum */
+ public static ErrorCode valueOf(int value) {
+ ErrorCode retval = _map.get(value);
+ if (retval != null)
+ return retval;
+ return GeneralError;
+ }
+
+ /** @return the first nonzero error code */
+ public static ErrorCode worstOne(ErrorCode errorCode1, ErrorCode errorCode2) {
+ if (errorCode1.value != 0)
+ return errorCode1;
+ return errorCode2;
+ }
+
+ /** @return the first nonzero error code */
+ public static ErrorCode worstOne(ErrorCode errorCode1, ErrorCode errorCode2, ErrorCode errorCode3) {
+ if (errorCode1.value != 0)
+ return errorCode1;
+ if (errorCode2.value != 0)
+ return errorCode2;
+ return errorCode3;
+ }
+
+ /** @return the first nonzero error code */
+ public static ErrorCode worstOne(ErrorCode errorCode1, ErrorCode errorCode2, ErrorCode errorCode3,
+ ErrorCode errorCode4) {
+ if (errorCode1.value != 0)
+ return errorCode1;
+ if (errorCode2.value != 0)
+ return errorCode2;
+ if (errorCode3.value != 0)
+ return errorCode3;
+ return errorCode4;
+ }
+};
diff --git a/java/src/com/ctre/phoenix/GadgeteerUartClient.java b/java/src/com/ctre/phoenix/GadgeteerUartClient.java
new file mode 100644
index 0000000..b40dad9
--- /dev/null
+++ b/java/src/com/ctre/phoenix/GadgeteerUartClient.java
@@ -0,0 +1,71 @@
+package com.ctre.phoenix;
+
+public interface GadgeteerUartClient
+{
+ public enum GadgeteerProxyType{
+ General(0),
+ Pigeon(1),
+ PC_HERO(2),
+ Unknown(-1);
+ private int value; private GadgeteerProxyType(int value) { this.value = value; }
+ public static GadgeteerProxyType valueOf(int value) {
+ for (GadgeteerProxyType e : GadgeteerProxyType.values()) {
+ if (e.value == value) {
+ return e;
+ }
+ }
+ return Unknown;
+ }
+ };
+
+ public enum GadgeteerConnection {
+ NotConnected (0),
+ Connecting (1),
+ Connected (2),
+ Unknown(-1);
+ private int value; private GadgeteerConnection(int value) { this.value = value; }
+ public static GadgeteerConnection valueOf(int value) {
+ for (GadgeteerConnection e : GadgeteerConnection.values()) {
+ if (e.value == value) {
+ return e;
+ }
+ }
+ return Unknown;
+ }
+ };
+
+ public static class GadgeteerUartStatus {
+ public GadgeteerProxyType type;
+ public GadgeteerConnection conn;
+ public int bitrate;
+ public int resetCount;
+ };
+
+
+ enum GadgeteerState
+ {
+ GadState_WaitChirp1(0),
+ GadState_WaitBLInfo(1),
+ GadState_WaitBitrateResp(2),
+ GadState_WaitSwitchDelay(3),
+ GadState_WaitChirp2(4),
+ GadState_Connected_Idle(5),
+ GadState_Connected_ReqChirp(6),
+ GadState_Connected_RespChirp(7),
+ GadState_Connected_ReqCanBus(8),
+ GadState_Connected_RespCanBus(9),
+ GadState_Connected_RespIsoThenChirp(10),
+ GadState_Connected_RespIsoThenCanBus(11);
+ private int value; private GadgeteerState(int value) { this.value = value; }
+ public static GadgeteerState valueOf(int value) {
+ for (GadgeteerState e : GadgeteerState.values()) {
+ if (e.value == value) {
+ return e;
+ }
+ }
+ return GadState_WaitChirp1;
+ }
+ };
+ int getGadgeteerStatus(GadgeteerUartStatus status);
+};
+
diff --git a/java/src/com/ctre/phoenix/ILoopable.java b/java/src/com/ctre/phoenix/ILoopable.java
new file mode 100644
index 0000000..1e52471
--- /dev/null
+++ b/java/src/com/ctre/phoenix/ILoopable.java
@@ -0,0 +1,9 @@
+package com.ctre.phoenix;
+
+public interface ILoopable
+{
+ public void onStart();
+ public void onLoop();
+ public boolean isDone();
+ public void onStop();
+}
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/Logger.java b/java/src/com/ctre/phoenix/Logger.java
new file mode 100644
index 0000000..c1caaca
--- /dev/null
+++ b/java/src/com/ctre/phoenix/Logger.java
@@ -0,0 +1,38 @@
+package com.ctre.phoenix;
+
+public class Logger
+{
+ /**
+ * Logs an entry into the Phoenix DS Error/Logger stream
+ * @param code Error code to log. If OKAY is passed, no action is taken.
+ * @param origin Origin string to send to DS/Log
+ * @return OKAY error code.
+ */
+ public static ErrorCode log(ErrorCode code, String origin) {
+ /* only take action if the error code is nonzero */
+ if (code != ErrorCode.OK) {
+ String stack = java.util.Arrays.toString(Thread.currentThread().getStackTrace());
+ stack = stack.replaceAll(",", "\n");
+ int errCode = code.value;
+ return ErrorCode.valueOf(CTRLoggerJNI.JNI_Logger_Log(errCode, origin, stack));
+ }
+ /* otherwise return OK */
+ return ErrorCode.OK;
+ }
+
+ //public static void close() {
+ // //CTRLoggerJNI.JNI_Logger_Close();
+ //}
+ //public static void open() {
+ // //CTRLoggerJNI.JNI_Logger_Open(2);
+ //}
+ /*
+ public static String getVerbose(int code) {
+ return CTRLoggerJNI.JNI_Logger_GetLong(code);
+ }
+ public static String getShort(int code) {
+ return CTRLoggerJNI.JNI_Logger_GetShort(code);
+ }
+ */
+}
+
diff --git a/java/src/com/ctre/phoenix/ParamEnum.java b/java/src/com/ctre/phoenix/ParamEnum.java
new file mode 100644
index 0000000..f6b3706
--- /dev/null
+++ b/java/src/com/ctre/phoenix/ParamEnum.java
@@ -0,0 +1,109 @@
+package com.ctre.phoenix;
+
+public enum ParamEnum
+ {
+ eOnBoot_BrakeMode ( 31),
+ eQuadFilterEn ( 91),
+ eQuadIdxPolarity(108),
+ eClearPositionOnIdx (100),
+ eMotionProfileHasUnderrunErr (119),
+ eClearPosOnLimitF (144),
+ eClearPosOnLimitR (145),
+
+ eStatusFramePeriod(300),
+ eOpenloopRamp(301),
+ eClosedloopRamp(302),
+ eNeutralDeadband(303),
+
+ ePeakPosOutput(305),
+ eNominalPosOutput(306),
+ ePeakNegOutput(307),
+ eNominalNegOutput(308),
+
+ eProfileParamSlot_P(310),
+ eProfileParamSlot_I(311),
+ eProfileParamSlot_D(312),
+ eProfileParamSlot_F(313),
+ eProfileParamSlot_IZone(314),
+ eProfileParamSlot_AllowableErr(315),
+ eProfileParamSlot_MaxIAccum(316),
+ eProfileParamSlot_PeakOutput(317),
+
+ eClearPositionOnLimitF(320),
+ eClearPositionOnLimitR(321),
+ eClearPositionOnQuadIdx(322),
+
+ eSampleVelocityPeriod(325),
+ eSampleVelocityWindow(326),
+
+ eFeedbackSensorType(330),
+ eSelectedSensorPosition(331),
+ eFeedbackNotContinuous (332),
+ eRemoteSensorSource (333), // RemoteSensorSource_t
+ eRemoteSensorDeviceID (334), // [0,62] DeviceID
+ eSensorTerm (335), // feedbackDevice_t (ordinal is the register)
+ eRemoteSensorClosedLoopDisableNeutralOnLOS (336),
+ ePIDLoopPolarity(337),
+ ePIDLoopPeriod(338),
+ eSelectedSensorCoefficient(339),
+
+ eForwardSoftLimitThreshold(340),
+ eReverseSoftLimitThreshold(341),
+ eForwardSoftLimitEnable(342),
+ eReverseSoftLimitEnable(343),
+
+ eNominalBatteryVoltage(350),
+ eBatteryVoltageFilterSize(351),
+
+ eContinuousCurrentLimitAmps(360),
+ ePeakCurrentLimitMs(361),
+ ePeakCurrentLimitAmps(362),
+
+ eClosedLoopIAccum(370),
+
+ eCustomParam(380),
+
+ eStickyFaults(390),
+
+ eAnalogPosition(400),
+ eQuadraturePosition(401),
+ ePulseWidthPosition(402),
+
+ eMotMag_Accel(410),
+ eMotMag_VelCruise(411),
+
+ eLimitSwitchSource (421), // ordinal (fwd=0,reverse=1), @see LimitSwitchSource_t
+ eLimitSwitchNormClosedAndDis ( 422), // ordinal (fwd=0,reverse=1). @see LimitSwitchNormClosedAndDis_t
+ eLimitSwitchDisableNeutralOnLOS ( 423),
+ eLimitSwitchRemoteDevID ( 424),
+ eSoftLimitDisableNeutralOnLOS(425),
+
+ ePulseWidthPeriod_EdgesPerRot(430),
+ ePulseWidthPeriod_FilterWindowSz(431),
+
+ eYawOffset(160),
+ eCompassOffset(161),
+ eBetaGain(162),
+ eEnableCompassFusion(163),
+ eGyroNoMotionCal ( 164),
+ eEnterCalibration ( 165),
+ eFusedHeadingOffset ( 166),
+ eStatusFrameRate ( 169),
+ eAccumZ ( 170),
+ eTempCompDisable ( 171),
+ eMotionMeas_tap_threshX ( 172),
+ eMotionMeas_tap_threshY ( 173),
+ eMotionMeas_tap_threshZ ( 174),
+ eMotionMeas_tap_count ( 175),
+ eMotionMeas_tap_time ( 176),
+ eMotionMeas_tap_time_multi ( 177),
+ eMotionMeas_shake_reject_thresh ( 178),
+ eMotionMeas_shake_reject_time ( 179),
+ eMotionMeas_shake_reject_timeout ( 180);
+
+ public final int value;
+ ParamEnum(int initValue)
+ {
+ this.value = initValue;
+ }
+};
diff --git a/java/src/com/ctre/phoenix/Util.java b/java/src/com/ctre/phoenix/Util.java
new file mode 100644
index 0000000..4ccedc7
--- /dev/null
+++ b/java/src/com/ctre/phoenix/Util.java
@@ -0,0 +1,48 @@
+package com.ctre.phoenix;
+
+public class Util
+{
+ public static double cap(double value, double peak)
+ {
+ if(value < -peak) value = -peak;
+ if(value > peak) value = peak;
+ return value;
+ }
+
+ public static int scaleRotationsToNativeUnits(double scalar, double fullRotations) {
+ /* first assume we don't have config info, prep the default return */
+ int retval = (int) fullRotations;
+ /* apply scalar if its available */
+ if (scalar > 0) {
+ retval = (int) (fullRotations * scalar);
+ }
+ return retval;
+ }
+ public static int scaleVelocityToNativeUnits(double scalar, double rpm) {
+ /* first assume we don't have config info, prep the default return */
+ int retval = (int) rpm;
+ /* apply scalar if its available */
+ if (scalar > 0) {
+ retval = (int) (rpm * scalar);
+ }
+ return retval;
+ }
+ public static double scaleNativeUnitsToRotations(double scalar, long nativePos) {
+ /* first assume we don't have config info, prep the default return */
+ double retval = (double) nativePos;
+ /* retrieve scaling info */
+ if (scalar > 0) {
+ retval = ((double) nativePos) / scalar;
+ }
+ return retval;
+ }
+ public static double scaleNativeUnitsToRpm(double scalar, long nativeVel) {
+ /* first assume we don't have config info, prep the default return */
+ double retval = (double) nativeVel;
+ /* apply scalar if its available */
+ if (scalar > 0) {
+ retval = (double) (nativeVel) / (scalar);
+ }
+ return retval;
+ }
+}
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/motion/MotionProfileStatus.java b/java/src/com/ctre/phoenix/motion/MotionProfileStatus.java
new file mode 100644
index 0000000..5901a75
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motion/MotionProfileStatus.java
@@ -0,0 +1,57 @@
+package com.ctre.phoenix.motion;
+
+/**
+ * Motion Profile Status This is simply a data transer object.
+ */
+public class MotionProfileStatus {
+ /**
+ * The available empty slots in the trajectory buffer.
+ *
+ * The robot API holds a "top buffer" of trajectory points, so your
+ * applicaion can dump several points at once. The API will then stream them
+ * into the Talon's low-level buffer, allowing the Talon to act on them.
+ */
+ public int topBufferRem;
+ /**
+ * The number of points in the top trajectory buffer.
+ */
+ public int topBufferCnt;
+ /**
+ * The number of points in the low level Talon buffer.
+ */
+ public int btmBufferCnt;
+ /**
+ * Set if isUnderrun ever gets set. Only is cleared by
+ * clearMotionProfileHasUnderrun() to ensure robot logic can react or
+ * instrument it.
+ *
+ * @see com.ctre.phoenix.motorcontrol.can.BaseMotorController#clearMotionProfileHasUnderrun(int)
+ */
+ public boolean hasUnderrun;
+ /**
+ * This is set if Talon needs to shift a point from its buffer into the
+ * active trajectory point however the buffer is empty. This gets cleared
+ * automatically when is resolved.
+ */
+ public boolean isUnderrun;
+ /**
+ * True if the active trajectory point has not empty, false otherwise. The
+ * members in activePoint are only valid if this signal is set.
+ */
+ public boolean activePointValid;
+
+ public boolean isLast;
+
+ public int profileSlotSelect;
+ /**
+ * The current output mode of the motion profile executer (disabled,
+ * enabled, or hold). When changing the set() value in MP mode, it's
+ * important to check this signal to confirm the change takes effect before
+ * interacting with the top buffer.
+ */
+ public SetValueMotionProfile outputEnable;
+
+ public int timeDurMs;
+
+ public int profileSlotSelect1;
+}
diff --git a/java/src/com/ctre/phoenix/motion/SetValueMotionProfile.java b/java/src/com/ctre/phoenix/motion/SetValueMotionProfile.java
new file mode 100644
index 0000000..82210c4
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motion/SetValueMotionProfile.java
@@ -0,0 +1,20 @@
+package com.ctre.phoenix.motion;
+
+public enum SetValueMotionProfile {
+ Invalid(-1), Disable(0), Enable(1), Hold(2);
+
+ public final int value;
+
+ SetValueMotionProfile(int initValue) {
+ this.value = initValue;
+ }
+
+ public static SetValueMotionProfile valueOf(int value) {
+ for (SetValueMotionProfile e : SetValueMotionProfile.values()) {
+ if (e.value == value) {
+ return e;
+ }
+ }
+ return Invalid;
+ }
+}
diff --git a/java/src/com/ctre/phoenix/motion/TrajectoryPoint.java b/java/src/com/ctre/phoenix/motion/TrajectoryPoint.java
new file mode 100644
index 0000000..293038f
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motion/TrajectoryPoint.java
@@ -0,0 +1,85 @@
+package com.ctre.phoenix.motion;
+
+/**
+ * Motion Profile Trajectory Point This is simply a data transfer object.
+ */
+public class TrajectoryPoint {
+ /**
+ * Duration to apply to a particular trajectory pt.
+ * This time unit is ADDED to the existing base time set by
+ * configMotionProfileTrajectoryPeriod().
+ */
+ public enum TrajectoryDuration
+ {
+ Trajectory_Duration_0ms(0),
+ Trajectory_Duration_5ms(5),
+ Trajectory_Duration_10ms(10),
+ Trajectory_Duration_20ms(20),
+ Trajectory_Duration_30ms(30),
+ Trajectory_Duration_40ms(40),
+ Trajectory_Duration_50ms(50),
+ Trajectory_Duration_100ms(100);
+
+ public int value = 5;
+
+ private TrajectoryDuration(int value)
+ {
+ this.value = value;
+ }
+
+ public TrajectoryDuration valueOf(int val)
+ {
+ for(TrajectoryDuration td: TrajectoryDuration.values())
+ {
+ if(td.value == val) return td;
+ }
+ return Trajectory_Duration_100ms;
+ }
+ }
+
+ public double position; // !< The position to servo to.
+ public double velocity; // !< The velocity to feed-forward.
+ public double headingDeg; // !< Not used. Use auxiliaryPos instead. @see auxiliaryPos
+ public double auxiliaryPos; // !< The position for auxiliary PID to target.
+
+ /**
+ * Which slot to get PIDF gains. PID is used for position servo. F is used
+ * as the Kv constant for velocity feed-forward. Typically this is hard-coded
+ * to a particular slot, but you are free to gain schedule if need be.
+ * Choose from [0,3]
+ */
+ public int profileSlotSelect0;
+
+ /**
+ * Which slot to get PIDF gains for auxiliary PId.
+ * This only has impact during MotionProfileArc Control mode.
+ * Choose from [0,1].
+ */
+ public int profileSlotSelect1;
+
+ /**
+ * Set to true to signal Talon that this is the final point, so do not
+ * attempt to pop another trajectory point from out of the Talon buffer.
+ * Instead continue processing this way point. Typically the velocity member
+ * variable should be zero so that the motor doesn't spin indefinitely.
+ */
+ public boolean isLastPoint;
+ /**
+ * Set to true to signal Talon to zero the selected sensor. When generating
+ * MPs, one simple method is to make the first target position zero, and the
+ * final target position the target distance from the current position. Then
+ * when you fire the MP, the current position gets set to zero. If this is
+ * the intent, you can set zeroPos on the first trajectory point.
+ *
+ * Otherwise you can leave this false for all points, and offset the
+ * positions of all trajectory points so they are correct.
+ */
+ public boolean zeroPos;
+
+ /**
+ * Duration to apply this trajectory pt.
+ * This time unit is ADDED to the existing base time set by
+ * configMotionProfileTrajectoryPeriod().
+ */
+ public TrajectoryDuration timeDur;
+}
diff --git a/java/src/com/ctre/phoenix/motorcontrol/ControlFrame.java b/java/src/com/ctre/phoenix/motorcontrol/ControlFrame.java
new file mode 100644
index 0000000..5b77424
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/ControlFrame.java
@@ -0,0 +1,14 @@
+package com.ctre.phoenix.motorcontrol;
+
+public enum ControlFrame
+{
+ Control_3_General(0x040080),
+ Control_4_Advanced(0x0400C0),
+ Control_6_MotProfAddTrajPoint(0x040140);
+
+ public final int value;
+ ControlFrame(int initValue)
+ {
+ this.value = initValue;
+ }
+};
diff --git a/java/src/com/ctre/phoenix/motorcontrol/ControlFrameEnhanced.java b/java/src/com/ctre/phoenix/motorcontrol/ControlFrameEnhanced.java
new file mode 100644
index 0000000..adc6512
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/ControlFrameEnhanced.java
@@ -0,0 +1,16 @@
+package com.ctre.phoenix.motorcontrol;
+
+public enum ControlFrameEnhanced
+{
+ Control_2_Enable_50m(0x040040),
+ Control_3_General(0x040080),
+ Control_4_Advanced(0x0400C0),
+ Control_5_FeedbackOutputOverride(0x040100),
+ Control_6_MotProfAddTrajPoint(0x040140);
+
+ public final int value;
+ ControlFrameEnhanced(int initValue)
+ {
+ this.value = initValue;
+ }
+};
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/motorcontrol/ControlMode.java b/java/src/com/ctre/phoenix/motorcontrol/ControlMode.java
new file mode 100644
index 0000000..834a8ce
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/ControlMode.java
@@ -0,0 +1,21 @@
+package com.ctre.phoenix.motorcontrol;
+
+public enum ControlMode
+{
+ PercentOutput(0),
+ Position(1),
+ Velocity(2),
+ Current(3),
+ Follower(5),
+ MotionProfile(6),
+ MotionMagic(7),
+ MotionProfileArc(10),
+
+ Disabled(15);
+
+ public final int value;
+ ControlMode(int initValue)
+ {
+ this.value = initValue;
+ }
+};
diff --git a/java/src/com/ctre/phoenix/motorcontrol/DemandType.java b/java/src/com/ctre/phoenix/motorcontrol/DemandType.java
new file mode 100644
index 0000000..b0688bb
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/DemandType.java
@@ -0,0 +1,25 @@
+package com.ctre.phoenix.motorcontrol;
+
+public enum DemandType {
+ /**
+ * Ignore the demand value and apply neutral/no-change.
+ */
+ Neutral(0),
+ /**
+ * When closed-looping, set the target of the aux PID loop to the demand value.
+ *
+ * When following, follow the processed output of the combined
+ * primary/aux PID output. The demand value is ignored.
+ */
+ AuxPID(1), //!< Target value of PID loop 1. When f
+ /**
+ * When closed-looping, add this arbitrarily to the closed-loop output.
+ */
+ ArbitraryFeedForward(2); //!< Simply add to the output
+
+ public int value;
+ DemandType(int value)
+ {
+ this.value = value;
+ }
+};
diff --git a/java/src/com/ctre/phoenix/motorcontrol/Faults.java b/java/src/com/ctre/phoenix/motorcontrol/Faults.java
new file mode 100644
index 0000000..47f5c91
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/Faults.java
@@ -0,0 +1,88 @@
+package com.ctre.phoenix.motorcontrol;
+
+public class Faults {
+ public boolean UnderVoltage;
+ public boolean ForwardLimitSwitch;
+ public boolean ReverseLimitSwitch;
+ public boolean ForwardSoftLimit;
+ public boolean ReverseSoftLimit;
+ public boolean HardwareFailure;
+ public boolean ResetDuringEn;
+ public boolean SensorOverflow;
+ public boolean SensorOutOfPhase;
+ public boolean HardwareESDReset;
+ public boolean RemoteLossOfSignal;
+ //!< True iff any of the above flags are true.
+ public boolean hasAnyFault() {
+ return UnderVoltage |
+ ForwardLimitSwitch |
+ ReverseLimitSwitch |
+ ForwardSoftLimit |
+ ReverseSoftLimit |
+ HardwareFailure |
+ ResetDuringEn |
+ SensorOverflow |
+ SensorOutOfPhase |
+ HardwareESDReset |
+ RemoteLossOfSignal;
+ }
+ public int toBitfield() {
+ int retval = 0;
+ int mask = 1;
+ retval |= UnderVoltage ? mask : 0; mask <<= 1;
+ retval |= ForwardLimitSwitch ? mask : 0; mask <<= 1;
+ retval |= ReverseLimitSwitch ? mask : 0; mask <<= 1;
+ retval |= ForwardSoftLimit ? mask : 0; mask <<= 1;
+ retval |= ReverseSoftLimit ? mask : 0; mask <<= 1;
+ retval |= HardwareFailure ? mask : 0; mask <<= 1;
+ retval |= ResetDuringEn ? mask : 0; mask <<= 1;
+ retval |= SensorOverflow ? mask : 0; mask <<= 1;
+ retval |= SensorOutOfPhase ? mask : 0; mask <<= 1;
+ retval |= HardwareESDReset ? mask : 0; mask <<= 1;
+ retval |= RemoteLossOfSignal ? mask : 0; mask <<= 1;
+ return retval;
+ }
+ public void update(int bits) {
+ int mask = 1;
+ UnderVoltage = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ ForwardLimitSwitch = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ ReverseLimitSwitch = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ ForwardSoftLimit = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ ReverseSoftLimit = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ HardwareFailure = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ ResetDuringEn = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ SensorOverflow = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ SensorOutOfPhase = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ HardwareESDReset = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ RemoteLossOfSignal = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ }
+ public Faults() {
+ UnderVoltage = false;
+ ForwardLimitSwitch = false;
+ ReverseLimitSwitch = false;
+ ForwardSoftLimit = false;
+ ReverseSoftLimit = false;
+ HardwareFailure =false;
+ ResetDuringEn = false;
+ SensorOverflow = false;
+ SensorOutOfPhase = false;
+ HardwareESDReset = false;
+ RemoteLossOfSignal = false;
+ }
+ public String toString() {
+ StringBuilder work = new StringBuilder();
+ work.append(" UnderVoltage:"); work.append(UnderVoltage ? "1" : "0");
+ work.append( " ForwardLimitSwitch:"); work.append(ForwardLimitSwitch ? "1" : "0");
+ work.append( " ReverseLimitSwitch:"); work.append(ReverseLimitSwitch ? "1" : "0");
+ work.append( " ForwardSoftLimit:"); work.append(ForwardSoftLimit ? "1" : "0");
+ work.append( " ReverseSoftLimit:"); work.append(ReverseSoftLimit ? "1" : "0");
+ work.append( " HardwareFailure:"); work.append(HardwareFailure ? "1" : "0");
+ work.append( " ResetDuringEn:"); work.append(ResetDuringEn ? "1" : "0");
+ work.append( " SensorOverflow:"); work.append(SensorOverflow ? "1" : "0");
+ work.append( " SensorOutOfPhase:"); work.append(SensorOutOfPhase ? "1" : "0");
+ work.append( " HardwareESDReset:"); work.append(HardwareESDReset ? "1" : "0");
+ work.append( " RemoteLossOfSignal:"); work.append(RemoteLossOfSignal ? "1" : "0");
+ return work.toString();
+ }
+};
+
diff --git a/java/src/com/ctre/phoenix/motorcontrol/FeedbackDevice.java b/java/src/com/ctre/phoenix/motorcontrol/FeedbackDevice.java
new file mode 100644
index 0000000..56b457d
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/FeedbackDevice.java
@@ -0,0 +1,25 @@
+package com.ctre.phoenix.motorcontrol;
+
+public enum FeedbackDevice {
+ None(-1),
+
+ QuadEncoder(0),
+ Analog(2),
+ Tachometer(4),
+ PulseWidthEncodedPosition(8),
+
+ SensorSum(9),
+ SensorDifference(10),
+ RemoteSensor0(11),
+ RemoteSensor1(12),
+ SoftwareEmulatedSensor(15),
+
+ CTRE_MagEncoder_Absolute(8),
+ CTRE_MagEncoder_Relative(0);
+
+ public final int value;
+ FeedbackDevice(int initValue)
+ {
+ this.value = initValue;
+ }
+};
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/motorcontrol/FollowerType.java b/java/src/com/ctre/phoenix/motorcontrol/FollowerType.java
new file mode 100644
index 0000000..57a0d37
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/FollowerType.java
@@ -0,0 +1,12 @@
+package com.ctre.phoenix.motorcontrol;
+
+public enum FollowerType {
+ PercentOutput(0),
+ AuxOutput1(1);
+
+ public int value;
+ FollowerType(int value)
+ {
+ this.value = value;
+ }
+};
diff --git a/java/src/com/ctre/phoenix/motorcontrol/GroupMotorControllers.java b/java/src/com/ctre/phoenix/motorcontrol/GroupMotorControllers.java
new file mode 100644
index 0000000..70bb15a
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/GroupMotorControllers.java
@@ -0,0 +1,23 @@
+package com.ctre.phoenix.motorcontrol;
+
+import java.util.*;
+
+public class GroupMotorControllers
+{
+ static List<IMotorController> _ms = new ArrayList<IMotorController>();
+
+ public static void register(IMotorController mc)
+ {
+ _ms.add(mc);
+ }
+
+ public static int getCount()
+ {
+ return _ms.size();
+ }
+
+ public static IMotorController get(int idx)
+ {
+ return _ms.get(idx);
+ }
+}
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/motorcontrol/IFollower.java b/java/src/com/ctre/phoenix/motorcontrol/IFollower.java
new file mode 100644
index 0000000..c31ee04
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/IFollower.java
@@ -0,0 +1,8 @@
+package com.ctre.phoenix.motorcontrol;
+import com.ctre.phoenix.motorcontrol.IMotorController;
+
+public interface IFollower
+{
+ void follow(IMotorController masterToFollow);
+ void valueUpdated();
+}
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/motorcontrol/IMotorController.java b/java/src/com/ctre/phoenix/motorcontrol/IMotorController.java
new file mode 100644
index 0000000..8eb6a20
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/IMotorController.java
@@ -0,0 +1,204 @@
+package com.ctre.phoenix.motorcontrol;
+
+import com.ctre.phoenix.ErrorCode;
+import com.ctre.phoenix.ParamEnum;
+import com.ctre.phoenix.motion.MotionProfileStatus;
+import com.ctre.phoenix.motion.TrajectoryPoint;
+
+public interface IMotorController
+ extends com.ctre.phoenix.signals.IOutputSignal, com.ctre.phoenix.signals.IInvertable, IFollower {
+ // ------ Set output routines. ----------//
+ public void set(ControlMode Mode, double demand);
+
+ public void set(ControlMode Mode, double demand0, double demand1);
+
+ public void set(ControlMode Mode, double demand0, DemandType demand1Type, double demand1);
+
+ public void neutralOutput();
+
+ public void setNeutralMode(NeutralMode neutralMode);
+
+ // ------ Invert behavior ----------//
+ public void setSensorPhase(boolean PhaseSensor);
+
+ public void setInverted(boolean invert);
+
+ public boolean getInverted();
+
+ // ----- general output shaping ------------------//
+ public ErrorCode configOpenloopRamp(double secondsFromNeutralToFull, int timeoutMs);
+
+ public ErrorCode configClosedloopRamp(double secondsFromNeutralToFull, int timeoutMs);
+
+ public ErrorCode configPeakOutputForward(double percentOut, int timeoutMs);
+
+ public ErrorCode configPeakOutputReverse(double percentOut, int timeoutMs);
+
+ public ErrorCode configNominalOutputForward(double percentOut, int timeoutMs);
+
+ public ErrorCode configNominalOutputReverse(double percentOut, int timeoutMs);
+
+ public ErrorCode configNeutralDeadband(double percentDeadband, int timeoutMs);
+
+ // ------ Voltage Compensation ----------//
+ public ErrorCode configVoltageCompSaturation(double voltage, int timeoutMs);
+
+ public ErrorCode configVoltageMeasurementFilter(int filterWindowSamples, int timeoutMs);
+
+ public void enableVoltageCompensation(boolean enable);
+
+ // ------ General Status ----------//
+ public double getBusVoltage() ;
+
+ public double getMotorOutputPercent() ;
+
+ public double getMotorOutputVoltage() ;
+
+ public double getOutputCurrent() ;
+
+ public double getTemperature() ;
+
+ // ------ sensor selection ----------//
+ public ErrorCode configSelectedFeedbackSensor(RemoteFeedbackDevice feedbackDevice, int pidIdx, int timeoutMs);
+
+ public ErrorCode configSelectedFeedbackCoefficient(double coefficient, int pidIdx, int timeoutMs);
+
+ public ErrorCode configRemoteFeedbackFilter(int deviceID, RemoteSensorSource remoteSensorSource, int remoteOrdinal,
+ int timeoutMs);
+
+ public ErrorCode configSensorTerm(SensorTerm sensorTerm, FeedbackDevice feedbackDevice, int timeoutMs);
+
+ // ------- sensor status --------- //
+ public int getSelectedSensorPosition(int pidIdx);
+
+ public int getSelectedSensorVelocity(int pidIdx);
+
+ public ErrorCode setSelectedSensorPosition(int sensorPos, int pidIdx, int timeoutMs);
+
+ // ------ status frame period changes ----------//
+ public ErrorCode setControlFramePeriod(ControlFrame frame, int periodMs);
+
+ public ErrorCode setStatusFramePeriod(StatusFrame frame, int periodMs, int timeoutMs);
+
+ public int getStatusFramePeriod(StatusFrame frame, int timeoutMs);
+
+ //----- velocity signal conditionaing ------//
+ /* not supported */
+
+ //------ remote limit switch ----------//
+ public ErrorCode configForwardLimitSwitchSource(RemoteLimitSwitchSource type, LimitSwitchNormal normalOpenOrClose,
+ int deviceID, int timeoutMs);
+
+ public ErrorCode configReverseLimitSwitchSource(RemoteLimitSwitchSource type, LimitSwitchNormal normalOpenOrClose,
+ int deviceID, int timeoutMs);
+
+ public void overrideLimitSwitchesEnable(boolean enable);
+
+ // ------ local limit switch ----------//
+ /* not supported */
+
+ // ------ soft limit ----------//
+ public ErrorCode configForwardSoftLimitThreshold(int forwardSensorLimit, int timeoutMs);
+
+ public ErrorCode configReverseSoftLimitThreshold(int reverseSensorLimit, int timeoutMs);
+
+ public ErrorCode configForwardSoftLimitEnable(boolean enable, int timeoutMs);
+
+ public ErrorCode configReverseSoftLimitEnable(boolean enable, int timeoutMs);
+
+ public void overrideSoftLimitsEnable(boolean enable);
+
+ // ------ Current Lim ----------//
+ /* not supported */
+
+ // ------ General Close loop ----------//
+ public ErrorCode config_kP(int slotIdx, double value, int timeoutMs);
+
+ public ErrorCode config_kI(int slotIdx, double value, int timeoutMs);
+
+ public ErrorCode config_kD(int slotIdx, double value, int timeoutMs);
+
+ public ErrorCode config_kF(int slotIdx, double value, int timeoutMs);
+
+ public ErrorCode config_IntegralZone(int slotIdx, int izone, int timeoutMs);
+
+ public ErrorCode configAllowableClosedloopError(int slotIdx, int allowableCloseLoopError, int timeoutMs);
+
+ public ErrorCode configMaxIntegralAccumulator(int slotIdx, double iaccum, int timeoutMs);
+
+ public ErrorCode configClosedLoopPeakOutput(int slotIdx, double percentOut, int timeoutMs);
+
+ public ErrorCode configClosedLoopPeriod(int slotIdx, int loopTimeMs, int timeoutMs);
+
+ public ErrorCode configAuxPIDPolarity(boolean invert, int timeoutMs);
+
+ //------ Close loop State ----------//
+ public ErrorCode setIntegralAccumulator(double iaccum, int pidIdx, int timeoutMs);
+
+ public int getClosedLoopError(int pidIdx);
+
+ public double getIntegralAccumulator(int pidIdx) ;
+
+ public double getErrorDerivative(int pidIdx) ;
+
+ public void selectProfileSlot(int slotIdx, int pidIdx);
+
+ public int getClosedLoopTarget(int pidIdx); // will be added to JNI
+
+ public int getActiveTrajectoryPosition();
+
+ public int getActiveTrajectoryVelocity();
+
+ public double getActiveTrajectoryHeading();
+
+ // ------ Motion Profile Settings used in Motion Magic and Motion Profile
+ public ErrorCode configMotionCruiseVelocity(int sensorUnitsPer100ms, int timeoutMs);
+
+ public ErrorCode configMotionAcceleration(int sensorUnitsPer100msPerSec, int timeoutMs);
+
+ public ErrorCode configMotionProfileTrajectoryPeriod(int baseTrajDurationMs, int timeoutMs);
+
+ // ------ Motion Profile Buffer ----------//
+ public ErrorCode clearMotionProfileTrajectories();
+ public int getMotionProfileTopLevelBufferCount();
+ public ErrorCode pushMotionProfileTrajectory(TrajectoryPoint trajPt);
+ public boolean isMotionProfileTopLevelBufferFull();
+ public void processMotionProfileBuffer();
+ public ErrorCode getMotionProfileStatus(MotionProfileStatus statusToFill);
+ public ErrorCode clearMotionProfileHasUnderrun(int timeoutMs);
+ public ErrorCode changeMotionControlFramePeriod(int periodMs);
+
+ // ------ error ----------//
+ public ErrorCode getLastError();
+
+ // ------ Faults ----------//
+ public ErrorCode getFaults(Faults toFill) ;
+
+ public ErrorCode getStickyFaults(StickyFaults toFill) ;
+
+ public ErrorCode clearStickyFaults(int timeoutMs);
+
+ // ------ Firmware ----------//
+ public int getFirmwareVersion();
+
+ public boolean hasResetOccurred();
+
+ // ------ Custom Persistent Params ----------//
+ public ErrorCode configSetCustomParam(int newValue, int paramIndex, int timeoutMs);
+
+ public int configGetCustomParam(int paramIndex, int timoutMs);
+
+ //------ Generic Param API, typically not used ----------//
+ public ErrorCode configSetParameter(ParamEnum param, double value, int subValue, int ordinal, int timeoutMs);
+ public ErrorCode configSetParameter(int param, double value, int subValue, int ordinal, int timeoutMs);
+
+ public double configGetParameter(ParamEnum paramEnum, int ordinal, int timeoutMs) ;
+ public double configGetParameter(int paramEnum, int ordinal, int timeoutMs) ;
+
+ //------ Misc. ----------//
+ public int getBaseID();
+ public int getDeviceID();
+ public ControlMode getControlMode();
+ // ----- Follower ------//
+ /* in parent interface */
+}
diff --git a/java/src/com/ctre/phoenix/motorcontrol/IMotorControllerEnhanced.java b/java/src/com/ctre/phoenix/motorcontrol/IMotorControllerEnhanced.java
new file mode 100644
index 0000000..5f93c2d
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/IMotorControllerEnhanced.java
@@ -0,0 +1,86 @@
+package com.ctre.phoenix.motorcontrol;
+
+import com.ctre.phoenix.ErrorCode;
+
+public interface IMotorControllerEnhanced extends IMotorController {
+ //------ Set output routines. ----------//
+ /* in parent */
+
+ //------ Invert behavior ----------//
+ /* in parent */
+
+ //----- general output shaping ------------------//
+ /* in parent */
+
+ //------ Voltage Compensation ----------//
+ /* in parent */
+
+ //------ General Status ----------//
+ /* in parent */
+
+ //------ sensor selection ----------//
+ /* expand the options */
+ public ErrorCode configSelectedFeedbackSensor(FeedbackDevice feedbackDevice, int pidIdx, int timeoutMs );
+
+ //------- sensor status --------- //
+ /* in parent */
+
+ //------ status frame period changes ----------//
+ public ErrorCode setStatusFramePeriod(StatusFrameEnhanced frame, int periodMs, int timeoutMs );
+ public int getStatusFramePeriod(StatusFrameEnhanced frame, int timeoutMs );
+
+ //----- velocity signal conditionaing ------//
+ public ErrorCode configVelocityMeasurementPeriod(VelocityMeasPeriod period, int timeoutMs );
+ public ErrorCode configVelocityMeasurementWindow(int windowSize, int timeoutMs );
+
+ //------ remote limit switch ----------//
+ /* in parent */
+
+ //------ local limit switch ----------//
+ public ErrorCode configForwardLimitSwitchSource(LimitSwitchSource type, LimitSwitchNormal normalOpenOrClose, int timeoutMs );
+ public ErrorCode configReverseLimitSwitchSource(LimitSwitchSource type, LimitSwitchNormal normalOpenOrClose, int timeoutMs );
+
+ //------ soft limit ----------//
+ /* in parent */
+
+ //------ Current Lim ----------//
+ public ErrorCode configPeakCurrentLimit(int amps, int timeoutMs );
+ public ErrorCode configPeakCurrentDuration(int milliseconds, int timeoutMs );
+ public ErrorCode configContinuousCurrentLimit(int amps, int timeoutMs );
+ public void enableCurrentLimit(boolean enable);
+
+ //------ General Close loop ----------//
+ /* in parent */
+
+ //------ Motion Profile Settings used in Motion Magic and Motion Profile ----------//
+ /* in parent */
+
+ //------ Motion Profile Buffer ----------//
+ /* in parent */
+
+ //------ error ----------//
+ /* in parent */
+
+ //------ Faults ----------//
+ /* in parent */
+
+ //------ Firmware ----------//
+ /* in parent */
+
+ //------ Custom Persistent Params ----------//
+ /* in parent */
+
+ //------ Generic Param API, typically not used ----------//
+ /* in parent */
+
+ //------ Misc. ----------//
+ /* in parent */
+
+ //------ RAW Sensor API ----------//
+ /**
+ * @retrieve object that can get/set individual RAW sensor values.
+ */
+ //SensorCollection SensorCollection { get; }
+
+
+}
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/motorcontrol/LimitSwitchNormal.java b/java/src/com/ctre/phoenix/motorcontrol/LimitSwitchNormal.java
new file mode 100644
index 0000000..139de84
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/LimitSwitchNormal.java
@@ -0,0 +1,11 @@
+package com.ctre.phoenix.motorcontrol;
+
+public enum LimitSwitchNormal {
+ NormallyOpen(0), NormallyClosed(1), Disabled(2);
+
+ public int value;
+
+ LimitSwitchNormal(int value) {
+ this.value = value;
+ }
+};
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/motorcontrol/LimitSwitchSource.java b/java/src/com/ctre/phoenix/motorcontrol/LimitSwitchSource.java
new file mode 100644
index 0000000..5118402
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/LimitSwitchSource.java
@@ -0,0 +1,11 @@
+package com.ctre.phoenix.motorcontrol;
+
+public enum LimitSwitchSource {
+ FeedbackConnector(0), RemoteTalonSRX(1), RemoteCANifier(2), Deactivated(3);
+
+ public int value;
+
+ LimitSwitchSource(int value) {
+ this.value = value;
+ }
+};
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/motorcontrol/NeutralMode.java b/java/src/com/ctre/phoenix/motorcontrol/NeutralMode.java
new file mode 100644
index 0000000..e2f56c2
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/NeutralMode.java
@@ -0,0 +1,17 @@
+package com.ctre.phoenix.motorcontrol;
+
+public enum NeutralMode {
+ /** Use the NeutralMode that is set by the jumper wire on the CAN device */
+ EEPROMSetting(0),
+ /** Do not attempt to stop the motor. Instead allow it to coast to a stop
+ without applying resistance. */
+ Coast(1),
+ /** Stop the motor's rotation by applying a force. */
+ Brake(2);
+
+ public int value;
+ NeutralMode(int value)
+ {
+ this.value = value;
+ }
+};
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/motorcontrol/RemoteFeedbackDevice.java b/java/src/com/ctre/phoenix/motorcontrol/RemoteFeedbackDevice.java
new file mode 100644
index 0000000..e2c54aa
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/RemoteFeedbackDevice.java
@@ -0,0 +1,17 @@
+package com.ctre.phoenix.motorcontrol;
+
+public enum RemoteFeedbackDevice {
+ None(-1),
+
+ SensorSum(9),
+ SensorDifference(10),
+ RemoteSensor0(11),
+ RemoteSensor1(12),
+ SoftwareEmulatedSensor(15);
+
+ public final int value;
+ RemoteFeedbackDevice(int initValue)
+ {
+ this.value = initValue;
+ }
+};
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/motorcontrol/RemoteLimitSwitchSource.java b/java/src/com/ctre/phoenix/motorcontrol/RemoteLimitSwitchSource.java
new file mode 100644
index 0000000..f634561
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/RemoteLimitSwitchSource.java
@@ -0,0 +1,11 @@
+package com.ctre.phoenix.motorcontrol;
+
+public enum RemoteLimitSwitchSource {
+ RemoteTalonSRX(1), RemoteCANifier(2), Deactivated(3);
+
+ public int value;
+
+ RemoteLimitSwitchSource(int value) {
+ this.value = value;
+ }
+};
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/motorcontrol/RemoteSensorSource.java b/java/src/com/ctre/phoenix/motorcontrol/RemoteSensorSource.java
new file mode 100644
index 0000000..dfdd4a8
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/RemoteSensorSource.java
@@ -0,0 +1,23 @@
+package com.ctre.phoenix.motorcontrol;
+
+public enum RemoteSensorSource {
+ Off(0),
+ TalonSRX_SelectedSensor(1),
+ Pigeon_Yaw(2),
+ Pigeon_Pitch(3),
+ Pigeon_Roll(4),
+ CANifier_Quadrature(5),
+ CANifier_PWMInput0(6),
+ CANifier_PWMInput1(7),
+ CANifier_PWMInput2(8),
+ CANifier_PWMInput3(9),
+ GadgeteerPigeon_Yaw(10),
+ GadgeteerPigeon_Pitch(11),
+ GadgeteerPigeon_Roll(12);
+
+ public int value;
+ RemoteSensorSource(int value)
+ {
+ this.value = value;
+ }
+};
diff --git a/java/src/com/ctre/phoenix/motorcontrol/SensorCollection.java b/java/src/com/ctre/phoenix/motorcontrol/SensorCollection.java
new file mode 100644
index 0000000..7045229
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/SensorCollection.java
@@ -0,0 +1,218 @@
+package com.ctre.phoenix.motorcontrol;
+
+import com.ctre.phoenix.ErrorCode;
+import com.ctre.phoenix.motorcontrol.can.BaseMotorController;
+import com.ctre.phoenix.motorcontrol.can.MotControllerJNI;
+
+public class SensorCollection {
+
+ private long _handle;
+
+ public SensorCollection(BaseMotorController motorController) {
+ _handle = motorController.getHandle();
+
+ }
+
+ /**
+ * Get the position of whatever is in the analog pin of the Talon, regardless of
+ * whether it is actually being used for feedback.
+ *
+ * @return the 24bit analog value. The bottom ten bits is the ADC (0 - 1023)
+ * on the analog pin of the Talon. The upper 14 bits tracks the overflows and underflows
+ * (continuous sensor).
+ */
+
+ public int getAnalogIn() {
+ return MotControllerJNI.GetAnalogIn(_handle);
+ }
+
+ /**
+ * Sets analog position.
+ *
+ * @param newPosition The new position.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ *
+ * @return an ErrorCode.
+ */
+
+ public ErrorCode setAnalogPosition(int newPosition, int timeoutMs) {
+ int retval = MotControllerJNI.SetAnalogPosition(_handle, newPosition, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Get the position of whatever is in the analog pin of the Talon, regardless of whether
+ * it is actually being used for feedback.
+ *
+ * @return the ADC (0 - 1023) on analog pin of the Talon.
+ */
+
+ public int getAnalogInRaw() {
+ return MotControllerJNI.GetAnalogInRaw(_handle);
+ }
+
+ /**
+ * Get the velocity of whatever is in the analog pin of the Talon, regardless of
+ * whether it is actually being used for feedback.
+ *
+ * @return the speed in units per 100ms where 1024 units is one rotation.
+ */
+
+ public int getAnalogInVel() {
+ return MotControllerJNI.GetAnalogInVel(_handle);
+ }
+
+ /**
+ * Get the quadrature position of the Talon, regardless of whether
+ * it is actually being used for feedback.
+ *
+ * @return the quadrature position.
+ */
+
+ public int getQuadraturePosition() {
+ return MotControllerJNI.GetQuadraturePosition(_handle);
+ }
+
+ /**
+ * Change the quadrature reported position. Typically this is used to "zero" the
+ * sensor. This only works with Quadrature sensor. To set the selected sensor position
+ * regardless of what type it is, see SetSelectedSensorPosition in the motor controller class.
+ *
+ * @param newPosition The position value to apply to the sensor.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ *
+ * @return error code.
+ */
+
+ public ErrorCode setQuadraturePosition(int newPosition, int timeoutMs) {
+ int retval = MotControllerJNI.SetQuadraturePosition(_handle, newPosition, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Get the quadrature velocity, regardless of whether
+ * it is actually being used for feedback.
+ *
+ * @return the quadrature velocity in units per 100ms.
+ */
+
+ public int getQuadratureVelocity() {
+ return MotControllerJNI.GetQuadratureVelocity(_handle);
+ }
+
+ /**
+ * Gets pulse width position, regardless of whether
+ * it is actually being used for feedback.
+ *
+ * @return the pulse width position.
+ */
+
+ public int getPulseWidthPosition() {
+ return MotControllerJNI.GetPulseWidthPosition(_handle);
+ }
+
+ /**
+ * Sets pulse width position.
+ *
+ * @param newPosition The position value to apply to the sensor.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ *
+ * @return an ErrErrorCode
+ */
+ public ErrorCode setPulseWidthPosition(int newPosition, int timeoutMs) {
+ int retval = MotControllerJNI.SetPulseWidthPosition(_handle, newPosition, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Gets pulse width velocity, regardless of whether
+ * it is actually being used for feedback.
+ *
+ * @return the pulse width velocity in units per 100ms (where 4096 units is 1 rotation).
+ */
+
+ public int getPulseWidthVelocity() {
+ return MotControllerJNI.GetPulseWidthVelocity(_handle);
+ }
+
+ /**
+ * Gets pulse width rise to fall time.
+ *
+ * @return the pulse width rise to fall time in microseconds.
+ */
+
+ public int getPulseWidthRiseToFallUs() {
+ return MotControllerJNI.GetPulseWidthRiseToFallUs(_handle);
+ }
+
+ /**
+ * Gets pulse width rise to rise time.
+ *
+ * @return the pulse width rise to rise time in microseconds.
+ */
+
+ public int getPulseWidthRiseToRiseUs() {
+ return MotControllerJNI.GetPulseWidthRiseToRiseUs(_handle);
+ }
+
+ /**
+ * Gets pin state quad a.
+ *
+ * @return the pin state of quad a (1 if asserted, 0 if not asserted).
+ */
+
+ public boolean getPinStateQuadA() {
+ return MotControllerJNI.GetPinStateQuadA(_handle) != 0;
+ }
+
+ /**
+ * Gets pin state quad b.
+ *
+ * @return Digital level of QUADB pin (1 if asserted, 0 if not asserted).
+ */
+
+ public boolean getPinStateQuadB() {
+ return MotControllerJNI.GetPinStateQuadB(_handle) != 0;
+ }
+
+ /**
+ * Gets pin state quad index.
+ *
+ * @return Digital level of QUAD Index pin (1 if asserted, 0 if not asserted).
+ */
+
+ public boolean getPinStateQuadIdx() {
+ return MotControllerJNI.GetPinStateQuadIdx(_handle) != 0;
+ }
+
+ /**
+ * Is forward limit switch closed.
+ *
+ * @return '1' iff forward limit switch is closed, 0 iff switch is open. This function works
+ * regardless if limit switch feature is enabled.
+ */
+
+ public boolean isFwdLimitSwitchClosed() {
+ return MotControllerJNI.IsFwdLimitSwitchClosed(_handle) != 0;
+ }
+
+ /**
+ * Is reverse limit switch closed.
+ *
+ * @return '1' iff reverse limit switch is closed, 0 iff switch is open. This function works
+ * regardless if limit switch feature is enabled.
+ */
+
+ public boolean isRevLimitSwitchClosed() {
+ return MotControllerJNI.IsRevLimitSwitchClosed(_handle) != 0;
+ }
+}
diff --git a/java/src/com/ctre/phoenix/motorcontrol/SensorTerm.java b/java/src/com/ctre/phoenix/motorcontrol/SensorTerm.java
new file mode 100644
index 0000000..8419a0d
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/SensorTerm.java
@@ -0,0 +1,14 @@
+package com.ctre.phoenix.motorcontrol;
+
+public enum SensorTerm {
+ Sum0(0),
+ Sum1(1),
+ Diff0(2),
+ Diff1(3);
+
+ public int value;
+ SensorTerm(int value)
+ {
+ this.value = value;
+ }
+};
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/motorcontrol/StatusFrame.java b/java/src/com/ctre/phoenix/motorcontrol/StatusFrame.java
new file mode 100644
index 0000000..e6108d6
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/StatusFrame.java
@@ -0,0 +1,30 @@
+package com.ctre.phoenix.motorcontrol;
+
+public enum StatusFrame {
+ Status_1_General(0x1400),
+ Status_2_Feedback0(0x1440),
+ Status_4_AinTempVbat(0x14C0),
+ Status_6_Misc(0x1540),
+ Status_7_CommStatus(0x1580),
+ Status_9_MotProfBuffer(0x1600),
+ /**
+ * Old name for Status 10 Frame.
+ * Use Status_10_Targets instead.
+ */
+ Status_10_MotionMagic(0x1640),
+ /**
+ * Correct name for Status 10 Frame.
+ * Functionally equivalent to Status_10_MotionMagic
+ */
+ Status_10_Targets(0x1640),
+ Status_12_Feedback1(0x16C0),
+ Status_13_Base_PIDF0(0x1700),
+ Status_14_Turn_PIDF1(0x1740),
+ Status_15_FirmwareApiStatus(0x1780);
+
+ public int value;
+ StatusFrame(int value)
+ {
+ this.value = value;
+ }
+};
diff --git a/java/src/com/ctre/phoenix/motorcontrol/StatusFrameEnhanced.java b/java/src/com/ctre/phoenix/motorcontrol/StatusFrameEnhanced.java
new file mode 100644
index 0000000..0a8c3c0
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/StatusFrameEnhanced.java
@@ -0,0 +1,25 @@
+package com.ctre.phoenix.motorcontrol;
+
+public enum StatusFrameEnhanced {
+ Status_1_General(0x1400),
+ Status_2_Feedback0(0x1440),
+ Status_4_AinTempVbat(0x14C0),
+ Status_6_Misc(0x1540),
+ Status_7_CommStatus(0x1580),
+ Status_9_MotProfBuffer(0x1600),
+ Status_10_MotionMagic(0x1640),
+ Status_12_Feedback1(0x16C0),
+ Status_13_Base_PIDF0(0x1700),
+ Status_14_Turn_PIDF1(0x1740),
+ Status_15_FirmareApiStatus(0x1780),
+
+ Status_3_Quadrature(0x1480),
+ Status_8_PulseWidth(0x15C0),
+ Status_11_UartGadgeteer(0x1680);
+
+ public int value;
+ StatusFrameEnhanced(int value)
+ {
+ this.value = value;
+ }
+};
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/motorcontrol/StickyFaults.java b/java/src/com/ctre/phoenix/motorcontrol/StickyFaults.java
new file mode 100644
index 0000000..e18f581
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/StickyFaults.java
@@ -0,0 +1,83 @@
+package com.ctre.phoenix.motorcontrol;
+
+public class StickyFaults {
+ public boolean UnderVoltage;
+ public boolean ForwardLimitSwitch;
+ public boolean ReverseLimitSwitch;
+ public boolean ForwardSoftLimit;
+ public boolean ReverseSoftLimit;
+ public boolean ResetDuringEn;
+ public boolean SensorOverflow;
+ public boolean SensorOutOfPhase;
+ public boolean HardwareESDReset;
+ public boolean RemoteLossOfSignal;
+
+ //!< True iff any of the above flags are true.
+ public boolean hasAnyFault() {
+ return UnderVoltage |
+ ForwardLimitSwitch |
+ ReverseLimitSwitch |
+ ForwardSoftLimit |
+ ReverseSoftLimit |
+ ResetDuringEn |
+ SensorOverflow |
+ SensorOutOfPhase |
+ HardwareESDReset |
+ RemoteLossOfSignal;
+ }
+ public int toBitfield() {
+ int retval = 0;
+ int mask = 1;
+ retval |= UnderVoltage ? mask : 0; mask <<= 1;
+ retval |= ForwardLimitSwitch ? mask : 0; mask <<= 1;
+ retval |= ReverseLimitSwitch ? mask : 0; mask <<= 1;
+ retval |= ForwardSoftLimit ? mask : 0; mask <<= 1;
+ retval |= ReverseSoftLimit ? mask : 0; mask <<= 1;
+ retval |= ResetDuringEn ? mask : 0; mask <<= 1;
+ retval |= SensorOverflow ? mask : 0; mask <<= 1;
+ retval |= SensorOutOfPhase ? mask : 0; mask <<= 1;
+ retval |= HardwareESDReset ? mask : 0; mask <<= 1;
+ retval |= RemoteLossOfSignal ? mask : 0; mask <<= 1;
+ return retval;
+ }
+ public void update(int bits) {
+ int mask = 1;
+ UnderVoltage = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ ForwardLimitSwitch = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ ReverseLimitSwitch = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ ForwardSoftLimit = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ ReverseSoftLimit = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ ResetDuringEn = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ SensorOverflow = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ SensorOutOfPhase = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ HardwareESDReset = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ RemoteLossOfSignal = ((bits & mask)!=0) ? true : false; mask <<= 1;
+ }
+ public StickyFaults() {
+ UnderVoltage = false;
+ ForwardLimitSwitch = false;
+ ReverseLimitSwitch = false;
+ ForwardSoftLimit = false;
+ ReverseSoftLimit = false;
+ ResetDuringEn = false;
+ SensorOverflow = false;
+ SensorOutOfPhase = false;
+ HardwareESDReset = false;
+ RemoteLossOfSignal = false;
+ }
+ public String toString() {
+ StringBuilder work = new StringBuilder();
+ work.append(" UnderVoltage:"); work.append(UnderVoltage ? "1" : "0");
+ work.append( " ForwardLimitSwitch:"); work.append(ForwardLimitSwitch ? "1" : "0");
+ work.append( " ReverseLimitSwitch:"); work.append(ReverseLimitSwitch ? "1" : "0");
+ work.append( " ForwardSoftLimit:"); work.append(ForwardSoftLimit ? "1" : "0");
+ work.append( " ReverseSoftLimit:"); work.append(ReverseSoftLimit ? "1" : "0");
+ work.append( " ResetDuringEn:"); work.append(ResetDuringEn ? "1" : "0");
+ work.append( " SensorOverflow:"); work.append(SensorOverflow ? "1" : "0");
+ work.append( " SensorOutOfPhase:"); work.append(SensorOutOfPhase ? "1" : "0");
+ work.append( " HardwareESDReset:"); work.append(HardwareESDReset ? "1" : "0");
+ work.append( " RemoteLossOfSignal:"); work.append(RemoteLossOfSignal ? "1" : "0");
+ return work.toString();
+ }
+};
+
diff --git a/java/src/com/ctre/phoenix/motorcontrol/VelocityMeasPeriod.java b/java/src/com/ctre/phoenix/motorcontrol/VelocityMeasPeriod.java
new file mode 100644
index 0000000..b708bb1
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/VelocityMeasPeriod.java
@@ -0,0 +1,18 @@
+package com.ctre.phoenix.motorcontrol;
+
+public enum VelocityMeasPeriod {
+ Period_1Ms(1),
+ Period_2Ms(2),
+ Period_5Ms(5),
+ Period_10Ms(10),
+ Period_20Ms(20),
+ Period_25Ms(25),
+ Period_50Ms(50),
+ Period_100Ms(100);
+
+ public int value;
+ VelocityMeasPeriod(int value)
+ {
+ this.value = value;
+ }
+};
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/motorcontrol/can/BaseMotorController.java b/java/src/com/ctre/phoenix/motorcontrol/can/BaseMotorController.java
new file mode 100644
index 0000000..0e15160
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/can/BaseMotorController.java
@@ -0,0 +1,1787 @@
+package com.ctre.phoenix.motorcontrol.can;
+
+import com.ctre.phoenix.motorcontrol.ControlFrame;
+import com.ctre.phoenix.motorcontrol.ControlMode;
+import com.ctre.phoenix.motorcontrol.DemandType;
+import com.ctre.phoenix.motorcontrol.Faults;
+import com.ctre.phoenix.motorcontrol.FeedbackDevice;
+import com.ctre.phoenix.motorcontrol.FollowerType;
+import com.ctre.phoenix.motorcontrol.IMotorController;
+import com.ctre.phoenix.motorcontrol.LimitSwitchNormal;
+import com.ctre.phoenix.motorcontrol.LimitSwitchSource;
+import com.ctre.phoenix.motorcontrol.NeutralMode;
+import com.ctre.phoenix.motorcontrol.RemoteFeedbackDevice;
+import com.ctre.phoenix.motorcontrol.RemoteLimitSwitchSource;
+import com.ctre.phoenix.motorcontrol.RemoteSensorSource;
+import com.ctre.phoenix.motorcontrol.SensorCollection;
+import com.ctre.phoenix.motorcontrol.SensorTerm;
+import com.ctre.phoenix.motorcontrol.StatusFrame;
+import com.ctre.phoenix.motorcontrol.StatusFrameEnhanced;
+import com.ctre.phoenix.motorcontrol.StickyFaults;
+import com.ctre.phoenix.motorcontrol.VelocityMeasPeriod;
+import com.ctre.phoenix.motorcontrol.can.MotControllerJNI;
+import com.ctre.phoenix.ParamEnum;
+import com.ctre.phoenix.motion.MotionProfileStatus;
+import com.ctre.phoenix.motion.SetValueMotionProfile;
+import com.ctre.phoenix.motion.TrajectoryPoint;
+import com.ctre.phoenix.ErrorCode;
+
+/**
+ * Base motor controller features for all CTRE CAN motor controllers.
+ */
+public abstract class BaseMotorController implements com.ctre.phoenix.motorcontrol.IMotorController {
+
+ private ControlMode m_controlMode = ControlMode.PercentOutput;
+ private ControlMode m_sendMode = ControlMode.PercentOutput;
+
+ private int _arbId = 0;
+ private boolean _invert = false;
+
+ protected long m_handle;
+
+ private int [] _motionProfStats = new int[11];
+
+ private SensorCollection _sensorColl;
+
+ // --------------------- Constructors -----------------------------//
+ /**
+ * Constructor for motor controllers.
+ *
+ * @param arbId
+ */
+ public BaseMotorController(int arbId) {
+ m_handle = MotControllerJNI.Create(arbId);
+ _arbId = arbId;
+
+ _sensorColl = new SensorCollection(this);
+ }
+ /**
+ * @return CCI handle for child classes.
+ */
+ public long getHandle() {
+ return m_handle;
+ }
+
+ /**
+ * Returns the Device ID
+ *
+ * @return Device number.
+ */
+ public int getDeviceID() {
+ return MotControllerJNI.GetDeviceNumber(m_handle);
+ }
+
+ // ------ Set output routines. ----------//
+ /**
+ * Sets the appropriate output on the talon, depending on the mode.
+ * @param mode The output mode to apply.
+ * In PercentOutput, the output is between -1.0 and 1.0, with 0.0 as stopped.
+ * In Current mode, output value is in amperes.
+ * In Velocity mode, output value is in position change / 100ms.
+ * In Position mode, output value is in encoder ticks or an analog value,
+ * depending on the sensor.
+ * In Follower mode, the output value is the integer device ID of the talon to
+ * duplicate.
+ *
+ * @param outputValue The setpoint value, as described above.
+ *
+ *
+ * Standard Driving Example:
+ * _talonLeft.set(ControlMode.PercentOutput, leftJoy);
+ * _talonRght.set(ControlMode.PercentOutput, rghtJoy);
+ */
+ public void set(ControlMode mode, double outputValue) {
+ set(mode, outputValue, DemandType.Neutral, 0);
+ }
+ /**
+ * @param mode Sets the appropriate output on the talon, depending on the mode.
+ * @param demand0 The output value to apply.
+ * such as advanced feed forward and/or auxiliary close-looping in firmware.
+ * In PercentOutput, the output is between -1.0 and 1.0, with 0.0 as stopped.
+ * In Current mode, output value is in amperes.
+ * In Velocity mode, output value is in position change / 100ms.
+ * In Position mode, output value is in encoder ticks or an analog value,
+ * depending on the sensor. See
+ * In Follower mode, the output value is the integer device ID of the talon to
+ * duplicate.
+ *
+ * @param demand1 Supplemental value. This will also be control mode specific for future features.
+ */
+ public void set(ControlMode mode, double demand0, double demand1) {
+ set(mode, demand0, DemandType.Neutral, demand1);
+ }
+ /**
+ * @param mode Sets the appropriate output on the talon, depending on the mode.
+ * @param demand0 The output value to apply.
+ * such as advanced feed forward and/or auxiliary close-looping in firmware.
+ * In PercentOutput, the output is between -1.0 and 1.0, with 0.0 as stopped.
+ * In Current mode, output value is in amperes.
+ * In Velocity mode, output value is in position change / 100ms.
+ * In Position mode, output value is in encoder ticks or an analog value,
+ * depending on the sensor. See
+ * In Follower mode, the output value is the integer device ID of the talon to
+ * duplicate.
+ *
+ * @param demand1Type The demand type for demand1.
+ * Neutral: Ignore demand1 and apply no change to the demand0 output.
+ * AuxPID: Use demand1 to set the target for the auxiliary PID 1.
+ * ArbitraryFeedForward: Use demand1 as an arbitrary additive value to the
+ * demand0 output. In PercentOutput the demand0 output is the motor output,
+ * and in closed-loop modes the demand0 output is the output of PID0.
+ * @param demand1 Supplmental output value. Units match the set mode.
+ *
+ *
+ * Arcade Drive Example:
+ * _talonLeft.set(ControlMode.PercentOutput, joyForward, DemandType.ArbitraryFeedForward, +joyTurn);
+ * _talonRght.set(ControlMode.PercentOutput, joyForward, DemandType.ArbitraryFeedForward, -joyTurn);
+ *
+ * Drive Straight Example:
+ * Note: Selected Sensor Configuration is necessary for both PID0 and PID1.
+ * _talonLeft.follow(_talonRght, FollwerType.AuxOutput1);
+ * _talonRght.set(ControlMode.PercentOutput, joyForward, DemandType.AuxPID, desiredRobotHeading);
+ *
+ * Drive Straight to a Distance Example:
+ * Note: Other configurations (sensor selection, PID gains, etc.) need to be set.
+ * _talonLeft.follow(_talonRght, FollwerType.AuxOutput1);
+ * _talonRght.set(ControlMode.MotionMagic, targetDistance, DemandType.AuxPID, desiredRobotHeading);
+ */
+ public void set(ControlMode mode, double demand0, DemandType demand1Type, double demand1){
+ m_controlMode = mode;
+ m_sendMode = mode;
+ int work;
+
+ switch (m_controlMode) {
+ case PercentOutput:
+ // case TimedPercentOutput:
+ MotControllerJNI.Set_4(m_handle, m_sendMode.value, demand0, demand1, demand1Type.value);
+ break;
+ case Follower:
+ /* did caller specify device ID */
+ if ((0 <= demand0) && (demand0 <= 62)) { // [0,62]
+ work = getBaseID();
+ work >>= 16;
+ work <<= 8;
+ work |= ((int) demand0) & 0xFF;
+ } else {
+ work = (int) demand0;
+ }
+ /* single precision guarantees 16bits of integral precision,
+ * so float/double cast on work is safe */
+ MotControllerJNI.Set_4(m_handle, m_sendMode.value, (double)work, demand1, demand1Type.value);
+ break;
+ case Velocity:
+ case Position:
+ case MotionMagic:
+ case MotionProfile:
+ case MotionProfileArc:
+ MotControllerJNI.Set_4(m_handle, m_sendMode.value, demand0, demand1, demand1Type.value);
+ break;
+ case Current:
+ MotControllerJNI.SetDemand(m_handle, m_sendMode.value, (int) (1000. * demand0), 0); /* milliamps */
+ break;
+ case Disabled:
+ /* fall thru... */
+ default:
+ MotControllerJNI.SetDemand(m_handle, m_sendMode.value, 0, 0);
+ break;
+ }
+
+ }
+
+ /**
+ * Neutral the motor output by setting control mode to disabled.
+ */
+ public void neutralOutput() {
+ set(ControlMode.Disabled, 0);
+ }
+
+ /**
+ * Sets the mode of operation during neutral throttle output.
+ *
+ * @param neutralMode
+ * The desired mode of operation when the Controller output
+ * throttle is neutral (ie brake/coast)
+ **/
+ public void setNeutralMode(NeutralMode neutralMode) {
+ MotControllerJNI.SetNeutralMode(m_handle, neutralMode.value);
+ }
+ /**
+ * Enables a future feature called "Heading Hold".
+ * For now this simply updates the CAN signal to the motor controller.
+ * Future firmware updates will use this.
+ *
+ * @param enable true/false enable
+ */
+ public void enableHeadingHold(boolean enable) {
+ /* this routine is moot as the Set() call updates the signal on each call */
+ //MotControllerJNI.EnableHeadingHold(m_handle, enable ? 1 : 0);
+ }
+ /**
+ * For now this simply updates the CAN signal to the motor controller.
+ * Future firmware updates will use this to control advanced auxiliary loop behavior.
+ *
+ * @param value
+ */
+ public void selectDemandType(boolean value) {
+ /* this routine is moot as the Set() call updates the signal on each call */
+ //MotControllerJNI.SelectDemandType(m_handle, value ? 1 : 0);
+ }
+
+ // ------ Invert behavior ----------//
+ /**
+ * Sets the phase of the sensor. Use when controller forward/reverse output
+ * doesn't correlate to appropriate forward/reverse reading of sensor.
+ * Pick a value so that positive PercentOutput yields a positive change in sensor.
+ * After setting this, user can freely call SetInvert() with any value.
+ *
+ * @param PhaseSensor
+ * Indicates whether to invert the phase of the sensor.
+ */
+ public void setSensorPhase(boolean PhaseSensor) {
+ MotControllerJNI.SetSensorPhase(m_handle, PhaseSensor);
+ }
+
+ /**
+ * Inverts the hbridge output of the motor controller.
+ *
+ * This does not impact sensor phase and should not be used to correct sensor polarity.
+ *
+ * This will invert the hbridge output but NOT the LEDs.
+ * This ensures....
+ * - Green LEDs always represents positive request from robot-controller/closed-looping mode.
+ * - Green LEDs correlates to forward limit switch.
+ * - Green LEDs correlates to forward soft limit.
+ *
+ * @param invert
+ * Invert state to set.
+ */
+ public void setInverted(boolean invert) {
+ _invert = invert; /* cache for getter */
+ MotControllerJNI.SetInverted(m_handle, invert);
+ }
+ /**
+ * @return invert setting of motor output.
+ */
+ public boolean getInverted() {
+ return _invert;
+ }
+
+ // ----- general output shaping ------------------//
+ /**
+ * Configures the open-loop ramp rate of throttle output.
+ *
+ * @param secondsFromNeutralToFull
+ * Minimum desired time to go from neutral to full throttle. A
+ * value of '0' will disable the ramp.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configOpenloopRamp(double secondsFromNeutralToFull, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigOpenLoopRamp(m_handle, secondsFromNeutralToFull, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Configures the closed-loop ramp rate of throttle output.
+ *
+ * @param secondsFromNeutralToFull
+ * Minimum desired time to go from neutral to full throttle. A
+ * value of '0' will disable the ramp.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configClosedloopRamp(double secondsFromNeutralToFull, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigClosedLoopRamp(m_handle, secondsFromNeutralToFull, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Configures the forward peak output percentage.
+ *
+ * @param percentOut
+ * Desired peak output percentage. [0,1]
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configPeakOutputForward(double percentOut, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigPeakOutputForward(m_handle, percentOut, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Configures the reverse peak output percentage.
+ *
+ * @param percentOut
+ * Desired peak output percentage.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configPeakOutputReverse(double percentOut, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigPeakOutputReverse(m_handle, percentOut, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Configures the forward nominal output percentage.
+ *
+ * @param percentOut
+ * Nominal (minimum) percent output. [0,+1]
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configNominalOutputForward(double percentOut, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigNominalOutputForward(m_handle, percentOut, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Configures the reverse nominal output percentage.
+ *
+ * @param percentOut
+ * Nominal (minimum) percent output. [-1,0]
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configNominalOutputReverse(double percentOut, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigNominalOutputReverse(m_handle, percentOut, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Configures the output deadband percentage.
+ *
+ * @param percentDeadband
+ * Desired deadband percentage. Minimum is 0.1%, Maximum is 25%.
+ * Pass 0.04 for 4% (factory default).
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configNeutralDeadband(double percentDeadband, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigNeutralDeadband(m_handle, percentDeadband, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ // ------ Voltage Compensation ----------//
+ /**
+ * Configures the Voltage Compensation saturation voltage.
+ *
+ * @param voltage
+ * This is the max voltage to apply to the hbridge when voltage
+ * compensation is enabled. For example, if 10 (volts) is specified
+ * and a TalonSRX is commanded to 0.5 (PercentOutput, closed-loop, etc)
+ * then the TalonSRX will attempt to apply a duty-cycle to produce 5V.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configVoltageCompSaturation(double voltage, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigVoltageCompSaturation(m_handle, voltage, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Configures the voltage measurement filter.
+ *
+ * @param filterWindowSamples
+ * Number of samples in the rolling average of voltage
+ * measurement.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configVoltageMeasurementFilter(int filterWindowSamples, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigVoltageMeasurementFilter(m_handle, filterWindowSamples, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Enables voltage compensation. If enabled, voltage compensation works in
+ * all control modes.
+ *
+ * @param enable
+ * Enable state of voltage compensation.
+ **/
+ public void enableVoltageCompensation(boolean enable) {
+ MotControllerJNI.EnableVoltageCompensation(m_handle, enable);
+ }
+
+ // ------ General Status ----------//
+ /**
+ * Gets the bus voltage seen by the device.
+ *
+ * @return The bus voltage value (in volts).
+ */
+ public double getBusVoltage() {
+ return MotControllerJNI.GetBusVoltage(m_handle);
+ }
+
+ /**
+ * Gets the output percentage of the motor controller.
+ *
+ * @return Output of the motor controller (in percent).
+ */
+ public double getMotorOutputPercent() {
+ return MotControllerJNI.GetMotorOutputPercent(m_handle);
+ }
+
+ /**
+ * @return applied voltage to motor in volts.
+ */
+ public double getMotorOutputVoltage() {
+ return getBusVoltage() * getMotorOutputPercent();
+ }
+
+ /**
+ * Gets the output current of the motor controller.
+ *
+ * @return The output current (in amps).
+ */
+ public double getOutputCurrent() {
+ return MotControllerJNI.GetOutputCurrent(m_handle);
+ }
+
+ /**
+ * Gets the temperature of the motor controller.
+ *
+ * @return Temperature of the motor controller (in 'C)
+ */
+ public double getTemperature() {
+ return MotControllerJNI.GetTemperature(m_handle);
+ }
+
+ // ------ sensor selection ----------//
+ /**
+ * Select the remote feedback device for the motor controller.
+ * Most CTRE CAN motor controllers will support remote sensors over CAN.
+ *
+ * @param feedbackDevice
+ * Remote Feedback Device to select.
+ * @param pidIdx
+ * 0 for Primary closed-loop. 1 for auxiliary closed-loop.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configSelectedFeedbackSensor(RemoteFeedbackDevice feedbackDevice, int pidIdx, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigSelectedFeedbackSensor(m_handle, feedbackDevice.value, pidIdx, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Select the feedback device for the motor controller.
+ *
+ * @param feedbackDevice
+ * Feedback Device to select.
+ * @param pidIdx
+ * 0 for Primary closed-loop. 1 for auxiliary closed-loop.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configSelectedFeedbackSensor(FeedbackDevice feedbackDevice, int pidIdx, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigSelectedFeedbackSensor(m_handle, feedbackDevice.value, pidIdx, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * The Feedback Coefficient is a scalar applied to the value of the
+ * feedback sensor. Useful when you need to scale your sensor values
+ * within the closed-loop calculations. Default value is 1.
+ *
+ * Selected Feedback Sensor register in firmware is the decoded sensor value
+ * multiplied by the Feedback Coefficient.
+ *
+ * @param coefficient
+ * Feedback Coefficient value. Maximum value of 1.
+ * Resolution is 1/(2^16). Cannot be 0.
+ * @param pidIdx
+ * 0 for Primary closed-loop. 1 for auxiliary closed-loop.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configSelectedFeedbackCoefficient(double coefficient, int pidIdx, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigSelectedFeedbackCoefficient(m_handle, coefficient, pidIdx, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Select what remote device and signal to assign to Remote Sensor 0 or Remote Sensor 1.
+ * After binding a remote device and signal to Remote Sensor X, you may select Remote Sensor X
+ * as a PID source for closed-loop features.
+ *
+ * @param deviceID
+ * The CAN ID of the remote sensor device.
+ * @param remoteSensorSource
+ * The remote sensor device and signal type to bind.
+ * @param remoteOrdinal
+ * 0 for configuring Remote Sensor 0
+ * 1 for configuring Remote Sensor 1
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configRemoteFeedbackFilter(int deviceID, RemoteSensorSource remoteSensorSource, int remoteOrdinal,
+ int timeoutMs) {
+ int retval = MotControllerJNI.ConfigRemoteFeedbackFilter(m_handle, deviceID, remoteSensorSource.value, remoteOrdinal,
+ timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Select what sensor term should be bound to switch feedback device.
+ * Sensor Sum = Sensor Sum Term 0 - Sensor Sum Term 1
+ * Sensor Difference = Sensor Diff Term 0 - Sensor Diff Term 1
+ * The four terms are specified with this routine. Then Sensor Sum/Difference
+ * can be selected for closed-looping.
+ *
+ * @param sensorTerm Which sensor term to bind to a feedback source.
+ * @param feedbackDevice The sensor signal to attach to sensorTerm.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configSensorTerm(SensorTerm sensorTerm, FeedbackDevice feedbackDevice, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigSensorTerm(m_handle, sensorTerm.value, feedbackDevice.value, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ // ------- sensor status --------- //
+ /**
+ * Get the selected sensor position (in raw sensor units).
+ *
+ * @param pidIdx
+ * 0 for Primary closed-loop. 1 for auxiliary closed-loop. See
+ * Phoenix-Documentation for how to interpret.
+ *
+ * @return Position of selected sensor (in raw sensor units).
+ */
+ public int getSelectedSensorPosition(int pidIdx) {
+ return MotControllerJNI.GetSelectedSensorPosition(m_handle, pidIdx);
+ }
+
+ /**
+ * Get the selected sensor velocity.
+ *
+ * @param pidIdx
+ * 0 for Primary closed-loop. 1 for auxiliary closed-loop.
+ * @return selected sensor (in raw sensor units) per 100ms.
+ * See Phoenix-Documentation for how to interpret.
+ */
+ public int getSelectedSensorVelocity(int pidIdx) {
+ return MotControllerJNI.GetSelectedSensorVelocity(m_handle, pidIdx);
+ }
+
+ /**
+ * Sets the sensor position to the given value.
+ *
+ * @param sensorPos
+ * Position to set for the selected sensor (in raw sensor units).
+ * @param pidIdx
+ * 0 for Primary closed-loop. 1 for auxiliary closed-loop.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setSelectedSensorPosition(int sensorPos, int pidIdx, int timeoutMs) {
+ int retval = MotControllerJNI.SetSelectedSensorPosition(m_handle, sensorPos, pidIdx, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ // ------ status frame period changes ----------//
+ /**
+ * Sets the period of the given control frame.
+ *
+ * @param frame
+ * Frame whose period is to be changed.
+ * @param periodMs
+ * Period in ms for the given frame.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setControlFramePeriod(ControlFrame frame, int periodMs) {
+ int retval = MotControllerJNI.SetControlFramePeriod(m_handle, frame.value, periodMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the period of the given status frame.
+ *
+ * User ensure CAN Bus utilization is not high.
+ *
+ * This setting is not persistent and is lost when device is reset.
+ * If this is a concern, calling application can use HasReset()
+ * to determine if the status frame needs to be reconfigured.
+ *
+ * @param frame
+ * Frame whose period is to be changed.
+ * @param periodMs
+ * Period in ms for the given frame.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setControlFramePeriod(int frame, int periodMs) {
+ int retval = MotControllerJNI.SetControlFramePeriod(m_handle, frame, periodMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the period of the given status frame.
+ *
+ * User ensure CAN Bus utilization is not high.
+ *
+ * This setting is not persistent and is lost when device is reset. If this
+ * is a concern, calling application can use HasReset() to determine if the
+ * status frame needs to be reconfigured.
+ *
+ * @param frameValue
+ * Frame whose period is to be changed.
+ * @param periodMs
+ * Period in ms for the given frame.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setStatusFramePeriod(int frameValue, int periodMs, int timeoutMs) {
+ int retval = MotControllerJNI.SetStatusFramePeriod(m_handle, frameValue, periodMs, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the period of the given status frame.
+ *
+ * @param frame
+ * Frame whose period is to be changed.
+ * @param periodMs
+ * Period in ms for the given frame.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setStatusFramePeriod(StatusFrame frame, int periodMs, int timeoutMs) {
+ return setStatusFramePeriod(frame.value, periodMs, timeoutMs);
+ }
+
+ /**
+ * Gets the period of the given status frame.
+ *
+ * @param frame
+ * Frame to get the period of.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Period of the given status frame.
+ */
+ public int getStatusFramePeriod(int frame, int timeoutMs) {
+ return MotControllerJNI.GetStatusFramePeriod(m_handle, frame, timeoutMs);
+ }
+
+ /**
+ * Gets the period of the given status frame.
+ *
+ * @param frame
+ * Frame to get the period of.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Period of the given status frame.
+ */
+ public int getStatusFramePeriod(StatusFrame frame, int timeoutMs) {
+ return MotControllerJNI.GetStatusFramePeriod(m_handle, frame.value, timeoutMs);
+ }
+
+ /**
+ * Gets the period of the given status frame.
+ *
+ * @param frame
+ * Frame to get the period of.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Period of the given status frame.
+ */
+ public int getStatusFramePeriod(StatusFrameEnhanced frame, int timeoutMs) {
+ return MotControllerJNI.GetStatusFramePeriod(m_handle, frame.value, timeoutMs);
+ }
+
+ // ----- velocity signal conditionaing ------//
+
+ /**
+ * Sets the period over which velocity measurements are taken.
+ *
+ * @param period
+ * Desired period for the velocity measurement. @see
+ * #VelocityMeasPeriod
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configVelocityMeasurementPeriod(VelocityMeasPeriod period, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigVelocityMeasurementPeriod(m_handle, period.value, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the number of velocity samples used in the rolling average velocity
+ * measurement.
+ *
+ * @param windowSize
+ * Number of samples in the rolling average of velocity
+ * measurement. Valid values are 1,2,4,8,16,32. If another value
+ * is specified, it will truncate to nearest support value.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configVelocityMeasurementWindow(int windowSize, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigVelocityMeasurementWindow(m_handle, windowSize, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ // ------ remote limit switch ----------//
+ /**
+ * Configures the forward limit switch for a remote source. For example, a
+ * CAN motor controller may need to monitor the Limit-F pin of another Talon
+ * or CANifier.
+ *
+ * @param type
+ * Remote limit switch source. User can choose between a remote
+ * Talon SRX, CANifier, or deactivate the feature.
+ * @param normalOpenOrClose
+ * Setting for normally open, normally closed, or disabled. This
+ * setting matches the web-based configuration drop down.
+ * @param deviceID
+ * Device ID of remote source (Talon SRX or CANifier device ID).
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configForwardLimitSwitchSource(RemoteLimitSwitchSource type, LimitSwitchNormal normalOpenOrClose,
+ int deviceID, int timeoutMs) {
+ return configForwardLimitSwitchSource(type.value, normalOpenOrClose.value, deviceID, timeoutMs);
+ }
+
+ /**
+ * Configures the reverse limit switch for a remote source. For example, a
+ * CAN motor controller may need to monitor the Limit-R pin of another Talon
+ * or CANifier.
+ *
+ * @param type
+ * Remote limit switch source. User can choose between a remote
+ * Talon SRX, CANifier, or deactivate the feature.
+ * @param normalOpenOrClose
+ * Setting for normally open, normally closed, or disabled. This
+ * setting matches the web-based configuration drop down.
+ * @param deviceID
+ * Device ID of remote source (Talon SRX or CANifier device ID).
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configReverseLimitSwitchSource(RemoteLimitSwitchSource type, LimitSwitchNormal normalOpenOrClose,
+ int deviceID, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigReverseLimitSwitchSource(m_handle, type.value, normalOpenOrClose.value,
+ deviceID, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Configures a limit switch for a local/remote source.
+ *
+ * For example, a CAN motor controller may need to monitor the Limit-R pin
+ * of another Talon, CANifier, or local Gadgeteer feedback connector.
+ *
+ * If the sensor is remote, a device ID of zero is assumed. If that's not
+ * desired, use the four parameter version of this function.
+ *
+ * @param type
+ * Limit switch source. @see #LimitSwitchSource User can choose
+ * between the feedback connector, remote Talon SRX, CANifier, or
+ * deactivate the feature.
+ * @param normalOpenOrClose
+ * Setting for normally open, normally closed, or disabled. This
+ * setting matches the web-based configuration drop down.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configForwardLimitSwitchSource(LimitSwitchSource type, LimitSwitchNormal normalOpenOrClose,
+ int timeoutMs) {
+ return configForwardLimitSwitchSource(type.value, normalOpenOrClose.value, 0x00000000, timeoutMs);
+ }
+
+ protected ErrorCode configForwardLimitSwitchSource(int typeValue, int normalOpenOrCloseValue, int deviceID,
+ int timeoutMs) {
+ int retval = MotControllerJNI.ConfigForwardLimitSwitchSource(m_handle, typeValue, normalOpenOrCloseValue,
+ deviceID, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Configures a limit switch for a local/remote source.
+ *
+ * For example, a CAN motor controller may need to monitor the Limit-R pin
+ * of another Talon, CANifier, or local Gadgeteer feedback connector.
+ *
+ * If the sensor is remote, a device ID of zero is assumed. If that's not
+ * desired, use the four parameter version of this function.
+ *
+ * @param typeValue
+ * Limit switch source. @see #LimitSwitchSource User can choose
+ * between the feedback connector, remote Talon SRX, CANifier, or
+ * deactivate the feature.
+ * @param normalOpenOrCloseValue
+ * Setting for normally open, normally closed, or disabled. This
+ * setting matches the web-based configuration drop down.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ protected ErrorCode configReverseLimitSwitchSource(int typeValue, int normalOpenOrCloseValue, int deviceID,
+ int timeoutMs) {
+ int retval = MotControllerJNI.ConfigReverseLimitSwitchSource(m_handle, typeValue, normalOpenOrCloseValue,
+ deviceID, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the enable state for limit switches.
+ *
+ * @param enable
+ * Enable state for limit switches.
+ **/
+ public void overrideLimitSwitchesEnable(boolean enable) {
+ MotControllerJNI.OverrideLimitSwitchesEnable(m_handle, enable);
+ }
+
+ // ------ soft limit ----------//
+ /**
+ * Configures the forward soft limit threhold.
+ *
+ * @param forwardSensorLimit
+ * Forward Sensor Position Limit (in raw sensor units).
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configForwardSoftLimitThreshold(int forwardSensorLimit, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigForwardSoftLimitThreshold(m_handle, forwardSensorLimit, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Configures the reverse soft limit threshold.
+ *
+ * @param reverseSensorLimit
+ * Reverse Sensor Position Limit (in raw sensor units).
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configReverseSoftLimitThreshold(int reverseSensorLimit, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigReverseSoftLimitThreshold(m_handle, reverseSensorLimit, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Configures the forward soft limit enable.
+ *
+ * @param enable
+ * Forward Sensor Position Limit Enable.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configForwardSoftLimitEnable(boolean enable, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigForwardSoftLimitEnable(m_handle, enable, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Configures the reverse soft limit enable.
+ *
+ * @param enable
+ * Reverse Sensor Position Limit Enable.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configReverseSoftLimitEnable(boolean enable, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigReverseSoftLimitEnable(m_handle, enable, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Can be used to override-disable the soft limits.
+ * This function can be used to quickly disable soft limits without
+ * having to modify the persistent configuration.
+ *
+ * @param enable
+ * Enable state for soft limit switches.
+ */
+ public void overrideSoftLimitsEnable(boolean enable) {
+ MotControllerJNI.OverrideSoftLimitsEnable(m_handle, enable);
+ }
+
+ // ------ Current Lim ----------//
+ /* not available in base */
+
+ // ------ General Close loop ----------//
+ /**
+ * Sets the 'P' constant in the given parameter slot.
+ *
+ * @param slotIdx
+ * Parameter slot for the constant.
+ * @param value
+ * Value of the P constant.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode config_kP(int slotIdx, double value, int timeoutMs) {
+ int retval = MotControllerJNI.Config_kP(m_handle, slotIdx, value, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the 'I' constant in the given parameter slot.
+ *
+ * @param slotIdx
+ * Parameter slot for the constant.
+ * @param value
+ * Value of the I constant.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode config_kI(int slotIdx, double value, int timeoutMs) {
+ int retval = MotControllerJNI.Config_kI(m_handle, slotIdx, value, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the 'D' constant in the given parameter slot.
+ *
+ * @param slotIdx
+ * Parameter slot for the constant.
+ * @param value
+ * Value of the D constant.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode config_kD(int slotIdx, double value, int timeoutMs) {
+ int retval = MotControllerJNI.Config_kD(m_handle, slotIdx, value, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the 'F' constant in the given parameter slot.
+ *
+ * @param slotIdx
+ * Parameter slot for the constant.
+ * @param value
+ * Value of the F constant.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode config_kF(int slotIdx, double value, int timeoutMs) {
+ int retval = MotControllerJNI.Config_kF(m_handle, slotIdx, value, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the Integral Zone constant in the given parameter slot. If the
+ * (absolute) closed-loop error is outside of this zone, integral
+ * accumulator is automatically cleared. This ensures than integral wind up
+ * events will stop after the sensor gets far enough from its target.
+ *
+ * @param slotIdx
+ * Parameter slot for the constant.
+ * @param izone
+ * Value of the Integral Zone constant (closed loop error units X
+ * 1ms).
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode config_IntegralZone(int slotIdx, int izone, int timeoutMs) {
+ int retval = MotControllerJNI.Config_IntegralZone(m_handle, slotIdx, izone, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the allowable closed-loop error in the given parameter slot.
+ *
+ * @param slotIdx
+ * Parameter slot for the constant.
+ * @param allowableClosedLoopError
+ * Value of the allowable closed-loop error.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configAllowableClosedloopError(int slotIdx, int allowableClosedLoopError, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigAllowableClosedloopError(m_handle, slotIdx, allowableClosedLoopError,
+ timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the maximum integral accumulator in the given parameter slot.
+ *
+ * @param slotIdx
+ * Parameter slot for the constant.
+ * @param iaccum
+ * Value of the maximum integral accumulator (closed loop error
+ * units X 1ms).
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configMaxIntegralAccumulator(int slotIdx, double iaccum, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigMaxIntegralAccumulator(m_handle, slotIdx, iaccum, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the peak closed-loop output. This peak output is slot-specific and
+ * is applied to the output of the associated PID loop.
+ * This setting is seperate from the generic Peak Output setting.
+ *
+ * @param slotIdx
+ * Parameter slot for the constant.
+ * @param percentOut
+ * Peak Percent Output from 0 to 1. This value is absolute and
+ * the magnitude will apply in both forward and reverse directions.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configClosedLoopPeakOutput(int slotIdx, double percentOut, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigClosedLoopPeakOutput(m_handle, slotIdx, percentOut, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the loop time (in milliseconds) of the PID closed-loop calculations.
+ * Default value is 1 ms.
+ *
+ * @param slotIdx
+ * Parameter slot for the constant.
+ * @param loopTimeMs
+ * Loop timing of the closed-loop calculations. Minimum value of
+ * 1 ms, maximum of 64 ms.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configClosedLoopPeriod(int slotIdx, int loopTimeMs, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigClosedLoopPeriod(m_handle, slotIdx, loopTimeMs, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Configures the Polarity of the Auxiliary PID (PID1).
+ *
+ * Standard Polarity:
+ * Primary Output = PID0 + PID1
+ * Auxiliary Output = PID0 - PID1
+ *
+ * Inverted Polarity:
+ * Primary Output = PID0 - PID1
+ * Auxiliary Output = PID0 + PID1
+ *
+ * @param invert
+ * If true, use inverted PID1 output polarity.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ * @return Error Code
+ */
+ public ErrorCode configAuxPIDPolarity(boolean invert, int timeoutMs){
+ return configSetParameter(ParamEnum.ePIDLoopPolarity, invert ? 1:0, 0, 1, timeoutMs);
+ }
+
+ /**
+ * Sets the integral accumulator. Typically this is used to clear/zero the
+ * integral accumulator, however some use cases may require seeding the
+ * accumulator for a faster response.
+ *
+ * @param iaccum
+ * Value to set for the integral accumulator (closed loop error
+ * units X 1ms).
+ * @param pidIdx
+ * 0 for Primary closed-loop. 1 for auxiliary closed-loop.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setIntegralAccumulator(double iaccum, int pidIdx, int timeoutMs) {
+ int retval = MotControllerJNI.SetIntegralAccumulator(m_handle, iaccum, pidIdx, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Gets the closed-loop error. The units depend on which control mode is in
+ * use. See Phoenix-Documentation information on units.
+ *
+ * @param pidIdx
+ * 0 for Primary closed-loop. 1 for auxiliary closed-loop.
+ * @return Closed-loop error value.
+ */
+ public int getClosedLoopError(int pidIdx) {
+ return MotControllerJNI.GetClosedLoopError(m_handle, pidIdx);
+ }
+
+ /**
+ * Gets the iaccum value.
+ *
+ * @param pidIdx
+ * 0 for Primary closed-loop. 1 for auxiliary closed-loop.
+ * @return Integral accumulator value (Closed-loop error X 1ms).
+ */
+ public double getIntegralAccumulator(int pidIdx) {
+ return MotControllerJNI.GetIntegralAccumulator(m_handle, pidIdx);
+ }
+
+
+ /**
+ * Gets the derivative of the closed-loop error.
+ *
+ * @param pidIdx
+ * 0 for Primary closed-loop. 1 for auxiliary closed-loop.
+ * @return The error derivative value.
+ */
+ public double getErrorDerivative(int pidIdx) {
+ return MotControllerJNI.GetErrorDerivative(m_handle, pidIdx);
+ }
+
+ /**
+ * Selects which profile slot to use for closed-loop control.
+ *
+ * @param slotIdx
+ * Profile slot to select.
+ * @param pidIdx
+ * 0 for Primary closed-loop. 1 for auxiliary closed-loop.
+ **/
+ public void selectProfileSlot(int slotIdx, int pidIdx) {
+ MotControllerJNI.SelectProfileSlot(m_handle, slotIdx, pidIdx);
+ }
+
+ /**
+ * Gets the current target of a given closed loop.
+ *
+ * @param pidIdx
+ * 0 for Primary closed-loop. 1 for auxiliary closed-loop.
+ * @return The closed loop target.
+ */
+ public int getClosedLoopTarget(int pidIdx) {
+ return MotControllerJNI.GetClosedLoopTarget(m_handle, pidIdx);
+ }
+
+ /**
+ * Gets the active trajectory target position using
+ * MotionMagic/MotionProfile control modes.
+ *
+ * @return The Active Trajectory Position in sensor units.
+ */
+ public int getActiveTrajectoryPosition() {
+ return MotControllerJNI.GetActiveTrajectoryPosition(m_handle);
+ }
+
+ /**
+ * Gets the active trajectory target velocity using
+ * MotionMagic/MotionProfile control modes.
+ *
+ * @return The Active Trajectory Velocity in sensor units per 100ms.
+ */
+ public int getActiveTrajectoryVelocity() {
+ return MotControllerJNI.GetActiveTrajectoryVelocity(m_handle);
+ }
+
+ /**
+ * Gets the active trajectory target heading using
+ * MotionMagicArc/MotionProfileArc control modes.
+ *
+ * @return The Active Trajectory Heading in degreees.
+ */
+ public double getActiveTrajectoryHeading() {
+ return MotControllerJNI.GetActiveTrajectoryHeading(m_handle);
+ }
+
+ // ------ Motion Profile Settings used in Motion Magic and Motion Profile ----------//
+
+ /**
+ * Sets the Motion Magic Cruise Velocity. This is the peak target velocity
+ * that the motion magic curve generator can use.
+ *
+ * @param sensorUnitsPer100ms
+ * Motion Magic Cruise Velocity (in raw sensor units per 100 ms).
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configMotionCruiseVelocity(int sensorUnitsPer100ms, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigMotionCruiseVelocity(m_handle, sensorUnitsPer100ms, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the Motion Magic Acceleration. This is the target acceleration that
+ * the motion magic curve generator can use.
+ *
+ * @param sensorUnitsPer100msPerSec
+ * Motion Magic Acceleration (in raw sensor units per 100 ms per
+ * second).
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configMotionAcceleration(int sensorUnitsPer100msPerSec, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigMotionAcceleration(m_handle, sensorUnitsPer100msPerSec, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ //------ Motion Profile Buffer ----------//
+ /**
+ * Clear the buffered motion profile in both controller's RAM (bottom), and in the
+ * API (top).
+ */
+ public ErrorCode clearMotionProfileTrajectories() {
+ int retval = MotControllerJNI.ClearMotionProfileTrajectories(m_handle);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Retrieve just the buffer count for the api-level (top) buffer. This
+ * routine performs no CAN or data structure lookups, so its fast and ideal
+ * if caller needs to quickly poll the progress of trajectory points being
+ * emptied into controller's RAM. Otherwise just use GetMotionProfileStatus.
+ *
+ * @return number of trajectory points in the top buffer.
+ */
+ public int getMotionProfileTopLevelBufferCount() {
+ return MotControllerJNI.GetMotionProfileTopLevelBufferCount(m_handle);
+ }
+ /**
+ * Push another trajectory point into the top level buffer (which is emptied
+ * into the motor controller's bottom buffer as room allows).
+ * @param trajPt to push into buffer.
+ * The members should be filled in with these values...
+ *
+ * targPos: servo position in sensor units.
+ * targVel: velocity to feed-forward in sensor units
+ * per 100ms.
+ * profileSlotSelect0 Which slot to get PIDF gains. PID is used for position servo. F is used
+ * as the Kv constant for velocity feed-forward. Typically this is hardcoded
+ * to the a particular slot, but you are free gain schedule if need be.
+ * Choose from [0,3]
+ * profileSlotSelect1 Which slot to get PIDF gains for auxiliary PId.
+ * This only has impact during MotionProfileArc Control mode.
+ * Choose from [0,1].
+ * isLastPoint set to nonzero to signal motor controller to keep processing this
+ * trajectory point, instead of jumping to the next one
+ * when timeDurMs expires. Otherwise MP executer will
+ * eventually see an empty buffer after the last point
+ * expires, causing it to assert the IsUnderRun flag.
+ * However this may be desired if calling application
+ * never wants to terminate the MP.
+ * zeroPos set to nonzero to signal motor controller to "zero" the selected
+ * position sensor before executing this trajectory point.
+ * Typically the first point should have this set only thus
+ * allowing the remainder of the MP positions to be relative to
+ * zero.
+ * timeDur Duration to apply this trajectory pt.
+ * This time unit is ADDED to the exising base time set by
+ * configMotionProfileTrajectoryPeriod().
+ * @return CTR_OKAY if trajectory point push ok. ErrorCode if buffer is
+ * full due to kMotionProfileTopBufferCapacity.
+ */
+ public ErrorCode pushMotionProfileTrajectory(TrajectoryPoint trajPt) {
+ int retval = MotControllerJNI.PushMotionProfileTrajectory2(m_handle,
+ trajPt.position, trajPt.velocity, trajPt.auxiliaryPos,
+ trajPt.profileSlotSelect0, trajPt.profileSlotSelect1,
+ trajPt.isLastPoint, trajPt.zeroPos, trajPt.timeDur.value);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Retrieve just the buffer full for the api-level (top) buffer. This
+ * routine performs no CAN or data structure lookups, so its fast and ideal
+ * if caller needs to quickly poll. Otherwise just use
+ * GetMotionProfileStatus.
+ *
+ * @return number of trajectory points in the top buffer.
+ */
+ public boolean isMotionProfileTopLevelBufferFull() {
+ return MotControllerJNI.IsMotionProfileTopLevelBufferFull(m_handle);
+ }
+
+ /**
+ * This must be called periodically to funnel the trajectory points from the
+ * API's top level buffer to the controller's bottom level buffer. Recommendation
+ * is to call this twice as fast as the execution rate of the motion
+ * profile. So if MP is running with 20ms trajectory points, try calling
+ * this routine every 10ms. All motion profile functions are thread-safe
+ * through the use of a mutex, so there is no harm in having the caller
+ * utilize threading.
+ */
+ public void processMotionProfileBuffer() {
+ MotControllerJNI.ProcessMotionProfileBuffer(m_handle);
+ }
+ /**
+ * Retrieve all status information.
+ * For best performance, Caller can snapshot all status information regarding the
+ * motion profile executer.
+ *
+ * @param statusToFill Caller supplied object to fill.
+ *
+ * The members are filled, as follows...
+ *
+ * topBufferRem: The available empty slots in the trajectory buffer.
+ * The robot API holds a "top buffer" of trajectory points, so your applicaion
+ * can dump several points at once. The API will then stream them into the
+ * low-level buffer, allowing the motor controller to act on them.
+ *
+ * topBufferRem: The number of points in the top trajectory buffer.
+ *
+ * btmBufferCnt: The number of points in the low level controller buffer.
+ *
+ * hasUnderrun: Set if isUnderrun ever gets set.
+ * Only is cleared by clearMotionProfileHasUnderrun() to ensure
+ *
+ * isUnderrun: This is set if controller needs to shift a point from its buffer into
+ * the active trajectory point however
+ * the buffer is empty.
+ * This gets cleared automatically when is resolved.
+ *
+ * activePointValid: True if the active trajectory point has not empty, false otherwise. The members in activePoint are only valid if this signal is set.
+ *
+ * isLast: is set/cleared based on the MP executer's current
+ * trajectory point's IsLast value. This assumes
+ * IsLast was set when PushMotionProfileTrajectory
+ * was used to insert the currently processed trajectory
+ * point.
+ *
+ * profileSlotSelect: The currently processed trajectory point's
+ * selected slot. This can differ in the currently selected slot used
+ * for Position and Velocity servo modes
+ *
+ * outputEnable: The current output mode of the motion profile
+ * executer (disabled, enabled, or hold). When changing the set()
+ * value in MP mode, it's important to check this signal to
+ * confirm the change takes effect before interacting with the top buffer.
+ */
+ public ErrorCode getMotionProfileStatus(MotionProfileStatus statusToFill) {
+ int retval = MotControllerJNI.GetMotionProfileStatus2(m_handle, _motionProfStats);
+ statusToFill.topBufferRem = _motionProfStats[0];
+ statusToFill.topBufferCnt = _motionProfStats[1];
+ statusToFill.btmBufferCnt = _motionProfStats[2];
+ statusToFill.hasUnderrun = _motionProfStats[3] != 0;
+ statusToFill.isUnderrun = _motionProfStats[4] != 0;
+ statusToFill.activePointValid = _motionProfStats[5] != 0;
+ statusToFill.isLast = _motionProfStats[6] != 0;
+ statusToFill.profileSlotSelect = _motionProfStats[7];
+ statusToFill.outputEnable = SetValueMotionProfile.valueOf(_motionProfStats[8]);
+ statusToFill.timeDurMs = _motionProfStats[9];
+ statusToFill.profileSlotSelect1 = _motionProfStats[10];
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Clear the "Has Underrun" flag. Typically this is called after application
+ * has confirmed an underrun had occured.
+ *
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode clearMotionProfileHasUnderrun(int timeoutMs) {
+ int retval = MotControllerJNI.ClearMotionProfileHasUnderrun(m_handle, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Calling application can opt to speed up the handshaking between the robot
+ * API and the controller to increase the download rate of the controller's Motion
+ * Profile. Ideally the period should be no more than half the period of a
+ * trajectory point.
+ *
+ * @param periodMs
+ * The transmit period in ms.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode changeMotionControlFramePeriod(int periodMs) {
+ int retval = MotControllerJNI.ChangeMotionControlFramePeriod(m_handle, periodMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * When trajectory points are processed in the motion profile executer, the MPE determines
+ * how long to apply the active trajectory point by summing baseTrajDurationMs with the
+ * timeDur of the trajectory point (see TrajectoryPoint).
+ *
+ * This allows general selection of the execution rate of the points with 1ms resolution,
+ * while allowing some degree of change from point to point.
+ * @param baseTrajDurationMs The base duration time of every trajectory point.
+ * This is summed with the trajectory points unique timeDur.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configMotionProfileTrajectoryPeriod(int baseTrajDurationMs, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigMotionProfileTrajectoryPeriod(m_handle, baseTrajDurationMs, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+ // ------ error ----------//
+ /**
+ * Gets the last error generated by this object. Not all functions return an
+ * error code but can potentially report errors. This function can be used
+ * to retrieve those error codes.
+ *
+ * @return Last Error Code generated by a function.
+ */
+ public ErrorCode getLastError() {
+ int retval = MotControllerJNI.GetLastError(m_handle);
+ return ErrorCode.valueOf(retval);
+ }
+
+ // ------ Faults ----------//
+ /**
+ * Polls the various fault flags.
+ *
+ * @param toFill
+ * Caller's object to fill with latest fault flags.
+ * @return Last Error Code generated by a function.
+ */
+ public ErrorCode getFaults(Faults toFill) {
+ int bits = MotControllerJNI.GetFaults(m_handle);
+ toFill.update(bits);
+ return getLastError();
+ }
+
+ /**
+ * Polls the various sticky fault flags.
+ *
+ * @param toFill
+ * Caller's object to fill with latest sticky fault flags.
+ * @return Last Error Code generated by a function.
+ */
+ public ErrorCode getStickyFaults(StickyFaults toFill) {
+ int bits = MotControllerJNI.GetStickyFaults(m_handle);
+ toFill.update(bits);
+ return getLastError();
+ }
+
+ /**
+ * Clears all sticky faults.
+ *
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ * @return Last Error Code generated by a function.
+ */
+ public ErrorCode clearStickyFaults(int timeoutMs) {
+ int retval = MotControllerJNI.ClearStickyFaults(m_handle, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ // ------ Firmware ----------//
+ /**
+ * Gets the firmware version of the device.
+ *
+ * @return Firmware version of device. For example: version 1-dot-2 is
+ * 0x0102.
+ */
+ public int getFirmwareVersion() {
+ return MotControllerJNI.GetFirmwareVersion(m_handle);
+ }
+
+ /**
+ * Returns true if the device has reset since last call.
+ *
+ * @return Has a Device Reset Occurred?
+ */
+ public boolean hasResetOccurred() {
+ return MotControllerJNI.HasResetOccurred(m_handle);
+ }
+
+ //------ Custom Persistent Params ----------//
+ /**
+ * Sets the value of a custom parameter. This is for arbitrary use.
+ *
+ * Sometimes it is necessary to save calibration/limit/target information in
+ * the device. Particularly if the device is part of a subsystem that can be
+ * replaced.
+ *
+ * @param newValue
+ * Value for custom parameter.
+ * @param paramIndex
+ * Index of custom parameter [0,1]
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configSetCustomParam(int newValue, int paramIndex, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigSetCustomParam(m_handle, newValue, paramIndex, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Gets the value of a custom parameter.
+ *
+ * @param paramIndex
+ * Index of custom parameter [0,1].
+ * @param timoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ * @return Value of the custom param.
+ */
+ public int configGetCustomParam(int paramIndex, int timoutMs) {
+ int retval = MotControllerJNI.ConfigGetCustomParam(m_handle, paramIndex, timoutMs);
+ return retval;
+ }
+
+ // ------ Generic Param API ----------//
+ /**
+ * Sets a parameter. Generally this is not used. This can be utilized in -
+ * Using new features without updating API installation. - Errata
+ * workarounds to circumvent API implementation. - Allows for rapid testing
+ * / unit testing of firmware.
+ *
+ * @param param
+ * Parameter enumeration.
+ * @param value
+ * Value of parameter.
+ * @param subValue
+ * Subvalue for parameter. Maximum value of 255.
+ * @param ordinal
+ * Ordinal of parameter.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configSetParameter(ParamEnum param, double value, int subValue, int ordinal, int timeoutMs) {
+ return configSetParameter(param.value, value, subValue, ordinal, timeoutMs);
+ }
+ /**
+ * Sets a parameter.
+ *
+ * @param param
+ * Parameter enumeration.
+ * @param value
+ * Value of parameter.
+ * @param subValue
+ * Subvalue for parameter. Maximum value of 255.
+ * @param ordinal
+ * Ordinal of parameter.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configSetParameter(int param, double value, int subValue, int ordinal, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigSetParameter(m_handle, param, value, subValue, ordinal,
+ timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Gets a parameter.
+ *
+ * @param param
+ * Parameter enumeration.
+ * @param ordinal
+ * Ordinal of parameter.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Value of parameter.
+ */
+ public double configGetParameter(ParamEnum param, int ordinal, int timeoutMs) {
+ return configGetParameter(param.value, ordinal, timeoutMs);
+ }
+ /**
+ * Gets a parameter.
+ *
+ * @param param
+ * Parameter enumeration.
+ * @param ordinal
+ * Ordinal of parameter.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Value of parameter.
+ */
+ public double configGetParameter(int param, int ordinal, int timeoutMs) {
+ return MotControllerJNI.ConfigGetParameter(m_handle, param, ordinal, timeoutMs);
+ }
+
+ // ------ Misc. ----------//
+ public int getBaseID() {
+ return _arbId;
+ }
+
+ /**
+ * @return control mode motor controller is in
+ */
+ public ControlMode getControlMode() {
+ return m_controlMode;
+ }
+
+ // ----- Follower ------//
+ /**
+ * Set the control mode and output value so that this motor controller will
+ * follow another motor controller. Currently supports following Victor SPX
+ * and Talon SRX.
+ *
+ * @param masterToFollow
+ * Motor Controller object to follow.
+ * @param followerType
+ * Type of following control. Use AuxOutput1 to follow the master
+ * device's auxiliary output 1.
+ * Use PercentOutput for standard follower mode.
+ */
+ public void follow(IMotorController masterToFollow, FollowerType followerType) {
+ int id32 = masterToFollow.getBaseID();
+ int id24 = id32;
+ id24 >>= 16;
+ id24 = (short) id24;
+ id24 <<= 8;
+ id24 |= (id32 & 0xFF);
+ set(ControlMode.Follower, id24);
+
+ switch (followerType){
+ case PercentOutput:
+ set(ControlMode.Follower, (double)id24);
+ break;
+ case AuxOutput1:
+ /* follow the motor controller, but set the aux flag
+ * to ensure we follow the processed output */
+ set(ControlMode.Follower, (double)id24, DemandType.AuxPID, 0);
+ break;
+ default:
+ neutralOutput();
+ break;
+ }
+ }
+ /**
+ * Set the control mode and output value so that this motor controller will
+ * follow another motor controller. Currently supports following Victor SPX
+ * and Talon SRX.
+ */
+ public void follow(IMotorController masterToFollow) {
+ follow(masterToFollow, FollowerType.PercentOutput);
+ }
+ /**
+ * When master makes a device, this routine is called to signal the update.
+ */
+ public void valueUpdated() {
+ // MT
+ }
+
+ /**
+ * @return object that can get/set individual raw sensor values.
+ */
+ public SensorCollection getSensorCollection() {
+ return _sensorColl;
+ }
+}
diff --git a/java/src/com/ctre/phoenix/motorcontrol/can/MotControllerJNI.java b/java/src/com/ctre/phoenix/motorcontrol/can/MotControllerJNI.java
new file mode 100644
index 0000000..635ce39
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/can/MotControllerJNI.java
@@ -0,0 +1,762 @@
+package com.ctre.phoenix.motorcontrol.can;
+
+import com.ctre.phoenix.CTREJNIWrapper;
+
+public class MotControllerJNI extends CTREJNIWrapper {
+
+ public static native long Create(int baseArbId);
+
+ /**
+ * Returns the Device ID
+ *
+ * @return Device number.
+ */
+ public static native int GetDeviceNumber(long handle);
+
+ /**
+ * Sets the demand (output) of the motor controller.
+ *
+ * @param mode
+ * Control Mode of the Motor Controller
+ * @param demand0
+ * Primary Demand value
+ * @param demand1
+ * Secondary Demand value
+ **/
+ public static native void SetDemand(long handle, int mode, int demand0, int demand1);
+
+ /**
+ * Sets the demand (output) of the motor controller.
+ **/
+ public static native void Set_4(long handle, int mode, double demand0, double demand1, int demand1Type);
+
+ /**
+ * Sets the mode of operation during neutral throttle output.
+ *
+ * @param neutralMode
+ * The desired mode of operation when the Controller output
+ * throttle is neutral (ie brake/coast)
+ **/
+ public static native void SetNeutralMode(long handle, int neutralMode);
+
+ /**
+ * Sets the phase of the sensor. Use when controller forward/reverse output
+ * doesn't correlate to appropriate forward/reverse reading of sensor.
+ *
+ * @param PhaseSensor
+ * Indicates whether to invert the phase of the sensor.
+ **/
+ public static native void SetSensorPhase(long handle, boolean PhaseSensor);
+
+ /**
+ * Inverts the output of the motor controller. LEDs, sensor phase, and limit
+ * switches will also be inverted to match the new forward/reverse
+ * directions.
+ *
+ * @param invert
+ * Invert state to set.
+ **/
+ public static native void SetInverted(long handle, boolean invert);
+
+ /**
+ * Configures the open-loop ramp rate of throttle output.
+ *
+ * @param secondsFromNeutralToFull
+ * Minimum desired time to go from neutral to full throttle. A
+ * value of '0' will disable the ramp.
+ * @param timeoutMs
+ * Timeout value in ms. Function will generate error if config is
+ * not successful within timeout.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigOpenLoopRamp(long handle, double secondsFromNeutralToFull, int timeoutMs);
+
+ /**
+ * Configures the closed-loop ramp rate of throttle output.
+ *
+ * @param secondsFromNeutralToFull
+ * Minimum desired time to go from neutral to full throttle. A
+ * value of '0' will disable the ramp.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigClosedLoopRamp(long handle, double secondsFromNeutralToFull, int timeoutMs);
+
+ /**
+ * Configures the forward peak output percentage.
+ *
+ * @param percentOut
+ * Desired peak output percentage.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigPeakOutputForward(long handle, double percentOut, int timeoutMs);
+
+ /**
+ * Configures the reverse peak output percentage.
+ *
+ * @param percentOut
+ * Desired peak output percentage.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigPeakOutputReverse(long handle, double percentOut, int timeoutMs);
+
+ /**
+ * Configures the forward nominal output percentage.
+ *
+ * @param percentOut
+ * Nominal (minimum) percent output.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigNominalOutputForward(long handle, double percentOut, int timeoutMs);
+
+ /**
+ * Configures the reverse nominal output percentage.
+ *
+ * @param percentOut
+ * Nominal (minimum) percent output.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigNominalOutputReverse(long handle, double percentOut, int timeoutMs);
+
+ /**
+ * Configures the output deadband percentage.
+ *
+ * @param percentDeadband
+ * Desired deadband percentage. Minimum is 0.1%, Maximum is 25%.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigNeutralDeadband(long handle, double percentDeadband, int timeoutMs);
+
+ /**
+ * Configures the Voltage Compensation saturation voltage.
+ *
+ * @param voltage
+ * TO-DO: Comment me!
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigVoltageCompSaturation(long handle, double voltage, int timeoutMs);
+
+ /**
+ * Configures the voltage measurement filter.
+ *
+ * @param filterWindowSamples
+ * Number of samples in the rolling average of voltage
+ * measurement.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigVoltageMeasurementFilter(long handle, int filterWindowSamples, int timeoutMs);
+
+ /**
+ * Enables voltage compensation. If enabled, voltage compensation works in
+ * all control modes.
+ *
+ * @param enable
+ * Enable state of voltage compensation.
+ **/
+ public static native void EnableVoltageCompensation(long handle, boolean enable);
+
+ /**
+ * Gets the bus voltage seen by the motor controller.
+ *
+ * @return The bus voltage value (in volts).
+ */
+ public static native double GetBusVoltage(long handle);
+
+ /**
+ * Gets the output percentage of the motor controller.
+ *
+ * @return Output of the motor controller (in percent).
+ */
+ public static native double GetMotorOutputPercent(long handle);
+
+ /**
+ * Gets the output current of the motor controller.
+ *
+ * @return Output current (in amps).
+ */
+ public static native double GetOutputCurrent(long handle);
+
+ /**
+ * Gets the temperature of the motor controller.
+ *
+ * @return The temperature of the motor controller (in 'C)
+ */
+ public static native double GetTemperature(long handle);
+
+ /**
+ * Configures the remote feedback filter.
+ *
+ * @param handle
+ * handle of device.
+ * @param deviceID
+ * ID of remote device.
+ * @param remoteSensorSource
+ * Type of remote sensor.
+ * @param remoteOrdinal
+ * Ordinal of remote source [0-1].
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigRemoteFeedbackFilter(long handle, int deviceID, int remoteSensorSource,
+ int remoteOrdinal, int timeoutMs);
+
+ /**
+ * Select the feedback device for the motor controller.
+ *
+ * @param feedbackDevice
+ * Feedback Device to select.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigSelectedFeedbackSensor(long handle, int feedbackDevice, int pidIdx, int timeoutMs);
+
+ public static native int ConfigSensorTerm(long handle, int sensorTerm, int feedbackDevice, int timeoutMs);
+
+ /**
+ * Get the selected sensor position.
+ *
+ * @return Position of selected sensor (in Raw Sensor Units).
+ */
+ public static native int GetSelectedSensorPosition(long handle, int pidIdx);
+
+ /**
+ * Get the selected sensor velocity.
+ *
+ * @return Velocity of selected sensor (in Raw Sensor Units per 100 ms).
+ */
+ public static native int GetSelectedSensorVelocity(long handle, int pidIdx);
+
+ /**
+ * Sets the sensor position to the given value.
+ *
+ * @param sensorPos
+ * Position to set for the selected sensor (in Raw Sensor Units).
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int SetSelectedSensorPosition(long handle, int sensorPos, int pidIdx, int timeoutMs);
+
+ /**
+ * Sets the period of the given control frame.
+ *
+ * @param frame
+ * Frame whose period is to be changed.
+ * @param periodMs
+ * Period in ms for the given frame.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int SetControlFramePeriod(long handle, int frame, int periodMs);
+
+ /**
+ * Sets the period of the given status frame.
+ *
+ * @param frame
+ * Frame whose period is to be changed.
+ * @param periodMs
+ * Period in ms for the given frame.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int SetStatusFramePeriod(long handle, int frame, int periodMs, int timeoutMs);
+
+ /**
+ * Gets the period of the given status frame.
+ *
+ * @param frame
+ * Frame to get the period of.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return The period of the given status frame.
+ */
+ public static native int GetStatusFramePeriod(long handle, int frame, int timeoutMs);
+
+ /**
+ * Sets the period over which velocity measurements are taken.
+ *
+ * @param period
+ * Desired period for the velocity measurement. @see
+ * #VelocityMeasPeriod
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigVelocityMeasurementPeriod(long handle, int period, int timeoutMs);
+
+ /**
+ * Sets the number of velocity samples used in the rolling average velocity
+ * measurement.
+ *
+ * @param windowSize
+ * Number of samples in the rolling average of velocity
+ * measurement.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigVelocityMeasurementWindow(long handle, int windowSize, int timeoutMs);
+
+ /**
+ * Configures the forward limit switch for a remote source.
+ *
+ * @param type
+ * Remote limit switch source. @see #LimitSwitchSource
+ * @param normalOpenOrClose
+ * Setting for normally open or normally closed.
+ * @param deviceID
+ * Device ID of remote source.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigForwardLimitSwitchSource(long handle, int type, int normalOpenOrClose, int deviceID,
+ int timeoutMs);
+
+ /**
+ * Configures the reverse limit switch for a remote source.
+ *
+ * @param type
+ * Remote limit switch source. @see #LimitSwitchSource
+ * @param normalOpenOrClose
+ * Setting for normally open or normally closed.
+ * @param deviceID
+ * Device ID of remote source.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigReverseLimitSwitchSource(long handle, int type, int normalOpenOrClose, int deviceID,
+ int timeoutMs);
+
+ /**
+ * Sets the enable state for limit switches.
+ *
+ * @param enable
+ * Enable state for limit switches.
+ **/
+ public static native void OverrideLimitSwitchesEnable(long handle, boolean enable);
+
+ /**
+ * Configures the forward soft limit.
+ *
+ * @param forwardSensorLimit
+ * Forward Sensor Position Limit (in Raw Sensor Units).
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigForwardSoftLimitThreshold(long handle, int forwardSensorLimit, int timeoutMs);
+
+ /**
+ * Configures the reverse soft limit.
+ *
+ * @param reverseSensorLimit
+ * Reverse Sensor Position Limit (in Raw Sensor Units).
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigReverseSoftLimitThreshold(long handle, int reverseSensorLimit, int timeoutMs);
+
+ public static native int ConfigForwardSoftLimitEnable(long handle, boolean enable, int timeoutMs);
+
+ public static native int ConfigReverseSoftLimitEnable(long handle, boolean enable, int timeoutMs);
+
+ /**
+ * Sets the enable state for soft limit switches.
+ *
+ * @param enable
+ * Enable state for soft limit switches.
+ **/
+ public static native void OverrideSoftLimitsEnable(long handle, boolean enable);
+
+ /**
+ * Sets the 'P' constant in the given parameter slot.
+ *
+ * @param slotIdx
+ * Parameter slot for the constant.
+ * @param value
+ * Value of the P constant.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int Config_kP(long handle, int slotIdx, double value, int timeoutMs);
+
+ /**
+ * Sets the 'I' constant in the given parameter slot.
+ *
+ * @param slotIdx
+ * Parameter slot for the constant.
+ * @param value
+ * Value of the I constant.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int Config_kI(long handle, int slotIdx, double value, int timeoutMs);
+
+ /**
+ * Sets the 'D' constant in the given parameter slot.
+ *
+ * @param slotIdx
+ * Parameter slot for the constant.
+ * @param value
+ * Value of the D constant.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int Config_kD(long handle, int slotIdx, double value, int timeoutMs);
+
+ /**
+ * Sets the 'F' constant in the given parameter slot.
+ *
+ * @param slotIdx
+ * Parameter slot for the constant.
+ * @param value
+ * Value of the F constant.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int Config_kF(long handle, int slotIdx, double value, int timeoutMs);
+
+ /**
+ * Sets the Integral Zone constant in the given parameter slot.
+ *
+ * @param slotIdx
+ * Parameter slot for the constant.
+ * @param izone
+ * Value of the Integral Zone constant.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int Config_IntegralZone(long handle, int slotIdx, double izone, int timeoutMs);
+
+ /**
+ * Sets the allowable closed-loop error in the given parameter slot.
+ *
+ * @param slotIdx
+ * Parameter slot for the constant.
+ * @param allowableClosedLoopError
+ * Value of the allowable closed-loop error.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigAllowableClosedloopError(long handle, int slotIdx, int allowableClosedLoopError,
+ int timeoutMs);
+
+ /**
+ * Sets the maximum integral accumulator in the given parameter slot.
+ *
+ * @param slotIdx
+ * Parameter slot for the constant.
+ * @param iaccum
+ * Value of the maximum integral accumulator.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigMaxIntegralAccumulator(long handle, int slotIdx, double iaccum, int timeoutMs);
+
+ /**
+ * Sets the integral accumulator.
+ *
+ * @param iaccum
+ * Value to set for the integral accumulator.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @param pidIdx
+ * Which closed loop to manipulate. 0 for primary, 1 for auxiliary
+ * secondary loop.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int SetIntegralAccumulator(long handle, double iaccum, int pidIdx, int timeoutMs);
+
+ /**
+ * Gets the closed-loop error.
+ *
+ * @param pidIdx
+ * Which closed loop to manipulate. 0 for primary, 1 for auxiliary
+ * secondary loop.
+ * @return Closed-loop error value.
+ */
+ public static native int GetClosedLoopError(long handle, int pidIdx);
+
+ /**
+ * Gets the iaccum value.
+ *
+ * @param pidIdx
+ * Which closed loop to manipulate. 0 for primary, 1 for auxiliary
+ * secondary loop.
+ * @return Integral accumulator value.
+ */
+ public static native double GetIntegralAccumulator(long handle, int pidIdx);
+
+ /**
+ * Gets the derivative of the closed-loop error.
+ *
+ * @param pidIdx
+ * Which closed loop to manipulate. 0 for primary, 1 for auxiliary
+ * secondary loop.
+ * @return Error derivative value.
+ */
+ public static native double GetErrorDerivative(long handle, int pidIdx);
+
+ /**
+ * Selects which profile slot to use for closed-loop control.
+ *
+ * @param slotIdx
+ * Profile slot to select.
+ * @param pidIdx
+ * Which closed loop to manipulate. 0 for primary, 1 for auxiliary
+ * secondary loop.
+ **/
+ public static native void SelectProfileSlot(long handle, int slotIdx, int pidIdx);
+
+ public static native int GetActiveTrajectoryPosition(long handle);
+
+ public static native int GetActiveTrajectoryVelocity(long handle);
+
+ public static native double GetActiveTrajectoryHeading(long handle);
+
+ /**
+ * Sets the Motion Magic Cruise Velocity.
+ *
+ * @param sensorUnitsPer100ms
+ * Motion Magic Cruise Velocity (in Raw Sensor Units per 100 ms).
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigMotionCruiseVelocity(long handle, int sensorUnitsPer100ms, int timeoutMs);
+
+ /**
+ * Sets the Motion Magic Acceleration.
+ *
+ * @param sensorUnitsPer100msPerSec
+ * Motion Magic Acceleration (in Raw Sensor Units per 100 ms per
+ * second).
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigMotionAcceleration(long handle, int sensorUnitsPer100msPerSec, int timeoutMs);
+
+ public static native int ClearMotionProfileTrajectories(long handle);
+
+ public static native int GetMotionProfileTopLevelBufferCount(long handle);
+
+ public static native int PushMotionProfileTrajectory(long handle, double position, double velocity,
+ double headingDeg, int profileSlotSelect, boolean isLastPoint, boolean zeroPos);
+
+ public static native int PushMotionProfileTrajectory2(long handle, double position, double velocity, double headingDeg,
+ int profileSlotSelect0, int profileSlotSelect1, boolean isLastPoint, boolean zeroPos, int durationMs);
+
+ public static native boolean IsMotionProfileTopLevelBufferFull(long handle);
+
+ public static native int ProcessMotionProfileBuffer(long handle);
+
+ public static native int GetMotionProfileStatus(long handle, int[] toFill_9);
+
+ public static native int GetMotionProfileStatus2(long handle, int[] toFill_11);
+
+ public static native int ClearMotionProfileHasUnderrun(long handle, int timeoutMs);
+
+ public static native int ChangeMotionControlFramePeriod(long handle, int periodMs);
+
+ public static native int ConfigMotionProfileTrajectoryPeriod(long handle, int periodMs, int timeoutMs);
+
+ /**
+ * Gets the last error generated by this object.
+ *
+ * @return Last Error Code generated by a function.
+ */
+ public static native int GetLastError(long handle);
+
+ /**
+ * Gets the firmware version of the device.
+ *
+ * @return Firmware version of device.
+ */
+ public static native int GetFirmwareVersion(long handle);
+
+ /**
+ * Returns true if the device has reset.
+ *
+ * @return Has a Device Reset Occurred?
+ */
+ public static native boolean HasResetOccurred(long handle);
+
+ /**
+ * Sets the value of a custom parameter.
+ *
+ * @param newValue
+ * Value for custom parameter.
+ * @param paramIndex
+ * Index of custom parameter.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigSetCustomParam(long handle, int newValue, int paramIndex, int timeoutMs);
+
+ /**
+ * Gets the value of a custom parameter.
+ *
+ * @param paramIndex
+ * Index of custom parameter.
+ * @param timoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Value of the custom param.
+ */
+ public static native int ConfigGetCustomParam(long handle, int paramIndex, int timoutMs);
+
+ /**
+ * Sets a parameter.
+ *
+ * @param param
+ * Parameter enumeration.
+ * @param value
+ * Value of parameter.
+ * @param subValue
+ * Subvalue for parameter. Maximum value of 255.
+ * @param ordinal
+ * Ordinal of parameter.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigSetParameter(long handle, int param, double value, int subValue, int ordinal,
+ int timeoutMs);
+
+ /**
+ * Gets a parameter.
+ *
+ * @param param
+ * Parameter enumeration.
+ * @param ordinal
+ * Ordinal of parameter.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Value of parameter.
+ */
+ public static native double ConfigGetParameter(long handle, int param, int ordinal, int timeoutMs);
+
+ /**
+ * Configures the peak current limit of the motor controller.
+ *
+ * @param amps
+ * Peak current limit (in amps).
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigPeakCurrentLimit(long handle, int amps, int timeoutMs);
+
+ /**
+ * Configures the maximum time allowed at peak current limit of the motor
+ * controller.
+ *
+ * @param milliseconds
+ * Maximum time allowed at peak current limit (in milliseconds).
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigPeakCurrentDuration(long handle, int milliseconds, int timeoutMs);
+
+ /**
+ * Configures the continuous current limit.
+ *
+ * @param amps
+ * Continuous Current Limit.
+ * @param timeoutMs
+ * Timeout value in ms. @see #ConfigOpenLoopRamp
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public static native int ConfigContinuousCurrentLimit(long handle, int amps, int timeoutMs);
+
+ /**
+ * Enables the current limit feature.
+ *
+ * @param enable
+ * Enable state of current limit.
+ **/
+ public static native int EnableCurrentLimit(long handle, boolean enable);
+
+ public static native int GetAnalogIn(long handle);
+
+ public static native int SetAnalogPosition(long handle, int newPosition, int timeoutMs);
+
+ public static native int GetAnalogInRaw(long handle);
+
+ public static native int GetAnalogInVel(long handle);
+
+ public static native int GetQuadraturePosition(long handle);
+
+ public static native int SetQuadraturePosition(long handle, int newPosition, int timeoutMs);
+
+ public static native int GetQuadratureVelocity(long handle);
+
+ public static native int GetPulseWidthPosition(long handle);
+
+ public static native int SetPulseWidthPosition(long handle, int newPosition, int timeoutMs);
+
+ public static native int GetPulseWidthVelocity(long handle);
+
+ public static native int GetPulseWidthRiseToFallUs(long handle);
+
+ public static native int GetPulseWidthRiseToRiseUs(long handle);
+
+ public static native int GetPinStateQuadA(long handle);
+
+ public static native int GetPinStateQuadB(long handle);
+
+ public static native int GetPinStateQuadIdx(long handle);
+
+ public static native int IsFwdLimitSwitchClosed(long handle);
+
+ public static native int IsRevLimitSwitchClosed(long handle);
+
+ public static native int GetFaults(long handle);
+
+ public static native int GetStickyFaults(long handle);
+
+ public static native int ClearStickyFaults(long handle, int timeoutMs);
+
+ public static native int SelectDemandType(long handle, int enable);
+
+ public static native int SetMPEOutput(long handle, int mpeOutput);
+
+ public static native int EnableHeadingHold(long handle, int enable);
+
+ public static native int GetClosedLoopTarget(long handle, int pidIdx);
+
+ public static native int ConfigSelectedFeedbackCoefficient(long handle, double coefficient, int pidIdx, int timeoutMs);
+
+ public static native int ConfigClosedLoopPeakOutput(long handle, int slotIdx, double percentOut, int timeoutMs);
+
+ public static native int ConfigClosedLoopPeriod(long handle, int slotIdx, int loopTimeMs, int timeoutMs);
+}
diff --git a/java/src/com/ctre/phoenix/motorcontrol/can/TalonSRX.java b/java/src/com/ctre/phoenix/motorcontrol/can/TalonSRX.java
new file mode 100644
index 0000000..1bbc149
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/can/TalonSRX.java
@@ -0,0 +1,232 @@
+package com.ctre.phoenix.motorcontrol.can;
+import com.ctre.phoenix.ErrorCode;
+import com.ctre.phoenix.motorcontrol.IMotorControllerEnhanced;
+import com.ctre.phoenix.motorcontrol.LimitSwitchNormal;
+import com.ctre.phoenix.motorcontrol.LimitSwitchSource;
+import com.ctre.phoenix.motorcontrol.StatusFrameEnhanced;
+import com.ctre.phoenix.motorcontrol.VelocityMeasPeriod;
+import com.ctre.phoenix.motorcontrol.can.MotControllerJNI;
+
+import edu.wpi.first.wpilibj.hal.FRCNetComm.tResourceType;
+import edu.wpi.first.wpilibj.hal.HAL;
+/**
+ * CTRE Talon SRX Motor Controller when used on CAN Bus.
+ */
+public class TalonSRX extends com.ctre.phoenix.motorcontrol.can.BaseMotorController
+ implements IMotorControllerEnhanced {
+
+ public TalonSRX(int deviceNumber) {
+ super(deviceNumber | 0x02040000);
+ HAL.report(tResourceType.kResourceType_CANTalonSRX, deviceNumber + 1);
+ }
+ /**
+ * Sets the period of the given status frame.
+ *
+ * User ensure CAN Bus utilization is not high.
+ *
+ * This setting is not persistent and is lost when device is reset.
+ * If this is a concern, calling application can use HasReset()
+ * to determine if the status frame needs to be reconfigured.
+ *
+ * @param frame
+ * Frame whose period is to be changed.
+ * @param periodMs
+ * Period in ms for the given frame.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setStatusFramePeriod(StatusFrameEnhanced frame, int periodMs, int timeoutMs) {
+ return super.setStatusFramePeriod(frame.value, periodMs, timeoutMs);
+ }
+ /**
+ * Gets the period of the given status frame.
+ *
+ * @param frame
+ * Frame to get the period of.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Period of the given status frame.
+ */
+ public int getStatusFramePeriod(StatusFrameEnhanced frame, int timeoutMs) {
+
+ return super.getStatusFramePeriod(frame, timeoutMs);
+ }
+ /**
+ * Configures the period of each velocity sample.
+ * Every 1ms a position value is sampled, and the delta between that sample
+ * and the position sampled kPeriod ms ago is inserted into a filter.
+ * kPeriod is configured with this function.
+ *
+ * @param period
+ * Desired period for the velocity measurement. @see
+ * #VelocityMeasPeriod
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configVelocityMeasurementPeriod(VelocityMeasPeriod period, int timeoutMs) {
+ return super.configVelocityMeasurementPeriod(period, timeoutMs);
+ }
+ /**
+ * Sets the number of velocity samples used in the rolling average velocity
+ * measurement.
+ *
+ * @param windowSize
+ * Number of samples in the rolling average of velocity
+ * measurement. Valid values are 1,2,4,8,16,32. If another
+ * value is specified, it will truncate to nearest support value.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configVelocityMeasurementWindow(int windowSize, int timeoutMs) {
+ return super.configVelocityMeasurementWindow(windowSize, timeoutMs);
+ }
+ /**
+ * Configures a limit switch for a local/remote source.
+ *
+ * For example, a CAN motor controller may need to monitor the Limit-R pin
+ * of another Talon, CANifier, or local Gadgeteer feedback connector.
+ *
+ * If the sensor is remote, a device ID of zero is assumed.
+ * If that's not desired, use the four parameter version of this function.
+ *
+ * @param type
+ * Limit switch source.
+ * User can choose between the feedback connector, remote Talon SRX, CANifier, or deactivate the feature.
+ * @param normalOpenOrClose
+ * Setting for normally open, normally closed, or disabled. This setting
+ * matches the web-based configuration drop down.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configForwardLimitSwitchSource(LimitSwitchSource type, LimitSwitchNormal normalOpenOrClose,
+ int timeoutMs) {
+
+ return super.configForwardLimitSwitchSource(type.value, normalOpenOrClose.value, 0x00000000, timeoutMs);
+ }
+ /**
+ * Configures a limit switch for a local/remote source.
+ *
+ * For example, a CAN motor controller may need to monitor the Limit-R pin
+ * of another Talon, CANifier, or local Gadgeteer feedback connector.
+ *
+ * If the sensor is remote, a device ID of zero is assumed. If that's not
+ * desired, use the four parameter version of this function.
+ *
+ * @param type
+ * Limit switch source. @see #LimitSwitchSource User can choose
+ * between the feedback connector, remote Talon SRX, CANifier, or
+ * deactivate the feature.
+ * @param normalOpenOrClose
+ * Setting for normally open, normally closed, or disabled. This
+ * setting matches the web-based configuration drop down.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configReverseLimitSwitchSource(LimitSwitchSource type, LimitSwitchNormal normalOpenOrClose,
+ int timeoutMs) {
+ return super.configReverseLimitSwitchSource(type.value, normalOpenOrClose.value, 0x00000000, timeoutMs);
+ }
+
+ // ------ Current Lim ----------//
+ /**
+ * Configure the peak allowable current (when current limit is enabled).
+ *
+ * Current limit is activated when current exceeds the peak limit for longer
+ * than the peak duration. Then software will limit to the continuous limit.
+ * This ensures current limiting while allowing for momentary excess current
+ * events.
+ *
+ * For simpler current-limiting (single threshold) use
+ * ConfigContinuousCurrentLimit() and set the peak to zero:
+ * ConfigPeakCurrentLimit(0).
+ *
+ * @param amps
+ * Amperes to limit.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ */
+ public ErrorCode configPeakCurrentLimit(int amps, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigPeakCurrentLimit(m_handle, amps, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Configure the peak allowable duration (when current limit is enabled).
+ *
+ * Current limit is activated when current exceeds the peak limit for longer
+ * than the peak duration. Then software will limit to the continuous limit.
+ * This ensures current limiting while allowing for momentary excess current
+ * events.
+ *
+ * For simpler current-limiting (single threshold) use
+ * ConfigContinuousCurrentLimit() and set the peak to zero:
+ * ConfigPeakCurrentLimit(0).
+ *
+ * @param milliseconds
+ * How long to allow current-draw past peak limit.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ */
+ public ErrorCode configPeakCurrentDuration(int milliseconds, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigPeakCurrentDuration(m_handle, milliseconds, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Configure the continuous allowable current-draw (when current limit is
+ * enabled).
+ *
+ * Current limit is activated when current exceeds the peak limit for longer
+ * than the peak duration. Then software will limit to the continuous limit.
+ * This ensures current limiting while allowing for momentary excess current
+ * events.
+ *
+ * For simpler current-limiting (single threshold) use
+ * ConfigContinuousCurrentLimit() and set the peak to zero:
+ * ConfigPeakCurrentLimit(0).
+ *
+ * @param amps
+ * Amperes to limit.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for config
+ * success and report an error if it times out. If zero, no
+ * blocking or checking is performed.
+ */
+ public ErrorCode configContinuousCurrentLimit(int amps, int timeoutMs) {
+ int retval = MotControllerJNI.ConfigContinuousCurrentLimit(m_handle, amps, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Enable or disable Current Limit.
+ *
+ * @param enable
+ * Enable state of current limit.
+ * @see ConfigPeakCurrentLimit, ConfigPeakCurrentDuration,
+ * ConfigContinuousCurrentLimit
+ */
+ public void enableCurrentLimit(boolean enable) {
+ MotControllerJNI.EnableCurrentLimit(m_handle, enable);
+ }
+}
diff --git a/java/src/com/ctre/phoenix/motorcontrol/can/VictorSPX.java b/java/src/com/ctre/phoenix/motorcontrol/can/VictorSPX.java
new file mode 100644
index 0000000..5bf8313
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/can/VictorSPX.java
@@ -0,0 +1,21 @@
+package com.ctre.phoenix.motorcontrol.can;
+
+import com.ctre.phoenix.motorcontrol.IMotorController;
+
+import edu.wpi.first.wpilibj.hal.HAL;
+/**
+ * VEX Victor SPX Motor Controller when used on CAN Bus.
+ */
+public class VictorSPX extends com.ctre.phoenix.motorcontrol.can.BaseMotorController
+ implements IMotorController {
+ /**
+ * Constructor
+ *
+ * @param deviceNumber
+ * [0,62]
+ */
+ public VictorSPX(int deviceNumber) {
+ super(deviceNumber | 0x01040000);
+ HAL.report(65, deviceNumber + 1);
+ }
+}
diff --git a/java/src/com/ctre/phoenix/motorcontrol/can/WPI_TalonSRX.java b/java/src/com/ctre/phoenix/motorcontrol/can/WPI_TalonSRX.java
new file mode 100644
index 0000000..5fd93f2
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/can/WPI_TalonSRX.java
@@ -0,0 +1,231 @@
+/**
+ * WPI Compliant motor controller class.
+ * WPILIB's object model requires many interfaces to be implemented to use
+ * the various features.
+ * This includes...
+ * - Software PID loops running in the robot controller
+ * - LiveWindow/Test mode features
+ * - Motor Safety (auto-turn off of motor if Set stops getting called)
+ * - Single Parameter set that assumes a simple motor controller.
+ */
+package com.ctre.phoenix.motorcontrol.can;
+
+import edu.wpi.first.wpilibj.SpeedController;
+import edu.wpi.first.wpilibj.livewindow.LiveWindow;
+import com.ctre.phoenix.motorcontrol.ControlMode;
+import edu.wpi.first.wpilibj.MotorSafety;
+import edu.wpi.first.wpilibj.MotorSafetyHelper;
+import edu.wpi.first.wpilibj.Sendable;
+import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
+import edu.wpi.first.wpilibj.hal.HAL;
+
+public class WPI_TalonSRX extends TalonSRX implements SpeedController, Sendable, MotorSafety {
+
+ private String _description;
+ private double _speed;
+ private MotorSafetyHelper _safetyHelper;
+
+ /** Constructor */
+ public WPI_TalonSRX(int deviceNumber) {
+ super(deviceNumber);
+ HAL.report(66, deviceNumber + 1);
+ _description = "Talon SRX " + deviceNumber;
+ /* prep motor safety */
+ _safetyHelper = new MotorSafetyHelper(this);
+ _safetyHelper.setExpiration(0.0);
+ _safetyHelper.setSafetyEnabled(false);
+
+ LiveWindow.add(this);
+ setName("Talon SRX ", deviceNumber);
+ }
+
+ // ------ set/get routines for WPILIB interfaces ------//
+ @Override
+ public void set(double speed) {
+ _speed = speed;
+ set(ControlMode.PercentOutput, _speed);
+ _safetyHelper.feed();
+ }
+
+ @Override
+ public void pidWrite(double output) {
+ set(output);
+ }
+
+ /**
+ * Common interface for getting the current set speed of a speed controller.
+ *
+ * @return The current set speed. Value is between -1.0 and 1.0.
+ */
+ @Override
+ public double get() {
+ return _speed;
+ }
+
+ // ---------Intercept CTRE calls for motor safety ---------//
+ public void set(ControlMode mode, double value) {
+ /* intercept the advanced Set and feed motor-safety */
+ super.set(mode, value);
+ _safetyHelper.feed();
+ }
+
+ public void set(ControlMode mode, double demand0, double demand1) {
+ /* intercept the advanced Set and feed motor-safety */
+ super.set(mode, demand0, demand1);
+ _safetyHelper.feed();
+ }
+
+ // ----------------------- Invert routines -------------------//
+ @Override
+ public void setInverted(boolean isInverted) {
+ super.setInverted(isInverted);
+ }
+
+ @Override
+ public boolean getInverted() {
+ return super.getInverted();
+ }
+
+ // ----------------------- turn-motor-off routines-------------------//
+ @Override
+ public void disable() {
+ neutralOutput();
+ }
+
+ /**
+ * Common interface to stop the motor until Set is called again.
+ */
+ @Override
+ public void stopMotor() {
+ neutralOutput();
+ }
+ // -------- Motor Safety--------//
+
+ /**
+ * Set the safety expiration time.
+ *
+ * @param timeout
+ * The timeout (in seconds) for this motor object
+ */
+ @Override
+ public void setExpiration(double timeout) {
+ _safetyHelper.setExpiration(timeout);
+ }
+
+ /**
+ * Return the safety expiration time.
+ *
+ * @return The expiration time value.
+ */
+ @Override
+ public double getExpiration() {
+ return _safetyHelper.getExpiration();
+ }
+
+ /**
+ * Check if the motor is currently alive or stopped due to a timeout.
+ *
+ * @return a bool value that is true if the motor has NOT timed out and
+ * should still be running.
+ */
+ @Override
+ public boolean isAlive() {
+ return _safetyHelper.isAlive();
+ }
+
+ /**
+ * Check if motor safety is enabled.
+ *
+ * @return True if motor safety is enforced for this object
+ */
+ @Override
+ public boolean isSafetyEnabled() {
+ return _safetyHelper.isSafetyEnabled();
+ }
+
+ @Override
+ public void setSafetyEnabled(boolean enabled) {
+ _safetyHelper.setSafetyEnabled(enabled);
+ }
+
+ // ---- essentially a copy of SendableBase -------//
+ private String m_name = "";
+ private String m_subsystem = "Ungrouped";
+
+ /**
+ * Free the resources used by this object.
+ */
+ public void free() {
+ LiveWindow.remove(this);
+ }
+
+ @Override
+ public final synchronized String getName() {
+ return m_name;
+ }
+
+ @Override
+ public final synchronized void setName(String name) {
+ m_name = name;
+ }
+
+ /**
+ * Sets the name of the sensor with a channel number.
+ *
+ * @param moduleType
+ * A string that defines the module name in the label for the
+ * value
+ * @param channel
+ * The channel number the device is plugged into
+ */
+ protected final void setName(String moduleType, int channel) {
+ setName(moduleType + "[" + channel + "]");
+ }
+
+ /**
+ * Sets the name of the sensor with a module and channel number.
+ *
+ * @param moduleType
+ * A string that defines the module name in the label for the
+ * value
+ * @param moduleNumber
+ * The number of the particular module type
+ * @param channel
+ * The channel number the device is plugged into (usually PWM)
+ */
+ protected final void setName(String moduleType, int moduleNumber, int channel) {
+ setName(moduleType + "[" + moduleNumber + "," + channel + "]");
+ }
+
+ @Override
+ public final synchronized String getSubsystem() {
+ return m_subsystem;
+ }
+
+ @Override
+ public final synchronized void setSubsystem(String subsystem) {
+ m_subsystem = subsystem;
+ }
+
+ /**
+ * Add a child component.
+ *
+ * @param child
+ * child component
+ */
+ protected final void addChild(Object child) {
+ LiveWindow.addChild(this, child);
+ }
+
+ @Override
+ public void initSendable(SendableBuilder builder) {
+ builder.setSmartDashboardType("Speed Controller");
+ builder.setSafeState(this::stopMotor);
+ builder.addDoubleProperty("Value", this::get, this::set);
+ }
+
+ @Override
+ public String getDescription() {
+ return _description;
+ }
+}
diff --git a/java/src/com/ctre/phoenix/motorcontrol/can/WPI_VictorSPX.java b/java/src/com/ctre/phoenix/motorcontrol/can/WPI_VictorSPX.java
new file mode 100644
index 0000000..9c7436f
--- /dev/null
+++ b/java/src/com/ctre/phoenix/motorcontrol/can/WPI_VictorSPX.java
@@ -0,0 +1,231 @@
+/**
+ * WPI Compliant motor controller class.
+ * WPILIB's object model requires many interfaces to be implemented to use
+ * the various features.
+ * This includes...
+ * - Software PID loops running in the robot controller
+ * - LiveWindow/Test mode features
+ * - Motor Safety (auto-turn off of motor if Set stops getting called)
+ * - Single Parameter set that assumes a simple motor controller.
+ */
+package com.ctre.phoenix.motorcontrol.can;
+
+import edu.wpi.first.wpilibj.SpeedController;
+import edu.wpi.first.wpilibj.livewindow.LiveWindow;
+import com.ctre.phoenix.motorcontrol.ControlMode;
+import edu.wpi.first.wpilibj.MotorSafety;
+import edu.wpi.first.wpilibj.MotorSafetyHelper;
+import edu.wpi.first.wpilibj.Sendable;
+import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
+import edu.wpi.first.wpilibj.hal.HAL;
+
+public class WPI_VictorSPX extends VictorSPX implements SpeedController, Sendable, MotorSafety {
+
+ private String _description;
+ private double _speed;
+ private MotorSafetyHelper _safetyHelper;
+
+ /** Constructor */
+ public WPI_VictorSPX(int deviceNumber) {
+ super(deviceNumber);
+ HAL.report(67, deviceNumber + 1);
+ _description = "Victor SPX " + deviceNumber;
+ /* prep motor safety */
+ _safetyHelper = new MotorSafetyHelper(this);
+ _safetyHelper.setExpiration(0.0);
+ _safetyHelper.setSafetyEnabled(false);
+
+ LiveWindow.add(this);
+ setName("Victor SPX ", deviceNumber);
+ }
+
+ // ------ set/get routines for WPILIB interfaces ------//
+ @Override
+ public void set(double speed) {
+ _speed = speed;
+ set(ControlMode.PercentOutput, _speed);
+ _safetyHelper.feed();
+ }
+
+ @Override
+ public void pidWrite(double output) {
+ set(output);
+ }
+
+ /**
+ * Common interface for getting the current set speed of a speed controller.
+ *
+ * @return The current set speed. Value is between -1.0 and 1.0.
+ */
+ @Override
+ public double get() {
+ return _speed;
+ }
+
+ // ---------Intercept CTRE calls for motor safety ---------//
+ public void set(ControlMode mode, double value) {
+ /* intercept the advanced Set and feed motor-safety */
+ super.set(mode, value);
+ _safetyHelper.feed();
+ }
+
+ public void set(ControlMode mode, double demand0, double demand1) {
+ /* intercept the advanced Set and feed motor-safety */
+ super.set(mode, demand0, demand1);
+ _safetyHelper.feed();
+ }
+
+ // ----------------------- Invert routines -------------------//
+ @Override
+ public void setInverted(boolean isInverted) {
+ super.setInverted(isInverted);
+ }
+
+ @Override
+ public boolean getInverted() {
+ return super.getInverted();
+ }
+
+ // ----------------------- turn-motor-off routines-------------------//
+ @Override
+ public void disable() {
+ neutralOutput();
+ }
+
+ /**
+ * Common interface to stop the motor until Set is called again.
+ */
+ @Override
+ public void stopMotor() {
+ neutralOutput();
+ }
+ // -------- Motor Safety--------//
+
+ /**
+ * Set the safety expiration time.
+ *
+ * @param timeout
+ * The timeout (in seconds) for this motor object
+ */
+ @Override
+ public void setExpiration(double timeout) {
+ _safetyHelper.setExpiration(timeout);
+ }
+
+ /**
+ * Return the safety expiration time.
+ *
+ * @return The expiration time value.
+ */
+ @Override
+ public double getExpiration() {
+ return _safetyHelper.getExpiration();
+ }
+
+ /**
+ * Check if the motor is currently alive or stopped due to a timeout.
+ *
+ * @return a bool value that is true if the motor has NOT timed out and
+ * should still be running.
+ */
+ @Override
+ public boolean isAlive() {
+ return _safetyHelper.isAlive();
+ }
+
+ /**
+ * Check if motor safety is enabled.
+ *
+ * @return True if motor safety is enforced for this object
+ */
+ @Override
+ public boolean isSafetyEnabled() {
+ return _safetyHelper.isSafetyEnabled();
+ }
+
+ @Override
+ public void setSafetyEnabled(boolean enabled) {
+ _safetyHelper.setSafetyEnabled(enabled);
+ }
+
+ // ---- essentially a copy of SendableBase -------//
+ private String m_name = "";
+ private String m_subsystem = "Ungrouped";
+
+ /**
+ * Free the resources used by this object.
+ */
+ public void free() {
+ LiveWindow.remove(this);
+ }
+
+ @Override
+ public final synchronized String getName() {
+ return m_name;
+ }
+
+ @Override
+ public final synchronized void setName(String name) {
+ m_name = name;
+ }
+
+ /**
+ * Sets the name of the sensor with a channel number.
+ *
+ * @param moduleType
+ * A string that defines the module name in the label for the
+ * value
+ * @param channel
+ * The channel number the device is plugged into
+ */
+ protected final void setName(String moduleType, int channel) {
+ setName(moduleType + "[" + channel + "]");
+ }
+
+ /**
+ * Sets the name of the sensor with a module and channel number.
+ *
+ * @param moduleType
+ * A string that defines the module name in the label for the
+ * value
+ * @param moduleNumber
+ * The number of the particular module type
+ * @param channel
+ * The channel number the device is plugged into (usually PWM)
+ */
+ protected final void setName(String moduleType, int moduleNumber, int channel) {
+ setName(moduleType + "[" + moduleNumber + "," + channel + "]");
+ }
+
+ @Override
+ public final synchronized String getSubsystem() {
+ return m_subsystem;
+ }
+
+ @Override
+ public final synchronized void setSubsystem(String subsystem) {
+ m_subsystem = subsystem;
+ }
+
+ /**
+ * Add a child component.
+ *
+ * @param child
+ * child component
+ */
+ protected final void addChild(Object child) {
+ LiveWindow.addChild(this, child);
+ }
+
+ @Override
+ public void initSendable(SendableBuilder builder) {
+ builder.setSmartDashboardType("Speed Controller");
+ builder.setSafeState(this::stopMotor);
+ builder.addDoubleProperty("Value", this::get, this::set);
+ }
+
+ @Override
+ public String getDescription() {
+ return _description;
+ }
+}
diff --git a/java/src/com/ctre/phoenix/schedulers/ConcurrentScheduler.java b/java/src/com/ctre/phoenix/schedulers/ConcurrentScheduler.java
new file mode 100644
index 0000000..bfc0a5d
--- /dev/null
+++ b/java/src/com/ctre/phoenix/schedulers/ConcurrentScheduler.java
@@ -0,0 +1,95 @@
+package com.ctre.phoenix.schedulers;
+import java.util.ArrayList;
+
+import com.ctre.phoenix.ILoopable;
+
+public class ConcurrentScheduler implements ILoopable {
+ ArrayList<ILoopable> _loops = new ArrayList<ILoopable>();
+ ArrayList<Boolean> _enabs = new ArrayList<Boolean>();
+
+ public void add(ILoopable aLoop, boolean enable) {
+ _loops.add(aLoop);
+ _enabs.add(enable);
+ }
+ public void add(ILoopable aLoop) {
+ add(aLoop, true);
+ }
+
+ public void removeAll() {
+ _loops.clear();
+ _enabs.clear();
+ }
+
+ public void start(ILoopable toStart) {
+ for (int i = 0; i < _loops.size(); ++i) {
+ ILoopable lp = (ILoopable) _loops.get(i);
+
+ if (lp == toStart) {
+ _enabs.set(i, true);
+ lp.onStart();
+ return;
+ }
+ }
+
+ }
+
+ public void stop(ILoopable toStop) {
+ for (int i = 0; i < (int) _loops.size(); ++i) {
+ ILoopable lp = (ILoopable) _loops.get(i);
+
+ if (lp == toStop) {
+ _enabs.set(i, false);
+ lp.onStop();
+ return;
+ }
+ }
+ }
+
+ public void startAll() { // All Loops
+
+ for (ILoopable loop : _loops) {
+ loop.onStart();
+ }
+ for (int i = 0; i < _enabs.size(); ++i) {
+ _enabs.set(i, true);
+ }
+ }
+
+ public void stopAll() { // All Loops
+ for (ILoopable loop : _loops) {
+ loop.onStop();
+ }
+ for (int i = 0; i < _enabs.size(); ++i) {
+ _enabs.set(i, false);
+ }
+ }
+
+ public void process() {
+ for (int i = 0; i < (int) _loops.size(); ++i) {
+ ILoopable loop = (ILoopable) _loops.get(i);
+ boolean en = (boolean) _enabs.get(i);
+ if (en) {
+ loop.onLoop();
+ } else {
+ /* Current ILoopable is turned off, don't call onLoop for it */
+ }
+ }
+ }
+
+ /* ILoopable */
+ public void onStart() {
+ startAll();
+ }
+
+ public void onLoop() {
+ process();
+ }
+
+ public void onStop() {
+ stopAll();
+ }
+
+ public boolean isDone() {
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/schedulers/SequentialScheduler.java b/java/src/com/ctre/phoenix/schedulers/SequentialScheduler.java
new file mode 100644
index 0000000..ba2b238
--- /dev/null
+++ b/java/src/com/ctre/phoenix/schedulers/SequentialScheduler.java
@@ -0,0 +1,97 @@
+package com.ctre.phoenix.schedulers;
+import java.util.ArrayList;
+
+public class SequentialScheduler implements com.ctre.phoenix.ILoopable
+{
+ boolean _running = false;
+ ArrayList<com.ctre.phoenix.ILoopable> _loops = new ArrayList<com.ctre.phoenix.ILoopable>();
+ int _periodMs;
+ int _idx;
+ boolean _iterated = false;
+
+ public SequentialScheduler(int periodMs)
+ {
+ _periodMs = periodMs;
+ }
+ public void add(com.ctre.phoenix.ILoopable aLoop)
+ {
+ _loops.add(aLoop);
+ }
+
+ public com.ctre.phoenix.ILoopable getCurrent()
+ {
+ return null;
+ }
+
+ public void removeAll()
+ {
+ _loops.clear();
+ }
+
+ public void start()
+ {
+ _idx = 0;
+ if(_loops.size() > 0)
+ _loops.get(0).onStart();
+
+ _running = true;
+ }
+ public void stop()
+ {
+ for (int i = 0; i < _loops.size(); i++)
+ {
+ _loops.get(i).onStop();
+ }
+ _running = false;
+ }
+ public void process()
+ {
+ _iterated = false;
+ if (_idx < _loops.size())
+ {
+ if (_running)
+ {
+ com.ctre.phoenix.ILoopable loop = _loops.get(_idx);
+ loop.onLoop();
+ if (loop.isDone())
+ {
+ _iterated = true;
+ ++_idx;
+ if (_idx < _loops.size()) _loops.get(_idx).onStart();
+ }
+ }
+ }
+ else
+ {
+ _running = false;
+ }
+ }
+ public boolean iterated()
+ {
+ return _iterated;
+ }
+ //--- Loopable ---/
+ public void onStart()
+ {
+ start();
+ }
+
+ public void onLoop()
+ {
+ process();
+ }
+
+ public boolean isDone()
+ {
+ /* Have to return something to know if we are done */
+ if (_running == false)
+ return true;
+ else
+ return false;
+ }
+
+ public void onStop()
+ {
+ stop();
+ }
+}
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/sensors/PigeonIMU.java b/java/src/com/ctre/phoenix/sensors/PigeonIMU.java
new file mode 100644
index 0000000..981b457
--- /dev/null
+++ b/java/src/com/ctre/phoenix/sensors/PigeonIMU.java
@@ -0,0 +1,908 @@
+/*
+ * Software License Agreement
+ *
+ * Copyright (C) Cross The Road Electronics. All rights
+ * reserved.
+ *
+ * Cross The Road Electronics (CTRE) licenses to you the right to
+ * use, publish, and distribute copies of CRF (Cross The Road) firmware files (*.crf) and Software
+ * API Libraries ONLY when in use with Cross The Road Electronics hardware products.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * CROSS THE ROAD ELECTRONICS BE LIABLE FOR ANY INCIDENTAL, SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE
+ */
+package com.ctre.phoenix.sensors;
+import com.ctre.phoenix.ErrorCode;
+import com.ctre.phoenix.ParamEnum;
+import com.ctre.phoenix.motorcontrol.can.TalonSRX;
+
+import edu.wpi.first.wpilibj.hal.FRCNetComm.tResourceType;
+import edu.wpi.first.wpilibj.hal.HAL;
+
+/**
+ * Pigeon IMU Class. Class supports communicating over CANbus and over
+ * ribbon-cable (CAN Talon SRX).
+ */
+public class PigeonIMU {
+ private long m_handle;
+
+ /** Data object for holding fusion information. */
+ public static class FusionStatus {
+ public double heading;
+ public boolean bIsValid;
+ public boolean bIsFusing;
+
+ /**
+ * Same as getLastError()
+ */
+ public ErrorCode lastError;
+
+ public String toString() {
+ String description;
+ if (lastError != ErrorCode.OK) {
+ description = "Could not receive status frame. Check wiring and web-config.";
+ } else if (bIsValid == false) {
+ description = "Fused Heading is not valid.";
+ } else if (bIsFusing == false) {
+ description = "Fused Heading is valid.";
+ } else {
+ description = "Fused Heading is valid and is fusing compass.";
+ }
+ return description;
+ }
+ }
+
+ /** Various calibration modes supported by Pigeon. */
+ public enum CalibrationMode {
+ BootTareGyroAccel(0), Temperature(1), Magnetometer12Pt(2), Magnetometer360(3), Accelerometer(5), Unknown(-1);
+ public final int value;
+
+ private CalibrationMode(int initValue) {
+ this.value = initValue;
+ }
+
+ public static CalibrationMode valueOf(int value) {
+ for (CalibrationMode e : CalibrationMode.values()) {
+ if (e.value == value) {
+ return e;
+ }
+ }
+ return Unknown;
+ }
+ };
+
+ /** Overall state of the Pigeon. */
+ public enum PigeonState {
+ NoComm(0), Initializing(1), Ready(2), UserCalibration(3), Unknown(-1);
+ public final int value;
+
+ private PigeonState(int initValue) {
+ this.value = initValue;
+ }
+
+ public static PigeonState valueOf(int value) {
+ for (PigeonState e : PigeonState.values()) {
+ if (e.value == value) {
+ return e;
+ }
+ }
+ return Unknown;
+ }
+ };
+
+ /**
+ * Data object for status on current calibration and general status.
+ *
+ * Pigeon has many calibration modes supported for a variety of uses. The
+ * modes generally collects and saves persistently information that makes
+ * the Pigeon signals more accurate. This includes collecting temperature,
+ * gyro, accelerometer, and compass information.
+ *
+ * For FRC use-cases, typically compass and temperature calibration is not
+ * required.
+ *
+ * Additionally when motion driver software in the Pigeon boots, it will
+ * perform a fast boot calibration to initially bias gyro and setup
+ * accelerometer.
+ *
+ * These modes can be enabled with the EnterCalibration mode.
+ *
+ * When a calibration mode is entered, caller can expect...
+ *
+ * - PigeonState to reset to Initializing and bCalIsBooting is set to true.
+ * Pigeon LEDs will blink the boot pattern. This is similar to the normal
+ * boot cal, however it can an additional ~30 seconds since calibration
+ * generally requires more information. currentMode will reflect the user's
+ * selected calibration mode.
+ *
+ * - PigeonState will eventually settle to UserCalibration and Pigeon LEDs
+ * will show cal specific blink patterns. bCalIsBooting is now false.
+ *
+ * - Follow the instructions in the Pigeon User Manual to meet the
+ * calibration specific requirements. When finished calibrationError will
+ * update with the result. Pigeon will solid-fill LEDs with red (for
+ * failure) or green (for success) for ~5 seconds. Pigeon then perform
+ * boot-cal to cleanly apply the newly saved calibration data.
+ */
+ public static class GeneralStatus {
+ /**
+ * The current state of the motion driver. This reflects if the sensor
+ * signals are accurate. Most calibration modes will force Pigeon to
+ * reinit the motion driver.
+ */
+ public PigeonState state;
+ /**
+ * The currently applied calibration mode if state is in UserCalibration
+ * or if bCalIsBooting is true. Otherwise it holds the last selected
+ * calibration mode (when calibrationError was updated).
+ */
+ public CalibrationMode currentMode;
+ /**
+ * The error code for the last calibration mode. Zero represents a
+ * successful cal (with solid green LEDs at end of cal) and nonzero is a
+ * failed calibration (with solid red LEDs at end of cal). Different
+ * calibration
+ */
+ public int calibrationError;
+ /**
+ * After caller requests a calibration mode, pigeon will perform a
+ * boot-cal before entering the requested mode. During this period, this
+ * flag is set to true.
+ */
+ public boolean bCalIsBooting;
+ /**
+ * Temperature in Celsius
+ */
+ public double tempC;
+ /**
+ * Number of seconds Pigeon has been up (since boot). This register is
+ * reset on power boot or processor reset. Register is capped at 255
+ * seconds with no wrap around.
+ */
+ public int upTimeSec;
+ /**
+ * Number of times the Pigeon has automatically rebiased the gyro. This
+ * counter overflows from 15 -> 0 with no cap.
+ */
+ public int noMotionBiasCount;
+ /**
+ * Number of times the Pigeon has temperature compensated the various
+ * signals. This counter overflows from 15 -> 0 with no cap.
+ */
+ public int tempCompensationCount;
+ /**
+ * Same as getLastError()
+ */
+ public ErrorCode lastError;
+
+ /**
+ * general string description of current status
+ */
+ public String toString() {
+ String description;
+ /* build description string */
+ if (lastError != ErrorCode.OK) { // same as NoComm
+ description = "Status frame was not received, check wired connections and web-based config.";
+ } else if (bCalIsBooting) {
+ description = "Pigeon is boot-caling to properly bias accel and gyro. Do not move Pigeon. When finished biasing, calibration mode will start.";
+ } else if (state == PigeonState.UserCalibration) {
+ /* mode specific descriptions */
+ switch (currentMode) {
+ case BootTareGyroAccel:
+ description = "Boot-Calibration: Gyro and Accelerometer are being biased.";
+ break;
+ case Temperature:
+ description = "Temperature-Calibration: Pigeon is collecting temp data and will finish when temp range is reached. \n";
+ description += "Do not move Pigeon.";
+ break;
+ case Magnetometer12Pt:
+ description = "Magnetometer Level 1 calibration: Orient the Pigeon PCB in the 12 positions documented in the User's Manual.";
+ break;
+ case Magnetometer360:
+ description = "Magnetometer Level 2 calibration: Spin robot slowly in 360' fashion. ";
+ break;
+ case Accelerometer:
+ description = "Accelerometer Calibration: Pigeon PCB must be placed on a level source. Follow User's Guide for how to level surfacee. ";
+ break;
+ default:
+ case Unknown:
+ description = "Unknown status";
+ break;
+ }
+ } else if (state == PigeonState.Ready) {
+ /*
+ * definitely not doing anything cal-related. So just instrument
+ * the motion driver state
+ */
+ description = "Pigeon is running normally. Last CAL error code was ";
+ description += Integer.toString(calibrationError);
+ description += ".";
+ } else if (state == PigeonState.Initializing) {
+ /*
+ * definitely not doing anything cal-related. So just instrument
+ * the motion driver state
+ */
+ description = "Pigeon is boot-caling to properly bias accel and gyro. Do not move Pigeon.";
+ } else {
+ description = "Not enough data to determine status.";
+ }
+ return description;
+ }
+ };
+
+ private int m_deviceNumber = 0;
+
+ private double[] _generalStatus = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ private double[] _fusionStatus = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ /**
+ * Create a Pigeon object that communicates with Pigeon on CAN Bus.
+ *
+ * @param deviceNumber
+ * CAN Device Id of Pigeon [0,62]
+ */
+ public PigeonIMU(int deviceNumber) {
+ m_handle = PigeonImuJNI.JNI_new_PigeonImu(deviceNumber);
+ m_deviceNumber = deviceNumber;
+ HAL.report(tResourceType.kResourceType_PigeonIMU, m_deviceNumber + 1);
+ }
+
+ /**
+ * Create a Pigeon object that communciates with Pigeon through the
+ * Gadgeteer ribbon cable connected to a Talon on CAN Bus.
+ *
+ * @param talonSrx
+ * Object for the TalonSRX connected via ribbon cable.
+ */
+ public PigeonIMU(TalonSRX talonSrx) {
+ m_deviceNumber = talonSrx.getDeviceID();
+ m_handle = PigeonImuJNI.JNI_new_PigeonImu_Talon(m_deviceNumber);
+ HAL.report(tResourceType.kResourceType_PigeonIMU, m_deviceNumber + 1);
+ HAL.report(64, m_deviceNumber + 1);
+ }
+
+ /**
+ * Sets the Yaw register to the specified value.
+ *
+ * @param angleDeg Degree of Yaw [+/- 23040 degrees]
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setYaw(double angleDeg, int timeoutMs) {
+ int retval = PigeonImuJNI.JNI_SetYaw(m_handle, angleDeg, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Atomically add to the Yaw register.
+ *
+ * @param angleDeg Degrees to add to the Yaw register.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode addYaw(double angleDeg, int timeoutMs) {
+ int retval = PigeonImuJNI.JNI_AddYaw(m_handle, angleDeg, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Sets the Yaw register to match the current compass value.
+ *
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setYawToCompass(int timeoutMs) {
+ int retval = PigeonImuJNI.JNI_SetYawToCompass(m_handle, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Sets the Fused Heading to the specified value.
+ *
+ * @param angleDeg Degree of heading [+/- 23040 degrees]
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setFusedHeading(double angleDeg, int timeoutMs) {
+ int retval = PigeonImuJNI.JNI_SetFusedHeading(m_handle, angleDeg, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Atomically add to the Fused Heading register.
+ *
+ * @param angleDeg Degrees to add to the Fused Heading register.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode addFusedHeading(double angleDeg, int timeoutMs) {
+ int retval = PigeonImuJNI.JNI_AddFusedHeading(m_handle, angleDeg, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Sets the Fused Heading register to match the current compass value.
+ *
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setFusedHeadingToCompass(int timeoutMs) {
+ int retval = PigeonImuJNI.JNI_SetFusedHeadingToCompass(m_handle, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Sets the AccumZAngle.
+ *
+ * @param angleDeg Degrees to set AccumZAngle to.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setAccumZAngle(double angleDeg, int timeoutMs) {
+ int retval = PigeonImuJNI.JNI_SetAccumZAngle(m_handle, angleDeg, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Enable/Disable Temp compensation. Pigeon defaults with this on at boot.
+ *
+ * @param bTempCompEnable Set to "True" to enable temperature compensation.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configTemperatureCompensationEnable(boolean bTempCompEnable, int timeoutMs) {
+ int retval = PigeonImuJNI.JNI_ConfigTemperatureCompensationEnable(m_handle, bTempCompEnable ? 1 : 0, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Set the declination for compass. Declination is the difference between
+ * Earth Magnetic north, and the geographic "True North".
+ *
+ * @param angleDegOffset Degrees to set Compass Declination to.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setCompassDeclination(double angleDegOffset, int timeoutMs) {
+ int retval = PigeonImuJNI.JNI_SetCompassDeclination(m_handle, angleDegOffset, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the compass angle. Although compass is absolute [0,360) degrees, the
+ * continuous compass register holds the wrap-arounds.
+ *
+ * @param angleDeg Degrees to set continuous compass angle to.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setCompassAngle(double angleDeg, int timeoutMs) {
+ int retval = PigeonImuJNI.JNI_SetCompassAngle(m_handle, angleDeg, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ // ----------------------- Calibration routines -----------------------//
+ /**
+ * Enters the Calbration mode. See the Pigeon IMU documentation for More
+ * information on Calibration.
+ *
+ * @param calMode Calibration to execute
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode enterCalibrationMode(CalibrationMode calMode, int timeoutMs) {
+ int retval = PigeonImuJNI.JNI_EnterCalibrationMode(m_handle, calMode.value, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Get the status of the current (or previousley complete) calibration.
+ *
+ * @param toFill Container for the status information.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode getGeneralStatus(GeneralStatus toFill) {
+ int retval = PigeonImuJNI.JNI_GetGeneralStatus(m_handle, _generalStatus);
+ toFill.state = PigeonState.valueOf((int) _generalStatus[0]);
+ toFill.currentMode = CalibrationMode.valueOf((int) _generalStatus[1]);
+ toFill.calibrationError = (int) _generalStatus[2];
+ toFill.bCalIsBooting = _generalStatus[3] != 0;
+ toFill.tempC = _generalStatus[4];
+ toFill.upTimeSec = (int) _generalStatus[5];
+ toFill.noMotionBiasCount = (int) _generalStatus[6];
+ toFill.tempCompensationCount = (int) _generalStatus[7];
+ toFill.lastError = ErrorCode.valueOf(retval);
+ return toFill.lastError;
+ }
+
+ // ----------------------- General Error status -----------------------//
+ /**
+ * Call GetLastError() generated by this object.
+ * Not all functions return an error code but can
+ * potentially report errors.
+ *
+ * This function can be used to retrieve those error codes.
+ *
+ * @return The last ErrorCode generated.
+ */
+ public ErrorCode getLastError() {
+ int retval = PigeonImuJNI.JNI_GetLastError(m_handle);
+ return ErrorCode.valueOf(retval);
+ }
+
+ // ----------------------- Strongly typed Signal decoders
+ // -----------------------//
+ /**
+ * Get 6d Quaternion data.
+ *
+ * @param wxyz Array to fill with quaternion data w[0], x[1], y[2], z[3]
+ * @return The last ErrorCode generated.
+ */
+ public ErrorCode get6dQuaternion(double[] wxyz) {
+ int retval = PigeonImuJNI.JNI_Get6dQuaternion(m_handle, wxyz);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Get Yaw, Pitch, and Roll data.
+ *
+ * @param ypr_deg Array to fill with yaw[0], pitch[1], and roll[2] data
+ * @return The last ErrorCode generated.
+ */
+ public ErrorCode getYawPitchRoll(double[] ypr_deg) {
+ int retval = PigeonImuJNI.JNI_GetYawPitchRoll(m_handle, ypr_deg);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Get AccumGyro data.
+ * AccumGyro is the integrated gyro value on each axis.
+ *
+ * @param xyz_deg Array to fill with x[0], y[1], and z[2] AccumGyro data
+ * @return The last ErrorCode generated.
+ */
+ public ErrorCode getAccumGyro(double[] xyz_deg) {
+ int retval = PigeonImuJNI.JNI_GetAccumGyro(m_handle, xyz_deg);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Get the absolute compass heading.
+ * @return compass heading [0,360) degrees.
+ */
+ public double getAbsoluteCompassHeading() {
+ double retval = PigeonImuJNI.JNI_GetAbsoluteCompassHeading(m_handle);
+ return retval;
+ }
+
+ /**
+ * Get the continuous compass heading.
+ * @return continuous compass heading [-23040, 23040) degrees. Use
+ * SetCompassHeading to modify the wrap-around portion.
+ */
+ public double getCompassHeading() {
+ double retval = PigeonImuJNI.JNI_GetCompassHeading(m_handle);
+ return retval;
+ }
+
+ /**
+ * Gets the compass' measured magnetic field strength.
+ * @return field strength in Microteslas (uT).
+ */
+ public double getCompassFieldStrength() {
+ double retval = PigeonImuJNI.JNI_GetCompassFieldStrength(m_handle);
+ return retval;
+ }
+ /**
+ * Gets the temperature of the pigeon.
+ *
+ * @return Temperature in ('C)
+ */
+ public double getTemp() {
+ double retval = PigeonImuJNI.JNI_GetTemp(m_handle);
+ return retval;
+ }
+
+ /**
+ * Gets the current Pigeon state
+ *
+ * @return PigeonState enum
+ */
+ public PigeonState getState() {
+ int retval = PigeonImuJNI.JNI_GetState(m_handle);
+ return PigeonState.valueOf(retval);
+ }
+
+ /**
+ * Gets the current Pigeon uptime.
+ *
+ * @return How long has Pigeon been running in whole seconds. Value caps at
+ * 255.
+ */
+ public int getUpTime() {
+ int retval = PigeonImuJNI.JNI_GetUpTime(m_handle);
+ return retval;
+ }
+ /**
+ * Get Raw Magnetometer data.
+ *
+ * @param rm_xyz Array to fill with x[0], y[1], and z[2] data
+ * Number is equal to 0.6 microTeslas per unit.
+ * @return The last ErrorCode generated.
+ */
+ public ErrorCode getRawMagnetometer(short[] rm_xyz) {
+ int retval = PigeonImuJNI.JNI_GetRawMagnetometer(m_handle, rm_xyz);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Get Biased Magnetometer data.
+ *
+ * @param bm_xyz Array to fill with x[0], y[1], and z[2] data
+ * Number is equal to 0.6 microTeslas per unit.
+ * @return The last ErrorCode generated.
+ */
+ public ErrorCode getBiasedMagnetometer(short[] bm_xyz) {
+ int retval = PigeonImuJNI.JNI_GetBiasedMagnetometer(m_handle, bm_xyz);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Get Biased Accelerometer data.
+ *
+ * @param ba_xyz Array to fill with x[0], y[1], and z[2] data.
+ * These are in fixed point notation Q2.14. eg. 16384 = 1G
+ * @return The last ErrorCode generated.
+ */
+ public ErrorCode getBiasedAccelerometer(short[] ba_xyz) {
+ int retval = PigeonImuJNI.JNI_GetBiasedAccelerometer(m_handle, ba_xyz);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Get Raw Gyro data.
+ *
+ * @param xyz_dps Array to fill with x[0], y[1], and z[2] data in degrees per second.
+ * @return The last ErrorCode generated.
+ */
+ public ErrorCode getRawGyro(double[] xyz_dps) {
+ int retval = PigeonImuJNI.JNI_GetRawGyro(m_handle, xyz_dps);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Get Accelerometer tilt angles.
+ *
+ * @param tiltAngles Array to fill with x[0], y[1], and z[2] angles in degrees.
+ * @return The last ErrorCode generated.
+ */
+ public ErrorCode getAccelerometerAngles(double[] tiltAngles) {
+ int retval = PigeonImuJNI.JNI_GetAccelerometerAngles(m_handle, tiltAngles);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Get the current Fusion Status (including fused heading)
+ *
+ * @param toFill object reference to fill with fusion status flags.
+ * Caller may pass null if flags are not needed.
+ * @return The fused heading in degrees.
+ */
+ public double getFusedHeading(FusionStatus toFill) {
+ int errorCode = PigeonImuJNI.JNI_GetFusedHeading(m_handle, _fusionStatus);
+
+ if (toFill != null) {
+ toFill.heading = _fusionStatus[0];
+ toFill.bIsFusing = (_fusionStatus[1] != 0);
+ toFill.bIsValid = (_fusionStatus[2] != 0);
+ toFill.lastError = ErrorCode.valueOf(errorCode);
+ }
+
+ return _fusionStatus[0];
+ }
+ /**
+ * Gets the Fused Heading
+ *
+ * @return The fused heading in degrees.
+ */
+ public double getFusedHeading() {
+ PigeonImuJNI.JNI_GetFusedHeading(m_handle, _fusionStatus);
+
+ return _fusionStatus[0];
+ }
+
+ /**
+ * Gets the firmware version of the device.
+ *
+ * @return param holds the firmware version of the device. Device must be powered
+ * cycled at least once.
+ */
+ public int getFirmwareVersion() {
+ int k = PigeonImuJNI.JNI_GetFirmwareVersion(m_handle);
+ return k;
+ }
+
+ /**
+ * @return true iff a reset has occurred since last call.
+ */
+ public boolean hasResetOccurred() {
+ boolean k = PigeonImuJNI.JNI_HasResetOccurred(m_handle);
+ return k;
+ }
+
+ /**
+ * Sets the value of a custom parameter. This is for arbitrary use.
+ *
+ * Sometimes it is necessary to save calibration/declination/offset
+ * information in the device. Particularly if the
+ * device is part of a subsystem that can be replaced.
+ *
+ * @param newValue
+ * Value for custom parameter.
+ * @param paramIndex
+ * Index of custom parameter. [0-1]
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configSetCustomParam(int newValue, int paramIndex, int timeoutMs) {
+ int retval = PigeonImuJNI.JNI_ConfigSetCustomParam(m_handle, newValue, paramIndex, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Gets the value of a custom parameter. This is for arbitrary use.
+ *
+ * Sometimes it is necessary to save calibration/declination/offset
+ * information in the device. Particularly if the
+ * device is part of a subsystem that can be replaced.
+ *
+ * @param paramIndex
+ * Index of custom parameter. [0-1]
+ * @param timoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Value of the custom param.
+ */
+ public int configGetCustomParam(int paramIndex, int timoutMs) {
+ int retval = PigeonImuJNI.JNI_ConfigGetCustomParam(m_handle, paramIndex, timoutMs);
+ return retval;
+ }
+
+ /**
+ * Sets a parameter. Generally this is not used.
+ * This can be utilized in
+ * - Using new features without updating API installation.
+ * - Errata workarounds to circumvent API implementation.
+ * - Allows for rapid testing / unit testing of firmware.
+ *
+ * @param param
+ * Parameter enumeration.
+ * @param value
+ * Value of parameter.
+ * @param subValue
+ * Subvalue for parameter. Maximum value of 255.
+ * @param ordinal
+ * Ordinal of parameter.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configSetParameter(ParamEnum param, double value, int subValue, int ordinal, int timeoutMs) {
+ return configSetParameter(param.value, value, subValue, ordinal, timeoutMs);
+ }
+ /**
+ * Sets a parameter. Generally this is not used.
+ * This can be utilized in
+ * - Using new features without updating API installation.
+ * - Errata workarounds to circumvent API implementation.
+ * - Allows for rapid testing / unit testing of firmware.
+ *
+ * @param param
+ * Parameter enumeration.
+ * @param value
+ * Value of parameter.
+ * @param subValue
+ * Subvalue for parameter. Maximum value of 255.
+ * @param ordinal
+ * Ordinal of parameter.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configSetParameter(int param, double value, int subValue, int ordinal, int timeoutMs) {
+ int retval = PigeonImuJNI.JNI_ConfigSetParameter(m_handle, param, value, subValue, ordinal,
+ timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Gets a parameter. Generally this is not used.
+ * This can be utilized in
+ * - Using new features without updating API installation.
+ * - Errata workarounds to circumvent API implementation.
+ * - Allows for rapid testing / unit testing of firmware.
+ *
+ * @param param
+ * Parameter enumeration.
+ * @param ordinal
+ * Ordinal of parameter.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Value of parameter.
+ */
+ public double configGetParameter(ParamEnum param, int ordinal, int timeoutMs) {
+ return configGetParameter(param.value, ordinal, timeoutMs);
+ }
+ /**
+ * Gets a parameter.
+ *
+ * @param param
+ * Parameter enumeration.
+ * @param ordinal
+ * Ordinal of parameter.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Value of parameter.
+ */
+ public double configGetParameter(int param, int ordinal, int timeoutMs) {
+ return PigeonImuJNI.JNI_ConfigGetParameter(m_handle, param, ordinal, timeoutMs);
+ }
+ /**
+ * Sets the period of the given status frame.
+ *
+ * @param statusFrame
+ * Frame whose period is to be changed.
+ * @param periodMs
+ * Period in ms for the given frame.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setStatusFramePeriod(PigeonIMU_StatusFrame statusFrame, int periodMs, int timeoutMs) {
+ int retval = PigeonImuJNI.JNI_SetStatusFramePeriod(m_handle, statusFrame.value, periodMs, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Sets the period of the given status frame.
+ *
+ * @param statusFrame
+ * Frame whose period is to be changed.
+ * @param periodMs
+ * Period in ms for the given frame.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setStatusFramePeriod(int statusFrame, int periodMs, int timeoutMs) {
+ int retval = PigeonImuJNI.JNI_SetStatusFramePeriod(m_handle, statusFrame, periodMs, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Gets the period of the given status frame.
+ *
+ * @param frame
+ * Frame to get the period of.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Period of the given status frame.
+ */
+ public int getStatusFramePeriod(PigeonIMU_StatusFrame frame, int timeoutMs) {
+ return PigeonImuJNI.JNI_GetStatusFramePeriod(m_handle, frame.value, timeoutMs);
+ }
+ /**
+ * Sets the period of the given control frame.
+ *
+ * @param frame
+ * Frame whose period is to be changed.
+ * @param periodMs
+ * Period in ms for the given frame.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setControlFramePeriod(PigeonIMU_ControlFrame frame, int periodMs) {
+ int retval = PigeonImuJNI.JNI_SetControlFramePeriod(m_handle, frame.value, periodMs);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Sets the period of the given control frame.
+ *
+ * @param frame
+ * Frame whose period is to be changed.
+ * @param periodMs
+ * Period in ms for the given frame.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setControlFramePeriod(int frame, int periodMs) {
+ int retval = PigeonImuJNI.JNI_SetControlFramePeriod(m_handle, frame, periodMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ // ------ Faults ----------//
+ /**
+ * Gets the fault status
+ *
+ * @param toFill
+ * Container for fault statuses.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode getFaults(PigeonIMU_Faults toFill) {
+ int bits = PigeonImuJNI.JNI_GetFaults(m_handle);
+ toFill.update(bits);
+ return getLastError();
+ }
+ /**
+ * Gets the sticky fault status
+ *
+ * @param toFill
+ * Container for sticky fault statuses.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode getStickyFaults(PigeonIMU_StickyFaults toFill) {
+ int bits = PigeonImuJNI.JNI_GetStickyFaults(m_handle);
+ toFill.update(bits);
+ return getLastError();
+ }
+ /**
+ * Clears the Sticky Faults
+ *
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode clearStickyFaults(int timeoutMs) {
+ int retval = PigeonImuJNI.JNI_ClearStickyFaults(m_handle, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * @return The Device Number
+ */
+ public int getDeviceID(){
+ return m_deviceNumber;
+ }
+}
diff --git a/java/src/com/ctre/phoenix/sensors/PigeonIMU_ControlFrame.java b/java/src/com/ctre/phoenix/sensors/PigeonIMU_ControlFrame.java
new file mode 100644
index 0000000..21ee565
--- /dev/null
+++ b/java/src/com/ctre/phoenix/sensors/PigeonIMU_ControlFrame.java
@@ -0,0 +1,21 @@
+package com.ctre.phoenix.sensors;
+
+/** Enumerated type for control frame types. */
+public enum PigeonIMU_ControlFrame {
+ Control_1(0x00042800);
+
+ public final int value;
+
+ PigeonIMU_ControlFrame(int initValue) {
+ this.value = initValue;
+ }
+
+ public static PigeonIMU_ControlFrame valueOf(int value) {
+ for (PigeonIMU_ControlFrame mode : values()) {
+ if (mode.value == value) {
+ return mode;
+ }
+ }
+ return null;
+ }
+}
diff --git a/java/src/com/ctre/phoenix/sensors/PigeonIMU_Faults.java b/java/src/com/ctre/phoenix/sensors/PigeonIMU_Faults.java
new file mode 100644
index 0000000..8628608
--- /dev/null
+++ b/java/src/com/ctre/phoenix/sensors/PigeonIMU_Faults.java
@@ -0,0 +1,16 @@
+package com.ctre.phoenix.sensors;
+
+public class PigeonIMU_Faults {
+ //!< True iff any of the above flags are true.
+ public boolean hasAnyFault() {
+ return false;
+ }
+ public int toBitfield() {
+ int retval = 0;
+ return retval;
+ }
+ public void update(int bits) {
+ }
+ public PigeonIMU_Faults() {
+ }
+};
diff --git a/java/src/com/ctre/phoenix/sensors/PigeonIMU_StatusFrame.java b/java/src/com/ctre/phoenix/sensors/PigeonIMU_StatusFrame.java
new file mode 100644
index 0000000..cec0b94
--- /dev/null
+++ b/java/src/com/ctre/phoenix/sensors/PigeonIMU_StatusFrame.java
@@ -0,0 +1,33 @@
+package com.ctre.phoenix.sensors;
+
+/**
+ * Enumerated types for frame rate ms.
+ */
+public enum PigeonIMU_StatusFrame {
+ CondStatus_1_General(0x042000),
+ CondStatus_9_SixDeg_YPR(0x042200),
+ CondStatus_6_SensorFusion(0x042140),
+ CondStatus_11_GyroAccum(0x042280),
+ CondStatus_2_GeneralCompass(0x042040),
+ CondStatus_3_GeneralAccel(0x042080),
+ CondStatus_10_SixDeg_Quat(0x042240),
+ RawStatus_4_Mag(0x041CC0),
+ BiasedStatus_2_Gyro(0x041C40),
+ BiasedStatus_4_Mag(0x041CC0),
+ BiasedStatus_6_Accel(0x41D40);
+
+ public final int value;
+
+ PigeonIMU_StatusFrame(int initValue) {
+ this.value = initValue;
+ }
+
+ public static PigeonIMU_StatusFrame valueOf(int value) {
+ for (PigeonIMU_StatusFrame mode : values()) {
+ if (mode.value == value) {
+ return mode;
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/sensors/PigeonIMU_StickyFaults.java b/java/src/com/ctre/phoenix/sensors/PigeonIMU_StickyFaults.java
new file mode 100644
index 0000000..77a99e2
--- /dev/null
+++ b/java/src/com/ctre/phoenix/sensors/PigeonIMU_StickyFaults.java
@@ -0,0 +1,16 @@
+package com.ctre.phoenix.sensors;
+
+public class PigeonIMU_StickyFaults {
+ //!< True iff any of the above flags are true.
+ public boolean hasAnyFault() {
+ return false;
+ }
+ public int toBitfield() {
+ int retval = 0;
+ return retval;
+ }
+ public void update(int bits) {
+ }
+ public PigeonIMU_StickyFaults() {
+ }
+};
diff --git a/java/src/com/ctre/phoenix/sensors/PigeonImuJNI.java b/java/src/com/ctre/phoenix/sensors/PigeonImuJNI.java
new file mode 100644
index 0000000..11932d8
--- /dev/null
+++ b/java/src/com/ctre/phoenix/sensors/PigeonImuJNI.java
@@ -0,0 +1,118 @@
+/*
+ * Software License Agreement
+ *
+ * Copyright (C) Cross The Road Electronics. All rights
+ * reserved.
+ *
+ * Cross The Road Electronics (CTRE) licenses to you the right to
+ * use, publish, and distribute copies of CRF (Cross The Road) firmware files ( *.crf) and Software
+ * API Libraries ONLY when in use with Cross The Road Electronics hardware products.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * CROSS THE ROAD ELECTRONICS BE LIABLE FOR ANY INCIDENTAL, SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE
+ */
+package com.ctre.phoenix.sensors;
+import com.ctre.phoenix.CTREJNIWrapper;
+
+
+public class PigeonImuJNI extends CTREJNIWrapper {
+
+ public static native long JNI_new_PigeonImu_Talon(int talonID);
+
+ public static native long JNI_new_PigeonImu(int deviceNumber);
+
+ public static native int JNI_ConfigSetCustomParam(long handle, int newValue, int paramIndex, int timeoutMs);
+
+ public static native int JNI_ConfigGetCustomParam(long handle, int paramIndex, int timoutMs);
+
+ public static native int JNI_ConfigSetParameter(long handle, int param, double value, int subValue, int ordinal,
+ int timeoutMs);
+
+ public static native double JNI_ConfigGetParameter(long handle, int param, int ordinal, int timeoutMs);
+
+ public static native int JNI_SetStatusFramePeriod(long handle, int statusFrame, int periodMs, int timeoutMs);
+
+ public static native int JNI_SetYaw(long handle, double angleDeg, int timeoutMs);
+
+ public static native int JNI_AddYaw(long handle, double angleDeg, int timeoutMs);
+
+ public static native int JNI_SetYawToCompass(long handle, int timeoutMs);
+
+ public static native int JNI_SetFusedHeading(long handle, double angleDeg, int timeoutMs);
+
+ public static native int JNI_AddFusedHeading(long handle, double angleDeg, int timeoutMs);
+
+ public static native int JNI_SetFusedHeadingToCompass(long handle, int timeoutMs);
+
+ public static native int JNI_SetAccumZAngle(long handle, double angleDeg, int timeoutMs);
+
+ public static native int JNI_ConfigTemperatureCompensationEnable(long handle, int bTempCompEnable, int timeoutMs);
+
+ public static native int JNI_SetCompassDeclination(long handle, double angleDegOffset, int timeoutMs);
+
+ public static native int JNI_SetCompassAngle(long handle, double angleDeg, int timeoutMs);
+
+ public static native int JNI_EnterCalibrationMode(long handle, int calMode, int timeoutMs);
+
+ public static native int JNI_GetGeneralStatus(long handle, double [] params);
+
+ public static native int JNI_Get6dQuaternion(long handle, double [] wxyz );
+
+ public static native int JNI_GetYawPitchRoll(long handle, double [] ypr);
+
+ public static native int JNI_GetAccumGyro(long handle, double [] xyz_deg);
+
+ public static native double JNI_GetAbsoluteCompassHeading(long handle);
+
+ public static native double JNI_GetCompassHeading(long handle);
+
+ public static native double JNI_GetCompassFieldStrength(long handle);
+
+ public static native double JNI_GetTemp(long handle);
+
+ public static native int JNI_GetUpTime(long handle);
+
+ public static native int JNI_GetRawMagnetometer(long handle, short [] rm_xyz);
+
+ public static native int JNI_GetBiasedMagnetometer(long handle, short [] bm_xyz);
+
+ public static native int JNI_GetBiasedAccelerometer(long handle, short [] ba_xyz);
+
+ public static native int JNI_GetRawGyro(long handle, double [] xyz_dps);
+
+ public static native int JNI_GetAccelerometerAngles(long handle, double [] tiltAngles);
+
+ public static native int JNI_GetFusedHeading(long handle, double [] params);
+
+ public static native int JNI_GetState(long handle);
+
+ public static native int JNI_GetResetCount(long handle);
+
+ public static native int JNI_GetResetFlags(long handle);
+
+ public static native int JNI_GetFirmwareVersion(long handle);
+
+ public static native int JNI_GetLastError(long handle);
+
+ public static native boolean JNI_HasResetOccurred(long handle);
+
+ public static native int JNI_GetStatusFramePeriod(long handle, int frame, int timeoutMs);
+
+ public static native int JNI_SetControlFramePeriod(long handle, int frame, int periodMs);
+
+ public static native int JNI_GetFaults(long handle);
+
+ public static native int JNI_GetStickyFaults(long handle);
+
+ public static native int JNI_ClearStickyFaults(long handle, int timeoutMs);
+
+}
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/signals/IInvertable.java b/java/src/com/ctre/phoenix/signals/IInvertable.java
new file mode 100644
index 0000000..e30a48d
--- /dev/null
+++ b/java/src/com/ctre/phoenix/signals/IInvertable.java
@@ -0,0 +1,7 @@
+package com.ctre.phoenix.signals;
+
+public interface IInvertable
+{
+ void setInverted(boolean invert);
+ boolean getInverted();
+}
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/signals/IOutputSignal.java b/java/src/com/ctre/phoenix/signals/IOutputSignal.java
new file mode 100644
index 0000000..13e6ced
--- /dev/null
+++ b/java/src/com/ctre/phoenix/signals/IOutputSignal.java
@@ -0,0 +1,6 @@
+package com.ctre.phoenix.signals;
+
+public interface IOutputSignal
+{
+ //void set(double value);
+}
\ No newline at end of file
diff --git a/java/src/com/ctre/phoenix/time/StopWatch.java b/java/src/com/ctre/phoenix/time/StopWatch.java
new file mode 100644
index 0000000..fc41340
--- /dev/null
+++ b/java/src/com/ctre/phoenix/time/StopWatch.java
@@ -0,0 +1,25 @@
+package com.ctre.phoenix.time;
+
+public class StopWatch
+{
+ private long _t0 = 0;
+ private long _t1 = 0;
+
+ public void start()
+ {
+ _t0 = System.currentTimeMillis();
+ }
+
+ public double getDuration()
+ {
+ return (double)getDurationMs() / 1000;
+ }
+ public int getDurationMs()
+ {
+ _t1 = System.currentTimeMillis();
+ long retval = _t1 - _t0;
+ if(retval < 0)
+ retval = 0;
+ return (int)retval;
+ }
+}
\ No newline at end of file