diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 3ff8121..cb22f61 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -6,9 +6,7 @@ "limitSymbolsToIncludedHeaders": false }, "includePath": [ - "/home/danielz/WRover_Software/devel/include/**", "/opt/ros/noetic/include/**", - "/home/danielz/catkin_ws/src/wrevolution/include/**", "/usr/include/**" ], "name": "ROS", @@ -19,4 +17,4 @@ } ], "version": 4 -} \ No newline at end of file +} diff --git a/CMakeLists.txt b/CMakeLists.txt index 42469da..055e76e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,6 +63,7 @@ add_service_files( ResetSettings.srv ResetEncoder.srv Reverse.srv + SetHeading.srv ZeroPowerBehavior.srv ) @@ -132,29 +133,17 @@ include_directories( # add_library(${PROJECT_NAME} # src/${PROJECT_NAME}/wrevolution.cpp # ) +if(${CMAKE_LIBRARY_ARCHITECTURE} STREQUAL "arm-linux-gnueabihf") # Jetson TK1 / Pi + set(PHOENIX_LIBS_DIR ${PROJECT_SOURCE_DIR}/lib/raspberry) +elseif(${CMAKE_LIBRARY_ARCHITECTURE} STREQUAL "aarch64-linux-gnu") # Jetson TX2 + set(PHOENIX_LIBS_DIR ${PROJECT_SOURCE_DIR}/lib/jetsontx) +else() + set(PHOENIX_LIBS_DIR ${PROJECT_SOURCE_DIR}/lib/x86-64) +endif() + function(MakeTalonTarget TARGET_NAME) - if(${CMAKE_LIBRARY_ARCHITECTURE} STREQUAL "arm-linux-gnueabihf") # Jetson TK1 / Pi - target_link_libraries(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/lib/raspberry/libCTRE_Phoenix.a) - target_link_libraries(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/lib/raspberry/libCTRE_PhoenixCCI.a) - target_link_libraries(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/lib/raspberry/libCTRE_PhoenixDiagnostics.a) - target_link_libraries(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/lib/raspberry/libCTRE_PhoenixPlatform_socketcan.a) - target_link_libraries(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/lib/raspberry/libCTRE_PhoenixCanutils.a) - target_link_libraries(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/lib/raspberry/libCTRE_PhoenixCore.a) - elseif(${CMAKE_LIBRARY_ARCHITECTURE} STREQUAL "aarch64-linux-gnu") # Jetson TX2 - target_link_libraries(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/lib/jetsontx/libCTRE_Phoenix.a) - target_link_libraries(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/lib/jetsontx/libCTRE_PhoenixCCI.a) - target_link_libraries(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/lib/jetsontx/libCTRE_PhoenixDiagnostics.a) - target_link_libraries(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/lib/jetsontx/libCTRE_PhoenixPlatform_socketcan.a) - target_link_libraries(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/lib/jetsontx/libCTRE_PhoenixCanutils.a) - target_link_libraries(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/lib/jetsontx/libCTRE_PhoenixCore.a) - else() - target_link_libraries(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/lib/x86-64/libCTRE_Phoenix.a) - target_link_libraries(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/lib/x86-64/libCTRE_PhoenixCCI.a) - target_link_libraries(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/lib/x86-64/libCTRE_PhoenixDiagnostics.a) - target_link_libraries(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/lib/x86-64/libCTRE_PhoenixPlatform_socketcan.a) - target_link_libraries(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/lib/x86-64/libCTRE_PhoenixCanutils.a) - target_link_libraries(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/lib/x86-64/libCTRE_PhoenixCore.a) - endif() + target_link_libraries(${TARGET_NAME} PRIVATE ${PHOENIX_LIBS_DIR}/libCTRE_Phoenix.so) + target_link_libraries(${TARGET_NAME} PRIVATE ${PHOENIX_LIBS_DIR}/libCTRE_PhoenixCCI.so) target_link_libraries(${TARGET_NAME} PRIVATE Threads::Threads) endfunction(MakeTalonTarget) @@ -164,4 +153,14 @@ function(MakeROSTarget TARGET_NAME) add_dependencies(${TARGET_NAME} ${catkin_EXPORTED_TARGETS}) endfunction(MakeROSTarget) -add_subdirectory(src) \ No newline at end of file +add_subdirectory(src) + +# Copy Phoenix shared libraries +file( + COPY ${PHOENIX_LIBS_DIR}/libCTRE_Phoenix.so + DESTINATION ${CATKIN_DEVEL_PREFIX}/lib +) +file( + COPY ${PHOENIX_LIBS_DIR}/libCTRE_PhoenixCCI.so + DESTINATION ${CATKIN_DEVEL_PREFIX}/lib +) diff --git a/include/ctre/Phoenix.h b/include/ctre/Phoenix.h index 40738da..edb4a7f 100644 --- a/include/ctre/Phoenix.h +++ b/include/ctre/Phoenix.h @@ -14,6 +14,7 @@ #include "ctre/phoenix/paramEnum.h" #include "ctre/phoenix/HsvToRgb.h" #include "ctre/phoenix/LinearInterpolation.h" +#include "ctre/phoenix/led/CANdle.h" #include "ctre/phoenix/motion/BufferedTrajectoryPointStream.h" #include "ctre/phoenix/motion/MotionProfileStatus.h" #include "ctre/phoenix/motion/TrajectoryPoint.h" @@ -30,6 +31,7 @@ #include "ctre/phoenix/music/Orchestra.h" #include "ctre/phoenix/sensors/CANCoder.h" #include "ctre/phoenix/sensors/PigeonIMU.h" +#include "ctre/phoenix/sensors/Pigeon2.h" #include "ctre/phoenix/signals/MovingAverage.h" #include "ctre/phoenix/tasking/Schedulers/ConcurrentScheduler.h" #include "ctre/phoenix/tasking/ILoopable.h" @@ -40,6 +42,9 @@ #include "ctre/phoenix/motorcontrol/can/WPI_TalonFX.h" #include "ctre/phoenix/motorcontrol/can/WPI_TalonSRX.h" #include "ctre/phoenix/motorcontrol/can/WPI_VictorSPX.h" +#include "ctre/phoenix/sensors/WPI_CANCoder.h" +#include "ctre/phoenix/sensors/WPI_PigeonIMU.h" +#include "ctre/phoenix/sensors/WPI_Pigeon2.h" #include "ctre/phoenix/tasking/ButtonMonitor.h" #endif @@ -56,6 +61,7 @@ */ using namespace ctre; using namespace ctre::phoenix; +using namespace ctre::phoenix::led; using namespace ctre::phoenix::motion; using namespace ctre::phoenix::motorcontrol; using namespace ctre::phoenix::motorcontrol::can; diff --git a/include/ctre/phoenix/CANifier.h b/include/ctre/phoenix/CANifier.h index 205b02e..da7e8e2 100644 --- a/include/ctre/phoenix/CANifier.h +++ b/include/ctre/phoenix/CANifier.h @@ -9,6 +9,7 @@ #include "ctre/phoenix/CANifierStatusFrame.h" #include "ctre/phoenix/CANifierStickyFaults.h" #include "ctre/phoenix/CANifierFaults.h" +#include "ctre/phoenix/sensors/SensorVelocityMeasPeriod.h" #include "ctre/phoenix/CANifierVelocityMeasPeriod.h" namespace ctre {namespace phoenix { @@ -20,7 +21,7 @@ struct CANifierConfiguration : CustomParamConfiguration{ /** * Velocity measurement period to use */ - CANifierVelocityMeasPeriod velocityMeasurementPeriod; + ctre::phoenix::sensors::SensorVelocityMeasPeriod velocityMeasurementPeriod; /** * Velocity measurement window to use */ @@ -39,7 +40,7 @@ struct CANifierConfiguration : CustomParamConfiguration{ bool clearPositionOnQuadIdx; CANifierConfiguration() : - velocityMeasurementPeriod(Period_100Ms), + velocityMeasurementPeriod(ctre::phoenix::sensors::SensorVelocityMeasPeriod::Period_100Ms), velocityMeasurementWindow(64), clearPositionOnLimitF(false), clearPositionOnLimitR(false), @@ -61,7 +62,7 @@ struct CANifierConfiguration : CustomParamConfiguration{ */ std::string toString(std::string prependString) { - std::string retstr = prependString + ".velocityMeasurementPeriod = " + CANifierVelocityMeasPeriodRoutines::toString(velocityMeasurementPeriod) + ";\n"; + std::string retstr = prependString + ".velocityMeasurementPeriod = " + ctre::phoenix::sensors::SensorVelocityMeasPeriodRoutines::toString(velocityMeasurementPeriod) + ";\n"; retstr += prependString + ".velocityMeasurementWindow = " + std::to_string(velocityMeasurementWindow) + ";\n"; retstr += prependString + ".clearPositionOnLimitF = " + std::to_string(clearPositionOnLimitF) + ";\n"; retstr += prependString + ".clearPositionOnLimitR = " + std::to_string(clearPositionOnLimitR) + ";\n"; @@ -325,6 +326,10 @@ class CANifier: public CANBusAddressable { * If zero, no blocking or checking is performed. * @return Error Code generated by function. 0 indicates no error. */ + ErrorCode ConfigVelocityMeasurementPeriod( + ctre::phoenix::sensors::SensorVelocityMeasPeriod period, int timeoutMs = 0); + + [[deprecated("Use the overload with SensorVelocityMeasPeriod instead")]] ErrorCode ConfigVelocityMeasurementPeriod( CANifierVelocityMeasPeriod period, int timeoutMs = 0); /** diff --git a/include/ctre/phoenix/ErrorCode.h b/include/ctre/phoenix/ErrorCode.h index ea7e7f4..3e61104 100644 --- a/include/ctre/phoenix/ErrorCode.h +++ b/include/ctre/phoenix/ErrorCode.h @@ -1,13 +1,16 @@ #pragma once + #include namespace ctre { namespace phoenix { enum ErrorCode -: int32_t +#ifdef __cplusplus + : int32_t +#endif { - OK = 0, + OK = 0, OKAY = 0, //!< No Error - Function executed as expected //CAN-Related @@ -30,7 +33,6 @@ enum ErrorCode BufferFailure = -10, FirwmwareNonFRC = -11, - //General GeneralError = -100, //!< User Specified General Error GENERAL_ERROR = -100, @@ -58,11 +60,12 @@ enum ErrorCode GainsAreNotSet = -503, WrongRemoteLimitSwitchSource = -504, DoubleVoltageCompensatingWPI = -505, + CANdleAnimSlotOutOfBounds = -506, //Higher Level IncompatibleMode = -600, InvalidHandle = -601, //!< Handle does not match stored map of handles - + //Firmware Versions FeatureRequiresHigherFirm = -700, MotorControllerFeatureRequiresHigherFirm = -701, @@ -70,12 +73,13 @@ enum ErrorCode ConfigFactoryDefaultRequiresHigherFirm = -702, ConfigMotionSCurveRequiresHigherFirm = -703, TalonFXFirmwarePreVBatDetect = -704, + CANdleAnimationsRequireHigherFirm = -705, //Operating system centric LibraryCouldNotBeLoaded = -800, MissingRoutineInLibrary = -801, ResourceNotAvailable = -802, - + //MIDI and Orchestra centric MusicFileNotFound = -900, MusicFileWrongSize = -901, @@ -85,7 +89,24 @@ enum ErrorCode MusicFileTooOld = -905, MusicInterrupted = -906, MusicNotSupported = -907, - + + kInvalidInterface = -1000, + kInvalidGuid = -1001, + kInvalidClass = -1002, + kInvalidProtocol = -1003, + kInvalidPath = -1004, + kGeneralWinUsbError = -1005, + kFailedSetup = -1006, + kListenFailed = -1007, + kSendFailed = -1008, + kReceiveFailed = -1009, + kInvalidRespFormat = -1010, + kWinUsbInitFailed = -1011, + kWinUsbQueryFailed = -1012, + kWinUsbGeneralError = -1013, + kAccessDenied = -1014, + kFirmwareInvalidResponse = -1015, + //CAN Related PulseWidthSensorNotPresent = +10, //!< Special Code for "isSensorPresent" @@ -97,11 +118,16 @@ enum ErrorCode FeaturesNotAvailableYet = 104, // feature will be release in an upcoming release ControlModeNotValid = 105, // Current control mode of motor controller not valid for this call ControlModeNotSupportedYet = 106, - CascadedPIDNotSupporteYet= 107, - AuxiliaryPIDNotSupportedYet= 107, - RemoteSensorsNotSupportedYet= 108, - MotProfFirmThreshold= 109, + CascadedPIDNotSupporteYet = 107, + AuxiliaryPIDNotSupportedYet = 107, + RemoteSensorsNotSupportedYet = 108, + MotProfFirmThreshold = 109, MotProfFirmThreshold2 = 110, + + //Simulation + SimDeviceNotFound = 200, + SimPhysicsTypeNotSupported = 201, + SimDeviceAlreadyExists = 202, }; class ErrorCollection { public: @@ -112,7 +138,7 @@ class ErrorCollection { _firstError = FirstOne(_firstError, err); } void NewError(int err) { - _firstError = FirstOne(_firstError, (ErrorCode) err); + _firstError = FirstOne(_firstError, (ErrorCode) err); } ErrorCode GetFirstNonZeroError() { diff --git a/include/ctre/phoenix/PhoenixVersion.h b/include/ctre/phoenix/PhoenixVersion.h new file mode 100644 index 0000000..9cb75e2 --- /dev/null +++ b/include/ctre/phoenix/PhoenixVersion.h @@ -0,0 +1 @@ +const int kPhoenixVersion = 0x00051501; \ No newline at end of file diff --git a/include/ctre/phoenix/cci/CANCoder_CCI.h b/include/ctre/phoenix/cci/CANCoder_CCI.h index d9ec48e..5293c2f 100644 --- a/include/ctre/phoenix/cci/CANCoder_CCI.h +++ b/include/ctre/phoenix/cci/CANCoder_CCI.h @@ -15,7 +15,7 @@ extern "C" { - CCIEXPORT void* c_CANCoder_Create1(int deviceNumber); + CCIEXPORT void* c_CANCoder_Create1(int deviceNumber, const char* canbus); CCIEXPORT void c_CANCoder_DestroyAll(); CCIEXPORT ctre::phoenix::ErrorCode c_CANCoder_Destroy(void* handle); CCIEXPORT ctre::phoenix::ErrorCode c_CANCoder_GetDescription(void* handle, char* toFill, int toFillByteSz, size_t* numBytesFilled); diff --git a/include/ctre/phoenix/cci/CANdle_CCI.h b/include/ctre/phoenix/cci/CANdle_CCI.h new file mode 100644 index 0000000..9fd0c7e --- /dev/null +++ b/include/ctre/phoenix/cci/CANdle_CCI.h @@ -0,0 +1,42 @@ +#pragma once + +#include "ctre/phoenix/cci/CCI.h" +#include "ctre/phoenix/ErrorCode.h" +#include +#include + +extern "C"{ + CCIEXPORT void *c_CANdle_Create1(int deviceNumber, const char* canbus); + CCIEXPORT void c_CANdle_DestroyAll(); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_Destroy(void *handle); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_GetDescription(void* handle, char* toFill, int toFillByteSz, size_t* numBytesFilled); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_GetLastError(void* handle); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_GetLastTimestamp(void* handle, double* timestamp); + CCIEXPORT void c_CANdle_SetLastError(void *handle, int error); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_ConfigSetParameter(void *handle, int param, double value, uint8_t subValue, int ordinal, int timeoutMs); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_ConfigGetParameter(void *handle, int param, double *value, int ordinal, int timeoutMs); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_ConfigSetCustomParam(void *handle, int newValue, int paramIndex, int timeoutMs); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_ConfigGetCustomParam(void *handle, int *readValue, int paramIndex, int timoutMs); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_ConfigFactoryDefault(void *handle, int timeoutMs); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_GetFaults(void *handle, int * param) ; + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_GetStickyFaults(void *handle, int * param) ; + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_ClearStickyFaults(void *handle, int timeoutMs) ; + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_GetFirmwareVersion(void *handle, int *firmwareVers); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_HasResetOccurred(void *handle, bool * hasReset); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_SetStatusFramePeriod(void *handle, int frame, uint8_t periodMs, int timeoutMs); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_GetStatusFramePeriod(void *handle, int frame, int *periodMs, int timeoutMs); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_SetControlFramePeriod(void *handle, int frame, int periodMs); + + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_BlockSet(void *handle, int r, int g, int b, int w, int startIdx, int count); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_SetStandardAnimation(void *handle, int idx, double brightness, double speed, int numLed, int ledOffset, double param4, double param5, bool reverseDirection, int animSlot); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_SetTwoSizeAnimation(void *handle, int idx, int r, int g, int b, int w, double speed, int numLed, int ledOffset, int direction, int size, int animSlot); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_ClearAnimation(void *handle, int animSlot); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_ModulateVBatOutput(void *handle, double percentModulation); + + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_GetBusVoltage(void *handle, double *voltage); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_Get5VRailVoltage(void *handle, double *voltage); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_GetCurrent(void *handle, double *current); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_GetTemperature(void *handle, double *temperature); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_GetVBatModulation(void *handle, double *modulation); + CCIEXPORT ctre::phoenix::ErrorCode c_CANdle_GetMaxSimultaneousAnimationCount(void *handle, int *maxAnimationCount); +} diff --git a/include/ctre/phoenix/cci/CCI.h b/include/ctre/phoenix/cci/CCI.h index e849d70..85dfbdf 100644 --- a/include/ctre/phoenix/cci/CCI.h +++ b/include/ctre/phoenix/cci/CCI.h @@ -1,3 +1,4 @@ +//Legacy Export Define. New code should use CTREXPORT from ctre/phoenix/export.h #ifndef CCIEXPORT #if defined(WIN32) || defined(_WIN32) || defined(_WIN64) diff --git a/include/ctre/phoenix/cci/Diagnostics_CCI.h b/include/ctre/phoenix/cci/Diagnostics_CCI.h index 61e16fa..e1ca91a 100644 --- a/include/ctre/phoenix/cci/Diagnostics_CCI.h +++ b/include/ctre/phoenix/cci/Diagnostics_CCI.h @@ -1,10 +1,11 @@ #pragma once #include -#include "ctre/phoenix/cci/CCI.h" +#include "ctre/phoenix/export.h" extern "C"{ - CCIEXPORT void c_Phoenix_Diagnostics_Create(); - CCIEXPORT void c_Phoenix_Diagnostics_Create1(int port); - CCIEXPORT void c_Phoenix_Diagnostics_SetSecondsToStart(int secondsToStart); + CTREXPORT void c_Phoenix_Diagnostics_Create(); + CTREXPORT void c_Phoenix_Diagnostics_Create1(int port); + CTREXPORT void c_Phoenix_Diagnostics_SetSecondsToStart(int secondsToStart); + CTREXPORT void c_Phoenix_Diagnostics_Dispose(); } \ No newline at end of file diff --git a/include/ctre/phoenix/cci/MotController_CCI.h b/include/ctre/phoenix/cci/MotController_CCI.h index e592845..3474a57 100644 --- a/include/ctre/phoenix/cci/MotController_CCI.h +++ b/include/ctre/phoenix/cci/MotController_CCI.h @@ -10,7 +10,7 @@ extern "C"{ CCIEXPORT void* c_MotController_Create1(int baseArbId); - CCIEXPORT void* c_MotController_Create2(int deviceID, const char * model); + CCIEXPORT void* c_MotController_Create2(int deviceID, const char * model, const char* canbus); CCIEXPORT void c_MotController_DestroyAll(); CCIEXPORT ctre::phoenix::ErrorCode c_MotController_Destroy(void *handle); CCIEXPORT ctre::phoenix::ErrorCode c_MotController_GetAppliedControlMode(void *handle, int &controlMode); diff --git a/include/ctre/phoenix/cci/Orchestra_CCI.h b/include/ctre/phoenix/cci/Orchestra_CCI.h index 08f70cd..f933ece 100644 --- a/include/ctre/phoenix/cci/Orchestra_CCI.h +++ b/include/ctre/phoenix/cci/Orchestra_CCI.h @@ -14,6 +14,7 @@ extern "C" { CCIEXPORT ctre::phoenix::ErrorCode c_Orchestra_Stop(void* handle); CCIEXPORT ctre::phoenix::ErrorCode c_Orchestra_Pause(void* handle); CCIEXPORT ctre::phoenix::ErrorCode c_Orchestra_IsPlaying(void* handle, bool &playing); + CCIEXPORT ctre::phoenix::ErrorCode c_Orchestra_GetCurrentTime(void* handle, uint32_t ¤tTime); CCIEXPORT ctre::phoenix::ErrorCode c_Orchestra_ClearInstruments(void* handle); CCIEXPORT ctre::phoenix::ErrorCode c_Orchestra_AddInstrument(void* handle, void* instrument); diff --git a/include/ctre/phoenix/cci/PDP_CCI.h b/include/ctre/phoenix/cci/PDP_CCI.h new file mode 100644 index 0000000..0fde830 --- /dev/null +++ b/include/ctre/phoenix/cci/PDP_CCI.h @@ -0,0 +1,6 @@ +#pragma once + +#include "ctre/phoenix/cci/CCI.h" +#include "ctre/phoenix/ErrorCode.h" + +CCIEXPORT ctre::phoenix::ErrorCode c_PDP_GetValues(int deviceID, double *voltage, double currents[], int currentCapacity, int *currentsFilled); \ No newline at end of file diff --git a/include/ctre/phoenix/cci/PigeonIMU_CCI.h b/include/ctre/phoenix/cci/PigeonIMU_CCI.h index 8289965..9d27e78 100644 --- a/include/ctre/phoenix/cci/PigeonIMU_CCI.h +++ b/include/ctre/phoenix/cci/PigeonIMU_CCI.h @@ -31,8 +31,8 @@ static std::map pigeonPresent; extern "C"{ - CCIEXPORT void *c_PigeonIMU_Create2(int talonDeviceID); - CCIEXPORT void *c_PigeonIMU_Create1(int deviceNumber); + CCIEXPORT void *c_PigeonIMU_Create2(int talonDeviceID, const char *version); + CCIEXPORT void *c_PigeonIMU_Create1(int deviceNumber, const char *version, const char *canbus); CCIEXPORT ctre::phoenix::ErrorCode c_PigeonIMU_Destroy(void *handle); CCIEXPORT void c_PigeonIMU_DestroyAll(); CCIEXPORT ctre::phoenix::ErrorCode c_PigeonIMU_GetDescription(void *handle, char * toFill, int toFillByteSz, size_t * numBytesFilled); @@ -55,8 +55,14 @@ CCIEXPORT ctre::phoenix::ErrorCode c_PigeonIMU_EnterCalibrationMode(void *handle, int calMode, int timeoutMs); CCIEXPORT ctre::phoenix::ErrorCode c_PigeonIMU_GetGeneralStatus(void *handle, int *state, int *currentMode, int *calibrationError, int *bCalIsBooting, double *tempC, int *upTimeSec, int *noMotionBiasCount, int *tempCompensationCount, int *lastError); CCIEXPORT ctre::phoenix::ErrorCode c_PigeonIMU_GetLastError(void *handle); + CCIEXPORT ctre::phoenix::ErrorCode c_PigeonIMU_GetLastTimestamp(void* handle, double* timestamp); CCIEXPORT ctre::phoenix::ErrorCode c_PigeonIMU_Get6dQuaternion(void *handle, double wxyz[4]); CCIEXPORT ctre::phoenix::ErrorCode c_PigeonIMU_GetYawPitchRoll(void *handle, double ypr[3]); + CCIEXPORT ctre::phoenix::ErrorCode c_PigeonIMU_GetYawPitchRoll2(void *handle, double ypr[3]); + CCIEXPORT ctre::phoenix::ErrorCode c_PigeonIMU_GetYaw(void *handle, double *yaw); + CCIEXPORT ctre::phoenix::ErrorCode c_PigeonIMU_GetPitch(void *handle, double *pitch); + CCIEXPORT ctre::phoenix::ErrorCode c_PigeonIMU_GetRoll(void *handle, double *roll); + CCIEXPORT ctre::phoenix::ErrorCode c_PigeonIMU_GetGravityVector(void *handle, double ypr[3]); CCIEXPORT ctre::phoenix::ErrorCode c_PigeonIMU_GetAccumGyro(void *handle, double xyz_deg[3]); CCIEXPORT ctre::phoenix::ErrorCode c_PigeonIMU_GetAbsoluteCompassHeading(void *handle, double *value); CCIEXPORT ctre::phoenix::ErrorCode c_PigeonIMU_GetCompassHeading(void *handle, double *value); diff --git a/include/ctre/phoenix/cci/PlatformCAN_CCI.h b/include/ctre/phoenix/cci/PlatformCAN_CCI.h index 95c93b2..8776bf9 100644 --- a/include/ctre/phoenix/cci/PlatformCAN_CCI.h +++ b/include/ctre/phoenix/cci/PlatformCAN_CCI.h @@ -6,7 +6,7 @@ #include "ctre/phoenix/autocache.h" extern "C" { - CCIEXPORT int32_t c_SetCANInterface(const char * canBusInterface); + CCIEXPORT int32_t c_RegisterCANbus(char const *canbus); CCIEXPORT ctre::phoenix::ErrorCode c_DestroyAll(); CCIEXPORT ctre::phoenix::ErrorCode c_StartAll(); CCIEXPORT void c_Autocache_SetAutocacheLevel(ctre::phoenix::AutocacheState state); diff --git a/include/ctre/phoenix/cci/Platform_CCI.h b/include/ctre/phoenix/cci/Platform_CCI.h index 1155158..62e659f 100644 --- a/include/ctre/phoenix/cci/Platform_CCI.h +++ b/include/ctre/phoenix/cci/Platform_CCI.h @@ -7,9 +7,10 @@ using namespace ctre::phoenix::platform; extern "C" { - CCIEXPORT int32_t c_SimCreate(DeviceType type, int id); - CCIEXPORT int32_t c_SimDestroy(DeviceType type, int id); - CCIEXPORT int32_t c_SimDestroyAll(); - CCIEXPORT int32_t c_SimConfigGet(DeviceType type, uint32_t param, uint32_t valueToSend, uint32_t & outValueReceived, uint32_t & outSubvalue, uint32_t ordinal, int id); - CCIEXPORT int32_t c_SimConfigSet(DeviceType type, uint32_t param, uint32_t value, uint32_t subValue, uint32_t ordinal, int id); + CCIEXPORT ctre::phoenix::ErrorCode c_SimCreate(DeviceType type, int id); + CCIEXPORT ctre::phoenix::ErrorCode c_SimDestroy(DeviceType type, int id); + CCIEXPORT ctre::phoenix::ErrorCode c_SimDestroyAll(); + CCIEXPORT ctre::phoenix::ErrorCode c_SimSetPhysicsInput(DeviceType type, int id, std::string const &physicsType, double value); + CCIEXPORT ctre::phoenix::ErrorCode c_SimGetPhysicsValue(DeviceType type, int id, std::string const &physicsType, double &value); + CCIEXPORT ctre::phoenix::ErrorCode c_SimGetLastError(DeviceType type, int id); } diff --git a/include/ctre/phoenix/defs/signalTypes.h b/include/ctre/phoenix/defs/signalTypes.h deleted file mode 100644 index c26562c..0000000 --- a/include/ctre/phoenix/defs/signalTypes.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef signalTypes__h_ -#define signalTypes__h_ - -enum{ - modeDutyCycleControl = 0, - modePosControl = 1, - modeSpeedControl = 2, - modeCurrentControl = 3, - modeSlaveFollower = 5, - modeMotionProfile = 6, - modeMotionMagic = 7, - motionMagicArc = 8, - //9 - motionProfileArc = 10, - //11 - //12 - //13 -#ifdef SUPPORT_ONE_SHOT_CONTROL_MODE - modeOneShot = 14, -#endif - modeNoDrive = 15, -}; - -typedef enum _feedbackDevice_t{ - kQuadEncoder = 0, - //1 - kAnalog = 2, - //3 - Tachometer= 4, - kPulseWidthEncodedPosition = 8, - - kSensorSum = 9, - kSensorDifference = 10, - kRemoteSensor0 = 11, - kRemoteSensor1 = 12, - //13 - //14 - kSoftwarEmulatedSensor=15, -}feedbackDevice_t; - -typedef enum _MotProf_OutputType_t { - MotProf_OutputType_Disabled = 0, - MotProf_OutputType_Enabled, - MotProf_OutputType_Hold, - MotProf_OutputType_Invalid, -}MotProf_OutputType_t; - -/** - * Saved to limitSwitchForward_Source/limitSwitchReverse_Source - */ -typedef enum _LimitSwitchSource_t { - LSS_Local=0, - LSS_RemoteTalon=1, - LSS_RemoteCanif=2, - LSS_Deactivated=3, -}LimitSwitchSource_t; - -/** - * Saved to limitSwitchForward_normClosedAndDis / limitSwitchReverse_normClosedAndDis - */ -typedef enum _LimitSwitchNormClosedAndDis_t { - LSNCD_NormallyOpen=0, - LSNCD_NormallyClosed=1, - LSNCD_NormallyDisabled=2, -}LimitSwitchNormClosedAndDis_t; - -typedef enum _RemoteSensorSource_t { - RSS_Off, - RSS_RemoteTalonSelSensor, - RSS_RemotePigeon_Yaw, - RSS_RemotePigeon_Pitch, - RSS_RemotePigeon_Roll, - RSS_RemoteCanif_Quad, - RSS_RemoteCanif_PWM0, - RSS_RemoteCanif_PWM1, - RSS_RemoteCanif_PWM2, - RSS_RemoteCanif_PWM3, -} RemoteSensorSource_t; - -typedef enum _SensorTermOrdinal_t { - SensorTermOrdinal_Sum0 = 0, - SensorTermOrdinal_Sum1 = 0, - SensorTermOrdinal_Diff0 = 0, - SensorTermOrdinal_Diff1 = 0, -}SensorTermOrdinal_t; - -#endif // signalTypes__h_ diff --git a/include/ctre/phoenix/export.h b/include/ctre/phoenix/export.h new file mode 100644 index 0000000..2d42244 --- /dev/null +++ b/include/ctre/phoenix/export.h @@ -0,0 +1,10 @@ +#ifndef CTREXPORT + + #if defined(WIN32) || defined(_WIN32) || defined(_WIN64) + #define CTREXPORT __declspec(dllexport) + #elif (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility) + #define CTREXPORT __attribute__((visibility("default"))) + #else + #define CTREXPORT + #endif +#endif \ No newline at end of file diff --git a/include/ctre/phoenix/jni/com_ctre_phoenix_MotorControl_CAN_MotControllerJNI.h b/include/ctre/phoenix/jni/com_ctre_phoenix_MotorControl_CAN_MotControllerJNI.h index 053a2f5..153d373 100644 --- a/include/ctre/phoenix/jni/com_ctre_phoenix_MotorControl_CAN_MotControllerJNI.h +++ b/include/ctre/phoenix/jni/com_ctre_phoenix_MotorControl_CAN_MotControllerJNI.h @@ -18,10 +18,10 @@ JNIEXPORT jlong JNICALL Java_com_ctre_phoenix_motorcontrol_can_MotControllerJNI_ /* * Class: com_ctre_phoenix_motorcontrol_can_MotControllerJNI * Method: Create2 - * Signature: (Ijava/lang/String;)J + * Signature: (Ijava/lang/String;java/lang/String;)J */ JNIEXPORT jlong JNICALL Java_com_ctre_phoenix_motorcontrol_can_MotControllerJNI_Create2 - (JNIEnv *, jclass, jint, jstring); + (JNIEnv *, jclass, jint, jstring, jstring); /* * Class: com_ctre_phoenix_motorcontrol_can_MotControllerJNI diff --git a/include/ctre/phoenix/jni/com_ctre_phoenix_OrchestraJNI.h b/include/ctre/phoenix/jni/com_ctre_phoenix_OrchestraJNI.h index 0d0b1a6..778a537 100644 --- a/include/ctre/phoenix/jni/com_ctre_phoenix_OrchestraJNI.h +++ b/include/ctre/phoenix/jni/com_ctre_phoenix_OrchestraJNI.h @@ -63,6 +63,14 @@ JNIEXPORT jint JNICALL Java_com_ctre_phoenix_music_OrchestraJNI_JNI_1Pause JNIEXPORT jboolean JNICALL Java_com_ctre_phoenix_music_OrchestraJNI_JNI_1IsPlaying (JNIEnv *, jclass, jlong); +/* + * Class: com_ctre_phoenix_OrchestraJNI + * Method: JNI_GetCurrentTime + * Signature: (J)Z + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_music_OrchestraJNI_JNI_1GetCurrentTime + (JNIEnv *, jclass, jlong); + /* * Class: com_ctre_phoenix_OrchestraJNI * Method: JNI_ClearInstruments diff --git a/include/ctre/phoenix/jni/com_ctre_phoenix_Sensors_PigeonImuJNI.h b/include/ctre/phoenix/jni/com_ctre_phoenix_Sensors_PigeonImuJNI.h index 5a68bdc..4f8fa38 100644 --- a/include/ctre/phoenix/jni/com_ctre_phoenix_Sensors_PigeonImuJNI.h +++ b/include/ctre/phoenix/jni/com_ctre_phoenix_Sensors_PigeonImuJNI.h @@ -10,18 +10,18 @@ extern "C" { /* * Class: com_ctre_phoenix_sensors_PigeonImuJNI * Method: JNI_new_PigeonImu_Talon - * Signature: (I)J + * Signature: (ILjava/lang/String;)J */ JNIEXPORT jlong JNICALL Java_com_ctre_phoenix_sensors_PigeonImuJNI_JNI_1new_1PigeonImu_1Talon - (JNIEnv *, jclass, jint); + (JNIEnv *, jclass, jint, jstring); /* * Class: com_ctre_phoenix_sensors_PigeonImuJNI * Method: JNI_new_PigeonImu - * Signature: (I)J + * Signature: (ILjava/lang/String;Ljava/lang/String;)J */ JNIEXPORT jlong JNICALL Java_com_ctre_phoenix_sensors_PigeonImuJNI_JNI_1new_1PigeonImu - (JNIEnv *, jclass, jint); + (JNIEnv *, jclass, jint, jstring, jstring); /* * Class: com_ctre_phoenix_sensors_PigeonImuJNI @@ -31,14 +31,6 @@ JNIEXPORT jlong JNICALL Java_com_ctre_phoenix_sensors_PigeonImuJNI_JNI_1new_1Pig JNIEXPORT jint JNICALL Java_com_ctre_phoenix_sensors_PigeonImuJNI_JNI_1destroy_1PigeonImu (JNIEnv *, jclass, jlong); -/* - * Class: com_ctre_phoenix_sensors_PigeonImuJNI - * Method: JNI_destroy_AllPigeonImus - * Signature: ()V - */ -//JNIEXPORT void JNICALL Java_com_ctre_phoenix_sensors_PigeonImuJNI_JNI_1destroy_1AllPigeonImus -// (JNIEnv *, jclass); - /* * Class: com_ctre_phoenix_sensors_PigeonImuJNI * Method: JNI_ConfigSetCustomParam @@ -199,6 +191,46 @@ JNIEXPORT jint JNICALL Java_com_ctre_phoenix_sensors_PigeonImuJNI_JNI_1Get6dQuat JNIEXPORT jint JNICALL Java_com_ctre_phoenix_sensors_PigeonImuJNI_JNI_1GetYawPitchRoll (JNIEnv *, jclass, jlong, jdoubleArray); +/* + * Class: com_ctre_phoenix_sensors_PigeonImuJNI + * Method: JNI_GetYawPitchRoll2 + * Signature: (J[D)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_sensors_PigeonImuJNI_JNI_1GetYawPitchRoll2 + (JNIEnv *, jclass, jlong, jdoubleArray); + +/* + * Class: com_ctre_phoenix_sensors_PigeonImuJNI + * Method: JNI_GetYaw + * Signature: (J)D + */ +JNIEXPORT jdouble JNICALL Java_com_ctre_phoenix_sensors_PigeonImuJNI_JNI_1GetYaw + (JNIEnv *, jclass, jlong); + +/* + * Class: com_ctre_phoenix_sensors_PigeonImuJNI + * Method: JNI_GetPitch + * Signature: (J)D + */ +JNIEXPORT jdouble JNICALL Java_com_ctre_phoenix_sensors_PigeonImuJNI_JNI_1GetPitch + (JNIEnv *, jclass, jlong); + +/* + * Class: com_ctre_phoenix_sensors_PigeonImuJNI + * Method: JNI_GetRoll + * Signature: (J)D + */ +JNIEXPORT jdouble JNICALL Java_com_ctre_phoenix_sensors_PigeonImuJNI_JNI_1GetRoll + (JNIEnv *, jclass, jlong); + +/* + * Class: com_ctre_phoenix_sensors_PigeonImuJNI + * Method: JNI_GetGravityVector + * Signature: (J[D)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_sensors_PigeonImuJNI_JNI_1GetGravityVector + (JNIEnv *, jclass, jlong, jdoubleArray); + /* * Class: com_ctre_phoenix_sensors_PigeonImuJNI * Method: JNI_GetAccumGyro @@ -335,6 +367,14 @@ JNIEXPORT jint JNICALL Java_com_ctre_phoenix_sensors_PigeonImuJNI_JNI_1GetFirmwa JNIEXPORT jint JNICALL Java_com_ctre_phoenix_sensors_PigeonImuJNI_JNI_1GetLastError (JNIEnv *, jclass, jlong); +/* + * Class: com_ctre_phoenix_sensors_PigeonImuJNI + * Method: JNI_GetLastTimestamp + * Signature: (J)D + */ +JNIEXPORT jdouble JNICALL Java_com_ctre_phoenix_sensors_PigeonImuJNI_JNI_1GetLastTimestamp + (JNIEnv *, jclass, jlong); + /* * Class: com_ctre_phoenix_sensors_PigeonImuJNI * Method: JNI_HasResetOccurred diff --git a/include/ctre/phoenix/jni/com_ctre_phoenix_led_CANdleJNI.h b/include/ctre/phoenix/jni/com_ctre_phoenix_led_CANdleJNI.h new file mode 100644 index 0000000..4d79e0c --- /dev/null +++ b/include/ctre/phoenix/jni/com_ctre_phoenix_led_CANdleJNI.h @@ -0,0 +1,229 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_ctre_phoenix_led_CANdleJNI */ + +#ifndef _Included_com_ctre_phoenix_led_CANdleJNI +#define _Included_com_ctre_phoenix_led_CANdleJNI +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: Create + * Signature: (ILjava/lang/String;)J + */ +JNIEXPORT jlong JNICALL Java_com_ctre_phoenix_led_CANdleJNI_Create + (JNIEnv *, jclass, jint, jstring); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: GetLastError + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_led_CANdleJNI_GetLastError + (JNIEnv *, jclass, jlong); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: GetLastTimestamp + * Signature: (J)D + */ +JNIEXPORT jdouble JNICALL Java_com_ctre_phoenix_led_CANdleJNI_GetLastTimestamp + (JNIEnv *, jclass, jlong); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: BlockSet + * Signature: (JIIIIII)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_led_CANdleJNI_BlockSet + (JNIEnv *, jclass, jlong, jint, jint, jint, jint, jint, jint); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: SetStandardAnimation + * Signature: (JIDDIIDDZI)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_led_CANdleJNI_SetStandardAnimation + (JNIEnv *, jclass, jlong, jint, jdouble, jdouble, jint, jint, jdouble, jdouble, jboolean, jint); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: SetTwoSizeAnimation + * Signature: (JIIIIIDIIIII)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_led_CANdleJNI_SetTwoSizeAnimation + (JNIEnv *, jclass, jlong, jint, jint, jint, jint, jint, jdouble, jint, jint, jint, jint, jint); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: ClearAnimation + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_led_CANdleJNI_ClearAnimation + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: ModulateVBatOutput + * Signature: (JD)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_led_CANdleJNI_ModulateVBatOutput + (JNIEnv *, jclass, jlong, jdouble); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: GetBusVoltage + * Signature: (J)D + */ +JNIEXPORT jdouble JNICALL Java_com_ctre_phoenix_led_CANdleJNI_GetBusVoltage + (JNIEnv *, jclass, jlong); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: Get5VRailVoltage + * Signature: (J)D + */ +JNIEXPORT jdouble JNICALL Java_com_ctre_phoenix_led_CANdleJNI_Get5VRailVoltage + (JNIEnv *, jclass, jlong); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: GetCurrent + * Signature: (J)D + */ +JNIEXPORT jdouble JNICALL Java_com_ctre_phoenix_led_CANdleJNI_GetCurrent + (JNIEnv *, jclass, jlong); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: GetTemperature + * Signature: (J)D + */ +JNIEXPORT jdouble JNICALL Java_com_ctre_phoenix_led_CANdleJNI_GetTemperature + (JNIEnv *, jclass, jlong); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: GetVbatModulation + * Signature: (J)D + */ +JNIEXPORT jdouble JNICALL Java_com_ctre_phoenix_led_CANdleJNI_GetVbatModulation + (JNIEnv *, jclass, jlong); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: GetMaxSimultaneousAnimationCount + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_led_CANdleJNI_GetMaxSimultaneousAnimationCount + (JNIEnv *, jclass, jlong); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: ConfigGetParameter + * Signature: (JIII)D + */ +JNIEXPORT jdouble JNICALL Java_com_ctre_phoenix_led_CANdleJNI_ConfigGetParameter + (JNIEnv *, jclass, jlong, jint, jint, jint); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: ConfigSetParameter + * Signature: (JIDIII)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_led_CANdleJNI_ConfigSetParameter + (JNIEnv *, jclass, jlong, jint, jdouble, jint, jint, jint); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: ConfigGetCustomParam + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_led_CANdleJNI_ConfigGetCustomParam + (JNIEnv *, jclass, jlong, jint, jint); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: ConfigSetCustomParam + * Signature: (JIII)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_led_CANdleJNI_ConfigSetCustomParam + (JNIEnv *, jclass, jlong, jint, jint, jint); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: ConfigFactoryDefault + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_led_CANdleJNI_ConfigFactoryDefault + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: GetFaults + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_led_CANdleJNI_GetFaults + (JNIEnv *, jclass, jlong); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: GetStickyFaults + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_led_CANdleJNI_GetStickyFaults + (JNIEnv *, jclass, jlong); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: ClearStickyFaults + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_led_CANdleJNI_ClearStickyFaults + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: GetFirmwareVersion + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_led_CANdleJNI_GetFirmwareVersion + (JNIEnv *, jclass, jlong); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: HasResetOccurred + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_ctre_phoenix_led_CANdleJNI_HasResetOccurred + (JNIEnv *, jclass, jlong); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: SetStatusFramePeriod + * Signature: (JIII)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_led_CANdleJNI_SetStatusFramePeriod + (JNIEnv *, jclass, jlong, jint, jint, jint); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: GetStatusFramePeriod + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_led_CANdleJNI_GetStatusFramePeriod + (JNIEnv *, jclass, jlong, jint, jint); + +/* + * Class: com_ctre_phoenix_led_CANdleJNI + * Method: SetControlFramePeriod + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_led_CANdleJNI_SetControlFramePeriod + (JNIEnv *, jclass, jlong, jint, jint); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/ctre/phoenix/jni/com_ctre_phoenix_platform_PlatformJNI.h b/include/ctre/phoenix/jni/com_ctre_phoenix_platform_PlatformJNI.h index f9bad7d..35db873 100644 --- a/include/ctre/phoenix/jni/com_ctre_phoenix_platform_PlatformJNI.h +++ b/include/ctre/phoenix/jni/com_ctre_phoenix_platform_PlatformJNI.h @@ -33,19 +33,27 @@ JNIEXPORT jint JNICALL Java_com_ctre_phoenix_platform_PlatformJNI_JNI_1SimDestro /* * Class: com_ctre_phoenix_platform_PlatformJNI - * Method: JNI_SimConfigGet - * Signature: (IIIII)I + * Method: JNI_SimSetPhysicsInput + * Signature: (IILjava/lang/String;D)I */ -JNIEXPORT jint JNICALL Java_com_ctre_phoenix_platform_PlatformJNI_JNI_1SimConfigGet - (JNIEnv *, jclass, jint, jint, jint, jint, jint); +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_platform_PlatformJNI_JNI_1SimSetPhysicsInput + (JNIEnv *, jclass, jint, jint, jstring, jdouble); /* * Class: com_ctre_phoenix_platform_PlatformJNI - * Method: JNI_SimConfigSet - * Signature: (IIIIII)I + * Method: JNI_SimGetPhysicsValue + * Signature: (IILjava/lang/String;)D */ -JNIEXPORT jint JNICALL Java_com_ctre_phoenix_platform_PlatformJNI_JNI_1SimConfigSet - (JNIEnv *, jclass, jint, jint, jint, jint, jint, jint); +JNIEXPORT jdouble JNICALL Java_com_ctre_phoenix_platform_PlatformJNI_JNI_1SimGetPhysicsValue + (JNIEnv *, jclass, jint, jint, jstring); + +/* + * Class: com_ctre_phoenix_platform_PlatformJNI + * Method: JNI_SimGetLastError + * Signature: (II)I + */ +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_platform_PlatformJNI_JNI_1SimGetLastError + (JNIEnv *, jclass, jint, jint); #ifdef __cplusplus } diff --git a/include/ctre/phoenix/jni/com_ctre_phoenix_platform_can_PlatformCANJNI.h b/include/ctre/phoenix/jni/com_ctre_phoenix_platform_can_PlatformCANJNI.h index 4a7e690..433c697 100644 --- a/include/ctre/phoenix/jni/com_ctre_phoenix_platform_can_PlatformCANJNI.h +++ b/include/ctre/phoenix/jni/com_ctre_phoenix_platform_can_PlatformCANJNI.h @@ -9,10 +9,10 @@ extern "C" { #endif /* * Class: com_ctre_phoenix_platform_can_PlatformCANJNI - * Method: JNI_SetCANInterface + * Method: JNI_RegisterCANbus * Signature: ([C)I */ -JNIEXPORT jint JNICALL Java_com_ctre_phoenix_platform_can_PlatformCANJNI_JNI_1SetCANInterface +JNIEXPORT jint JNICALL Java_com_ctre_phoenix_platform_can_PlatformCANJNI_JNI_1RegisterCANbus (JNIEnv *, jclass, jcharArray); /* diff --git a/include/ctre/phoenix/jni/com_ctre_phoenix_sensors_CANCoderJNI.h b/include/ctre/phoenix/jni/com_ctre_phoenix_sensors_CANCoderJNI.h index 87a4a4e..9703d83 100644 --- a/include/ctre/phoenix/jni/com_ctre_phoenix_sensors_CANCoderJNI.h +++ b/include/ctre/phoenix/jni/com_ctre_phoenix_sensors_CANCoderJNI.h @@ -10,10 +10,10 @@ extern "C" { /* * Class: com_ctre_phoenix_sensors_CANCoderJNI * Method: Create - * Signature: (I)J + * Signature: (Ijava/lang/String;)J */ JNIEXPORT jlong JNICALL Java_com_ctre_phoenix_sensors_CANCoderJNI_Create - (JNIEnv *, jclass, jint); + (JNIEnv *, jclass, jint, jstring); /* * Class: com_ctre_phoenix_sensors_CANCoderJNI diff --git a/include/ctre/phoenix/led/Animation.h b/include/ctre/phoenix/led/Animation.h new file mode 100644 index 0000000..f619d20 --- /dev/null +++ b/include/ctre/phoenix/led/Animation.h @@ -0,0 +1,53 @@ +#pragma once + +#include + +namespace ctre{ namespace phoenix{ namespace led{ + +class BaseStandardAnimation; +class BaseTwoSizeAnimation; + +/** + * The base class for all animations that CANdle supports. + */ +class Animation { + int _animationIdx, _numLed, _ledOffset; + double _speed; +public: + /** + * Constructor for an Animation class + * @param idx The animation-specific ID + * @param speed The rate at which the animation runs at. Higher is generally faster + * @param numLed The number of LEDs to run the animation on + * @param ledOffset Where to start the animation + */ + Animation(int idx, double speed, int numLed, int ledOffset); + virtual ~Animation(); + /** + * Sets the speed of the animation + * @param speed The rate at which the animation runs at. Higher is generally faster + */ + void SetSpeed(double speed); + /** + * Sets the number of LEDs the animation will run on + * @param numLed The number of LEDs to run the animation on + */ + void SetNumLed(int numLed); + /** + * Sets where the animation starts along the strip + * @param ledOffset Where to start the animation along the strip + */ + void SetLedOffset(int ledOffset); + + virtual BaseStandardAnimation *GetBaseStandardAnimation() = 0; + virtual BaseTwoSizeAnimation *GetBaseTwoSizeAnimation() = 0; + + int GetAnimationIdx(); + double GetSpeed(); + int GetNumLed(); + int GetLedOffset(); +}; + +} // namespace led +} // namespace phoenix +} // namespace ctre \ No newline at end of file diff --git a/include/ctre/phoenix/led/BaseStandardAnimation.h b/include/ctre/phoenix/led/BaseStandardAnimation.h new file mode 100644 index 0000000..98cc7db --- /dev/null +++ b/include/ctre/phoenix/led/BaseStandardAnimation.h @@ -0,0 +1,53 @@ +#pragma once + +#include "ctre/phoenix/led/Animation.h" + +namespace ctre{ namespace phoenix{ namespace led{ + +/** + * The base class for one generic type of animation. + * These animations do not allow the user to specify a color. + */ +class BaseStandardAnimation : public Animation { + double _brightness, _param4, _param5; + bool _reverseDirection; +public: + /** + * Constructor for the BaseStandardAnimation object + * @param idx The animation-specific ID + * @param brightness The brightness to run the animation at. This is a scalar from [0, 1] + * @param speed The rate at which the animation runs at. Higher is generally faster + * @param numLed The number of LEDs to run the animation on + * @param param4 Animation-specific parameter + * @param param5 Animation-specific parameter + * @param reverseDirection True to reverse the animation direction, so instead of going "away" from the CANdle, it will go "toward" the CANdle. + * @param ledOffset Where to start the animation + */ + BaseStandardAnimation(int idx, double brightness, double speed, int numLed, double param4, double param5, bool reverseDirection, int ledOffset); + ~BaseStandardAnimation(); + + BaseStandardAnimation *GetBaseStandardAnimation(); + BaseTwoSizeAnimation *GetBaseTwoSizeAnimation(); + + /** + * Sets the brightness of this animation + * @param brightness The brightness to run the animation at. This is a scalar from [0, 1] + */ + void SetBrightness(double brightness); + void SetParam4(double param4); + void SetParam5(double param5); + /** + * Set the Direction of the animation + * @param reverseDirection True to reverse the animation direction, so instead of fire going "away" from the CANdle, it will go "toward" the CANdle. + */ + void SetReverseDirection(bool reverseDirection); + + double GetBrightness(); + double GetParam4(); + double GetParam5(); + bool GetReverseDirection(); +}; + +} // namespace led +} // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/led/BaseTwoSizeAnimation.h b/include/ctre/phoenix/led/BaseTwoSizeAnimation.h new file mode 100644 index 0000000..2a89ad2 --- /dev/null +++ b/include/ctre/phoenix/led/BaseTwoSizeAnimation.h @@ -0,0 +1,70 @@ +#pragma once + +#include "ctre/phoenix/led/Animation.h" + +namespace ctre{ namespace phoenix{ namespace led{ + +/** + * The base class for one generic type of animation. + * These animations do allow the user to specify a color. + */ +class BaseTwoSizeAnimation : public Animation { + int _r, _g, _b, _w; + int _direction, _size; + +public: + + /** + * Constructor for the BaseStandardAnimation object + * @param idx The animation-specific ID + * @param r The amount of red to set, a value between [0, 255] + * @param g The amount of green to set, a value between [0, 255] + * @param b The amount of blue to set, a value between [0, 255] + * @param w The amount of white to set, a value between [0, 255] + * @param speed The rate at which the animation runs at. Higher is generally faster + * @param numLed The number of LEDs to run the animation on + * @param direction An animation-specific parameter for its direction + * @param size An animation-specific parameter for its size + * @param ledOffset Where to start the animation + */ + BaseTwoSizeAnimation(int idx, int r, int g, int b, int w, double speed, int numLed, int direction, int size, int ledOffset); + ~BaseTwoSizeAnimation(); + + BaseStandardAnimation *GetBaseStandardAnimation(); + BaseTwoSizeAnimation *GetBaseTwoSizeAnimation(); + + /** + * Sets the R value of the LEDs + * @param r The amount of red to set, a value between [0, 255] + */ + void SetR(int r); + /** + * Sets the G value of the LEDs + * @param g The amount of green to set, a value between [0, 255] + */ + void SetG(int g); + /** + * Sets the B value of the LEDs + * @param b The amount of blue to set, a value between [0, 255] + */ + void SetB(int b); + /** + * Sets the W value of the LEDs + * @param w The amount of white to set, a value between [0, 255] + */ + void SetW(int w); + void SetDirection(int direction); + void SetSize(int size); + + int GetR(); + int GetG(); + int GetB(); + int GetW(); + int GetDirection(); + int GetSize(); +}; + +} // namespace led +} // namespace phoenix +} // namespace ctre + diff --git a/include/ctre/phoenix/led/CANdle.h b/include/ctre/phoenix/led/CANdle.h new file mode 100644 index 0000000..cce8a37 --- /dev/null +++ b/include/ctre/phoenix/led/CANdle.h @@ -0,0 +1,403 @@ +#pragma once + +#include "ctre/phoenix/led/Animation.h" +#include "ctre/phoenix/led/BaseStandardAnimation.h" +#include "ctre/phoenix/led/BaseTwoSizeAnimation.h" +#include "ctre/phoenix/led/CANdleFaults.h" +#include "ctre/phoenix/led/CANdleStatusFrame.h" +#include "ctre/phoenix/led/CANdleControlFrame.h" +#include "ctre/phoenix/led/CANdleConfiguration.h" +#include "ctre/phoenix/led/CANdleConfigUtil.h" +#include "ctre/phoenix/led/CANdleLedStripType.h" +#include "ctre/phoenix/led/VBatOutputMode.h" +#include "ctre/phoenix/cci/CANdle_CCI.h" +#include "ctre/phoenix/paramEnum.h" +#include "ctre/phoenix/ErrorCode.h" + +namespace ctre{ namespace phoenix{ namespace led{ + +/** + * CTRE CANdle + * + * Device for controlling LEDs from the CAN bus. + * + *
+ * {@code
+ * // Example usage of a CANdle
+ * CANdle candle{0}; // creates a new CANdle with ID 0
+ *
+ * CANdleConfiguration config;
+ * config.stripType = LEDStripType::RGB; // set the strip type to RGB
+ * config.brightnessScalar = 0.5; // dim the LEDs to half brightness
+ * candle.ConfigAllSettings(config);
+ *
+ * candle.SetLEDs(255, 255, 255); // set the CANdle LEDs to white
+ *
+ * // create a rainbow animation:
+ * // - max brightness
+ * // - half speed
+ * // - 64 LEDs
+ * RainbowAnimation rainbowAnim{1, 0.5, 64};
+ * candle.Animate(rainbowAnim);
+ *
+ * ErrorCode error = candle.GetLastError(); // gets the last error generated by the CANdle
+ * CANdleFaults faults;
+ * ErrorCode faultsError = candle.GetFaults(faults); // fills faults with the current CANdle faults; returns the last error generated
+ * }
+ * 
+ */ +class CANdle { +private: + void *_handle; + + + ctre::phoenix::ErrorCode AnimateStandard(BaseStandardAnimation& animation, int animSlot); + ctre::phoenix::ErrorCode AnimateTwoSize(BaseTwoSizeAnimation& animation, int animSlot); +public: + + /** + * Constructor for a CANdle Device + * @param deviceId The Device ID of the CANdle + * @param canbus Name of the CANbus; can be a SocketCAN interface (on Linux), + * or a CANivore device name or serial number + */ + CANdle(int deviceId, std::string const &canbus = ""); + ~CANdle(); + + /** + * Gets the Voltage of VBat as measured by CANdle + * @return Voltage of VBat + */ + double GetBusVoltage(); + /** + * Gets the Voltage of the 5V line as measured by CANdle + * @return Voltage of the 5V line + */ + double Get5VRailVoltage(); + /** + * Gets the low-side current as measured by CANdle + * @return Current in Amps + */ + double GetCurrent(); + /** + * Gets the temperature of the CANdle in Celcius + * @return Temperature in Celcius + */ + double GetTemperature(); + /** + * Gets the applied vbat modulation in percent. + * If the CANdle is configured to always enable VBat, this returns 1 + * If the CANdle is confgigured to always disable VBat, this returns 0 + * Otherwise it returns the last set Modulation as a value [0, 1] + * @return VBat Output Modulation + */ + double GetVBatModulation(); + /** + * Gets the maximum number of simultaneous animations this version of CANdle firmware supports. + * If you specify an animation slot >= to this return, Phoenix will error out. + * You can also get the maximum count from a self-test snapshot. + * @return Maximum number of simultaneous animations this version of firmware supports. + */ + int GetMaxSimultaneousAnimationCount(); + + /** + * Animates the CANdle with the passed-in animation + * If the animation changes after calling this function, + * it must be passed into animate again for the changes to take effect + * @param animation The animation that CANdle will run. If this is null, it will clear the animation at the specified slot + * @param animSlot The animation slot to use for the animation, range is [0, getMaxSimultaneousAnimationCount()) exclusive + * @return ErrorCode generated by function. OK indicates no error. + */ + ctre::phoenix::ErrorCode Animate(Animation& animation, int animSlot = 0); + + /** + * Clears the animation occurring in the selected selected animSlot. + * @param animSlot Animation slot to clear + * @return ErrorCode generated by function. OK indicates no error. + */ + ctre::phoenix::ErrorCode ClearAnimation(int animSlot); + + /** + * Sets a block of LEDs to the specified color + * @param r The amount of Red to set, range is [0, 255] + * @param g The amount of Green to set, range is [0, 255] + * @param b The amount of Blue to set, range is [0, 255] + * @param w The amount of White to set, range is [0, 255]. This only applies for LED strips with white in them. + * @param startIdx Where to start setting the LEDs + * @param count The number of LEDs to apply this to + * @return ErrorCode generated by function. OK indicates no error. + */ + ctre::phoenix::ErrorCode SetLEDs(int r, int g, int b, int w = 0, int startIdx = 0, int count = 512); + + /** + * Modulates the VBat output to the specified duty cycle percentage + * This function will only do something if the CANdle's VBatOutput is configured to Modulated + * @param dutyCyclePrcnt The duty cycle of the output modulation [0, 1] + * @return ErrorCode generated by function. OK indicates no error. + */ + ErrorCode ModulateVBatOutput(double dutyCyclePrcnt); + + /** + * Configures what the CANdle should do if it loses communications to the Controller + * @param disableWhenLOS Set to true to disable the LEDs on Loss of Signal. + * @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 ErrorCode generated by function. OK indicates no error. + */ + ErrorCode ConfigLOSBehavior(bool disableWhenLOS, int timeoutMs = 0); + /** + * Configures the type of LED the CANdle controls + * @param type The type of the LEDs the CANdle controls + * @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 ErrorCode generated by function. OK indicates no error. + */ + ErrorCode ConfigLEDType(LEDStripType type, int timeoutMs = 0); + /** + * Configures the brightness scalar to be applied to every LED output. + * This value is bounded to [0, 1]. + * + * Setting this to 1 will allow the LEDs to function at max brightness. + * Setting this to 0.5 will scale all values to half their applied value. + * Setting this to 0 will turn off the LEDs. + * + * Forcing the LEDs off this way may be useful in certain testing circumstances + * but is generally not necessary. Self-test (Tuner) may be used to verify what + * the effective scalar is in case user forgot to restore the scalar to a + * non-zero value. + * + * @param brightness Value from [0, 1] that will scale the LED output. + * @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. + */ + ErrorCode ConfigBrightnessScalar(double brightness, int timeoutMs = 0); + + /** + * Configures how the status led will behave when the CANdle is actively controlling LEDs + * If the CANdle is LOS or not actively commanded a value, it will always turn on its status LED. + * @param disableWhenRunning Disables the status LED when the CANdle is running + * @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. + */ + ErrorCode ConfigStatusLedState(bool disableWhenRunning, int timeoutMs = 0); + /** + * Configures how the VBat Output will behave + * @param mode VBat Output Behavior + * @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. + */ + ErrorCode ConfigVBatOutput(VBatOutputMode mode, int timeoutMs = 0); + /** + * Configures the enable state for the 5V rail. This also affects the on-board LEDs. + * @param v5Enabled True to enable the 5V rail. + * @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 ErrorCode generated by function. OK indicates no error. + */ + ErrorCode configV5Enabled(bool v5Enabled, int timeoutMs = 0); + + /** + * 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. + */ + double ConfigGetParameter(ParamEnum param, int ordinal, int timeoutMs = 0); + /** + * 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. + */ + ErrorCode ConfigSetParameter(ParamEnum param, double value, int subValue = 0, int ordinal = 0, int timeoutMs = 0); + /** + * 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 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 the custom param. + */ + int ConfigGetCustomParam(int paramIndex, int timeoutMs = 0); + /** + * 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. + */ + ErrorCode ConfigSetCustomParam(int paramIndex, int value, int timeoutMs = 0); + /** + * Configures all persistent settings to defaults. + * + * @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. + */ + ErrorCode ConfigFactoryDefault(int timeoutMs = 50); + /** + * Gets the CANdle fault status + * + * @param toFill Container for fault statuses. + * @return Error Code generated by function. OK indicates no error. + */ + ErrorCode GetFaults(CANdleFaults& toFill); + /** + * Gets the CANdle sticky fault status + * + * @param toFill Container for sticky fault statuses. + * @return Error Code generated by function. OK indicates no error. + */ + ErrorCode GetStickyFaults(CANdleStickyFaults& toFill); + /** + * Clears the 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 Error Code generated by function. 0 indicates no error. + */ + ErrorCode ClearStickyFaults(int timeoutMs = 0); + /** + * Returns true if the device has reset since last call. + * + * @return Has a Device Reset Occurred? + */ + bool HasResetOccurred(); + /** + * 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. + */ + ErrorCode SetStatusFramePeriod(CANdleStatusFrame frame, int periodMs, int timeoutMs = 0); + /** + * 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. + */ + int GetStatusFramePeriod(CANdleStatusFrame frame, int timeoutMs = 0); + /** + * 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. + */ + ErrorCode SetControlFramePeriod(CANdleControlFrame frame, int periodMs); + + /** + * Configures all persistent settings. + * + * @param allConfigs Object with all of the persistant settings + * @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. + */ + ErrorCode ConfigAllSettings(CANdleConfiguration allConfigs, int timeoutMs = 50); + /** + * Gets all persistant settings. + * + * @param allConfigs Object with all of the persistant settings + * @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. + */ + void GetAllConfigs(CANdleConfiguration allConfigs, int timeoutMs = 50); + + /** + * 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. + */ + ErrorCode GetLastError(); +}; + +} // namespace led +} // namespace phoenix +} // namespace ctre + diff --git a/include/ctre/phoenix/led/CANdleConfigUtil.h b/include/ctre/phoenix/led/CANdleConfigUtil.h new file mode 100644 index 0000000..953f53b --- /dev/null +++ b/include/ctre/phoenix/led/CANdleConfigUtil.h @@ -0,0 +1,26 @@ +#pragma once + +#include "ctre/phoenix/led/CANdleConfiguration.h" +#include "ctre/phoenix/CustomParamConfiguration.h" +#include "ctre/phoenix/Utilities.h" + +namespace ctre{ namespace phoenix{ namespace led{ + +/** + * Util class to help with configuring CANifier + */ +class CANdleConfigUtil : public CustomParamConfigUtil{ + static CANdleConfiguration _default; +public: + + static bool StripTypeDifferent (CANdleConfiguration settings); + static bool BrightnessScalarDifferent (CANdleConfiguration settings); + static bool DisableWhenLOSDifferent (CANdleConfiguration settings); + static bool StatusLedOffWhenActiveDifferent (CANdleConfiguration settings); + static bool VBatOutputModeDifferent (CANdleConfiguration settings); + static bool V5EnabledDifferent (CANdleConfiguration settings); +}; + +} // namespace led +} // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/led/CANdleConfiguration.h b/include/ctre/phoenix/led/CANdleConfiguration.h new file mode 100644 index 0000000..dbbe652 --- /dev/null +++ b/include/ctre/phoenix/led/CANdleConfiguration.h @@ -0,0 +1,52 @@ +#pragma once + +#include "ctre/phoenix/CustomParamConfiguration.h" +#include "ctre/phoenix/led/CANdleLedStripType.h" +#include "ctre/phoenix/led/VBatOutputMode.h" +#include + +namespace ctre{ namespace phoenix{ namespace led{ + +/** + * Configurables available to CANifier + */ +struct CANdleConfiguration : public CustomParamConfiguration { + /** + * What type of LEDs the CANdle controls + */ + LEDStripType stripType {LEDStripType::RGB}; + /** + * Brightness scalar for all LEDs controlled + */ + double brightnessScalar {1.0}; + /** + * True to turn off LEDs when Loss of Signal occurrs + */ + bool disableWhenLOS {false}; + /** + * True to turn off Status LED when CANdle is actively being controlled + */ + bool statusLedOffWhenActive {false}; + /** + * The behavior of VBat output + */ + VBatOutputMode vBatOutputMode {VBatOutputMode::On}; + /** + * True to turn off the 5V rail. This turns off the on-board LEDs as well. + */ + bool v5Enabled {false}; + + CANdleConfiguration(); + + /** + * @param prependString + * String to prepend to configs + * @return String representation of configs + */ + std::string toString(std::string prependString = ""); + +}; + +} // namespace led +} // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/led/CANdleControlFrame.h b/include/ctre/phoenix/led/CANdleControlFrame.h new file mode 100644 index 0000000..ec072a7 --- /dev/null +++ b/include/ctre/phoenix/led/CANdleControlFrame.h @@ -0,0 +1,15 @@ +#pragma once + +namespace ctre { +namespace phoenix { +namespace led { + +/** Enumerated type for status frame types. */ +enum CANdleControlFrame { + CANdle_Control_1_General = 0x040000, + CANdle_Control_2_ModulatedVBatOutput = 0x040040, +}; + +} // namespace led +} // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/led/CANdleFaults.h b/include/ctre/phoenix/led/CANdleFaults.h new file mode 100644 index 0000000..fbc9c6f --- /dev/null +++ b/include/ctre/phoenix/led/CANdleFaults.h @@ -0,0 +1,219 @@ +#pragma once + +#include + +namespace ctre { +namespace phoenix { +namespace led{ + +/** + * Faults available to CANdle (Currently has none) + */ +struct CANdleFaults { + /** + * Device detects hardware failure + */ + bool HardwareFault; + /** + * API error detected. Make sure API and firmware versions are compatible. + */ + bool APIError; + /** + * Boot while receiving an enable frame + */ + bool BootDuringEnable; + /** + * VBat is under 5V + */ + bool VBatTooLow; + /** + * VBat is over 30V + */ + bool VBatTooHigh; + /** + * 5V Line is under 4 V + */ + bool V5TooLow; + /** + * 5V Line is over 6V + */ + bool V5TooHigh; + /** + * Exceeded output current of 6 amps + */ + bool SoftwareFuse; + /** + * Device is over temperature + */ + bool ThermalFault; + /** + * Output pin is shorted to something + */ + bool ShortCircuit; + + /** + * @return true if any faults are tripped + */ + bool HasAnyFault() const { + return HardwareFault | + APIError | + BootDuringEnable | + VBatTooLow | + VBatTooHigh | + V5TooLow | + V5TooHigh | + SoftwareFuse | + ThermalFault | + ShortCircuit; + } + /** + * @return Current fault list as a bit field + */ + int ToBitfield() const { + uint64_t commonFaults = 0; + commonFaults |= ShortCircuit ? 1 : 0; commonFaults <<= 1; + commonFaults |= ThermalFault ? 1 : 0; commonFaults <<= 1; + commonFaults |= SoftwareFuse ? 1 : 0; commonFaults <<= 1; + commonFaults |= V5TooLow ? 1 : 0; commonFaults <<= 1; + commonFaults |= V5TooHigh ? 1 : 0; commonFaults <<= 1; + commonFaults |= VBatTooLow ? 1 : 0; commonFaults <<= 1; + commonFaults |= VBatTooHigh ? 1 : 0; commonFaults <<= 1; + commonFaults |= BootDuringEnable ? 1 : 0; commonFaults <<= 1; + commonFaults |= APIError ? 1 : 0; commonFaults <<= 1; + commonFaults |= HardwareFault ? 1 : 0; + + return commonFaults; + } + void Update(uint64_t bits) { + uint64_t mask = 1; + HardwareFault = (bits & mask) ? true : false; mask <<= 1; + APIError = (bits & mask) ? true : false; mask <<= 1; + BootDuringEnable = (bits & mask) ? true : false; mask <<= 1; + VBatTooHigh = (bits & mask) ? true : false; mask <<= 1; + VBatTooLow = (bits & mask) ? true : false; mask <<= 1; + V5TooHigh = (bits & mask) ? true : false; mask <<= 1; + V5TooLow = (bits & mask) ? true : false; mask <<= 1; + SoftwareFuse = (bits & mask) ? true : false; mask <<= 1; + ThermalFault = (bits & mask) ? true : false; mask <<= 1; + ShortCircuit = (bits & mask) ? true : false; mask <<= 1; + } + /** + * Updates current fault list with specified bit field of faults + * + * @param bits bit field of faults to update with + */ + CANdleFaults(int bits) { + Update(bits); + } + CANdleFaults() { + Update(0); + } +}; +/** + * Faults available to CANdle (Currently has none) + */ +struct CANdleStickyFaults { + /** + * Device detects hardware failure + */ + bool HardwareFault; + /** + * API error detected. Make sure API and firmware versions are compatible. + */ + bool APIError; + /** + * Boot while receiving an enable frame + */ + bool BootDuringEnable; + /** + * VBat is under 5V + */ + bool VBatTooLow; + /** + * VBat is over 30V + */ + bool VBatTooHigh; + /** + * 5V Line is under 4 V + */ + bool V5TooLow; + /** + * 5V Line is over 6V + */ + bool V5TooHigh; + /** + * Exceeded output current of 6 amps + */ + bool SoftwareFuse; + /** + * Device is over temperature + */ + bool ThermalFault; + /** + * Output pin is shorted to something + */ + bool ShortCircuit; + + /** + * @return true if any faults are tripped + */ + bool HasAnyFault() const { + return HardwareFault | + APIError | + BootDuringEnable | + VBatTooLow | + VBatTooHigh | + V5TooLow | + V5TooHigh | + SoftwareFuse | + ThermalFault | + ShortCircuit; + } + /** + * @return Current fault list as a bit field + */ + int ToBitfield() const { + uint64_t commonFaults = 0; + commonFaults |= ShortCircuit ? 1 : 0; commonFaults <<= 1; + commonFaults |= ThermalFault ? 1 : 0; commonFaults <<= 1; + commonFaults |= SoftwareFuse ? 1 : 0; commonFaults <<= 1; + commonFaults |= V5TooLow ? 1 : 0; commonFaults <<= 1; + commonFaults |= V5TooHigh ? 1 : 0; commonFaults <<= 1; + commonFaults |= VBatTooLow ? 1 : 0; commonFaults <<= 1; + commonFaults |= VBatTooHigh ? 1 : 0; commonFaults <<= 1; + commonFaults |= BootDuringEnable ? 1 : 0; commonFaults <<= 1; + commonFaults |= APIError ? 1 : 0; commonFaults <<= 1; + commonFaults |= HardwareFault ? 1 : 0; + + return commonFaults; + } + void Update(uint64_t bits) { + uint64_t mask = 1; + HardwareFault = (bits & mask) ? true : false; mask <<= 1; + APIError = (bits & mask) ? true : false; mask <<= 1; + BootDuringEnable = (bits & mask) ? true : false; mask <<= 1; + VBatTooHigh = (bits & mask) ? true : false; mask <<= 1; + VBatTooLow = (bits & mask) ? true : false; mask <<= 1; + V5TooHigh = (bits & mask) ? true : false; mask <<= 1; + V5TooLow = (bits & mask) ? true : false; mask <<= 1; + SoftwareFuse = (bits & mask) ? true : false; mask <<= 1; + ThermalFault = (bits & mask) ? true : false; mask <<= 1; + ShortCircuit = (bits & mask) ? true : false; mask <<= 1; + } + /** + * Updates current fault list with specified bit field of faults + * + * @param bits bit field of faults to update with + */ + CANdleStickyFaults(int bits) { + Update(bits); + } + CANdleStickyFaults() { + Update(0); + } +}; + +} // led +} // phoenix +} // ctre + diff --git a/include/ctre/phoenix/led/CANdleLedStripType.h b/include/ctre/phoenix/led/CANdleLedStripType.h new file mode 100644 index 0000000..b1ea11e --- /dev/null +++ b/include/ctre/phoenix/led/CANdleLedStripType.h @@ -0,0 +1,36 @@ +#pragma once + +namespace ctre{ namespace phoenix{ namespace led{ + /** + * The various LED types that the CANdle can support + */ + enum LEDStripType { + /** + * LEDs that are controlled by Green-Red-Blue values + */ + GRB = 0, + /** + * LEDs that are controlled by Red-Green-Blue values + */ + RGB = 1, + /** + * LEDs that are controlled by Blue-Red-Green values + */ + BRG = 2, + /** + * LEDs that are controlled by Green-Red-Blue-White values + */ + GRBW = 6, + /** + * LEDs that are controlled by Red-Green-Blue-White values + */ + RGBW = 7, + /** + * LEDs that are controlled by Blue-Red-Green-White values + */ + BRGW = 8, + }; + +} // namespace led +} // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/led/CANdleStatusFrame.h b/include/ctre/phoenix/led/CANdleStatusFrame.h new file mode 100644 index 0000000..03e0cb1 --- /dev/null +++ b/include/ctre/phoenix/led/CANdleStatusFrame.h @@ -0,0 +1,20 @@ +#pragma once + +namespace ctre { +namespace phoenix { +namespace led { + +/** Enumerated type for status frame types. */ +enum CANdleStatusFrame { + CANdleStatusFrame_Status_1_General = 0x041400, + CANdleStatusFrame_Status_2_Startup = 0x041440, + CANdleStatusFrame_Status_3_FirmwareApiStatus = 0x041480, + CANdleStatusFrame_Status_4_ControlTelem = 0x0414C0, + CANdleStatusFrame_Status_5_PixelPulseTrain = 0x041500, + CANdleStatusFrame_Status_6_BottomPixels = 0x041540, + CANdleStatusFrame_Status_7_TopPixels = 0x041580, +}; + +} // namespace led +} // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/led/ColorFlowAnimation.h b/include/ctre/phoenix/led/ColorFlowAnimation.h new file mode 100644 index 0000000..0cca714 --- /dev/null +++ b/include/ctre/phoenix/led/ColorFlowAnimation.h @@ -0,0 +1,48 @@ +#pragma once + +#include "ctre/phoenix/led/BaseTwoSizeAnimation.h" + +namespace ctre {namespace phoenix {namespace led { + +/** + * Animation that gradually lights the entire LED strip one LED at a time. + */ +class ColorFlowAnimation : public BaseTwoSizeAnimation { +public: + /** + * What direction does the color go + */ + enum Direction { + /** + * Color goes forward, away from CANdle + */ + Forward = 0, + /** + * Color goes backward, toward CANdle + */ + Backward = 1, + }; + + /** + * Constructor for a ColorFlowAnimation + * @param r How much red should the color have [0, 255] + * @param g How much green should the color have [0, 255] + * @param b How much blue should the color have [0, 255] + * @param w How much white should the color have [0, 255] + * @param speed How fast should the color travel the strip [0, 1] + * @param numLed How many LEDs is the CANdle controlling + * @param direction What direction should the color move in + * @param ledOffset Where to start the animation + */ + ColorFlowAnimation(int r, int g, int b, int w, double speed = 1, int numLed = -1, Direction direction = Direction::Forward, int ledOffset = 0); + + /** + * Sets the direction the color flow moves in + * @param direction What direction should the color move in + */ + void SetDirection(Direction direction); +}; + +} // namespace led +} // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/led/FireAnimation.h b/include/ctre/phoenix/led/FireAnimation.h new file mode 100644 index 0000000..76aec08 --- /dev/null +++ b/include/ctre/phoenix/led/FireAnimation.h @@ -0,0 +1,37 @@ +#pragma once + +#include "ctre/phoenix/led/BaseStandardAnimation.h" + +namespace ctre {namespace phoenix {namespace led { + +/** + * Animation that looks similarly to a flame flickering + */ +class FireAnimation : public BaseStandardAnimation { +public: + /** + * Constructor for a FireAnimation + * @param brightness How bright should the animation be [0, 1] + * @param speed How fast will the flame be processed at [0, 1] + * @param numLed How many LEDs is the CANdle controlling + * @param sparking The rate at which the Fire "Sparks" [0, 1] + * @param cooling The rate at which the Fire "Cools" along the travel [0, 1] + * @param reverseDirection True to reverse the animation direction, so instead of fire going "away" from the CANdle, it will go "toward" the CANdle. + * @param ledOffset Where to start the animation + */ + FireAnimation(double brightness = 1, double speed = 1, int numLed = -1, double sparking = 1, double cooling = 1, bool reverseDirection = false, int ledOffset = 0); + /** + * Sets the sparking value of the FireAnimation + * @param sparking The rate at which the Fire "Sparks" [0, 1] + */ + void SetSparking(double sparking); + /** + * Sets the cooling value of the FireAnimation + * @param cooling The rate at which the Fire "Cools" [0, 1] + */ + void SetCooling(double cooling); +}; + +} // namespace led +} // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/led/LarsonAnimation.h b/include/ctre/phoenix/led/LarsonAnimation.h new file mode 100644 index 0000000..59e93df --- /dev/null +++ b/include/ctre/phoenix/led/LarsonAnimation.h @@ -0,0 +1,58 @@ +#pragma once + +#include "ctre/phoenix/led/BaseTwoSizeAnimation.h" + +namespace ctre {namespace phoenix {namespace led { + +/** + * Animation that sends a pocket of light across the LED strip. + */ +class LarsonAnimation : public BaseTwoSizeAnimation { +public: + /** + * How the pocket of light behaves when it reaches the end of the strip + */ + enum BounceMode { + /** + * Bounce the pocket as soon as the first LED reaches the end of the strip + */ + Front = 0, + /** + * Bounce the pocket once it is midway through the end of the strip + */ + Center = 1, + /** + * Bounce the pocket once all the LEDs are off the strip + */ + Back = 2, + }; + /** + * Constructor for a LarsonAnimation + * @param r How much red should the color have [0, 255] + * @param g How much green should the color have [0, 255] + * @param b How much blue should the color have [0, 255] + * @param w How much white should the color have [0, 255] + * @param speed How fast should the color travel the strip [0, 1] + * @param numLed The number of LEDs the CANdle will control + * @param mode How the pocket of LEDs will behave once it reaches the end of the strip + * @param size How large the pocket of LEDs are [0, 7] + * @param ledOffset Where to start the animation + */ + LarsonAnimation(int r, int g, int b, int w = 0, double speed = 1, int numLed = -1, BounceMode mode = BounceMode::Front, int size = 2, int ledOffset = 0); + + /** + * Sets the bounce mode of the animation. + * @param mode How the pocket of LEDs will behave once it reaches the end of the strip + */ + void SetBounceMode(BounceMode mode); + + /** + * Sets the size of the pocket of LEDs + * @param size The size of the pocket [0, 7] + */ + void SetSize(int size); +}; + +} // namespace led +} // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/led/RainbowAnimation.h b/include/ctre/phoenix/led/RainbowAnimation.h new file mode 100644 index 0000000..a30c209 --- /dev/null +++ b/include/ctre/phoenix/led/RainbowAnimation.h @@ -0,0 +1,25 @@ +#pragma once + +#include "ctre/phoenix/led/BaseStandardAnimation.h" + +namespace ctre {namespace phoenix {namespace led { + +/** + * Animation that creates a rainbow throughout all the LEDs + */ +class RainbowAnimation : public BaseStandardAnimation { +public: + /** + * Constructor for a RainbowAnimation + * @param brightness The brightness of the LEDs [0, 1] + * @param speed How fast the rainbow travels through the leds [0, 1] + * @param numLed How many LEDs are controlled by the CANdle + * @param reverseDirection True to reverse the animation direction, so instead of going "toward" the CANdle, it will go "away" from the CANdle. + * @param ledOffset Where to start the animation + */ + RainbowAnimation(double brightness = 1, double speed = 1, int numLed = -1, bool reverseDirection = false, int ledOffset = 0); +}; + +} // namespace led +} // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/led/RgbFadeAnimation.h b/include/ctre/phoenix/led/RgbFadeAnimation.h new file mode 100644 index 0000000..1851798 --- /dev/null +++ b/include/ctre/phoenix/led/RgbFadeAnimation.h @@ -0,0 +1,24 @@ +#pragma once + +#include "ctre/phoenix/led/BaseStandardAnimation.h" + +namespace ctre {namespace phoenix {namespace led { + +/** + * Animation that fades all the LEDs of a strip simultaneously between Red, Green, and Blue + */ +class RgbFadeAnimation : public BaseStandardAnimation { +public: + /** + * Constructor for an RgbFadeAnimation + * @param brightness How bright the LEDs are [0, 1] + * @param speed How fast the LEDs fade between Red, Green, and Blue [0, 1] + * @param numLed How many LEDs are controlled by the CANdle + * @param ledOffset Where to start the animation + */ + RgbFadeAnimation(double brightness = 1, double speed = 1, int numLed = -1, int ledOffset = 0); +}; + +} // namespace led +} // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/led/SingleFadeAnimation.h b/include/ctre/phoenix/led/SingleFadeAnimation.h new file mode 100644 index 0000000..f03f336 --- /dev/null +++ b/include/ctre/phoenix/led/SingleFadeAnimation.h @@ -0,0 +1,27 @@ +#pragma once + +#include "ctre/phoenix/led/BaseTwoSizeAnimation.h" + +namespace ctre {namespace phoenix {namespace led { + +/** + * Animation that fades into and out of a specified color + */ +class SingleFadeAnimation : public BaseTwoSizeAnimation { +public: + /** + * Constructor for a SingleFadeAnimation + * @param r How much red should the color have [0, 255] + * @param g How much green should the color have [0, 255] + * @param b How much blue should the color have [0, 255] + * @param w How much white should the color have [0, 255] + * @param speed How fast should the color travel the strip [0, 1] + * @param numLed How many LEDs the CANdle controls + * @param ledOffset Where to start the animation + */ + SingleFadeAnimation(int r, int g, int b, int w = 0, double speed = 1, int numLed = -1, int ledOffset = 0); +}; + +} // namespace led +} // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/led/StrobeAnimation.h b/include/ctre/phoenix/led/StrobeAnimation.h new file mode 100644 index 0000000..eabbdab --- /dev/null +++ b/include/ctre/phoenix/led/StrobeAnimation.h @@ -0,0 +1,27 @@ +#pragma once + +#include "ctre/phoenix/led/BaseTwoSizeAnimation.h" + +namespace ctre {namespace phoenix {namespace led { + +/** + * Animation that strobes the LEDs a specified color + */ +class StrobeAnimation : public BaseTwoSizeAnimation { +public: + /** + * Constructor for a StrobeAnimation + * @param r How much red should the color have [0, 255] + * @param g How much green should the color have [0, 255] + * @param b How much blue should the color have [0, 255] + * @param w How much white should the color have [0, 255] + * @param speed How fast should the color travel the strip [0, 1] + * @param numLed How many LEDs the CANdle controls + * @param ledOffset Where to start the animation + */ + StrobeAnimation(int r, int g, int b, int w = 0, double speed = 1, int numLed = -1, int ledOffset = 0); +}; + +} // namespace led +} // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/led/TwinkleAnimation.h b/include/ctre/phoenix/led/TwinkleAnimation.h new file mode 100644 index 0000000..982f490 --- /dev/null +++ b/include/ctre/phoenix/led/TwinkleAnimation.h @@ -0,0 +1,71 @@ +#pragma once + +#include "ctre/phoenix/led/BaseTwoSizeAnimation.h" + +namespace ctre {namespace phoenix {namespace led { + +/** + * Animation that randomly turns LEDs on and off to a certain color + */ +class TwinkleAnimation : public BaseTwoSizeAnimation { +public: + /** + * The percentage of LEDs that are allowed to be on at any one point + */ + enum TwinklePercent { + /** + * All the LEDs are allowed to turn on + */ + Percent100 = 0, + /** + * 88% of LEDs are allowed to turn on + */ + Percent88 = 1, + /** + * 76% of LEDs are allowed to turn on + */ + Percent76 = 2, + /** + * 64% of LEDs are allowed to turn on + */ + Percent64 = 3, + /** + * 42% of LEDs are allowed to turn on + */ + Percent42 = 4, + /** + * 30% of LEDs are allowed to turn on + */ + Percent30 = 5, + /** + * 18% of LEDs are allowed to turn on + */ + Percent18 = 6, + /** + * 6% of LEDs are allowed to turn on + */ + Percent6 = 7, + }; + + /** + * Constructor for a TwinkleAnimation + * @param r How much red should the color have [0, 255] + * @param g How much green should the color have [0, 255] + * @param b How much blue should the color have [0, 255] + * @param w How much white should the color have [0, 255] + * @param speed How fast should the color travel the strip [0, 1] + * @param numLed How many LEDs the CANdle controls + * @param divider What percentage of LEDs can be on at any point + * @param ledOffset Where to start the animation + */ + TwinkleAnimation(int r, int g, int b, int w = 0, double speed = 1, int numLed = -1, TwinklePercent divider = TwinklePercent::Percent100, int ledOffset = 0); + /** + * Sets the percentage of LEDs that are allowed on + * @param divider The percentage of LEDs that are allowed on at any point + */ + void SetDivider(TwinklePercent divider); +}; + +} // namespace led +} // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/led/TwinkleOffAnimation.h b/include/ctre/phoenix/led/TwinkleOffAnimation.h new file mode 100644 index 0000000..4ed3cd8 --- /dev/null +++ b/include/ctre/phoenix/led/TwinkleOffAnimation.h @@ -0,0 +1,71 @@ +#pragma once + +#include "ctre/phoenix/led/BaseTwoSizeAnimation.h" + +namespace ctre {namespace phoenix {namespace led { + +/** + * Animation that randomly turns on LEDs, until it reaches the maximum count and turns them all off + */ +class TwinkleOffAnimation : public BaseTwoSizeAnimation { +public: + /** + * The maximum percentage of LEDs that are allowed to turn on + */ + enum TwinkleOffPercent { + /** + * All the LEDs are allowed to turn on + */ + Percent100 = 0, + /** + * 88% of LEDs are allowed to turn on + */ + Percent88 = 1, + /** + * 76% of LEDs are allowed to turn on + */ + Percent76 = 2, + /** + * 64% of LEDs are allowed to turn on + */ + Percent64 = 3, + /** + * 42% of LEDs are allowed to turn on + */ + Percent42 = 4, + /** + * 30% of LEDs are allowed to turn on + */ + Percent30 = 5, + /** + * 18% of LEDs are allowed to turn on + */ + Percent18 = 6, + /** + * 6% of LEDs are allowed to turn on + */ + Percent6 = 7, + }; + + /** + * Constructor for a TwinkleAnimation + * @param r How much red should the color have [0, 255] + * @param g How much green should the color have [0, 255] + * @param b How much blue should the color have [0, 255] + * @param w How much white should the color have [0, 255] + * @param speed How fast should the color travel the strip [0, 1] + * @param numLed How many LEDs the CANdle controls + * @param divider What percentage of LEDs can be on at any point + * @param ledOffset Where to start the animation + */ + TwinkleOffAnimation(int r, int g, int b, int w = 0, double speed = 1, int numLed = -1, TwinkleOffPercent divider = TwinkleOffPercent::Percent100, int ledOffset = 0); + /** + * Sets the percentage of LEDs that are allowed on + * @param divider The percentage of LEDs that are allowed on at any point + */ + void SetDivider(TwinkleOffPercent divider); +}; + +} // namespace led +} // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/led/VBatOutputMode.h b/include/ctre/phoenix/led/VBatOutputMode.h new file mode 100644 index 0000000..2ce3019 --- /dev/null +++ b/include/ctre/phoenix/led/VBatOutputMode.h @@ -0,0 +1,24 @@ +#pragma once + +namespace ctre{ namespace phoenix{ namespace led{ + + /** + * The various methods of managing the VBat output behavior + */ + enum VBatOutputMode { + /** + * VBat output is on at full power, no modulation + */ + On = 0, + /** + * VBat output is off, no modulation + */ + Off = 1, + /** + * VBat output is on at the specified modulation + */ + Modulated = 2, + }; +} // namespace led +} // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/motorcontrol/FeedbackDevice.h b/include/ctre/phoenix/motorcontrol/FeedbackDevice.h index bf4c28a..04adbe9 100644 --- a/include/ctre/phoenix/motorcontrol/FeedbackDevice.h +++ b/include/ctre/phoenix/motorcontrol/FeedbackDevice.h @@ -29,7 +29,7 @@ namespace ctre { */ Tachometer = 4, /** - * CTRE Mag Encoder in Relative mode or + * CTRE Mag Encoder in Absolute mode or * any other device that uses PWM to encode its output */ PulseWidthEncodedPosition = 8, @@ -88,7 +88,7 @@ namespace ctre { */ Tachometer = 4, /** - * CTRE Mag Encoder in Relative mode or + * CTRE Mag Encoder in Absolute mode or * any other device that uses PWM to encode its output */ PulseWidthEncodedPosition = 8, diff --git a/include/ctre/phoenix/motorcontrol/IMotorController.h b/include/ctre/phoenix/motorcontrol/IMotorController.h index a81636e..747e9d0 100644 --- a/include/ctre/phoenix/motorcontrol/IMotorController.h +++ b/include/ctre/phoenix/motorcontrol/IMotorController.h @@ -23,6 +23,11 @@ namespace ctre { namespace phoenix { namespace motorcontrol { +namespace can { +// Forward-Proto BaseTalon +class BaseTalon; +} + /** * Interface for motor controllers */ @@ -51,22 +56,6 @@ class IMotorController: public virtual IFollower { */ virtual void Set(ControlMode Mode, double demand) = 0; /** - * @deprecated use 4 parameter set - * @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. - */ - virtual void Set(ControlMode Mode, double demand0, double demand1) = 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. @@ -420,6 +409,23 @@ class IMotorController: public virtual IFollower { * @return Error Code generated by function. 0 indicates no error. */ virtual ErrorCode ConfigRemoteFeedbackFilter(ctre::phoenix::sensors::CANCoder &canCoderRef, int remoteOrdinal, int timeoutMs = 0)= 0; + /** + * 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 talonRef + * Talon device reference to use. + * @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. + */ + virtual ErrorCode ConfigRemoteFeedbackFilter(ctre::phoenix::motorcontrol::can::BaseTalon &talonRef, int remoteOrdinal, int timeoutMs = 0)= 0; /** * Select what sensor term should be bound to switch feedback device. * Sensor Sum = Sensor Sum Term 0 - Sensor Sum Term 1 @@ -447,7 +453,7 @@ class IMotorController: public virtual IFollower { * * @return Position of selected sensor (in raw sensor units). */ - virtual int GetSelectedSensorPosition(int pidIdx = 0) = 0; + virtual double GetSelectedSensorPosition(int pidIdx = 0) = 0; /** * Get the selected sensor velocity. * @@ -456,7 +462,7 @@ class IMotorController: public virtual IFollower { * @return selected sensor (in raw sensor units) per 100ms. * See Phoenix-Documentation for how to interpret. */ - virtual int GetSelectedSensorVelocity(int pidIdx = 0) = 0; + virtual double GetSelectedSensorVelocity(int pidIdx = 0) = 0; /** * Sets the sensor position to the given value. * @@ -470,7 +476,7 @@ class IMotorController: public virtual IFollower { * If zero, no blocking or checking is performed. * @return Error Code generated by function. 0 indicates no error. */ - virtual ErrorCode SetSelectedSensorPosition(int sensorPos, int pidIdx = 0, + virtual ErrorCode SetSelectedSensorPosition(double sensorPos, int pidIdx = 0, int timeoutMs = 50) = 0; //------ status frame period changes ----------// @@ -590,7 +596,7 @@ class IMotorController: public virtual IFollower { * If zero, no blocking or checking is performed. * @return Error Code generated by function. 0 indicates no error. */ - virtual ErrorCode ConfigForwardSoftLimitThreshold(int forwardSensorLimit, + virtual ErrorCode ConfigForwardSoftLimitThreshold(double forwardSensorLimit, int timeoutMs = 0) = 0; /** * Configures the reverse soft limit threshold. @@ -603,7 +609,7 @@ class IMotorController: public virtual IFollower { * If zero, no blocking or checking is performed. * @return Error Code generated by function. 0 indicates no error. */ - virtual ErrorCode ConfigReverseSoftLimitThreshold(int reverseSensorLimit, + virtual ErrorCode ConfigReverseSoftLimitThreshold(double reverseSensorLimit, int timeoutMs = 0) = 0; /** * Configures the forward soft limit enable. @@ -733,7 +739,7 @@ class IMotorController: public virtual IFollower { * blocking or checking is performed. * @return Error Code generated by function. 0 indicates no error. */ - virtual ErrorCode Config_IntegralZone(int slotIdx, int izone, + virtual ErrorCode Config_IntegralZone(int slotIdx, double izone, int timeoutMs = 0) = 0; /** * Sets the allowable closed-loop error in the given parameter slot. @@ -749,7 +755,7 @@ class IMotorController: public virtual IFollower { * @return Error Code generated by function. 0 indicates no error. */ virtual ErrorCode ConfigAllowableClosedloopError(int slotIdx, - int allowableCloseLoopError, int timeoutMs = 0) = 0; + double allowableCloseLoopError, int timeoutMs = 0) = 0; /** * Sets the maximum integral accumulator in the given parameter slot. * @@ -860,7 +866,7 @@ class IMotorController: public virtual IFollower { * 0 for Primary closed-loop. 1 for auxiliary closed-loop. * @return Closed-loop error value. */ - virtual int GetClosedLoopError(int pidIdx = 0) = 0; + virtual double GetClosedLoopError(int pidIdx = 0) = 0; /** * Gets the iaccum value. * @@ -904,7 +910,7 @@ class IMotorController: public virtual IFollower { * 0 for Primary closed-loop. 1 for auxiliary closed-loop. * @return The Active Trajectory Position in sensor units. */ - virtual int GetActiveTrajectoryPosition(int pidIdx = 0) = 0; + virtual double GetActiveTrajectoryPosition(int pidIdx = 0) = 0; /** * Gets the active trajectory target velocity for using * MotionMagic/MotionProfile control modes. @@ -913,7 +919,7 @@ class IMotorController: public virtual IFollower { * 0 for Primary closed-loop. 1 for auxiliary closed-loop. * @return The Active Trajectory Velocity in sensor units per 100ms. */ - virtual int GetActiveTrajectoryVelocity(int pidIdx = 0) = 0; + virtual double GetActiveTrajectoryVelocity(int pidIdx = 0) = 0; /** * Gets the active trajectory arbitrary feedforward using * MotionMagic/MotionProfile control modes. @@ -924,14 +930,6 @@ class IMotorController: public virtual IFollower { * (where 0.01 is 1%). */ virtual double GetActiveTrajectoryArbFeedFwd(int pidIdx = 0) = 0; - /** - * Gets the active trajectory target heading using - * MotionMagicArc/MotionProfileArc control modes. - * - * @return The Active Trajectory Heading in degrees. - * @deprecated Use {@link #GetActiveTrajectoryPosition(int)} with 1 passed as an argument instead. - */ - virtual double GetActiveTrajectoryHeading() = 0; //------ Motion Profile Settings used in Motion Magic ----------// /** @@ -946,7 +944,7 @@ class IMotorController: public virtual IFollower { * blocking or checking is performed. * @return Error Code generated by function. 0 indicates no error. */ - virtual ErrorCode ConfigMotionCruiseVelocity(int sensorUnitsPer100ms, + virtual ErrorCode ConfigMotionCruiseVelocity(double sensorUnitsPer100ms, int timeoutMs = 0) = 0; /** * Sets the Motion Magic Acceleration. This is the target acceleration that @@ -961,7 +959,7 @@ class IMotorController: public virtual IFollower { * blocking or checking is performed. * @return Error Code generated by function. 0 indicates no error. */ - virtual ErrorCode ConfigMotionAcceleration(int sensorUnitsPer100msPerSec, + virtual ErrorCode ConfigMotionAcceleration(double sensorUnitsPer100msPerSec, int timeoutMs = 0) = 0; /** diff --git a/include/ctre/phoenix/motorcontrol/IMotorControllerEnhanced.h b/include/ctre/phoenix/motorcontrol/IMotorControllerEnhanced.h index cfef323..86c4448 100644 --- a/include/ctre/phoenix/motorcontrol/IMotorControllerEnhanced.h +++ b/include/ctre/phoenix/motorcontrol/IMotorControllerEnhanced.h @@ -2,18 +2,21 @@ #include "ctre/phoenix/motorcontrol/ControlMode.h" #include "ctre/phoenix/motorcontrol/ControlFrame.h" +#include "ctre/phoenix/motorcontrol/IMotorController.h" +#include "ctre/phoenix/motorcontrol/IFollower.h" #include "ctre/phoenix/motorcontrol/NeutralMode.h" #include "ctre/phoenix/motorcontrol/FeedbackDevice.h" #include "ctre/phoenix/motorcontrol/SensorCollection.h" +#include "ctre/phoenix/motorcontrol/SupplyCurrentLimitConfiguration.h" #include "ctre/phoenix/motorcontrol/StatusFrame.h" #include "ctre/phoenix/motorcontrol/LimitSwitchType.h" #include "ctre/phoenix/motorcontrol/Faults.h" #include "ctre/phoenix/motorcontrol/StickyFaults.h" +#include "ctre/phoenix/motorcontrol/VelocityMeasPeriod.h" #include "ctre/phoenix/paramEnum.h" #include "ctre/phoenix/motion/TrajectoryPoint.h" #include "ctre/phoenix/motion/MotionProfileStatus.h" #include "ctre/phoenix/ErrorCode.h" -#include "IFollower.h" namespace ctre { namespace phoenix { @@ -78,6 +81,18 @@ class IMotorControllerEnhanced: public virtual IMotorController { virtual ErrorCode ConfigSelectedFeedbackSensor( RemoteFeedbackDevice feedbackDevice, int pidIdx = 0, int timeoutMs = 0) = 0; + //------ Current Limit ----------// + /** + * Configures the supply-side current limit. + * @param currLimitCfg Current limit configuration + * @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. + */ + virtual ErrorCode ConfigSupplyCurrentLimit(const SupplyCurrentLimitConfiguration& currLimitConfigs, int timeoutMs = 50) = 0; + //------- sensor status --------- // /* in parent */ diff --git a/include/ctre/phoenix/motorcontrol/LimitSwitchType.h b/include/ctre/phoenix/motorcontrol/LimitSwitchType.h index 8d7c3fc..85e4216 100644 --- a/include/ctre/phoenix/motorcontrol/LimitSwitchType.h +++ b/include/ctre/phoenix/motorcontrol/LimitSwitchType.h @@ -12,10 +12,14 @@ enum LimitSwitchSource { * Limit switch directly connected to motor controller */ LimitSwitchSource_FeedbackConnector = 0, + /** + * Use Limit switch connected to Talon on CAN + */ + LimitSwitchSource_RemoteTalon = 1, /** * Use Limit switch connected to TalonSRX on CAN */ - LimitSwitchSource_RemoteTalonSRX = 1, + LimitSwitchSource_RemoteTalonSRX = LimitSwitchSource_RemoteTalon, /** * User Limit switch connected to CANifier */ @@ -32,10 +36,14 @@ enum RemoteLimitSwitchSource { * Don't use limit switch, this is the factory default value */ RemoteLimitSwitchSource_FactoryDefaultOff = 0, + /** + * Use Limit switch connected to Talon on CAN + */ + RemoteLimitSwitchSource_RemoteTalon = 1, /** * Use Limit switch connected to TalonSRX on CAN */ - RemoteLimitSwitchSource_RemoteTalonSRX = 1, + RemoteLimitSwitchSource_RemoteTalonSRX = RemoteLimitSwitchSource_RemoteTalon, /** * User Limit switch connected to CANifier */ @@ -101,7 +109,7 @@ class LimitSwitchRoutines { static std::string toString(LimitSwitchSource value) { switch(value) { case LimitSwitchSource_FeedbackConnector : return "LimitSwitchSource_FeedbackConnector"; - case LimitSwitchSource_RemoteTalonSRX : return "LimitSwitchSource_RemoteTalonSRX"; + case LimitSwitchSource_RemoteTalon : return "LimitSwitchSource_RemoteTalon"; case LimitSwitchSource_RemoteCANifier : return "LimitSwitchSource_RemoteCANifier"; case LimitSwitchSource_Deactivated : return "LimitSwitchSource_Deactivated"; default : return "InvalidValue"; @@ -115,7 +123,7 @@ class LimitSwitchRoutines { static std::string toString(RemoteLimitSwitchSource value) { switch(value) { case RemoteLimitSwitchSource_FactoryDefaultOff: return "None (factory default value)"; - case RemoteLimitSwitchSource_RemoteTalonSRX : return "RemoteLimitSwitchSource_RemoteTalonSRX"; + case RemoteLimitSwitchSource_RemoteTalon : return "RemoteLimitSwitchSource_RemoteTalon"; case RemoteLimitSwitchSource_RemoteCANifier : return "RemoteLimitSwitchSource_RemoteCANifier"; case RemoteLimitSwitchSource_Deactivated : return "RemoteLimitSwitchSource_Deactivated"; default : return "InvalidValue"; diff --git a/include/ctre/phoenix/motorcontrol/SensorCollection.h b/include/ctre/phoenix/motorcontrol/SensorCollection.h index d1401b9..b15191d 100644 --- a/include/ctre/phoenix/motorcontrol/SensorCollection.h +++ b/include/ctre/phoenix/motorcontrol/SensorCollection.h @@ -38,6 +38,9 @@ namespace ctre { /** * Get the position of whatever is in the analog pin of the Talon, regardless of * whether it is actually being used for feedback. + * + * This method relies on the Status 4 message, which has a default period of 150ms. For more + * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html * * @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 @@ -63,6 +66,9 @@ namespace ctre { /** * Get the position of whatever is in the analog pin of the Talon, regardless of whether * it is actually being used for feedback. + * + * This method relies on the Status 4 message, which has a default period of 150ms. For more + * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html * * @return the ADC (0 - 1023) on analog pin of the Talon. */ @@ -72,6 +78,9 @@ namespace ctre { /** * Get the velocity of whatever is in the analog pin of the Talon, regardless of * whether it is actually being used for feedback. + * + * This method relies on the Status 4 message, which has a default period of 150ms. For more + * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html * * @return the speed in units per 100ms where 1024 units is one rotation. */ @@ -81,6 +90,9 @@ namespace ctre { /** * Get the quadrature position of the Talon, regardless of whether * it is actually being used for feedback. + * + * This method relies on the Status 3 message, which has a default period of 150ms. For more + * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html * * @return the quadrature position. */ @@ -128,6 +140,9 @@ namespace ctre { /** * Get the quadrature velocity, regardless of whether * it is actually being used for feedback. + * + * This method relies on the Status 3 message, which has a default period of 150ms. For more + * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html * * @return the quadrature velocity in units per 100ms. */ @@ -137,6 +152,9 @@ namespace ctre { /** * Gets pulse width position, regardless of whether * it is actually being used for feedback. + * + * This method relies on the Status 8 message, which has a default period of 150ms. For more + * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html * * @return the pulse width position. */ @@ -159,6 +177,9 @@ namespace ctre { /** * Gets pulse width velocity, regardless of whether * it is actually being used for feedback. + * + * This method relies on the Status 8 message, which has a default period of 150ms. For more + * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html * * @return the pulse width velocity in units per 100ms (where 4096 units is 1 rotation). */ @@ -167,6 +188,9 @@ namespace ctre { /** * Gets pulse width rise to fall time. + * + * This method relies on the Status 8 message, which has a default period of 150ms. For more + * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html * * @return the pulse width rise to fall time in microseconds. */ @@ -175,6 +199,9 @@ namespace ctre { /** * Gets pulse width rise to rise time. + * + * This method relies on the Status 8 message, which has a default period of 150ms. For more + * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html * * @return the pulse width rise to rise time in microseconds. */ @@ -183,6 +210,9 @@ namespace ctre { /** * Gets pin state quad a. + * + * This method relies on the Status 3 message, which has a default period of 150ms. For more + * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html * * @return the pin state of quad a (1 if asserted, 0 if not asserted). */ @@ -191,6 +221,9 @@ namespace ctre { /** * Gets pin state quad b. + * + * This method relies on the Status 3 message, which has a default period of 150ms. For more + * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html * * @return Digital level of QUADB pin (1 if asserted, 0 if not asserted). */ @@ -199,6 +232,9 @@ namespace ctre { /** * Gets pin state quad index. + * + * This method relies on the Status 3 message, which has a default period of 150ms. For more + * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html * * @return Digital level of QUAD Index pin (1 if asserted, 0 if not asserted). */ @@ -207,6 +243,9 @@ namespace ctre { /** * Is forward limit switch closed. + * + * This method relies on the Status 1 message, which has a default period of 10ms. For more + * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html * * @return '1' iff forward limit switch is closed, 0 iff switch is open. This function works * regardless if limit switch feature is enabled. Remote limit features do not impact this routine. @@ -216,6 +255,9 @@ namespace ctre { /** * Is reverse limit switch closed. + * + * This method relies on the Status 1 message, which has a default period of 10ms. For more + * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html * * @return '1' iff reverse limit switch is closed, 0 iff switch is open. This function works * regardless if limit switch feature is enabled. Remote limit features do not impact this routine. diff --git a/include/ctre/phoenix/motorcontrol/StatusFrame.h b/include/ctre/phoenix/motorcontrol/StatusFrame.h index 01a2011..6a4f89d 100644 --- a/include/ctre/phoenix/motorcontrol/StatusFrame.h +++ b/include/ctre/phoenix/motorcontrol/StatusFrame.h @@ -58,6 +58,11 @@ enum StatusFrameEnhanced { /** * Firmware & API status information */ + Status_15_FirmwareApiStatus = 0x1780, + /** + * Firmware & API status information + * [[deprecated("Use Status_15_FirmwareApiStatus instead.")]] + */ Status_15_FirmareApiStatus = 0x1780, /** * MotionProfile Targets for Auxiliary PID1. @@ -137,6 +142,11 @@ enum StatusFrame { /** * Firmware & API status information */ + Status_15_FirmwareApiStatus_ = 0x1780, + /** + * Firmware & API status information + * [[deprecated("Use Status_15_FirmwareApiStatus_ instead.")]] + */ Status_15_FirmareApiStatus_ = 0x1780, /** * MotionProfile Targets for Auxiliary PID1. diff --git a/include/ctre/phoenix/motorcontrol/TalonFXSensorCollection.h b/include/ctre/phoenix/motorcontrol/TalonFXSensorCollection.h index 2ad0160..98aff87 100644 --- a/include/ctre/phoenix/motorcontrol/TalonFXSensorCollection.h +++ b/include/ctre/phoenix/motorcontrol/TalonFXSensorCollection.h @@ -39,6 +39,9 @@ namespace ctre { * Get the IntegratedSensor position of the Talon FX, regardless of whether * it is actually being used for feedback. The units are 2048 per rotation. * Note : Future versions of software may support scaling features (rotations, radians, degrees, etc) depending on the configuration. + * + * This method relies on the Status 21 message, which has a default period of 240ms. For more + * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html * * @return the IntegratedSensor position. */ @@ -49,6 +52,9 @@ namespace ctre { * it is actually being used for feedback. This will be within one rotation (2048 units). * The signage and range will depend on the configuration. * Note : Future versions of software may support scaling features (rotations, radians, degrees, etc) depending on the configuration. + * + * This method relies on the Status 21 message, which has a default period of 240ms. For more + * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html * * @return the IntegratedSensor absolute position. */ @@ -60,6 +66,9 @@ namespace ctre { * One unit represents one position unit per 100ms (2048 position units per 100ms). * The signage and range will depend on the configuration. * Note : Future versions of software may support scaling features (rotations, radians, degrees, etc) depending on the configuration. + * + * This method relies on the Status 21 message, which has a default period of 240ms. For more + * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html * * @return the IntegratedSensor velocity. */ @@ -95,6 +104,9 @@ namespace ctre { /** * Is forward limit switch closed. + * + * This method relies on the Status 1 message, which has a default period of 10ms. For more + * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html * * @return '1' iff forward limit switch is closed, 0 iff switch is open. This function works * regardless if limit switch feature is enabled. Remote limit features do not impact this routine. @@ -104,6 +116,9 @@ namespace ctre { /** * Is reverse limit switch closed. + * + * This method relies on the Status 1 message, which has a default period of 10ms. For more + * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html * * @return '1' iff reverse limit switch is closed, 0 iff switch is open. This function works * regardless if limit switch feature is enabled. Remote limit features do not impact this routine. diff --git a/include/ctre/phoenix/motorcontrol/TalonFXSimCollection.h b/include/ctre/phoenix/motorcontrol/TalonFXSimCollection.h new file mode 100644 index 0000000..a81a173 --- /dev/null +++ b/include/ctre/phoenix/motorcontrol/TalonFXSimCollection.h @@ -0,0 +1,145 @@ +#pragma once + +#include "ctre/phoenix/ErrorCode.h" + +/* forward proto's */ +namespace ctre { + namespace phoenix { + namespace motorcontrol { + namespace can { + class BaseTalon; + } + } + } +} + +namespace ctre { + namespace phoenix { + namespace motorcontrol { + + /** + * Collection of simulation commands available to a TalonFX motor controller. + * + * Use the getSimCollection() routine inside your motor controller to create the respective sim collection. + */ + class TalonFXSimCollection { + public: + /** + * Constructor for TalonFXSimCollection + * @param motorController TalonFX Motor Controller to connect Collection to + */ + TalonFXSimCollection(ctre::phoenix::motorcontrol::can::BaseTalon& motorController); + + /** + * 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. + */ + ErrorCode GetLastError(); + + /** + * Gets the simulated output voltage across M+ and M- for the motor. + * + * @return applied voltage to the motor in volts + */ + double GetMotorOutputLeadVoltage(); + + /** + * Sets the simulated bus voltage of the TalonFX. + * + * The minimum allowed bus voltage is 4 V - values + * below this will be promoted to 4 V. + * + * @param vbat the bus voltage in volts + * + * @return error code + */ + ErrorCode SetBusVoltage(double vbat); + + /** + * Sets the simulated supply current of the TalonFX. + * + * @param currA the supply current in amps + * + * @return error code + */ + ErrorCode SetSupplyCurrent(double currA); + + /** + * Sets the simulated stator current of the TalonFX. + * + * @param currA the stator current in amps + * + * @return error code + */ + ErrorCode SetStatorCurrent(double currA); + + /** + * Sets the simulated forward limit switch of the TalonFX. + * + * @param isClosed true if the limit switch is closed + * + * @return error code + */ + ErrorCode SetLimitFwd(bool isClosed); + + /** + * Sets the simulated reverse limit switch of the TalonFX. + * + * @param isClosed true if the limit switch is closed + * + * @return error code + */ + ErrorCode SetLimitRev(bool isClosed); + + /** + * Sets the simulated raw integrated sensor position of the TalonFX. + * + * The TalonFX integrates this to calculate the true reported integrated sensor + * position. + * + * When using the WPI Sim GUI, you will notice a readonly 'position' and + * settable 'rawPositionInput'. The readonly signal is the emulated position + * which will match self-test in Tuner and the hardware API. Changes to + * 'rawPositionInput' will be integrated into the emulated position. This way + * a simulator can modify the position without overriding your + * hardware API calls for home-ing your sensor. + * + * Inputs to this function over time should be continuous, + * as user calls of SetSelectedSensorPosition() and SetIntegratedSensorPosition() + * will be accounted for in the calculation. + * + * @param newPos the new raw position in native units + * + * @return error code + */ + ErrorCode SetIntegratedSensorRawPosition(int newPos); + + /** + * Adds to the simulated integrated sensor position of the TalonFX. + * + * @param dPos the change in position in native units + * + * @return error code + */ + ErrorCode AddIntegratedSensorPosition(int dPos); + + /** + * Sets the simulated integrated sensor velocity of the TalonFX. + * + * @param newVel the new velocity in native units per 100ms + * + * @return error code + */ + ErrorCode SetIntegratedSensorVelocity(int newVel); + + private: + int _id; + + }; + + } // namespace motorcontrol + } // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/motorcontrol/TalonSRXSimCollection.h b/include/ctre/phoenix/motorcontrol/TalonSRXSimCollection.h new file mode 100644 index 0000000..ce857cc --- /dev/null +++ b/include/ctre/phoenix/motorcontrol/TalonSRXSimCollection.h @@ -0,0 +1,217 @@ +#pragma once + +#include "ctre/phoenix/ErrorCode.h" + +/* forward proto's */ +namespace ctre { + namespace phoenix { + namespace motorcontrol { + namespace can { + class BaseTalon; + } + } + } +} + +namespace ctre { + namespace phoenix { + namespace motorcontrol { + + /** + * Collection of simulation commands available to a TalonSRX motor controller. + * + * Use the getSimCollection() routine inside your motor controller to create the respective sim collection. + */ + class TalonSRXSimCollection { + public: + /** + * Constructor for TalonSRXSimCollection + * @param motorController TalonSRX Motor Controller to connect Collection to + */ + TalonSRXSimCollection(ctre::phoenix::motorcontrol::can::BaseTalon& motorController); + + /** + * 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. + */ + ErrorCode GetLastError(); + + /** + * Gets the simulated output voltage across M+ and M- for the motor. + * + * @return applied voltage to the motor in volts + */ + double GetMotorOutputLeadVoltage(); + + /** + * Sets the simulated bus voltage of the TalonSRX. + * + * The minimum allowed bus voltage is 4 V - values + * below this will be promoted to 4 V. + * + * @param vbat the bus voltage in volts + * + * @return error code + */ + ErrorCode SetBusVoltage(double vbat); + + /** + * Sets the simulated supply current of the TalonSRX. + * + * @param currA the supply current in amps + * + * @return error code + */ + ErrorCode SetSupplyCurrent(double currA); + + /** + * Sets the simulated stator current of the TalonSRX. + * + * @param currA the stator current in amps + * + * @return error code + */ + ErrorCode SetStatorCurrent(double currA); + + /** + * Sets the simulated forward limit switch of the TalonSRX. + * + * @param isClosed true if the limit switch is closed + * + * @return error code + */ + ErrorCode SetLimitFwd(bool isClosed); + + /** + * Sets the simulated reverse limit switch of the TalonSRX. + * + * @param isClosed true if the limit switch is closed + * + * @return error code + */ + ErrorCode SetLimitRev(bool isClosed); + + /** + * Sets the simulated analog position of the TalonSRX. + * + * @param newPos the new position in native units + * + * @return error code + */ + ErrorCode SetAnalogPosition(int newPos); + + /** + * Adds to the simulated analog position of the TalonSRX. + * + * @param dPos the change in position in native units + * + * @return error code + */ + ErrorCode AddAnalogPosition(int dPos); + + /** + * Sets the simulated analog velocity of the TalonSRX. + * + * @param newVel the new velocity in native units per 100ms + * + * @return error code + */ + ErrorCode SetAnalogVelocity(int newVel); + + /** + * Sets if the simulated pulse width sensor is connected to the TalonSRX. + * + * @param isConnected true if the pulse width sensor is connected + * + * @return error code + */ + ErrorCode SetPulseWidthConnected(bool isConnected); + + /** + * Sets the simulated pulse width rise to rise time of the TalonSRX. + * + * @param periodUs the pulse width rise to rise time in microseconds + * + * @return error code + */ + ErrorCode SetPulseWidthRiseToRiseUs(double periodUs); + + /** + * Sets the simulated pulse width position of the TalonSRX. + * + * @param newPos the new position in native units + * + * @return error code + */ + ErrorCode SetPulseWidthPosition(int newPos); + + /** + * Adds to the simulated pulse width position of the TalonSRX. + * + * @param dPos the change in position in native units + * + * @return error code + */ + ErrorCode AddPulseWidthPosition(int dPos); + + /** + * Sets the simulated pulse width velocity of the TalonSRX. + * + * @param newVel the new velocity in native units per 100ms + * + * @return error code + */ + ErrorCode SetPulseWidthVelocity(int newVel); + + /** + * Sets the simulated raw quadrature position of the TalonSRX. + * + * The TalonSRX integrates this to calculate the true reported quadrature + * position. + * + * When using the WPI Sim GUI, you will notice a readonly 'position' and + * settable 'rawPositionInput'. The readonly signal is the emulated position + * which will match self-test in Tuner and the hardware API. Changes to + * 'rawPositionInput' will be integrated into the emulated position. This way + * a simulator can modify the position without overriding your + * hardware API calls for home-ing your sensor. + * + * Inputs to this function over time should be continuous, + * as user calls of SetSelectedSensorPosition() and SetQuadraturePosition() + * will be accounted for in the calculation. + * + * @param newPos the new raw position in native units + * + * @return error code + */ + ErrorCode SetQuadratureRawPosition(int newPos); + + /** + * Adds to the simulated quadrature position of the TalonSRX. + * + * @param dPos the change in position in native units + * + * @return error code + */ + ErrorCode AddQuadraturePosition(int dPos); + + /** + * Sets the simulated quadrature velocity of the TalonSRX. + * + * @param newVel the new velocity in native units per 100ms + * + * @return error code + */ + ErrorCode SetQuadratureVelocity(int newVel); + + private: + int _id; + + }; + + } // namespace motorcontrol + } // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/motorcontrol/VictorSPXSimCollection.h b/include/ctre/phoenix/motorcontrol/VictorSPXSimCollection.h new file mode 100644 index 0000000..72cab27 --- /dev/null +++ b/include/ctre/phoenix/motorcontrol/VictorSPXSimCollection.h @@ -0,0 +1,68 @@ +#pragma once + +#include "ctre/phoenix/ErrorCode.h" + +/* forward proto's */ +namespace ctre { + namespace phoenix { + namespace motorcontrol { + namespace can { + class BaseMotorController; + } + } + } +} + +namespace ctre { + namespace phoenix { + namespace motorcontrol { + + /** + * Collection of simulation commands available to a VictorSPX motor controller. + * + * Use the getSimCollection() routine inside your motor controller to create the respective sim collection. + */ + class VictorSPXSimCollection { + public: + /** + * Constructor for VictorSPXSimCollection + * @param motorController VictorSPX Motor Controller to connect Collection to + */ + VictorSPXSimCollection(ctre::phoenix::motorcontrol::can::BaseMotorController& motorController); + + /** + * 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. + */ + ErrorCode GetLastError(); + + /** + * Gets the simulated output voltage across M+ and M- for the motor. + * + * @return applied voltage to the motor in volts + */ + double GetMotorOutputLeadVoltage(); + + /** + * Sets the simulated bus voltage of the VictorSPX. + * + * The minimum allowed bus voltage is 4 V - values + * below this will be promoted to 4 V. + * + * @param vbat the bus voltage in volts + * + * @return error code + */ + ErrorCode SetBusVoltage(double vbat); + + private: + int _id; + + }; + + } // namespace motorcontrol + } // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/motorcontrol/can/BaseMotorController.h b/include/ctre/phoenix/motorcontrol/can/BaseMotorController.h index 8188ba0..512112b 100644 --- a/include/ctre/phoenix/motorcontrol/can/BaseMotorController.h +++ b/include/ctre/phoenix/motorcontrol/can/BaseMotorController.h @@ -16,6 +16,8 @@ #include "ctre/phoenix/motion/BufferedTrajectoryPointStream.h" #include "ctre/phoenix/CANBusAddressable.h" #include "ctre/phoenix/CustomParamConfiguration.h" +#include "ctre/phoenix/motorcontrol/VictorSPXSimCollection.h" +#include "ctre/phoenix/sensors/SensorVelocityMeasPeriod.h" #include @@ -179,12 +181,12 @@ namespace ctre { * accumulator is automatically cleared. This ensures than integral wind up * events will stop after the sensor gets far enough from its target. */ - int integralZone; + double integralZone; /** * Allowable closed loop error to neutral (in native units) * */ - int allowableClosedloopError; + double allowableClosedloopError; /** * Max integral accumulator (in native units) */ @@ -203,8 +205,8 @@ namespace ctre { kI(0.0), kD(0.0), kF(0.0), - integralZone(0), - allowableClosedloopError(0), + integralZone(0.0), + allowableClosedloopError(0.0), maxIntegralAccumulator(0.0), closedLoopPeakOutput(1.0), closedLoopPeriod(1) @@ -313,7 +315,7 @@ namespace ctre { /** * Desired period for velocity measurement */ - VelocityMeasPeriod velocityMeasurementPeriod; + ctre::phoenix::sensors::SensorVelocityMeasPeriod velocityMeasurementPeriod; /** * Desired window for velocity measurement */ @@ -321,11 +323,11 @@ namespace ctre { /** * Threshold for soft limits in forward direction (in raw sensor units) */ - int forwardSoftLimitThreshold; + double forwardSoftLimitThreshold; /** * Threshold for soft limits in reverse direction (in raw sensor units) */ - int reverseSoftLimitThreshold; + double reverseSoftLimitThreshold; /** * Enable forward soft limit */ @@ -373,11 +375,11 @@ namespace ctre { /** * Motion Magic cruise velocity in raw sensor units per 100 ms. */ - int motionCruiseVelocity; + double motionCruiseVelocity; /** * Motion Magic acceleration in (raw sensor units per 100 ms) per second. */ - int motionAcceleration; + double motionAcceleration; /** * Zero to use trapezoidal motion during motion magic. [1,8] for S-Curve, higher value for greater smoothing. */ @@ -440,15 +442,15 @@ namespace ctre { neutralDeadband(41.0 / 1023.0), voltageCompSaturation(0.0), voltageMeasurementFilter(32), - velocityMeasurementPeriod(Period_100Ms), + velocityMeasurementPeriod(ctre::phoenix::sensors::SensorVelocityMeasPeriod::Period_100Ms), velocityMeasurementWindow(64), - forwardSoftLimitThreshold(0), - reverseSoftLimitThreshold(0), + forwardSoftLimitThreshold(0.0), + reverseSoftLimitThreshold(0.0), forwardSoftLimitEnable(false), reverseSoftLimitEnable(false), auxPIDPolarity(false), - motionCruiseVelocity(0), - motionAcceleration(0), + motionCruiseVelocity(0.0), + motionAcceleration(0.0), motionCurveStrength(0), motionProfileTrajectoryPeriod(0), feedbackNotContinuous(false), @@ -488,7 +490,7 @@ namespace ctre { retstr += prependString + ".neutralDeadband = " + std::to_string(neutralDeadband) + ";\n"; retstr += prependString + ".voltageCompSaturation = " + std::to_string(voltageCompSaturation) + ";\n"; retstr += prependString + ".voltageMeasurementFilter = " + std::to_string(voltageMeasurementFilter) + ";\n"; - retstr += prependString + ".velocityMeasurementPeriod = " + VelocityMeasPeriodRoutines::toString(velocityMeasurementPeriod) + ";\n"; + retstr += prependString + ".velocityMeasurementPeriod = " + ctre::phoenix::sensors::SensorVelocityMeasPeriodRoutines::toString(velocityMeasurementPeriod) + ";\n"; retstr += prependString + ".velocityMeasurementWindow = " + std::to_string(velocityMeasurementWindow) + ";\n"; retstr += prependString + ".forwardSoftLimitThreshold = " + std::to_string(forwardSoftLimitThreshold) + ";\n"; retstr += prependString + ".reverseSoftLimitThreshold = " + std::to_string(reverseSoftLimitThreshold) + ";\n"; @@ -590,7 +592,11 @@ namespace ctre { bool _isVcompEn = false; + ctre::phoenix::motorcontrol::VictorSPXSimCollection* _simCollSpx; + protected: + ctre::phoenix::motorcontrol::VictorSPXSimCollection& GetVictorSPXSimCollection() { return *_simCollSpx; } + /** * Configures all base persistant settings. * @@ -642,10 +648,12 @@ namespace ctre { * Constructor for motor controllers. * * @param arbId Device ID [0,62] - * @param model String model of device. + * @param model String model of device. * Examples: "Talon SRX", "Talon FX", "Victor SPX". + * @param canbus Name of the CANbus; can be a SocketCAN interface (on Linux), + * or a CANivore device name or serial number */ - BaseMotorController(int deviceNumber, const char* model); + BaseMotorController(int deviceNumber, const char* model, std::string const &canbus = ""); virtual ~BaseMotorController(); BaseMotorController() = delete; BaseMotorController(BaseMotorController const&) = delete; @@ -682,23 +690,6 @@ namespace ctre { * _talonRght.set(ControlMode.PercentOutput, rghtJoy); */ virtual void Set(ControlMode mode, double value); - /** - * @deprecated use 4 parameter set - * @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. - */ - [[deprecated("Use 4-paremeter Set() instead.")]] - virtual void Set(ControlMode mode, double demand0, double demand1); /** * @param mode Sets the appropriate output on the talon, depending on the mode. * @param demand0 The output value to apply. @@ -750,23 +741,6 @@ namespace ctre { * throttle is neutral (ie brake/coast) **/ virtual void SetNeutralMode(NeutralMode neutralMode); - /** - * 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 - * @deprecated This has been replaced with the 4 param Set. - */ - void EnableHeadingHold(bool enable); - /** - * 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 - * @deprecated This has been replaced with the 4 param Set. - */ - void SelectDemandType(bool value); //------ Invert behavior ----------// /** * Sets the phase of the sensor. Use when controller forward/reverse output @@ -960,7 +934,7 @@ namespace ctre { virtual void EnableVoltageCompensation(bool enable); /** * Returns the enable state of Voltage Compensation that the caller has set. - * + * * @return TRUE if voltage compensation is enabled. */ virtual bool IsVoltageCompensationEnabled(); @@ -1080,6 +1054,23 @@ namespace ctre { * @return Error Code generated by function. 0 indicates no error. */ virtual ErrorCode ConfigRemoteFeedbackFilter(ctre::phoenix::sensors::CANCoder &canCoderRef, int remoteOrdinal, int timeoutMs = 0); + /** + * 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 talonRef + * Talon device reference to use. + * @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. + */ + virtual ErrorCode ConfigRemoteFeedbackFilter(ctre::phoenix::motorcontrol::can::BaseTalon &talonRef, int remoteOrdinal, int timeoutMs = 0); /** * Select what sensor term should be bound to switch feedback device. * Sensor Sum = Sensor Sum Term 0 - Sensor Sum Term 1 @@ -1125,7 +1116,7 @@ namespace ctre { * * @return Position of selected sensor (in raw sensor units). */ - virtual int GetSelectedSensorPosition(int pidIdx = 0); + virtual double GetSelectedSensorPosition(int pidIdx = 0); /** * Get the selected sensor velocity. * @@ -1134,7 +1125,7 @@ namespace ctre { * @return selected sensor (in raw sensor units) per 100ms. * See Phoenix-Documentation for how to interpret. */ - virtual int GetSelectedSensorVelocity(int pidIdx = 0); + virtual double GetSelectedSensorVelocity(int pidIdx = 0); /** * Sets the sensor position to the given value. * @@ -1148,7 +1139,7 @@ namespace ctre { * If zero, no blocking or checking is performed. * @return Error Code generated by function. 0 indicates no error. */ - virtual ctre::phoenix::ErrorCode SetSelectedSensorPosition(int sensorPos, int pidIdx = 0, int timeoutMs = 50); + virtual ctre::phoenix::ErrorCode SetSelectedSensorPosition(double sensorPos, int pidIdx = 0, int timeoutMs = 50); //------ status frame period changes ----------// /** * Sets the period of the given control frame. @@ -1232,13 +1223,17 @@ namespace ctre { * * @param period * Desired period for the velocity measurement. @see - * #VelocityMeasPeriod + * #SensorVelocityMeasPeriod * @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. */ + virtual ctre::phoenix::ErrorCode ConfigVelocityMeasurementPeriod(ctre::phoenix::sensors::SensorVelocityMeasPeriod period, + int timeoutMs = 0); + + [[deprecated("Use the overload with SensorVelocityMeasPeriod instead.")]] virtual ctre::phoenix::ErrorCode ConfigVelocityMeasurementPeriod(VelocityMeasPeriod period, int timeoutMs = 0); /** @@ -1370,7 +1365,7 @@ namespace ctre { * If zero, no blocking or checking is performed. * @return Error Code generated by function. 0 indicates no error. */ - virtual ctre::phoenix::ErrorCode ConfigForwardSoftLimitThreshold(int forwardSensorLimit, + virtual ctre::phoenix::ErrorCode ConfigForwardSoftLimitThreshold(double forwardSensorLimit, int timeoutMs = 0); /** * Configures the reverse soft limit threshold. @@ -1383,7 +1378,7 @@ namespace ctre { * If zero, no blocking or checking is performed. * @return Error Code generated by function. 0 indicates no error. */ - virtual ctre::phoenix::ErrorCode ConfigReverseSoftLimitThreshold(int reverseSensorLimit, + virtual ctre::phoenix::ErrorCode ConfigReverseSoftLimitThreshold(double reverseSensorLimit, int timeoutMs = 0); /** * Configures the forward soft limit enable. @@ -1511,7 +1506,7 @@ namespace ctre { * blocking or checking is performed. * @return Error Code generated by function. 0 indicates no error. */ - virtual ctre::phoenix::ErrorCode Config_IntegralZone(int slotIdx, int izone, + virtual ctre::phoenix::ErrorCode Config_IntegralZone(int slotIdx, double izone, int timeoutMs = 0); /** * Sets the allowable closed-loop error in the given parameter slot. @@ -1527,7 +1522,7 @@ namespace ctre { * @return Error Code generated by function. 0 indicates no error. */ virtual ctre::phoenix::ErrorCode ConfigAllowableClosedloopError(int slotIdx, - int allowableCloseLoopError, int timeoutMs = 0); + double allowableCloseLoopError, int timeoutMs = 0); /** * Sets the maximum integral accumulator in the given parameter slot. * @@ -1636,7 +1631,7 @@ namespace ctre { * 0 for Primary closed-loop. 1 for auxiliary closed-loop. * @return Closed-loop error value. */ - virtual int GetClosedLoopError(int pidIdx = 0); + virtual double GetClosedLoopError(int pidIdx = 0); /** * Gets the iaccum value. * @@ -1677,14 +1672,14 @@ namespace ctre { * MotionMagic/MotionProfile control modes. * * @return The Active Trajectory Position in sensor units. - */ virtual int GetActiveTrajectoryPosition(int pidIdx = 0); + */ virtual double GetActiveTrajectoryPosition(int pidIdx = 0); /** * Gets the active trajectory target velocity using * MotionMagic/MotionProfile control modes. * * @return The Active Trajectory Velocity in sensor units per 100ms. */ - virtual int GetActiveTrajectoryVelocity(int pidIdx = 0); /** + virtual double GetActiveTrajectoryVelocity(int pidIdx = 0); /** * Gets the active trajectory arbitrary feedforward using * MotionMagic/MotionProfile control modes. * @@ -1692,14 +1687,8 @@ namespace ctre { * 0 for Primary closed-loop. 1 for auxiliary closed-loop. * @return The Active Trajectory ArbFeedFwd in units of percent output * (where 0.01 is 1%). - */ virtual double GetActiveTrajectoryArbFeedFwd(int pidIdx = 0); /** - * Gets the active trajectory target heading using - * MotionMagicArc/MotionProfileArc control modes. - * - * @return The Active Trajectory Heading in degrees. */ - [[deprecated("Replaced by GetActiveTrajectoryPosition(1)")]] - virtual double GetActiveTrajectoryHeading(); + virtual double GetActiveTrajectoryArbFeedFwd(int pidIdx = 0); //------ Motion Profile Settings used in Motion Magic ----------// /** @@ -1714,7 +1703,7 @@ namespace ctre { * blocking or checking is performed. * @return Error Code generated by function. 0 indicates no error. */ - virtual ctre::phoenix::ErrorCode ConfigMotionCruiseVelocity(int sensorUnitsPer100ms, + virtual ctre::phoenix::ErrorCode ConfigMotionCruiseVelocity(double sensorUnitsPer100ms, int timeoutMs = 0); /** * Sets the Motion Magic Acceleration. This is the target acceleration that @@ -1729,7 +1718,7 @@ namespace ctre { * blocking or checking is performed. * @return Error Code generated by function. 0 indicates no error. */ - virtual ctre::phoenix::ErrorCode ConfigMotionAcceleration(int sensorUnitsPer100msPerSec, + virtual ctre::phoenix::ErrorCode ConfigMotionAcceleration(double sensorUnitsPer100msPerSec, int timeoutMs = 0); /** * Sets the Motion Magic S Curve Strength. diff --git a/include/ctre/phoenix/motorcontrol/can/BaseTalon.h b/include/ctre/phoenix/motorcontrol/can/BaseTalon.h index d6f4d1f..7e590e8 100644 --- a/include/ctre/phoenix/motorcontrol/can/BaseTalon.h +++ b/include/ctre/phoenix/motorcontrol/can/BaseTalon.h @@ -10,6 +10,8 @@ #include "ctre/phoenix/CustomParamConfiguration.h" #include "ctre/phoenix/motorcontrol/SensorCollection.h" #include "ctre/phoenix/motorcontrol/TalonFXSensorCollection.h" +#include "ctre/phoenix/motorcontrol/TalonSRXSimCollection.h" +#include "ctre/phoenix/motorcontrol/TalonFXSimCollection.h" /* forward proto's */ namespace ctre { @@ -33,9 +35,9 @@ namespace ctre { * Feedback device for a particular PID loop. * Note the FeedbackDevice enum holds all possible sensor types. Consult product documentation to confirm what is available. * Alternatively the product specific enum can be used instead. - * @code - * configs.primaryPID.selectedFeedbackSensor = (FeedbackDevice)TalonSRXFeedbackDevice::QuadEncoder; - * configs.primaryPID.selectedFeedbackSensor = (FeedbackDevice)TalonFXFeedbackDevice::IntegratedSensor; + * @code + * configs.primaryPID.selectedFeedbackSensor = (FeedbackDevice)TalonSRXFeedbackDevice::QuadEncoder; + * configs.primaryPID.selectedFeedbackSensor = (FeedbackDevice)TalonFXFeedbackDevice::IntegratedSensor; * @endcode */ FeedbackDevice selectedFeedbackSensor; @@ -135,9 +137,9 @@ namespace ctre { * Feedback Device for Sum 0 Term * Note the FeedbackDevice enum holds all possible sensor types. Consult product documentation to confirm what is available. * Alternatively the product specific enum can be used instead. - * @code - * configs.sum0Term = (FeedbackDevice)TalonSRXFeedbackDevice::QuadEncoder; - * configs.sum0Term = (FeedbackDevice)TalonFXFeedbackDevice::IntegratedSensor; + * @code + * configs.sum0Term = (FeedbackDevice)TalonSRXFeedbackDevice::QuadEncoder; + * configs.sum0Term = (FeedbackDevice)TalonFXFeedbackDevice::IntegratedSensor; * @endcode */ FeedbackDevice sum0Term; @@ -145,9 +147,9 @@ namespace ctre { * Feedback Device for Sum 1 Term * Note the FeedbackDevice enum holds all possible sensor types. Consult product documentation to confirm what is available. * Alternatively the product specific enum can be used instead. - * @code - * configs.sum1Term = (FeedbackDevice)TalonSRXFeedbackDevice::QuadEncoder; - * configs.sum1Term = (FeedbackDevice)TalonFXFeedbackDevice::IntegratedSensor; + * @code + * configs.sum1Term = (FeedbackDevice)TalonSRXFeedbackDevice::QuadEncoder; + * configs.sum1Term = (FeedbackDevice)TalonFXFeedbackDevice::IntegratedSensor; * @endcode */ FeedbackDevice sum1Term; @@ -155,9 +157,9 @@ namespace ctre { * Feedback Device for Diff 0 Term * Note the FeedbackDevice enum holds all possible sensor types. Consult product documentation to confirm what is available. * Alternatively the product specific enum can be used instead. - * @code - * configs.diff0Term = (FeedbackDevice)TalonSRXFeedbackDevice::QuadEncoder; - * configs.diff0Term = (FeedbackDevice)TalonFXFeedbackDevice::IntegratedSensor; + * @code + * configs.diff0Term = (FeedbackDevice)TalonSRXFeedbackDevice::QuadEncoder; + * configs.diff0Term = (FeedbackDevice)TalonFXFeedbackDevice::IntegratedSensor; * @endcode */ FeedbackDevice diff0Term; @@ -165,9 +167,9 @@ namespace ctre { * Feedback Device for Diff 1 Term * Note the FeedbackDevice enum holds all possible sensor types. Consult product documentation to confirm what is available. * Alternatively the product specific enum can be used instead. - * @code - * configs.diff1Term = (FeedbackDevice)TalonSRXFeedbackDevice::QuadEncoder; - * configs.diff1Term = (FeedbackDevice)TalonFXFeedbackDevice::IntegratedSensor; + * @code + * configs.diff1Term = (FeedbackDevice)TalonSRXFeedbackDevice::QuadEncoder; + * configs.diff1Term = (FeedbackDevice)TalonFXFeedbackDevice::IntegratedSensor; * @endcode */ FeedbackDevice diff1Term; @@ -266,10 +268,16 @@ namespace ctre { ctre::phoenix::motorcontrol::SensorCollection* _sensorCollSrx; ctre::phoenix::motorcontrol::TalonFXSensorCollection* _sensorCollFx; + ctre::phoenix::motorcontrol::TalonSRXSimCollection* _simCollSrx; + ctre::phoenix::motorcontrol::TalonFXSimCollection* _simCollFx; + protected: ctre::phoenix::motorcontrol::SensorCollection& GetTalonSRXSensorCollection() { return *_sensorCollSrx; } ctre::phoenix::motorcontrol::TalonFXSensorCollection& GetTalonFXSensorCollection() { return *_sensorCollFx; } + ctre::phoenix::motorcontrol::TalonSRXSimCollection& GetTalonSRXSimCollection() { return *_simCollSrx; } + ctre::phoenix::motorcontrol::TalonFXSimCollection& GetTalonFXSimCollection() { return *_simCollFx; } + ctre::phoenix::ErrorCode ConfigurePID(const BaseTalonPIDSetConfiguration& pid, int pidIdx, int timeoutMs, bool enableOptimizations); @@ -311,8 +319,10 @@ namespace ctre { /** * Constructor for a Talon * @param deviceNumber CAN Device ID of BaseTalon + * @param canbus Name of the CANbus; can be a SocketCAN interface (on Linux), + * or a CANivore device name or serial number */ - BaseTalon(int deviceNumber, const char* model); + BaseTalon(int deviceNumber, const char* model, std::string const &canbus = ""); virtual ~BaseTalon(); BaseTalon() = delete; BaseTalon(BaseTalon const&) = delete; @@ -450,13 +460,17 @@ namespace ctre { * * @param period * Desired period for the velocity measurement. @see - * #VelocityMeasPeriod + * #SensorVelocityMeasPeriod * @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. */ + virtual ctre::phoenix::ErrorCode ConfigVelocityMeasurementPeriod(ctre::phoenix::sensors::SensorVelocityMeasPeriod period, + int timeoutMs = 0); + + [[deprecated("Use the overload with SensorVelocityMeasPeriod instead.")]] virtual ctre::phoenix::ErrorCode ConfigVelocityMeasurementPeriod(VelocityMeasPeriod period, int timeoutMs = 0); /** @@ -581,7 +595,7 @@ namespace ctre { LimitSwitchNormal normalOpenOrClose, int deviceID, int timeoutMs = 0); //------ Current Limit ----------// - virtual ctre::phoenix::ErrorCode ConfigSupplyCurrentLimit(const SupplyCurrentLimitConfiguration& currLimitConfigs, int timeoutMs = 0) = 0; + virtual ctre::phoenix::ErrorCode ConfigSupplyCurrentLimit(const SupplyCurrentLimitConfiguration& currLimitConfigs, int timeoutMs = 50); //------ RAW Sensor API ----------// /** diff --git a/include/ctre/phoenix/motorcontrol/can/TalonFX.h b/include/ctre/phoenix/motorcontrol/can/TalonFX.h index 02d1708..975e751 100644 --- a/include/ctre/phoenix/motorcontrol/can/TalonFX.h +++ b/include/ctre/phoenix/motorcontrol/can/TalonFX.h @@ -121,6 +121,33 @@ namespace ctre { /** * CTRE Talon FX Motor Controller when used on CAN Bus. + * + *
+				 * {@code
+				 * // Example usage of a TalonFX motor controller
+				 * TalonFX motor{0}; // creates a new TalonFX with ID 0
+				 *
+				 * TalonFXConfiguration config;
+				 * config.supplyCurrLimit.enable = true;
+				 * config.supplyCurrLimit.triggerThresholdCurrent = 40; // the peak supply current, in amps
+				 * config.supplyCurrLimit.triggerThresholdTime = 1.5; // the time at the peak supply current before the limit triggers, in sec
+				 * config.supplyCurrLimit.currentLimit = 30; // the current to maintain if the peak supply limit is triggered
+				 * motor.ConfigAllSettings(config); // apply the config settings; this selects the quadrature encoder
+				 *
+				 * motor.Set(TalonFXControlMode::PercentOutput, 0.5); // runs the motor at 50% power
+				 *
+				 * std::cout << motor.GetSelectedSensorPosition() << std::endl; // prints the position of the selected sensor
+				 * std::cout << motor.GetSelectedSensorVelocity() << std::endl; // prints the velocity recorded by the selected sensor
+				 * std::cout << motor.GetMotorOutputPercent() << std::endl; // prints the percent output of the motor (0.5)
+				 * std::cout << motor.GetStatorCurrent() << std::endl; // prints the output current of the motor
+				 *
+				 * ErrorCode error = motor.GetLastError(); // gets the last error generated by the motor controller
+				 * Faults faults;
+				 * ErrorCode faultsError = motor.GetFaults(faults); // fills faults with the current motor controller faults; returns the last error generated
+				 *
+				 * motor.SetStatusFramePeriod(StatusFrameEnhanced::Status_2_Feedback0, 10); // changes the period of the Status 2 frame (GetSelectedSensor*()) to 10ms
+				 * }
+				 * 
*/ class TalonFX : public virtual BaseTalon { @@ -130,8 +157,10 @@ namespace ctre { /** * Constructor for a Talon * @param deviceNumber CAN Device ID of TalonFX + * @param canbus Name of the CANbus; can be a SocketCAN interface (on Linux), + * or a CANivore device name or serial number */ - TalonFX(int deviceNumber); + TalonFX(int deviceNumber, std::string const &canbus = ""); ~TalonFX(); TalonFX() = delete; TalonFX(TalonFX const&) = delete; @@ -271,6 +300,13 @@ namespace ctre { * @return object that can get/set individual RAW sensor values. */ ctre::phoenix::motorcontrol::TalonFXSensorCollection& GetSensorCollection(); + + //------ Simulation API ----------// + /** + * @return object that can set simulation inputs. + */ + ctre::phoenix::motorcontrol::TalonFXSimCollection& GetSimCollection(); + //------ All Configs ----------// /** diff --git a/include/ctre/phoenix/motorcontrol/can/TalonSRX.h b/include/ctre/phoenix/motorcontrol/can/TalonSRX.h index 4aa11a4..5e78953 100644 --- a/include/ctre/phoenix/motorcontrol/can/TalonSRX.h +++ b/include/ctre/phoenix/motorcontrol/can/TalonSRX.h @@ -13,6 +13,7 @@ namespace ctre { namespace phoenix { namespace motorcontrol { class SensorCollection; + class TalonSRXSimCollection; } } } @@ -112,6 +113,32 @@ namespace ctre { /** * CTRE Talon SRX Motor Controller when used on CAN Bus. + * + *
+				 * {@code
+				 * // Example usage of a TalonSRX motor controller
+				 * TalonSRX motor{0}; // creates a new TalonSRX with ID 0
+				 *
+				 * TalonSRXConfiguration config;
+				 * config.peakCurrentLimit = 40; // the peak current, in amps
+				 * config.peakCurrentDuration = 1500; // the time at the peak current before the limit triggers, in ms
+				 * config.continuousCurrentLimit = 30; // the current to maintain if the peak limit is triggered
+				 * motor.ConfigAllSettings(config); // apply the config settings; this selects the quadrature encoder
+				 *
+				 * motor.Set(TalonSRXControlMode::PercentOutput, 0.5); // runs the motor at 50% power
+				 *
+				 * std::cout << motor.GetSelectedSensorPosition() << std::endl; // prints the position of the selected sensor
+				 * std::cout << motor.GetSelectedSensorVelocity() << std::endl; // prints the velocity recorded by the selected sensor
+				 * std::cout << motor.GetMotorOutputPercent() << std::endl; // prints the percent output of the motor (0.5)
+				 * std::cout << motor.GetStatorCurrent() << std::endl; // prints the output current of the motor
+				 *
+				 * ErrorCode error = motor.GetLastError(); // gets the last error generated by the motor controller
+				 * Faults faults;
+				 * ErrorCode faultsError = motor.GetFaults(faults); // fills faults with the current motor controller faults; returns the last error generated
+				 *
+				 * motor.SetStatusFramePeriod(StatusFrameEnhanced::Status_2_Feedback0, 10); // changes the period of the Status 2 frame (GetSelectedSensor*()) to 10ms
+				 * }
+				 * 
*/ class TalonSRX : public virtual BaseTalon { @@ -123,6 +150,16 @@ namespace ctre { * @param deviceNumber CAN Device ID of TalonSRX */ TalonSRX(int deviceNumber); + +#ifndef __FRC_ROBORIO__ + /** + * Constructor so non-FRC platforms can specify a CAN 2.0 socketcan bus + * @param deviceNumber CAN Device ID of TalonSRX + * @param canbus String specifying the bus + */ + TalonSRX(int deviceNumber, std::string const &canbus); +#endif + ~TalonSRX(); TalonSRX() = delete; TalonSRX(TalonSRX const&) = delete; @@ -334,6 +371,12 @@ namespace ctre { */ ctre::phoenix::motorcontrol::SensorCollection& GetSensorCollection(); + //------ Simulation API ----------// + /** + * @return object that can set simulation inputs. + */ + ctre::phoenix::motorcontrol::TalonSRXSimCollection& GetSimCollection(); + //------ All Configs ----------// /** diff --git a/include/ctre/phoenix/motorcontrol/can/VictorSPX.h b/include/ctre/phoenix/motorcontrol/can/VictorSPX.h index 24f5fdf..0d0ee1f 100644 --- a/include/ctre/phoenix/motorcontrol/can/VictorSPX.h +++ b/include/ctre/phoenix/motorcontrol/can/VictorSPX.h @@ -205,6 +205,22 @@ class VictorConfigUtil { /** * VEX Victor SPX Motor Controller when used on CAN Bus. + * + *
+ * {@code
+ * // Example usage of a VictorSPX motor controller
+ * VictorSPX motor{0}; // creates a new VictorSPX with ID 0
+ *
+ * motor.Set(VictorSPXControlMode::PercentOutput, 0.5); // runs the motor at 50% power
+ *
+ * std::cout << motor.GetMotorOutputPercent() << std::endl; // prints the percent output of the motor (0.5)
+ * std::cout << motor.GetBusVoltage() << std::endl; // prints the bus voltage seen by the motor controller
+ *
+ * ErrorCode error = motor.GetLastError(); // gets the last error generated by the motor controller
+ * Faults faults;
+ * ErrorCode faultsError = motor.GetFaults(faults); // fills faults with the current motor controller faults; returns the last error generated
+ * }
+ * 
*/ class VictorSPX: public virtual ctre::phoenix::motorcontrol::can::BaseMotorController, public virtual ctre::phoenix::motorcontrol::IMotorController { @@ -230,6 +246,16 @@ class VictorSPX: public virtual ctre::phoenix::motorcontrol::can::BaseMotorContr * [0,62] */ VictorSPX(int deviceNumber); + +#ifndef __FRC_ROBORIO__ + /** + * Constructor so non-FRC platforms can specify a CAN 2.0 socketcan bus + * @param deviceNumber CAN Device ID of VictorSPX + * @param canbus String specifying the bus + */ + VictorSPX(int deviceNumber, std::string const &canbus); +#endif + virtual ~VictorSPX() { } VictorSPX(VictorSPX const&) = delete; @@ -293,6 +319,12 @@ class VictorSPX: public virtual ctre::phoenix::motorcontrol::can::BaseMotorContr */ void Set(ctre::phoenix::motorcontrol::VictorSPXControlMode mode, double demand0, ctre::phoenix::motorcontrol::DemandType demand1Type, double demand1); + //------ Simulation API ----------// + /** + * @return object that can set simulation inputs. + */ + ctre::phoenix::motorcontrol::VictorSPXSimCollection& GetSimCollection(); + //------ All Configs ----------// /** * Gets all PID set persistant settings. diff --git a/include/ctre/phoenix/motorcontrol/can/WPI_TalonSRX.h b/include/ctre/phoenix/motorcontrol/can/WPI_TalonSRX.h deleted file mode 100644 index c238473..0000000 --- a/include/ctre/phoenix/motorcontrol/can/WPI_TalonSRX.h +++ /dev/null @@ -1,128 +0,0 @@ -/** - * 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. - */ -#pragma once -#if defined(CTR_INCLUDE_WPILIB_CLASSES) || defined(__FRC_ROBORIO__) -#include "ctre/phoenix/MotorControl/CAN/TalonSRX.h" -#include "SmartDashboard/SendableBase.h" -#include "SmartDashboard/SendableBuilder.h" -#include "SpeedController.h" -#include "MotorSafety.h" -#include "MotorSafetyHelper.h" - -namespace ctre { -namespace phoenix { -namespace motorcontrol { -namespace can { - - -class WPI_TalonSRX: public virtual TalonSRX, - public virtual frc::SpeedController, - public frc::SendableBase, - public frc::MotorSafety { -public: - WPI_TalonSRX(int deviceNumber); - virtual ~WPI_TalonSRX(); - - WPI_TalonSRX() = delete; - WPI_TalonSRX(WPI_TalonSRX const&) = delete; - WPI_TalonSRX& operator=(WPI_TalonSRX const&) = delete; - - //----------------------- set/get routines for WPILIB interfaces -------------------// - /** - * Common interface for setting the speed of a simple speed controller. - * - * @param speed The speed to set. Value should be between -1.0 and 1.0. - * Value is also saved for Get(). - */ - virtual void Set(double speed); - virtual void PIDWrite(double 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. - */ - virtual double Get() const; - - //----------------------- Intercept CTRE calls for motor safety -------------------// - virtual void Set(ControlMode mode, double value); - virtual void Set(ControlMode mode, double demand0, double demand1); - //----------------------- Invert routines -------------------// - /** - * Common interface for inverting direction of a speed controller. - * - * @param isInverted The state of inversion, true is inverted. - */ - virtual void SetInverted(bool isInverted); - /** - * Common interface for returning the inversion state of a speed controller. - * - * @return isInverted The state of inversion, true is inverted. - */ - virtual bool GetInverted() const; - //----------------------- turn-motor-off routines-------------------// - /** - * Common interface for disabling a motor. - */ - virtual void Disable(); - /** - * Common interface to stop the motor until Set is called again. - */ - virtual void StopMotor(); - - //----------------------- Motor Safety-------------------// - - /** - * Set the safety expiration time. - * - * @param timeout The timeout (in seconds) for this motor object - */ - void SetExpiration(double timeout); - - /** - * Return the safety expiration time. - * - * @return The expiration time value. - */ - double GetExpiration() const; - - /** - * 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. - */ - bool IsAlive() const; - - /** - * Check if motor safety is enabled. - * - * @return True if motor safety is enforced for this object - */ - bool IsSafetyEnabled() const; - - void SetSafetyEnabled(bool enabled); - - void GetDescription(llvm::raw_ostream& desc) const; - -protected: - virtual void InitSendable(frc::SendableBuilder& builder); -private: - double _speed = 0; - std::string _desc; - frc::MotorSafetyHelper _safetyHelper; -}; - -} // namespace can -} // namespace motorcontrol -} // namespace phoenix -} // namespace ctre -#endif diff --git a/include/ctre/phoenix/motorcontrol/can/WPI_VictorSPX.h b/include/ctre/phoenix/motorcontrol/can/WPI_VictorSPX.h deleted file mode 100644 index fdae654..0000000 --- a/include/ctre/phoenix/motorcontrol/can/WPI_VictorSPX.h +++ /dev/null @@ -1,128 +0,0 @@ -/** - * 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. - */ -#pragma once -#if defined(CTR_INCLUDE_WPILIB_CLASSES) || defined(__FRC_ROBORIO__) -#include "ctre/phoenix/MotorControl/CAN/VictorSPX.h" -#include "SmartDashboard/SendableBase.h" -#include "SmartDashboard/SendableBuilder.h" -#include "SpeedController.h" -#include "MotorSafety.h" -#include "MotorSafetyHelper.h" - -namespace ctre { -namespace phoenix { -namespace motorcontrol { -namespace can { - - -class WPI_VictorSPX: public virtual VictorSPX, - public virtual frc::SpeedController, - public frc::SendableBase, - public frc::MotorSafety { -public: - WPI_VictorSPX(int deviceNumber); - virtual ~WPI_VictorSPX(); - - WPI_VictorSPX() = delete; - WPI_VictorSPX(WPI_VictorSPX const&) = delete; - WPI_VictorSPX& operator=(WPI_VictorSPX const&) = delete; - - //----------------------- set/get routines for WPILIB interfaces -------------------// - /** - * Common interface for setting the speed of a simple speed controller. - * - * @param speed The speed to set. Value should be between -1.0 and 1.0. - * Value is also saved for Get(). - */ - virtual void Set(double speed); - virtual void PIDWrite(double 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. - */ - virtual double Get() const; - - //----------------------- Intercept CTRE calls for motor safety -------------------// - virtual void Set(ControlMode mode, double value); - virtual void Set(ControlMode mode, double demand0, double demand1); - //----------------------- Invert routines -------------------// - /** - * Common interface for inverting direction of a speed controller. - * - * @param isInverted The state of inversion, true is inverted. - */ - virtual void SetInverted(bool isInverted); - /** - * Common interface for returning the inversion state of a speed controller. - * - * @return isInverted The state of inversion, true is inverted. - */ - virtual bool GetInverted() const; - //----------------------- turn-motor-off routines-------------------// - /** - * Common interface for disabling a motor. - */ - virtual void Disable(); - /** - * Common interface to stop the motor until Set is called again. - */ - virtual void StopMotor(); - - //----------------------- Motor Safety-------------------// - - /** - * Set the safety expiration time. - * - * @param timeout The timeout (in seconds) for this motor object - */ - void SetExpiration(double timeout); - - /** - * Return the safety expiration time. - * - * @return The expiration time value. - */ - double GetExpiration() const; - - /** - * 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. - */ - bool IsAlive() const; - - /** - * Check if motor safety is enabled. - * - * @return True if motor safety is enforced for this object - */ - bool IsSafetyEnabled() const; - - void SetSafetyEnabled(bool enabled); - - void GetDescription(llvm::raw_ostream& desc) const; - -protected: - virtual void InitSendable(frc::SendableBuilder& builder); -private: - double _speed = 0; - std::string _desc; - frc::MotorSafetyHelper _safetyHelper; -}; - -} // namespace can -} // namespace motorcontrol -} // namespace phoenix -} // namespace ctre -#endif diff --git a/include/ctre/phoenix/music/Orchestra.h b/include/ctre/phoenix/music/Orchestra.h index cc99355..5156531 100644 --- a/include/ctre/phoenix/music/Orchestra.h +++ b/include/ctre/phoenix/music/Orchestra.h @@ -58,7 +58,7 @@ namespace ctre { * The path to the Chirp File. * @return Error Code generated by function. 0 indicates no error. */ - ErrorCode LoadMusic(std::string& filePath); + ErrorCode LoadMusic(const std::string& filePath); /** * Plays the music file that's loaded. * If the player is paused, this will resume. @@ -84,6 +84,12 @@ namespace ctre { * @return True if playing, false otherwise */ bool IsPlaying(); + /** + * @return The current timestamp of the music file (playing or paused) in milliseconds. + * The timestamp will reset to zero whenever LoadMusic() or Stop() is called. + * If IsPlaying() returns false, this routine can be used to determine if music is stopped or paused. + */ + uint32_t GetCurrentTime(); /** * Adds another instrument to the orchestra. * @param instrument @@ -99,4 +105,4 @@ namespace ctre { }; } } -} \ No newline at end of file +} diff --git a/include/ctre/phoenix/paramEnum.h b/include/ctre/phoenix/paramEnum.h index d5d000d..eae7151 100644 --- a/include/ctre/phoenix/paramEnum.h +++ b/include/ctre/phoenix/paramEnum.h @@ -40,19 +40,6 @@ namespace ctre { eClearPositionOnLimitR = 321, eClearPositionOnQuadIdx = 322, - /* - *@deprecated use above - */ - eClearPosOnLimitF = eClearPositionOnLimitF, - /* - *@deprecated use above - */ - eClearPosOnLimitR = eClearPositionOnLimitR, - /* - *@deprecated use above - */ - eClearPositionOnIdx = eClearPositionOnQuadIdx, - eSampleVelocityPeriod = 325, eSampleVelocityWindow = 326, @@ -148,6 +135,49 @@ namespace ctre { eMagnetOffset, eSensorSync, eAbsSensorRange, + + /* Pigeon2 */ + eChangeCompassUse = 800, + eRestartKalman, + eAccNoiseAmplificationGain, + eMagNoiseAmplificationGain, + eGyrNoiseAmplificationGain, + eMaxAccKg, + eMaxMagKg, + eGyroBias, + eAccelOffsets, + eMagCal, + eMagCalSlot, + eMagCalRunning, + eGyrResolution, + eAccelKalmanBiasGain, + eMagKalmanBiasGain, + eTempCalRunning, + eApplyTempCal, + eClearTempCal, + eDontRunThermComp, + eChangeHeatOutput, + eSetNoMotionCalDisable, + eClearMagCal, + eSetGyrSensitivity, + eSetVsenseScalar, + eConfigMountPoseYaw, + eConfigMountPosePitch, + eConfigMountPoseRoll, + eConfigAccelScalar, + eConfigGyroScalarX, + eConfigGyroScalarY, + eConfigGyroScalarZ, + eCustomParam0, + eCustomParam1, + + /* CANdle */ + eLEDStripType = 900, + eLossOfSignalBehavior, + eBrightnessCoefficient, + eStatusLedState, + eVBatOutput, + eV5Enabled, }; } // namespace phoenix diff --git a/include/ctre/phoenix/platform/BasePlatform.h b/include/ctre/phoenix/platform/BasePlatform.h new file mode 100644 index 0000000..4104d5c --- /dev/null +++ b/include/ctre/phoenix/platform/BasePlatform.h @@ -0,0 +1,92 @@ +#pragma once + +#include "Platform-pack.h" +#include "canframe.h" +#include +#include + +/* forward prototype, defined in platform implementation */ +class CANivoreSocket; + +namespace ctre { +namespace phoenix { +namespace platform { +namespace can { + + /* interface for CAN Platforms */ + class BaseCANbusDispatcher { + public: + /* the CANbusDispatcher implementation will define this */ + static BaseCANbusDispatcher &GetInstance(void); + + virtual void Dispose(void); + + //-------------- CANivore diagnostic interface, this is required only for the CANivore dispatchers ---------------// + virtual int32_t CANivoreDiagTransaction(uint8_t *data, uint32_t txDataLen, uint32_t rxDataCapacity, uint32_t &rxDataLen, uint32_t timeoutMs, char const *canbus, bool printErr); + + //------------ CANBus registration interface, this is required when multiple CAN buses are possible -------------// + virtual int32_t RegisterCANbus(char const *canbus); + virtual std::string GetCANivoreDevName(char const *canbus); + + //-------------------------- Low Level CANBus interface, this is required for everyone --------------------------// + virtual std::vector GetCANbusList(void) = 0; + virtual void GetStatus(float &busUtilPerc, uint32_t &busOffCount, uint32_t &txFullCount, uint32_t &rec, uint32_t &tec, int32_t &status, char const *canbus, bool printErr) = 0; + virtual int32_t SendFrame(uint32_t messageID, uint8_t const *data, uint8_t dataSize, char const *canbus, bool printErr) = 0; + + //----------- Mid Level CANBus interface, this is required for everyone (BusMgr for phoenix-canutil) ------------// + virtual void CANComm_SendMessage(uint32_t messageID, uint8_t const *data, uint8_t dataSize, int32_t periodMs, int32_t *status, char const *canbus, bool printErr) = 0; + virtual void CANComm_ReceiveMessage(uint32_t *messageID, uint32_t messageIDMask, uint8_t *data, uint8_t *dataSize, uint32_t *timeStamp, int32_t *status, char const *canbus, bool printErr) = 0; + virtual void CANComm_OpenStreamSession(uint32_t *sessionHandle, uint32_t messageID, uint32_t messageIDMask, uint32_t maxMessages, int32_t *status, char const *canbus, bool printErr) = 0; + virtual void CANComm_CloseStreamSession(uint32_t sessionHandle, char const *canbus, bool printErr) = 0; + virtual void CANComm_ReadStreamSession(uint32_t sessionHandle, canframe_t *messages, uint32_t messagesToRead, uint32_t *messagesRead, int32_t *status, char const *canbus, bool printErr) = 0; + virtual int32_t CANComm_GetTxSchedulerStatus(void *unusedControlWorld, char const *canbus, bool printErr) = 0; // used to be GetControlWord + }; + + /* interface for CAN Platforms using BusMgr */ + class BaseCANDriver { + public: + /* the CANDriver implementation will define this */ + static BaseCANDriver &GetInstance(void); + + virtual void GetStatus(float &busUtilPerc, uint32_t &busOffCount, uint32_t &txFullCount, uint32_t &rec, uint32_t &tec, int32_t &status, CANivoreSocket const *socket) = 0; + /* When possible, implementations should NOT make this blocking */ + virtual int32_t SendFrame(uint32_t messageID, uint8_t const *data, uint8_t dataSize, CANivoreSocket const *socket) = 0; + virtual uint16_t GetMinRxBufferSz(void) = 0; + /* Windows: This routine will block up to a fixed timeout (10ms). This is necessary for good performance. + * Linux: This routine is non-blocking to prevent mutex-blocks. Caller should have a yield to prevent high-cpu spinning. */ + virtual int32_t ReceiveFrame(canframe_t *toFill, uint32_t frameCap, uint32_t &numFilled, CANivoreSocket const *socket) = 0; + }; + +} //namespace can +} //namespace platform +} //namespace phoenix +} //namespace ctre + +namespace ctre { +namespace phoenix { +namespace platform { + + /** list of all supporte device types */ + #define kDeviceTypeListInitializer TalonSRXType, VictorSPXType, PigeonIMUType, RibbonPigeonIMUType, TalonFXType, CANCoderType + + enum DeviceType {kDeviceTypeListInitializer}; + + /* interface for Platforms */ + class BaseSimPlatform { + public: + /* the Platform implementation will define this */ + static BaseSimPlatform &GetInstance(void); + + virtual int32_t SimCreate(DeviceType type, int id); + + virtual int32_t SimDestroy(DeviceType type, int id); + virtual int32_t SimDestroyAll(); + + virtual int32_t SimSetPhysicsInput(DeviceType type, int id, std::string const &physicsType, double value); + virtual int32_t SimGetPhysicsValue(DeviceType type, int id, std::string const &physicsType, double &value); + virtual int32_t SimGetLastError(DeviceType type, int id); + }; + +} // namespace platform +} // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/platform/Platform-pack.h b/include/ctre/phoenix/platform/Platform-pack.h index afa2c67..46b68d0 100644 --- a/include/ctre/phoenix/platform/Platform-pack.h +++ b/include/ctre/phoenix/platform/Platform-pack.h @@ -65,22 +65,6 @@ #define CTRE_REGISTER_SHUTDOWN_HANDLER(shutdown_handler) \ do{ (void)SetConsoleCtrlHandler(CTRE_Global_ConsoleHandlerRoutine, TRUE); } while(0) -#elif defined(__GNUC__) - - #include - - #define CTRE_IMPLEMENT_SHUTDOWN_HANDLER(shutdown_handler) \ - static void shutdown_handler(int signo) - - #define CTRE_REGISTER_SHUTDOWN_HANDLER(shutdown_handler) \ - { \ - struct sigaction sigact; \ - sigact.sa_handler = shutdown_handler; \ - sigemptyset(&sigact.sa_mask); \ - sigact.sa_flags = 0; \ - sigaction(SIGINT, &sigact, NULL); \ - sigaction(SIGTERM, &sigact, NULL); \ - } #else #define CTRE_IMPLEMENT_SHUTDOWN_HANDLER(shutdown_handler) static void shutdown_handler(int signo) diff --git a/include/ctre/phoenix/platform/Platform.h b/include/ctre/phoenix/platform/Platform.h index 5b679c5..af16213 100644 --- a/include/ctre/phoenix/platform/Platform.h +++ b/include/ctre/phoenix/platform/Platform.h @@ -1,53 +1,35 @@ #pragma once -#include "ctre/phoenix/platform/Platform-pack.h" -#include -#include -/* small wrinkle for RIO platform */ -#ifdef __FRC_ROBORIO__ - struct tCANStreamMessage; -#endif +#include "BasePlatform.h" +#include "SleepUs.h" +#include "ReportError.h" +#include "ctre/phoenix/export.h" +#include "ctre/phoenix/ErrorCode.h" namespace ctre { namespace phoenix { namespace platform { namespace can { - /** - * "plain old data" container for holding a CAN Frame Event. - * Assignment of this type resolves to a copy-by-value. - */ - typedef struct _canframe_t { - uint32_t arbID; //!< ArbID of the CAN frame. - uint32_t timeStampUs; //!< Timestamp if receive event. Zero otherwise. - uint8_t data[8]; //!< Data bytes - uint32_t flags; //!< Zero for now. Can be used for detecting arbID type (29bit vs 11bit). - uint8_t dlc; //!< Number of bytes in payload - } canframe_t; - //-------------- Low Level CANBus interface, this is required if using phoenix-canutil--------------------------// - void CANbus_GetStatus(float *busUtilPerc, uint32_t *busOffCount, uint32_t *txFullCount, uint32_t *rec, uint32_t *tec, int32_t *status); - int32_t CANbus_SendFrame(uint32_t messageID, const uint8_t *data, uint8_t dataSize); - /* assumed blocking */ - int32_t CANbus_ReceiveFrame(canframe_t * toFill, uint32_t frameCap, uint32_t *numFilled); - - /** - * Set the CAN interface to use, for example on Linux you may select "can0". - * @param CANInterface CAN interface string. - * @return errorcode, zero if successful. - */ - int32_t SetCANInterface(const char * CANInterface); + //-------------- CANivore diagnostic interface, this is only implemented by the CANivore dispatchers ---------------// + CTREXPORT int32_t CANivoreDiagTransaction(uint8_t *data, uint32_t txDataLen, uint32_t rxDataCapacity, uint32_t &rxDataLen, uint32_t timeoutMs, char const *canbus, bool printErr = true); + + //------------ CANBus registration interface, this is implemented when multiple CAN buses are possible -------------// + CTREXPORT int32_t RegisterCANbus(char const *canbus); + CTREXPORT std::string GetCANivoreDevName(char const *canbus); + + //-------------------------- Low Level CANBus interface, this is implemented by everyone ---------------------------// + CTREXPORT std::vector GetCANbusList(void); + CTREXPORT void CANbus_GetStatus(float &busUtilPerc, uint32_t &busOffCount, uint32_t &txFullCount, uint32_t &rec, uint32_t &tec, int32_t &status, char const *canbus, bool printErr = true); + CTREXPORT int32_t CANbus_SendFrame(uint32_t messageID, uint8_t const *data, uint8_t dataSize, char const *canbus, bool printErr = true); - //-------------- Mid Level CANBus interface, this is required if NOT using phoenix-canutil, --------------------------// - void CANComm_SendMessage(uint32_t messageID, const uint8_t *data, uint8_t dataSize, int32_t periodMs, int32_t *status); - void CANComm_ReceiveMessage(uint32_t *messageID, uint32_t messageIDMask, uint8_t *data, uint8_t *dataSize, uint32_t *timeStamp, int32_t *status); - void CANComm_OpenStreamSession(uint32_t *sessionHandle, uint32_t messageID, uint32_t messageIDMask, uint32_t maxMessages, int32_t *status); - void CANComm_CloseStreamSession(uint32_t sessionHandle); -#ifdef __FRC_ROBORIO__ - void CANComm_ReadStreamSession(uint32_t sessionHandle, struct tCANStreamMessage *messages, uint32_t messagesToRead, uint32_t *messagesRead, int32_t *status); -#else - void CANComm_ReadStreamSession(uint32_t sessionHandle, canframe_t *messages, uint32_t messagesToRead, uint32_t *messagesRead, int32_t *status); -#endif - int32_t CANComm_GetTxSchedulerStatus(void *unusedControlWorld); // used to be GetControlWord + //------------ Mid Level CANBus interface, this is implemented by everyone (BusMgr for phoenix-canutil) ------------// + CTREXPORT void CANComm_SendMessage(uint32_t messageID, uint8_t const *data, uint8_t dataSize, int32_t periodMs, int32_t *status, char const *canbus, bool printErr = true); + CTREXPORT void CANComm_ReceiveMessage(uint32_t *messageID, uint32_t messageIDMask, uint8_t *data, uint8_t *dataSize, uint32_t *timeStamp, int32_t *status, char const *canbus, bool printErr = true); + CTREXPORT void CANComm_OpenStreamSession(uint32_t *sessionHandle, uint32_t messageID, uint32_t messageIDMask, uint32_t maxMessages, int32_t *status, char const *canbus, bool printErr = true); + CTREXPORT void CANComm_CloseStreamSession(uint32_t sessionHandle, char const *canbus, bool printErr = true); + CTREXPORT void CANComm_ReadStreamSession(uint32_t sessionHandle, canframe_t *messages, uint32_t messagesToRead, uint32_t *messagesRead, int32_t *status, char const *canbus, bool printErr = true); + CTREXPORT int32_t CANComm_GetTxSchedulerStatus(void *unusedControlWorld, char const *canbus, bool printErr = true); // used to be GetControlWord } //namespace can } //namespace platform @@ -58,40 +40,25 @@ namespace ctre { namespace phoenix { namespace platform { - enum DeviceType {TalonSRXType, VictorSPXType, CANifierType, PigeonIMUType}; - - /** - * @param timeUs How long to yield current thread in microseconds (us). - * If platform cannot honor us resolution, round to nearest - * value that platform can honor. - */ - void SleepUs(int timeUs); - /** * Get a stack trace, ignoring the first "offset" symbols. * * @param offset The number of symbols at the top of the stack to ignore */ - std::string GetStackTrace(int offset); - - void ReportError(int isError, int32_t errorCode, int isLVCode, - const char *details, const char *location, const char *callStack); + CTREXPORT std::string GetStackTrace(int offset); - int32_t SimCreate(DeviceType type, int id); + CTREXPORT int32_t DisposePlatform(); + CTREXPORT int32_t StartPlatform(); - int32_t SimConfigGet(DeviceType type, uint32_t param, uint32_t valueToSend, uint32_t & outValueReceived, uint32_t & outSubvalue, uint32_t ordinal, uint32_t id); - - int32_t SimConfigSet(DeviceType type, uint32_t param, uint32_t value, uint32_t subValue, uint32_t ordinal, uint32_t id); + CTREXPORT int32_t SimCreate(DeviceType type, int id); - int32_t SimDestroy(DeviceType type, int id); - int32_t SimDestroyAll(); + CTREXPORT int32_t SimDestroy(DeviceType type, int id); + CTREXPORT int32_t SimDestroyAll(); - int32_t DisposePlatform(); - int32_t StartPlatform(); + CTREXPORT int32_t SimSetPhysicsInput(DeviceType type, int id, std::string const &physicsType, double value); + CTREXPORT int32_t SimGetPhysicsValue(DeviceType type, int id, std::string const &physicsType, double &value); + CTREXPORT int32_t SimGetLastError(DeviceType type, int id); - int32_t DisposeMgr(); - int32_t StartMgr(); - } // namespace platform } // namespace phoenix } // namespace ctre diff --git a/include/ctre/phoenix/platform/PlatformSim.h b/include/ctre/phoenix/platform/PlatformSim.h deleted file mode 100644 index a966cbd..0000000 --- a/include/ctre/phoenix/platform/PlatformSim.h +++ /dev/null @@ -1,61 +0,0 @@ -#include "ctre/phoenix/platform/Platform.h" -#include "ctre/phoenix/cci/Platform_CCI.h" - -namespace ctre { -namespace phoenix { -namespace platform { - -/** - * Class for simulation as a platform - */ -class PlatformSim { - -public: - /** - * Create Device - * @param type Device Type - * @param id Device ID - * @return ErrorCode - */ - static int32_t SimCreate(DeviceType type, int id); - /** - * Destroy Device - * @param type Device Type - * @param id Device ID - * @return ErrorCode - */ - static int32_t SimDestroy(DeviceType type, int id); - /** - * Destroy all devices in sim - * @return ErrorCode - */ - static int32_t SimDestroyAll(); - /** - * Get configs of simulated device - * @param type Device Type - * @param param Param to get - * @param valueToSend subValue - * @param outValueReceived requested value - * @param outSubvalue requested subValue - * @param ordinal Ordinal - * @param id Device ID - * @return ErrorCode - */ - static int32_t SimConfigGet(DeviceType type, uint32_t param, uint32_t valueToSend, uint32_t & outValueReceived, uint32_t & outSubvalue, uint32_t ordinal, int32_t id); - /** - * Sets configs of simulated device - * @param type Device Type - * @param param Param to send - * @param value Value to send - * @param subValue Subvalue to send - * @param ordinal Ordinal - * @param id Device ID - * @return ErrorCode - */ - static int32_t SimConfigSet(DeviceType type, uint32_t param, uint32_t value, uint32_t subValue, uint32_t ordinal, int32_t id); - -}; - -} -} -} diff --git a/include/ctre/phoenix/platform/ReportError.h b/include/ctre/phoenix/platform/ReportError.h new file mode 100644 index 0000000..4f7d217 --- /dev/null +++ b/include/ctre/phoenix/platform/ReportError.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +namespace ctre { +namespace phoenix { +namespace platform { + + void ReportError(int isError, int32_t errorCode, int isLVCode, const char *details, + const char *location, const char *callStack); + +} // namespace platform +} // namespace phoenix +} // namespace ctre \ No newline at end of file diff --git a/include/ctre/phoenix/platform/SleepUs.h b/include/ctre/phoenix/platform/SleepUs.h new file mode 100644 index 0000000..792b9ec --- /dev/null +++ b/include/ctre/phoenix/platform/SleepUs.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include + +#ifdef __FRC_ROBORIO__ +#include +#endif + +namespace ctre { +namespace phoenix { +namespace platform { + + /** + * @param timeUs How long to yield current thread in microseconds (us). + * If platform cannot honor us resolution, round to nearest + * value that platform can honor. + */ + static inline void SleepUs(int timeUs) + { +#ifdef __FRC_ROBORIO__ + usleep(timeUs); +#else + std::this_thread::sleep_for(std::chrono::microseconds(timeUs)); +#endif + } + +} // namespace platform +} // namespace phoenix +} // namespace ctre \ No newline at end of file diff --git a/include/ctre/phoenix/platform/can/PlatformCAN.h b/include/ctre/phoenix/platform/can/PlatformCAN.h index 5511099..4275fc7 100644 --- a/include/ctre/phoenix/platform/can/PlatformCAN.h +++ b/include/ctre/phoenix/platform/can/PlatformCAN.h @@ -16,9 +16,18 @@ class PlatformCAN { * Set CAN interface * @param canInterface Can interface to set. Linux example: "can0". * @return ErrorCode generated by function + * @deprecated pass the CAN interface to device constructors instead, + * or call RegisterCANbus */ static int32_t SetCANInterface(const char * canInterface); + /** + * Registers a non-compliant CANbus + * @param canbus CANbus to register. Linux example: "can0". + * @return ErrorCode generated by function + */ + static int32_t RegisterCANbus(char const *canbus); + /** * Starts all items in interface */ diff --git a/include/ctre/phoenix/platform/canframe.h b/include/ctre/phoenix/platform/canframe.h new file mode 100644 index 0000000..0a13252 --- /dev/null +++ b/include/ctre/phoenix/platform/canframe.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +namespace ctre { +namespace phoenix { +namespace platform { +namespace can { + + /** + * "plain old data" container for holding a CAN Frame Event. + * Assignment of this type resolves to a copy-by-value. + */ + typedef struct _canframe_t { + uint32_t arbID; //!< ArbID of the CAN frame. + uint32_t timeStampUs; //!< Timestamp if receive event. Zero otherwise. + uint8_t data[64]; //!< Data bytes + uint32_t flags; //!< Zero for now. Can be used for detecting arbID type (29bit vs 11bit). + uint8_t len; //!< Number of bytes in payload + } canframe_t; + +} //namespace can +} //namespace platform +} //namespace phoenix +} //namespace ctre diff --git a/include/ctre/phoenix/platform/canivore_device.h b/include/ctre/phoenix/platform/canivore_device.h new file mode 100644 index 0000000..14eb9d0 --- /dev/null +++ b/include/ctre/phoenix/platform/canivore_device.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +constexpr size_t kCANivoreMaxStrLen = 100; + +typedef struct _canivore_device_t { + char status[kCANivoreMaxStrLen]; + char name[kCANivoreMaxStrLen]; + char serial_num[kCANivoreMaxStrLen]; + char firm_vers[16]; + char discoveryStatus[kCANivoreMaxStrLen]; +} canivore_device_t; diff --git a/include/ctre/phoenix/platform/ctr_assert.h b/include/ctre/phoenix/platform/ctr_assert.h new file mode 100644 index 0000000..dff0bfb --- /dev/null +++ b/include/ctre/phoenix/platform/ctr_assert.h @@ -0,0 +1,23 @@ +#ifndef ctr_assert__h_ +#define ctr_assert__h_ + +#include "ctre/phoenix/platform/Platform-pack.h" // assert + +#if defined(_DEBUG) || defined(DEBUG) + #define CTR_DEBUGGING (1) +#else + #define CTR_DEBUGGING (0) +#endif + +#define CTR_STOP_DEBUGGER_ON_ASSERT (0) /* turn this off before deploying the so, otherwise RIO goes into safe mode. */ + +#define ctr_assert(cond) \ + do{ \ + if(CTR_DEBUGGING && !(cond)){ \ + if (CTR_STOP_DEBUGGER_ON_ASSERT) { CTRE_ASSERT(cond); } \ + printf("ctr_assert : %s : %s : %i\n",#cond,__FILE__,__LINE__); \ + } \ + }while(0) + +#endif /* ctr_assert__h_ */ + diff --git a/include/ctre/phoenix/runtime/LibLoader.h b/include/ctre/phoenix/runtime/LibLoader.h deleted file mode 100644 index 83e3c43..0000000 --- a/include/ctre/phoenix/runtime/LibLoader.h +++ /dev/null @@ -1,274 +0,0 @@ -/** - * @brief OS abstracted Library Loader class for DLLs/shared-objects. - * @author Ozrien - * - * This is useful for basic plugin systems. - - * Example Use... - *
- * {@code
- *     ctre::phoenix::runtime::LibLoader ldr;
- *     typedef int (*example_func_t)(...params...);
- *     try {
- *         ldr.Open("example.dll");
- *         int retval = LIBLOADER_LOOKUP(ldr, example_func_t)(...params...);
- *     } catch (const LibLoaderException & e) {}
- * }
- * 
- */ -#pragma once - -#include "ctre/phoenix/ErrorCode.h" -#include -#include -#include - - /** - * Use preprocessor to simplifiy getting func ptr by name, then calling. - * Example use: LIBLOADER_LOOKUP(loader, some_func_typedef)(... some func params ...) - */ -#define LIBLOADER_LOOKUP(libloader, funcT) (libloader).LookupFunc(#funcT) - -namespace ctre { - namespace phoenix { - namespace runtime { - /** - * LibLoaderException - */ - class LibLoaderException : public std::runtime_error { - public: - - LibLoaderException(phoenix::ErrorCode errorCode, const std::string& BaseMessage, const std::string & libPath) - : std::runtime_error((BaseMessage + " " + libPath).c_str()) - { - _errorCode = errorCode; - } - LibLoaderException(phoenix::ErrorCode errorCode, const std::string& BaseMessage, const std::string & libPath, const std::string & funcName) - : std::runtime_error((BaseMessage + " " + funcName + " in " + libPath).c_str()) - { - _errorCode = errorCode; - } - - phoenix::ErrorCode GetPhoenixErrorCode() const - { - return _errorCode; - } - private: - phoenix::ErrorCode _errorCode; - }; - } // runtime - } // phoenix -} // ctre - -#if defined(WIN32) || defined(_WIN32) || defined(_WIN64) -#include -namespace ctre { - namespace phoenix { - namespace runtime { - /** - * LibLoader - */ - class LibLoader { - - public: - /** default c'tor */ - LibLoader() { /* empty */ } - - /* no copy c'tr */ - LibLoader(const LibLoader&) = delete; - - /** d'tor */ - ~LibLoader() { Close(); } - - /** - * @param libPath filePath to dll to load, passed into LoadLibrary. - * Routine will throw LibLoaderException on failure. - */ - void Open(const std::string & libPath) { - /* if library already loaded, close it and start all over */ - Close(); - /* keep a copy for posterity */ - _libPath = libPath; - /* attempt to load the module (dll) */ - _handle = LoadLibraryA(_libPath.c_str()); - /* throw if it didn't load */ - if (_handle == NULL) { throw LibLoaderException(ErrorCode::LibraryCouldNotBeLoaded, "Could not load", _libPath); } - } - /** - * @return true if DLL/SO is loaded. - */ - bool IsOpen() const{ - return (_handle != NULL); - } - - /** - * Close DLL and clear func ptrs. - */ - void Close() { - /* dump the table, this is not necessary but good to dump bad func ptr*/ - _mp.clear(); - /* free the module */ - if (_handle != NULL) { - FreeLibrary(_handle); - _handle = NULL; - } - } - /** - * Lookup a function by name inside DLL. If func has been found already, performance should - * be fast since it is a map lookup. - * @param funcName string copy of function name. - * @return pointer to found function. - * Routine will throw LibLoaderException on failure. - */ - template T LookupFunc(const std::string & funcName) - { - /* make sure Open was called successfully */ - if (_handle == NULL) { throw LibLoaderException(ErrorCode::LibraryCouldNotBeLoaded, "Could not load", _libPath); } - - /* first check map, we might have it already */ - auto iter = _mp.find(funcName); - if (iter != _mp.end()) { return (T)iter->second; } - - /* pull func ptr out of lib */ - T funcPtr = (T)GetProcAddress(_handle, funcName.c_str()); - - /* did we get it? */ - if (funcPtr == NULL) { - /* couldn't find it dll, throw to caller */ - throw LibLoaderException(ErrorCode::MissingRoutineInLibrary, "Could not find routine", _libPath, funcName); - } - /* insert into coll */ - _mp[funcName] = (void*)funcPtr; - - /* pass new ptr to caller */ - return funcPtr; - } - - private: - std::string _libPath; //!< Copy of lib path, mostly for error reporting - std::map _mp; //!< Coll for func ptrs we've found this far - HINSTANCE _handle = NULL; //!< handle to module (dll) - }; - } // runtime - } // phoenix -} // ctre -#else -#include -#include - -namespace ctre { - namespace phoenix { - namespace runtime { - /** - * LibLoader - */ - class LibLoader { - - public: - /** default c'tor */ - LibLoader() { /* empty */ } - - /* no copy c'tr */ - LibLoader(const LibLoader&) = delete; - - /** d'tor */ - ~LibLoader() { Close(); } - - /** - * @param libPath filePath to dll to load, passed into LoadLibrary. - * Routine will throw LibLoaderException on failure. - */ - void Open(const std::string & libPath) { - /* if library already loaded, close it and start all over */ - Close(); - /* keep a copy for posterity */ - _libPath = libPath; - /* attempt to load the module (dll) */ - - _handle = dlopen(_libPath.c_str(), RTLD_NOW); - - /* throw if it didn't load */ - if (!_handle) { - std::string baseErr = dlerror(); - baseErr += " | With path: "; - - std::cout << baseErr << _libPath << std::endl; - throw; //LibLoaderException(ErrorCode::LibraryCouldNotBeLoaded, baseErr, _libPath); - } - } - /** - * @return true if DLL/SO is loaded. - */ - bool IsOpen() const{ - return (_handle != NULL); - } - - /** - * Close DLL and clear func ptrs. - */ - void Close(bool performDlclose) { - /* dump the table, this is not necessary but good to dump bad func ptr*/ - _mp.clear(); - /* free the module (fails in linux for unknown reasons). */ - if (_handle && performDlclose) { - dlclose(_handle); - } - } - - void Close() { - Close(false); - } - - /** - * Lookup a function by name inside DLL. If func has been found already, performance should - * be fast since it is a map lookup. - * @param funcName string copy of function name. - * @return pointer to found function. - * Routine will throw LibLoaderException on failure. - */ - template T LookupFunc(const std::string & funcName) - { - /* make sure Open was called successfully */ - if (!_handle) { - std::string baseErr = dlerror(); - baseErr += " | With path: "; - - std::cout << baseErr << _libPath << std::endl; - throw; //LibLoaderException(ErrorCode::LibraryCouldNotBeLoaded,baseErr, _libPath); - } - - /* first check map, we might have it already */ - auto iter = _mp.find(funcName); - if (iter != _mp.end()) { return (T)iter->second; } - - /* pull func ptr out of lib */ - T funcPtr = (T)dlsym(_handle, funcName.c_str()); - - /* did we get it? */ - if (funcPtr == NULL) { - /* couldn't find it dll, throw to caller */ - std::string baseErr = dlerror(); - baseErr += " | For: "; - - std::cout << baseErr << funcName << " in " << _libPath << std::endl; - - throw;// LibLoaderException(ErrorCode::MissingRoutineInLibrary,"Could not find routine", _libPath, funcName); - } - /* insert into coll */ - _mp[funcName] = (void*)funcPtr; - - /* pass new ptr to caller */ - return funcPtr; - } - - private: - std::string _libPath; //!< Copy of lib path, mostly for error reporting - std::map _mp; //!< Coll for func ptrs we've found this far - void *_handle = NULL; //!< handle to module (dll) - }; - } // runtime - } // phoenix -} // ctre - - -#endif diff --git a/include/ctre/phoenix/sensors/BasePigeon.h b/include/ctre/phoenix/sensors/BasePigeon.h new file mode 100644 index 0000000..8ded8da --- /dev/null +++ b/include/ctre/phoenix/sensors/BasePigeon.h @@ -0,0 +1,548 @@ +/* + * 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 + */ + +#pragma once + +#include +#include "ctre/phoenix/CANBusAddressable.h" +#include "ctre/phoenix/CustomParamConfiguration.h" +#include "ctre/phoenix/paramEnum.h" +#include "ctre/phoenix/ErrorCode.h" +#include "ctre/phoenix/sensors/PigeonIMU_ControlFrame.h" +#include "ctre/phoenix/sensors/PigeonIMU_Faults.h" +#include "ctre/phoenix/sensors/PigeonIMU_StatusFrame.h" +#include "ctre/phoenix/sensors/PigeonIMU_StickyFaults.h" +#include "ctre/phoenix/sensors/BasePigeonSimCollection.h" + +/* forward prototype */ +namespace ctre { +namespace phoenix { +namespace motorcontrol { +namespace can { +class TalonSRX; +} +} +} +} + +namespace ctre { +namespace phoenix { +/** sensors namespace */ +namespace sensors { + +/** + * Configurables available to Pigeon + */ +struct BasePigeonConfiguration : CustomParamConfiguration{ + BasePigeonConfiguration() {} + + /** + * @return String representation of configs + */ + std::string toString() { + return toString(""); + } + + /** + * @param prependString + * String to prepend to configs + * @return String representation of configs + */ + std::string toString(std::string prependString) { + std::string retstr = CustomParamConfiguration::toString(prependString); + + return retstr; + } +};// struct BasePigeon + +/** + * Util class to help with Pigeon configurations + */ +struct BasePigeonConfigUtils { +private: + static BasePigeonConfiguration _default; +public: + /** + * Determine if specified value is different from default + * @param settings settings to compare against + * @return if specified value is different from default + * @{ + */ + static bool CustomParam0Different (const BasePigeonConfiguration & settings) { return (!(settings.customParam0 == _default.customParam0)) || !settings.enableOptimizations; } + static bool CustomParam1Different (const BasePigeonConfiguration & settings) { return (!(settings.customParam1 == _default.customParam1)) || !settings.enableOptimizations; } + /** @} */ +}; + +/** + * Pigeon IMU Class. + * Class supports communicating over CANbus and over ribbon-cable (CAN Talon SRX). + */ +class BasePigeon: public CANBusAddressable { +public: + + /** + * Create a Pigeon object that communicates with Pigeon on CAN Bus. + * + * @param deviceNumber + * CAN Device Id of Pigeon [0,62] + * @param canbus Name of the CANbus; can be a SocketCAN interface (on Linux), + * or a CANivore device name or serial number + */ + BasePigeon(int deviceNumber, std::string const &version, std::string const &canbus = ""); + + ~BasePigeon(); + + /** + * Destructs all pigeon objects + */ + static void DestroyAllBasePigeons(); + + /** + * Sets the Yaw register to the specified value. + * + * @param angleDeg Degree of Yaw [+/- 368,640 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. + */ + int SetYaw(double angleDeg, int timeoutMs = 0); + /** + * 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. + */ + int AddYaw(double angleDeg, int timeoutMs = 0); + /** + * 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. + */ + int SetYawToCompass(int timeoutMs = 0); + + /** + * 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. + */ + int SetAccumZAngle(double angleDeg, int timeoutMs = 0); + /** + * 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. + */ + ErrorCode GetLastError() const; + /** + * 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. + */ + ErrorCode Get6dQuaternion(double wxyz[4]) const; + /** + * Get Yaw, Pitch, and Roll data. + * + * @param ypr Array to fill with yaw[0], pitch[1], and roll[2] data. + * Yaw is within [-368,640, +368,640] degrees. + * Pitch is within [-90,+90] degrees. + * Roll is within [-90,+90] degrees. + * @return The last ErrorCode generated. + */ + ErrorCode GetYawPitchRoll(double ypr[3]) const; + /** + * Get the yaw from the Pigeon + * @return Yaw + */ + double GetYaw() const; + /** + * Get the pitch from the Pigeon + * @return Pitch + */ + double GetPitch() const; + /** + * Get the roll from the Pigeon + * @return Roll + */ + double GetRoll() const; + /** + * 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. + */ + int GetAccumGyro(double xyz_deg[3]) const; + /** + * Get the absolute compass heading. + * @return compass heading [0,360) degrees. + */ + double GetAbsoluteCompassHeading() const; + /** + * Get the continuous compass heading. + * @return continuous compass heading [-23040, 23040) degrees. Use + * SetCompassHeading to modify the wrap-around portion. + */ + double GetCompassHeading() const; + /** + * Gets the compass' measured magnetic field strength. + * @return field strength in Microteslas (uT). + */ + double GetCompassFieldStrength() const; + /** + * Gets the temperature of the pigeon. + * + * @return Temperature in ('C) + */ + double GetTemp() const; + /** + * Gets the current Pigeon uptime. + * + * @return How long has Pigeon been running in whole seconds. Value caps at + * 255. + */ + uint32_t GetUpTime() const; + /** + * 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. + */ + int GetRawMagnetometer(int16_t rm_xyz[3]) const; + + /** + * 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. + */ + int GetBiasedMagnetometer(int16_t bm_xyz[3]) const; + /** + * 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. + */ + int GetBiasedAccelerometer(int16_t ba_xyz[3]) const; + /** + * 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. + */ + int GetRawGyro(double xyz_dps[3]) const; + /** + * @return number of times Pigeon Reset + */ + uint32_t GetResetCount() const; + /** + * @return Reset flags for Pigeon + */ + uint32_t GetResetFlags() const; + /** + * @return firmware version of Pigeon + */ + uint32_t GetFirmVers() const; + + /** + * @return true iff a reset has occurred since last call. + */ + bool HasResetOccurred() const; + + /** + * 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. + */ + ErrorCode ConfigSetCustomParam(int newValue, int paramIndex, int timeoutMs = 0); + /** + * 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 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 the custom param. + */ + int ConfigGetCustomParam(int paramIndex, int timeoutMs = 0); + /** + * 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. + */ + ErrorCode ConfigSetParameter(ParamEnum param, double value, + uint8_t subValue, int ordinal, int timeoutMs = 0); + /** + * 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. + */ + double ConfigGetParameter(ctre::phoenix::ParamEnum param, int ordinal, int timeoutMs = 0); + /** + * Gets a parameter by passing an int by reference + * + * @param param + * Parameter enumeration + * @param valueToSend + * Value to send to parameter + * @param valueReceived + * Reference to integer to receive + * @param subValue + * SubValue of parameter + * @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. + */ + ErrorCode ConfigGetParameter(ParamEnum param, int32_t valueToSend, + int32_t & valueReceived, uint8_t & subValue, int32_t ordinal, + int32_t 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. + */ + ErrorCode SetStatusFramePeriod(PigeonIMU_StatusFrame statusFrame, uint8_t periodMs, + int timeoutMs = 0); + + /** + * 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. + */ + int GetStatusFramePeriod(PigeonIMU_StatusFrame frame, + int timeoutMs = 0) ; + /** + * 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. + */ + ErrorCode SetControlFramePeriod(PigeonIMU_ControlFrame frame, + int periodMs); + /** + * Gets the firmware version of the device. + * + * @return param holds the firmware version of the device. Device must be powered + * cycled at least once. + */ + int GetFirmwareVersion() ; + /** + * Clears the Sticky Faults + * + * @return Error Code generated by function. 0 indicates no error. + */ + ErrorCode ClearStickyFaults(int timeoutMs = 0); + + /** + * @return Pigeon resource handle. + */ + void* GetLowLevelHandle() const { + return _handle; + } + + //------ All Configs ----------// + /** + * Configures all persistent settings. + * + * @param allConfigs Object with all of the persistant settings + * @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. + */ + virtual ctre::phoenix::ErrorCode ConfigAllSettings(const BasePigeonConfiguration &allConfigs, int timeoutMs = 50); + /** + * Gets all persistant settings. + * + * @param allConfigs Object with all of the persistant settings + * @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. + */ + virtual void GetAllConfigs(BasePigeonConfiguration &allConfigs, int timeoutMs = 50); + /** + * Configures all persistent settings to defaults. + * + * @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. + */ + virtual ErrorCode ConfigFactoryDefault(int timeoutMs = 50); + + /** + * @return object that can set simulation inputs. + */ + virtual BasePigeonSimCollection& GetSimCollection(); +private: + /** firmware state reported over CAN */ + enum MotionDriverState { + Init0 = 0, + WaitForPowerOff = 1, + ConfigAg = 2, + SelfTestAg = 3, + StartDMP = 4, + ConfigCompass_0 = 5, + ConfigCompass_1 = 6, + ConfigCompass_2 = 7, + ConfigCompass_3 = 8, + ConfigCompass_4 = 9, + ConfigCompass_5 = 10, + SelfTestCompass = 11, + WaitForGyroStable = 12, + AdditionalAccelAdjust = 13, + Idle = 14, + Calibration = 15, + LedInstrum = 16, + Error = 31, + }; + /** sub command for the various Set param enums */ + enum TareType { + SetValue = 0x00, AddOffset = 0x01, MatchCompass = 0x02, SetOffset = 0xFF, + }; + /** data storage for reset signals */ + struct ResetStats { + int32_t resetCount; + int32_t resetFlags; + int32_t firmVers; + bool hasReset; + }; + ResetStats _resetStats = { 0, 0, 0, false }; + + /** Portion of the arbID for all status and control frames. */ + void* _handle; + uint32_t _deviceNumber; + uint32_t _usageHist = 0; + uint64_t _cache; + uint32_t _len; + BasePigeonSimCollection* _simCollection; + + /** overall threshold for when frame data is too old */ + const uint32_t EXPECTED_RESPONSE_TIMEOUT_MS = (200); + + int PrivateSetParameter(ParamEnum paramEnum, TareType tareType, + double angleDeg, int timeoutMs = 0); + + double GetTemp(const uint64_t & statusFrame); + +protected: + BasePigeon(ctre::phoenix::motorcontrol::can::TalonSRX& talonSrx); + +};// class BasePigeon +} // namespace signals +} // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/sensors/BasePigeonSimCollection.h b/include/ctre/phoenix/sensors/BasePigeonSimCollection.h new file mode 100644 index 0000000..9b88260 --- /dev/null +++ b/include/ctre/phoenix/sensors/BasePigeonSimCollection.h @@ -0,0 +1,67 @@ +#pragma once + +#include "ctre/phoenix/ErrorCode.h" +#include "ctre/phoenix/cci/Platform_CCI.h" + +/* forward proto's */ +namespace ctre { + namespace phoenix { + namespace sensors { + class BasePigeon; + } + } +} + +namespace ctre { + namespace phoenix { + namespace sensors { + /** + * Collection of simulation functions available to a Pigeon IMU. + * Use the getSimCollection() function in your BasePigeon object to create the respective sim collection. + */ + class BasePigeonSimCollection { + public: + /** + * @param pigeon Pigeon IMU to connect so sim collection + */ + BasePigeonSimCollection(ctre::phoenix::sensors::BasePigeon& pigeon, bool isRibbonCable); + + /** + * Sets the simulated input heading position of the Pigeon IMU. + * + * The Pigeon IMU integrates the delta between each new raw heading value and uses + * this to calculate the true reported yaw and fused heading. + * + * When using the WPI Sim GUI, you will notice a readonly 'yaw' and + * settable 'RawHeading'. The readonly signal is the emulated yaw + * which will match self-test in Tuner and the hardware API. Changes to + * 'RawHeading' will be integrated into the emulated yaw. This way + * a simulator can modify the heading without overriding your + * hardware API calls for home-ing your sensor. + * + * Inputs to this function over time should be continuous, + * as user calls of setYaw() or setFusedHeading() + * will be accounted for in the calculation. + * + * @param newHeading the new input heading in degrees + * + * @return error code + */ + ErrorCode SetRawHeading(double newHeading); + + /** + * Adds to the simulated heading of the Pigeon IMU + * + * @param dHeading the change in heading in degrees + * + * @return error code + */ + ErrorCode AddHeading(double dHeading); + + private: + int _id; + ctre::phoenix::platform::DeviceType _type; + }; + } + } +} \ No newline at end of file diff --git a/include/ctre/phoenix/sensors/CANCoder.h b/include/ctre/phoenix/sensors/CANCoder.h index 5b695f6..e7156f8 100644 --- a/include/ctre/phoenix/sensors/CANCoder.h +++ b/include/ctre/phoenix/sensors/CANCoder.h @@ -6,6 +6,7 @@ #include "ctre/phoenix/ErrorCode.h" #include "ctre/phoenix/paramEnum.h" #include "ctre/phoenix/sensors/AbsoluteSensorRange.h" +#include "ctre/phoenix/sensors/CANCoderSimCollection.h" #include "ctre/phoenix/sensors/CANCoderStatusFrame.h" #include "ctre/phoenix/sensors/CANCoderStickyFaults.h" #include "ctre/phoenix/sensors/CANCoderFaults.h" @@ -140,17 +141,40 @@ namespace ctre { /** - * CTRE CANCoder + * CTRE CANCoder. * - * Device for interfacing common devices to the CAN bus. + *
+			 * {@code
+			 * // Example usage of a CANCoder
+			 * CANCoder cancoder{0}; // creates a new CANCoder with ID 0
+			 *
+			 * CANCoderConfiguration config;
+			 * // set units of the CANCoder to radians, with velocity being radians per second
+			 * config.sensorCoefficient = 2 * M_PI / 4096.0;
+			 * config.unitString = "rad";
+			 * config.sensorTimeBase = SensorTimeBase::PerSecond;
+			 * cancoder.ConfigAllSettings(config);
+			 *
+			 * std::cout << cancoder.GetPosition() << std::endl; // prints the position of the CANCoder
+			 * std::cout << cancoder.GetVelocity() << std::endl; // prints the velocity recorded by the CANCoder
+			 *
+			 * ErrorCode error = cancoder.GetLastError(); // gets the last error generated by the CANCoder
+			 * CANCoderFaults faults;
+			 * ErrorCode faultsError = cancoder.GetFaults(faults); // fills faults with the current CANCoder faults; returns the last error generated
+			 *
+			 * cancoder.SetStatusFramePeriod(CANCoderStatusFrame_SensorData, 10); // changes the period of the sensor data frame to 10ms
+			 * }
+			 * 
*/ class CANCoder : public CANBusAddressable { public: /** * Constructor. * @param deviceNumber The CAN Device ID of the CANCoder. + * @param canbus Name of the CANbus; can be a SocketCAN interface (on Linux), + * or a CANivore device name or serial number */ - CANCoder(int deviceNumber); + CANCoder(int deviceNumber, std::string const &canbus = ""); ~CANCoder(); @@ -517,10 +541,16 @@ namespace ctre { */ ErrorCode ConfigFactoryDefault(int timeoutMs = 50); + /** + * @return object that can set simulation inputs. + */ + CANCoderSimCollection& GetSimCollection(); + private: void* m_handle; + CANCoderSimCollection* _simCollection; - };// class CANCoder + };// class CANCoder } // namespace sensor } // namespace phoenix diff --git a/include/ctre/phoenix/sensors/CANCoderSimCollection.h b/include/ctre/phoenix/sensors/CANCoderSimCollection.h new file mode 100644 index 0000000..13c6f7e --- /dev/null +++ b/include/ctre/phoenix/sensors/CANCoderSimCollection.h @@ -0,0 +1,89 @@ +#pragma once + +#include "ctre/phoenix/ErrorCode.h" +#include "ctre/phoenix/cci/Platform_CCI.h" + +/* forward proto's */ +namespace ctre { + namespace phoenix { + namespace sensors { + class CANCoder; + } + } +} + +namespace ctre { + namespace phoenix { + namespace sensors { + /** + * Collection of simulation functions available to a CANCoder. + * + * Use the getSimCollection() function in your CANCoder object to create the respective sim collection. + */ + class CANCoderSimCollection { + public: + /** + * Constructor for CANCoderSimCollection + * + * @param canCoder CANCoder to connect Collection to + */ + CANCoderSimCollection(ctre::phoenix::sensors::CANCoder& canCoder); + + /** + * Sets the simulated bus voltage of the CANCoder. + * + * The minimum allowed bus voltage is 4 V - values + * below this will be promoted to 4 V. + * + * @param vbat the bus voltage in volts + * + * @return error code + */ + ErrorCode SetBusVoltage(double vbat); + + /** + * Sets the simulated raw position of the CANCoder. + * + * The CANCoder integrates this to calculate the true reported position. + * + * When using the WPI Sim GUI, you will notice a readonly 'position' and + * settable 'rawPositionInput'. The readonly signal is the emulated position + * which will match self-test in Tuner and the hardware API. Changes to + * 'rawPositionInput' will be integrated into the emulated position. This way + * a simulator can modify the position without overriding your + * hardware API calls for home-ing your sensor. + * + * Inputs to this function over time should be continuous, as user calls + * of setPosition() will be accounted for in the calculation. + * + * @param newPos the new raw position in native units + * + * @return error code + */ + ErrorCode SetRawPosition(int newPos); + + /** + * Adds to the simulated position of the CANCoder. + * + * @param dPos the change in position in native units + * + * @return error code + */ + ErrorCode AddPosition(int dPos); + + /** + * Sets the simulated velocity of the CANCoder. + * + * @param newVel the new velocity in native units per 100ms + * + * @return error code + */ + ErrorCode SetVelocity(int newVel); + + private: + int _id; + ctre::phoenix::platform::DeviceType _type; + }; + } + } +} \ No newline at end of file diff --git a/include/ctre/phoenix/sensors/Pigeon2.h b/include/ctre/phoenix/sensors/Pigeon2.h new file mode 100644 index 0000000..92a3e91 --- /dev/null +++ b/include/ctre/phoenix/sensors/Pigeon2.h @@ -0,0 +1,349 @@ +/* + * 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 + */ + +#pragma once + +#include +#include "ctre/phoenix/CANBusAddressable.h" +#include "ctre/phoenix/CustomParamConfiguration.h" +#include "ctre/phoenix/paramEnum.h" +#include "ctre/phoenix/ErrorCode.h" +#include "ctre/phoenix/sensors/PigeonIMU_ControlFrame.h" +#include "ctre/phoenix/sensors/Pigeon2_Faults.h" +#include "ctre/phoenix/sensors/PigeonIMU_StatusFrame.h" +#include "ctre/phoenix/sensors/Pigeon2_StickyFaults.h" +#include "ctre/phoenix/sensors/BasePigeonSimCollection.h" +#include "ctre/phoenix/sensors/BasePigeon.h" + +/* forward prototype */ +namespace ctre { +namespace phoenix { +namespace motorcontrol { +namespace can { +class TalonSRX; +} +} +} +} + +namespace ctre { +namespace phoenix { +/** sensors namespace */ +namespace sensors { + +/** + * Configurables available to Pigeon + */ +struct Pigeon2Configuration : CustomParamConfiguration{ + double MountPoseYaw {0}; + double MountPosePitch {0}; + double MountPoseRoll {0}; + bool EnableCompass {false}; + bool DisableTemperatureCompensation {false}; + bool DisableNoMotionCalibration {false}; + double XAxisGyroError{0}; + double YAxisGyroError{0}; + double ZAxisGyroError{0}; + Pigeon2Configuration() {} + + /** + * @return String representation of configs + */ + std::string toString() { + return toString(""); + } + + /** + * @param prependString + * String to prepend to configs + * @return String representation of configs + */ + std::string toString(std::string prependString) { + std::string retstr = CustomParamConfiguration::toString(prependString); + + return retstr; + } +};// struct Pigeon2 + +/** + * Util class to help with Pigeon configurations + */ +struct Pigeon2ConfigUtils { +private: + static Pigeon2Configuration _default; +public: + /** + * Determine if specified value is different from default + * @param settings settings to compare against + * @return if specified value is different from default + * @{ + */ + static bool MountPoseYawDifferent (const Pigeon2Configuration & settings) { return (!(settings.MountPoseYaw == _default.MountPoseYaw)) || !settings.enableOptimizations; } + static bool MountPosePitchDifferent (const Pigeon2Configuration & settings) { return (!(settings.MountPosePitch == _default.MountPosePitch)) || !settings.enableOptimizations; } + static bool MountPoseRollDifferent(const Pigeon2Configuration & settings) { return (!(settings.MountPoseRoll == _default.MountPoseRoll)) || !settings.enableOptimizations; } + static bool EnableCompassDifferent(const Pigeon2Configuration & settings) { return (!(settings.EnableCompass == _default.EnableCompass)) || !settings.enableOptimizations; } + static bool DisableTemperatureCompensationDifferent(const Pigeon2Configuration & settings) { return (!(settings.DisableTemperatureCompensation == _default.DisableTemperatureCompensation)) || !settings.enableOptimizations; } + static bool DisableNoMotionCalibrationDifferent(const Pigeon2Configuration & settings) { return (!(settings.DisableNoMotionCalibration == _default.DisableNoMotionCalibration)) || !settings.enableOptimizations; } + static bool XAxisGyroErrorDifferent(Pigeon2Configuration settings) { return (!(settings.XAxisGyroError == _default.XAxisGyroError)) || !settings.enableOptimizations; } + static bool YAxisGyroErrorDifferent(Pigeon2Configuration settings) { return (!(settings.YAxisGyroError == _default.YAxisGyroError)) || !settings.enableOptimizations; } + static bool ZAxisGyroErrorDifferent(Pigeon2Configuration settings) { return (!(settings.ZAxisGyroError == _default.ZAxisGyroError)) || !settings.enableOptimizations; } + static bool CustomParam0Different (const Pigeon2Configuration & settings) { return (!(settings.customParam0 == _default.customParam0)) || !settings.enableOptimizations; } + static bool CustomParam1Different (const Pigeon2Configuration & settings) { return (!(settings.customParam1 == _default.customParam1)) || !settings.enableOptimizations; } + /** @} */ +}; + +/** + * Enumerations for what primary axis to talk about + * Positive indicates in n the direction, negative indicates in the opposite direction + */ +enum class AxisDirection { + PositiveZ, + PositiveY, + PositiveX, + NegativeZ, + NegativeY, + NegativeX, +}; + +/** + * Pigeon 2 Class. Class supports communicating over CANbus. + * + *
+ * {@code
+ * // Example usage of a Pigeon 2
+ * Pigeon2 pigeon{0}; // creates a new Pigeon2 with ID 0
+ *
+ * Pigeon2Configuration config;
+ * // set mount pose as rolled 90 degrees counter-clockwise
+ * config.MountPoseYaw = 0;
+ * config.MountPosePitch = 0;
+ * config.MountPoseRoll = 90;
+ * pigeon.ConfigAllSettings(config);
+ *
+ * std::cout << pigeon.GetYaw() << std::endl; // prints the yaw of the Pigeon
+ * std::cout << pigeon.GetPitch() << std::endl; // prints the pitch of the Pigeon
+ * std::cout << pigeon.GetRoll() << std::endl; // prints the roll of the Pigeon
+ *
+ * double gravityVec[3];
+ * pigeon.GetGravityVector(gravityVec); // gets the gravity vector of the Pigeon 2
+ *
+ * ErrorCode error = pigeon.GetLastError(); // gets the last error generated by the Pigeon
+ * Pigeon2_Faults faults;
+ * ErrorCode faultsError = pigeon.GetFaults(faults); // fills faults with the current Pigeon 2 faults; returns the last error generated
+ * }
+ * 
+ */ +class Pigeon2: public BasePigeon { +public: + /** + * Create a Pigeon object that communicates with Pigeon on CAN Bus. + * + * @param deviceNumber + * CAN Device Id of Pigeon [0,62] + * @param canbus Name of the CANbus; can be a SocketCAN interface (on Linux), + * or a CANivore device name or serial number + */ + Pigeon2(int deviceNumber, std::string const &canbus = ""); + /** + * Gets the fault status + * + * @param toFill + * Container for fault statuses. + * @return Error Code generated by function. 0 indicates no error. + */ + ErrorCode GetFaults(Pigeon2_Faults & toFill) ; + /** + * Gets the sticky fault status + * + * @param toFill + * Container for sticky fault statuses. + * @return Error Code generated by function. 0 indicates no error. + */ + ErrorCode GetStickyFaults(Pigeon2_StickyFaults & toFill); + + /** + * Configure the Mount Pose using the primary axis. + * This is useful if the Pigeon 2.0 is mounted straight, and you only + * need to describe what axis is forward and what axis is up. + * + * @param forward Axis that points forward from the robot + * @param up Axis that points up from the robot + * @param timeoutMs Config timeout in milliseconds. + * @return OK if successful, InvalidParamValue if both forward and up are of the same primary axis, otherwise config return. + */ + ErrorCode ConfigMountPose(AxisDirection forward, AxisDirection up, int timeoutMs = 50); + + /** + * Configure the mounting pose of the Pigeon2.

+ * This is the Yaw-Pitch-Roll the Pigeon2 underwent to get to its current + * orientation, referenced from the robot's point of view.

+ * This is only necessary if the Pigeon2 is mounted at an exotic angle + * near the gimbal lock point or not forward.

+ * If the pigeon is relatively flat and pointed forward, this is not needed.

+ *

+ * Examples:

+ * If the Pigeon2 is pointed directly right, that corresponds to a -90 yaw, + * 0 pitch, and 0 roll, as it yaw'd 90 degrees clockwise.

+ * If the Pigeon2 points upwards, that's a 0 yaw, -90 pitch, 0 roll, as it + * pitched 90 degrees clockwise.

+ * @param yaw Yaw angle needed to reach the current orientation in degrees. + * @param pitch Pitch angle needed to reach the current orientation in degrees. + * @param roll Roll angle needed to reach the current orientation in degrees. + * @param timeoutMs Config timeout in milliseconds. + * @return Worst error code of all config sets. + */ + ErrorCode ConfigMountPose(double yaw, double pitch, double roll, int timeoutMs = 0); + /** + * Configure the mounting pose Yaw of the Pigeon2. + * See {@link #configMountPose(double, double, double, int)} + * + * @param yaw Yaw angle needed to reach the current orientation in degrees. + * @param timeoutMs Config timeout in milliseconds. + * @return ErrorCode of configSet + */ + ErrorCode ConfigMountPoseYaw(double yaw, int timeoutMs = 0); + /** + * Configure the mounting pose Pitch of the Pigeon2. + * See {@link #configMountPose(double, double, double, int)} + * + * @param pitch Pitch angle needed to reach the current orientation in degrees. + * @param timeoutMs Config timeout in milliseconds. + * @return ErrorCode of configSet + */ + ErrorCode ConfigMountPosePitch(double pitch, int timeoutMs = 0); + /** + * Configure the mounting pose Roll of the Pigeon2. + * See {@link #configMountPose(double, double, double, int)} + * + * @param roll Roll angle needed to reach the current orientation in degrees. + * @param timeoutMs Config timeout in milliseconds. + * @return ErrorCode of configSet + */ + ErrorCode ConfigMountPoseRoll(double roll, int timeoutMs = 0); + /** + * Configures the X Axis Gyroscope Error for 1 rotation + * @param err Degrees that Pigeon 2.0 overshot after 1 rotation (i.e. overshot 1 degree is 1; undershot by 3 degrees is -3) + * @param timeoutMs Config timeout in milliseconds. + * @return ErrorCode fo configSet + */ + ErrorCode ConfigXAxisGyroError(double err, int timeoutMs = 0); + /** + * Configures the Y Axis Gyroscope Error for 1 rotation + * @param err Degrees that Pigeon 2.0 overshot after 1 rotation (i.e. overshot 1 degree is 1; undershot by 3 degrees is -3) + * @param timeoutMs Config timeout in milliseconds. + * @return ErrorCode fo configSet + */ + ErrorCode ConfigYAxisGyroError(double err, int timeoutMs = 0); + /** + * Configures the Z Axis Gyroscope Error for 1 rotation + * @param err Degrees that Pigeon 2.0 overshot after 1 rotation (i.e. overshot 1 degree is 1; undershot by 3 degrees is -3) + * @param timeoutMs Config timeout in milliseconds. + * @return ErrorCode fo configSet + */ + ErrorCode ConfigZAxisGyroError(double err, int timeoutMs = 0); + + /** + * Enables the magnetometer fusion for Pigeon2. This is **not** recommended for FRC use + * + * @param enable Boolean to enable/disable magnetometer fusion + * @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 ErrorCode Status of the config response + */ + ErrorCode ConfigEnableCompass(bool enable, int timeoutMs = 0); + /** + * Disables temperature compensation from Pigeon2. + * + * @param disable Boolean to disable/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 ErrorCode Status of the config response + */ + ErrorCode ConfigDisableTemperatureCompensation(bool disable, int timeoutMs = 0); + /** + * Disables the no-motion calibration from Pigeon2 + * + * @param disable Boolean to disable/enable no-motion calibration + * @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 ErrorCode Status of the config response + */ + ErrorCode ConfigDisableNoMotionCalibration(bool disable, int timeoutMs = 0); + + /** + * Performs an offset calibration on gyro bias + * + * @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 ErrorCode Status of the config response + */ + ErrorCode ZeroGyroBiasNow(int timeoutMs = 0); + + /** + * Get the Gravity Vector. + * + * This provides a vector that points toward ground. This is useful for applications like + * an arm, where the z-value of the gravity vector corresponds to the feed-forward needed + * to hold the arm steady. + * The gravity vector is calculated after the mount pose, so if the pigeon is where it was + * mounted, the gravity vector is {0, 0, 1}. + * @param gravVector Pass in a double array of size 3 to get the gravity vector + * @return Errorcode of getter + */ + ErrorCode GetGravityVector(double gravVector[3]) const; + + /** + * Configures all persistent settings. + * + * @param allConfigs Object with all of the persistant settings + * @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. + */ + ErrorCode ConfigAllSettings(Pigeon2Configuration& settings, int timeoutMs = 50); + /** + * Gets all persistant settings. + * + * @param allConfigs Object with all of the persistant settings + * @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. + */ + void GetAllConfigs(Pigeon2Configuration& allConfigs, int timeoutMs = 50); + +};// class Pigeon2 +} // namespace signals +} // namespace phoenix +} // namespace ctre diff --git a/include/ctre/phoenix/sensors/Pigeon2_Faults.h b/include/ctre/phoenix/sensors/Pigeon2_Faults.h new file mode 100644 index 0000000..e7331b9 --- /dev/null +++ b/include/ctre/phoenix/sensors/Pigeon2_Faults.h @@ -0,0 +1,148 @@ +#pragma once + +#include + +namespace ctre { +namespace phoenix { +namespace sensors { + +/** + * Sticky faults available to Pigeon + */ +struct Pigeon2_Faults { + /** + * Device detects hardware failure + */ + bool HardwareFault; + /** + * API error detected. Make sure API and firmware versions are compatible. + */ + bool APIError; + /** + * Device is under 6.5V + */ + bool UnderVoltage; + /** + * Device was powered-on or reset while robot is enabled. + * Check your breakers and wiring. + */ + bool ResetDuringEn; + /** + * The device rotated at a rate that exceeded its maximum. + * Increase the range or slow the rate of rotation. + */ + bool SaturatedRotVelocity; + /** + * The device saw an acceleration that exceeded its maximum. + * Increase the range or avoid high-g events. + */ + bool SaturatedAccel; + /** + * The device saw a magnetic field that exceeded its maximum. + * Keep the device far from strong magnetic fields. + */ + bool SaturatedMag; + /** + * The Pigeon saw motion as soon as it booted, and didn't + * attempt to self-test its features. + * This isn't an issue, but to prevent this don't turn the + * robot on while moving it. + */ + bool BootIntoMotion; + /** + * The magnetometer failed its self-test. + * This is likely due to hardware damage, oftentimes from + * exposing the Pigeon to a very large magnetic field. + */ + bool MagnetometerFault; + /** + * The gyro failed its self-test. + * This is likely due to hardware damage. + */ + bool GyroFault; + /** + * The Accelerometer failed its self-test. + * This is likely due to hardware damage, oftentimes from + * exposing the Pigeon to a very large impact. + */ + bool AccelFault; + + /** + * @return true if any faults are tripped + */ + bool HasAnyFault() const { + return HardwareFault | + APIError | + UnderVoltage | + ResetDuringEn | + SaturatedRotVelocity | + SaturatedAccel | + SaturatedMag | + BootIntoMotion | + MagnetometerFault | + GyroFault | + AccelFault; + } + /** + * @return Current fault list as a bit field + */ + uint64_t ToBitfield() const { + uint64_t commonFaults = 0; + commonFaults |= HardwareFault ? 1 : 0; commonFaults <<= 1; + commonFaults |= APIError ? 1 : 0; commonFaults <<= 1; + commonFaults |= UnderVoltage ? 1 : 0; commonFaults <<= 1; + commonFaults |= ResetDuringEn ? 1 : 0; commonFaults <<= 1; + + uint64_t deviceFaults = 0; + deviceFaults |= SaturatedRotVelocity ? 1 : 0; deviceFaults <<= 1; + deviceFaults |= SaturatedAccel ? 1 : 0; deviceFaults <<= 1; + deviceFaults |= SaturatedMag ? 1 : 0; deviceFaults <<= 1; + deviceFaults <<= 1; /* Unused bitfield */ + deviceFaults <<= 1; + deviceFaults <<= 1; + deviceFaults |= BootIntoMotion ? 1 : 0; deviceFaults <<= 1; + deviceFaults |= MagnetometerFault ? 1 : 0; deviceFaults <<= 1; + deviceFaults |= GyroFault ? 1 : 0; deviceFaults <<= 1; + deviceFaults |= AccelFault ? 1 : 0; deviceFaults <<= 1; + + return commonFaults | (deviceFaults << 30); + } + /** + * Updates current fault list with specified bit field of faults + * + * @param bits bit field of faults to update with + */ + void Update(uint64_t bits) { + uint64_t mask = 1; + HardwareFault = (bits & mask) ? true : false; mask <<= 1; + APIError = (bits & mask) ? true : false; mask <<= 1; + UnderVoltage = (bits & mask) ? true : false; mask <<= 1; + ResetDuringEn = (bits & mask) ? true : false; mask <<= 1; + mask <<= 30; /* 30 faults currently unused */ + AccelFault = (bits & mask) ? true : false; mask <<= 1; + GyroFault = (bits & mask) ? true : false; mask <<= 1; + MagnetometerFault = (bits & mask) ? true : false; mask <<= 1; + BootIntoMotion = (bits & mask) ? true : false; mask <<= 1; + mask <<= 1; + mask <<= 1; + mask <<= 1; /* unused bit field */ + SaturatedMag = (bits & mask) ? true : false; mask <<= 1; + SaturatedAccel = (bits & mask) ? true : false; mask <<= 1; + SaturatedRotVelocity = (bits & mask) ? true : false; mask <<= 1; + } + /** + * Creates fault list with specified bit field of faults + * + * @param bits bit field of faults to update with + */ + Pigeon2_Faults(uint64_t bits) { + Update(bits); + } + Pigeon2_Faults() { + Update(0); // Default everything to false + } +}; + +} // sensors +} // phoenix +} // ctre diff --git a/include/ctre/phoenix/sensors/Pigeon2_StickyFaults.h b/include/ctre/phoenix/sensors/Pigeon2_StickyFaults.h new file mode 100644 index 0000000..02ff46c --- /dev/null +++ b/include/ctre/phoenix/sensors/Pigeon2_StickyFaults.h @@ -0,0 +1,148 @@ +#pragma once + +#include + +namespace ctre { +namespace phoenix { +namespace sensors { + +/** + * Sticky faults available to Pigeon + */ +struct Pigeon2_StickyFaults { + /** + * Device detects hardware failure + */ + bool HardwareFault; + /** + * API error detected. Make sure API and firmware versions are compatible. + */ + bool APIError; + /** + * Device is under 6.5V + */ + bool UnderVoltage; + /** + * Device was powered-on or reset while robot is enabled. + * Check your breakers and wiring. + */ + bool ResetDuringEn; + /** + * The device rotated at a rate that exceeded its maximum. + * Increase the range or slow the rate of rotation. + */ + bool SaturatedRotVelocity; + /** + * The device saw an acceleration that exceeded its maximum. + * Increase the range or avoid high-g events. + */ + bool SaturatedAccel; + /** + * The device saw a magnetic field that exceeded its maximum. + * Keep the device far from strong magnetic fields. + */ + bool SaturatedMag; + /** + * The Pigeon saw motion as soon as it booted, and didn't + * attempt to self-test its features. + * This isn't an issue, but to prevent this don't turn the + * robot on while moving it. + */ + bool BootIntoMotion; + /** + * The magnetometer failed its self-test. + * This is likely due to hardware damage, oftentimes from + * exposing the Pigeon to a very large magnetic field. + */ + bool MagnetometerFault; + /** + * The gyro failed its self-test. + * This is likely due to hardware damage. + */ + bool GyroFault; + /** + * The Accelerometer failed its self-test. + * This is likely due to hardware damage, oftentimes from + * exposing the Pigeon to a very large impact. + */ + bool AccelFault; + + /** + * @return true if any faults are tripped + */ + bool HasAnyFault() const { + return HardwareFault | + APIError | + UnderVoltage | + ResetDuringEn | + SaturatedRotVelocity | + SaturatedAccel | + SaturatedMag | + BootIntoMotion | + MagnetometerFault | + GyroFault | + AccelFault; + } + /** + * @return Current fault list as a bit field + */ + uint64_t ToBitfield() const { + uint64_t commonFaults = 0; + commonFaults |= HardwareFault ? 1 : 0; commonFaults <<= 1; + commonFaults |= APIError ? 1 : 0; commonFaults <<= 1; + commonFaults |= UnderVoltage ? 1 : 0; commonFaults <<= 1; + commonFaults |= ResetDuringEn ? 1 : 0; commonFaults <<= 1; + + uint64_t deviceFaults = 0; + deviceFaults |= SaturatedRotVelocity ? 1 : 0; deviceFaults <<= 1; + deviceFaults |= SaturatedAccel ? 1 : 0; deviceFaults <<= 1; + deviceFaults |= SaturatedMag ? 1 : 0; deviceFaults <<= 1; + deviceFaults <<= 1; /* Unused bitfield */ + deviceFaults <<= 1; + deviceFaults <<= 1; + deviceFaults |= BootIntoMotion ? 1 : 0; deviceFaults <<= 1; + deviceFaults |= MagnetometerFault ? 1 : 0; deviceFaults <<= 1; + deviceFaults |= GyroFault ? 1 : 0; deviceFaults <<= 1; + deviceFaults |= AccelFault ? 1 : 0; deviceFaults <<= 1; + + return commonFaults | (deviceFaults << 30); + } + /** + * Updates current fault list with specified bit field of faults + * + * @param bits bit field of faults to update with + */ + void Update(uint64_t bits) { + uint64_t mask = 1; + HardwareFault = (bits & mask) ? true : false; mask <<= 1; + APIError = (bits & mask) ? true : false; mask <<= 1; + UnderVoltage = (bits & mask) ? true : false; mask <<= 1; + ResetDuringEn = (bits & mask) ? true : false; mask <<= 1; + mask <<= 30; /* 30 faults currently unused */ + AccelFault = (bits & mask) ? true : false; mask <<= 1; + GyroFault = (bits & mask) ? true : false; mask <<= 1; + MagnetometerFault = (bits & mask) ? true : false; mask <<= 1; + BootIntoMotion = (bits & mask) ? true : false; mask <<= 1; + mask <<= 1; + mask <<= 1; + mask <<= 1; /* unused bit field */ + SaturatedMag = (bits & mask) ? true : false; mask <<= 1; + SaturatedAccel = (bits & mask) ? true : false; mask <<= 1; + SaturatedRotVelocity = (bits & mask) ? true : false; mask <<= 1; + } + /** + * Creates fault list with specified bit field of faults + * + * @param bits bit field of faults to update with + */ + Pigeon2_StickyFaults(uint64_t bits) { + Update(bits); + } + Pigeon2_StickyFaults() { + Update(0); // Default everything to false + } +}; + +} // sensors +} // phoenix +} // ctre diff --git a/include/ctre/phoenix/sensors/PigeonIMU.h b/include/ctre/phoenix/sensors/PigeonIMU.h index 9cc0779..363ff4e 100644 --- a/include/ctre/phoenix/sensors/PigeonIMU.h +++ b/include/ctre/phoenix/sensors/PigeonIMU.h @@ -24,14 +24,7 @@ #pragma once #include -#include "ctre/phoenix/CANBusAddressable.h" -#include "ctre/phoenix/CustomParamConfiguration.h" -#include "ctre/phoenix/paramEnum.h" -#include "ctre/phoenix/ErrorCode.h" -#include "ctre/phoenix/sensors/PigeonIMU_ControlFrame.h" -#include "ctre/phoenix/sensors/PigeonIMU_Faults.h" -#include "ctre/phoenix/sensors/PigeonIMU_StatusFrame.h" -#include "ctre/phoenix/sensors/PigeonIMU_StickyFaults.h" +#include "ctre/phoenix/sensors/BasePigeon.h" /* forward prototype */ namespace ctre { @@ -52,7 +45,7 @@ namespace sensors { /** * Configurables available to Pigeon */ -struct PigeonIMUConfiguration : CustomParamConfiguration{ +struct PigeonIMUConfiguration : public BasePigeonConfiguration{ PigeonIMUConfiguration() {} /** @@ -68,7 +61,7 @@ struct PigeonIMUConfiguration : CustomParamConfiguration{ * @return String representation of configs */ std::string toString(std::string prependString) { - std::string retstr = CustomParamConfiguration::toString(prependString); + std::string retstr = BasePigeonConfiguration::toString(prependString); return retstr; } @@ -77,18 +70,10 @@ struct PigeonIMUConfiguration : CustomParamConfiguration{ /** * Util class to help with Pigeon configurations */ -struct PigeonIMUConfigUtils { +struct PigeonIMUConfigUtils : public BasePigeonConfigUtils { private: static PigeonIMUConfiguration _default; public: - /** - * Determine if specified value is different from default - * @param settings settings to compare against - * @return if specified value is different from default - * @{ - */ - static bool CustomParam0Different (const PigeonIMUConfiguration & settings) { return (!(settings.customParam0 == _default.customParam0)) || !settings.enableOptimizations; } - static bool CustomParam1Different (const PigeonIMUConfiguration & settings) { return (!(settings.customParam1 == _default.customParam1)) || !settings.enableOptimizations; } /** @} */ }; @@ -96,7 +81,7 @@ struct PigeonIMUConfigUtils { * Pigeon IMU Class. * Class supports communicating over CANbus and over ribbon-cable (CAN Talon SRX). */ -class PigeonIMU: public CANBusAddressable { +class PigeonIMU: public BasePigeon { public: /** Data object for holding fusion information. */ struct FusionStatus { @@ -261,51 +246,21 @@ class PigeonIMU: public CANBusAddressable { /** * Create a Pigeon object that communciates with Pigeon through the * Gadgeteer ribbon cable connected to a Talon on CAN Bus. + * + * [[deprecated("Pass in a TalonSRX reference instead.")]] * * @param talonSrx * Object for the TalonSRX connected via ribbon cable. */ PigeonIMU(ctre::phoenix::motorcontrol::can::TalonSRX * talonSrx); - - ~PigeonIMU(); - - /** - * Destructs all pigeon objects - */ - static void DestroyAllPigeonIMUs(); - - /** - * Sets the Yaw register to the specified value. - * - * @param angleDeg Degree of Yaw [+/- 368,640 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. - */ - int SetYaw(double angleDeg, int timeoutMs = 0); /** - * 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. - */ - int AddYaw(double angleDeg, int timeoutMs = 0); - /** - * Sets the Yaw register to match the current compass value. + * Create a Pigeon object that communciates with Pigeon through the + * Gadgeteer ribbon cable connected to a Talon on CAN Bus. * - * @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. + * @param talonSrx + * Object for the TalonSRX connected via ribbon cable. */ - int SetYawToCompass(int timeoutMs = 0); + PigeonIMU(ctre::phoenix::motorcontrol::can::TalonSRX& talonSrx); /** * Sets the Fused Heading to the specified value. @@ -339,35 +294,6 @@ class PigeonIMU: public CANBusAddressable { * @return Error Code generated by function. 0 indicates no error. */ int SetFusedHeadingToCompass(int timeoutMs = 0); - /** - * 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. - */ - int SetAccumZAngle(double angleDeg, int timeoutMs = 0); - - /** - * @deprecated use setTemperatureCompensationDisable instead - * This was done to better match with the lower level API. - * NOTE: this isn't a persistant config, every boot temperature - * compensation will be enabled - * This was also done so the default value for the paramter is false instead of true. - * 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. - */ - int ConfigTemperatureCompensationEnable(bool bTempCompEnable, - int timeoutMs = 0); /** * Disable/Enable Temp compensation. Pigeon has this on/False at boot. @@ -428,108 +354,12 @@ class PigeonIMU: public CANBusAddressable { * @return Error Code generated by function. 0 indicates no error. */ int GetGeneralStatus(PigeonIMU::GeneralStatus & statusToFill); - /** - * 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. - */ - ErrorCode GetLastError(); - /** - * 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. - */ - int Get6dQuaternion(double wxyz[4]); - /** - * Get Yaw, Pitch, and Roll data. - * - * @param ypr Array to fill with yaw[0], pitch[1], and roll[2] data. - * Yaw is within [-368,640, +368,640] degrees. - * Pitch is within [-90,+90] degrees. - * Roll is within [-90,+90] degrees. - * @return The last ErrorCode generated. - */ - int GetYawPitchRoll(double ypr[3]); - /** - * 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. - */ - int GetAccumGyro(double xyz_deg[3]); - /** - * Get the absolute compass heading. - * @return compass heading [0,360) degrees. - */ - double GetAbsoluteCompassHeading(); - /** - * Get the continuous compass heading. - * @return continuous compass heading [-23040, 23040) degrees. Use - * SetCompassHeading to modify the wrap-around portion. - */ - double GetCompassHeading(); - /** - * Gets the compass' measured magnetic field strength. - * @return field strength in Microteslas (uT). - */ - double GetCompassFieldStrength(); - /** - * Gets the temperature of the pigeon. - * - * @return Temperature in ('C) - */ - double GetTemp(); /** * Gets the current Pigeon state * * @return PigeonState enum */ PigeonState GetState(); - /** - * Gets the current Pigeon uptime. - * - * @return How long has Pigeon been running in whole seconds. Value caps at - * 255. - */ - uint32_t GetUpTime(); - /** - * 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. - */ - int GetRawMagnetometer(int16_t rm_xyz[3]); - - /** - * 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. - */ - int GetBiasedMagnetometer(int16_t bm_xyz[3]); - /** - * 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. - */ - int GetBiasedAccelerometer(int16_t ba_xyz[3]); - /** - * 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. - */ - int GetRawGyro(double xyz_dps[3]); /** * Get Accelerometer tilt angles. * @@ -550,7 +380,7 @@ class PigeonIMU: public CANBusAddressable { * * @return The fused heading in degrees. */ - double GetFusedHeading(); + double GetFusedHeading() const; /** * @return number of times Pigeon Reset */ @@ -559,15 +389,6 @@ class PigeonIMU: public CANBusAddressable { * @return Reset flags for Pigeon */ uint32_t GetResetFlags(); - /** - * @return firmware version of Pigeon - */ - uint32_t GetFirmVers(); - - /** - * @return true iff a reset has occurred since last call. - */ - bool HasResetOccurred(); /** * Gets the string representation of a PigeonState @@ -616,69 +437,6 @@ class PigeonIMU: public CANBusAddressable { * @return Value of the custom param. */ int ConfigGetCustomParam(int paramIndex, int timeoutMs = 0); - /** - * 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. - */ - ErrorCode ConfigSetParameter(ParamEnum param, double value, - uint8_t subValue, int ordinal, int timeoutMs = 0); - /** - * 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. - */ - double ConfigGetParameter(ctre::phoenix::ParamEnum param, int ordinal, int timeoutMs = 0); - /** - * Gets a parameter by passing an int by reference - * - * @param param - * Parameter enumeration - * @param valueToSend - * Value to send to parameter - * @param valueReceived - * Reference to integer to receive - * @param subValue - * SubValue of parameter - * @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. - */ - ErrorCode ConfigGetParameter(ParamEnum param, int32_t valueToSend, - int32_t & valueReceived, uint8_t & subValue, int32_t ordinal, - int32_t timeoutMs); /** * Sets the period of the given status frame. @@ -750,13 +508,6 @@ class PigeonIMU: public CANBusAddressable { */ ErrorCode ClearStickyFaults(int timeoutMs = 0); - /** - * @return Pigeon resource handle. - */ - void* GetLowLevelHandle() { - return _handle; - } - //------ All Configs ----------// /** * Configures all persistent settings. @@ -827,8 +578,6 @@ class PigeonIMU: public CANBusAddressable { ResetStats _resetStats = { 0, 0, 0, false }; /** Portion of the arbID for all status and control frames. */ - void* _handle; - uint32_t _deviceNumber; uint32_t _usageHist = 0; uint64_t _cache; uint32_t _len; diff --git a/include/ctre/phoenix/sensors/PigeonIMU_Faults.h b/include/ctre/phoenix/sensors/PigeonIMU_Faults.h index 0a86055..f4f0c78 100644 --- a/include/ctre/phoenix/sensors/PigeonIMU_Faults.h +++ b/include/ctre/phoenix/sensors/PigeonIMU_Faults.h @@ -1,39 +1,49 @@ #pragma once +#include + namespace ctre { namespace phoenix { namespace sensors { /** - * Faults available to Pigeon (Currently has none) + * Sticky faults available to Pigeon */ struct PigeonIMU_Faults { + /** * @return true if any faults are tripped */ bool HasAnyFault() const { - return false; + return false; } /** * @return Current fault list as a bit field */ - int ToBitfield() const { - int retval = 0; - return retval; + uint64_t ToBitfield() const { + return 0; } /** * Updates current fault list with specified bit field of faults + * + * @param bits bit field of faults to update with + */ + void Update(uint64_t bits) { + (void)bits; + } + /** + * Creates fault list with specified bit field of faults * * @param bits bit field of faults to update with */ - PigeonIMU_Faults(int bits) { - (void)bits; + PigeonIMU_Faults(uint64_t bits) { + Update(bits); } PigeonIMU_Faults() { + Update(0); // Default everything to false } }; } // sensors } // phoenix } // ctre - diff --git a/include/ctre/phoenix/sensors/PigeonIMU_StickyFaults.h b/include/ctre/phoenix/sensors/PigeonIMU_StickyFaults.h index 79f53b4..f3da588 100644 --- a/include/ctre/phoenix/sensors/PigeonIMU_StickyFaults.h +++ b/include/ctre/phoenix/sensors/PigeonIMU_StickyFaults.h @@ -1,5 +1,7 @@ #pragma once +#include + namespace ctre { namespace phoenix { namespace sensors { @@ -8,28 +10,36 @@ namespace sensors { * Sticky faults available to Pigeon */ struct PigeonIMU_StickyFaults { + /** * @return true if any faults are tripped */ bool HasAnyFault() const { - return false; + return false; } /** * @return Current fault list as a bit field */ - int ToBitfield() const { - int retval = 0; - return retval; + uint64_t ToBitfield() const { + return 0; + } + /** + * Updates current fault list with specified bit field of faults + * + * @param bits bit field of faults to update with + */ + void Update(uint64_t bits) { } /** * Creates fault list with specified bit field of faults * * @param bits bit field of faults to update with */ - PigeonIMU_StickyFaults(int bits) { - (void)bits; + PigeonIMU_StickyFaults(uint64_t bits) { + Update(bits); } PigeonIMU_StickyFaults() { + Update(0); // Default everything to false } }; diff --git a/include/ctre/phoenix/string_util/string_util.h b/include/ctre/phoenix/string_util/string_util.h index a92cd24..0f44efa 100644 --- a/include/ctre/phoenix/string_util/string_util.h +++ b/include/ctre/phoenix/string_util/string_util.h @@ -1,4 +1,5 @@ #pragma once +#include "ctre/phoenix/export.h" #include #include #include @@ -7,15 +8,16 @@ namespace ctre { namespace phoenix { namespace string_util { - std::deque string_split(const std::string& input, char delimiter); - std::string toLower(const std::string& input); - int strcmp_nocase(char const* a, char const* b); - uint32_t safe_memcpy_(uint8_t* dest, const uint8_t* src, uint32_t numBytesToCopy, uint32_t capacity); - uint32_t safe_memcpy_(uint8_t* dest, const uint8_t* src, int32_t numBytesToCopy, int32_t capacity); - uint32_t safe_copyDoubles(double* dest, const double* src, int32_t numDoubles, int32_t capacityDoubles); - uint32_t safe_copyDoubles(double* dest, const std::vector& src, int32_t capacityDoubles); - uint32_t safe_strlen(const char* s, int32_t maxsize); - void safe_strcopy(std::string& dest, const char* src); + CTREXPORT std::deque string_split(const std::string& input, char delimiter); + CTREXPORT std::string toLower(const std::string& input); + CTREXPORT int strcmp_nocase(char const* a, char const* b); + CTREXPORT uint32_t safe_memcpy_(uint8_t* dest, const uint8_t* src, uint32_t numBytesToCopy, uint32_t capacity); + CTREXPORT uint32_t safe_memcpy_(uint8_t* dest, const uint8_t* src, int32_t numBytesToCopy, int32_t capacity); + CTREXPORT uint32_t safe_copyDoubles(double* dest, const double* src, int32_t numDoubles, int32_t capacityDoubles); + CTREXPORT uint32_t safe_copyDoubles(double* dest, const std::vector& src, int32_t capacityDoubles); + CTREXPORT uint32_t safe_strlen(const char* s, int32_t maxsize); + CTREXPORT void safe_strcopy(std::string& dest, const char* src); + CTREXPORT char *strtok_next(char **str_ptr, char const *delimiters); } // namespace string_util } // namespace phoenix } // namespace ctre diff --git a/include/ctre/phoenix/tasking/ButtonMonitor.h b/include/ctre/phoenix/tasking/ButtonMonitor.h deleted file mode 100644 index ff8878e..0000000 --- a/include/ctre/phoenix/tasking/ButtonMonitor.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "ctre/phoenix/Tasking/ILoopable.h" -#include "ctre/phoenix/Tasking/IProcessable.h" -#include - -#if defined(CTR_INCLUDE_WPILIB_CLASSES) || defined(__FRC_ROBORIO__) - -/* forward proto's */ -namespace frc { - class GenericHID; -} - -namespace ctre { -namespace phoenix { -namespace tasking { - -class ButtonMonitor: public IProcessable, public ILoopable { -public: - - class IButtonPressEventHandler { - public: - virtual ~IButtonPressEventHandler(){} - virtual void OnButtonPress(int idx, bool isDown) = 0; - }; - - ButtonMonitor(frc::GenericHID * controller, int buttonIndex, IButtonPressEventHandler * ButtonPressEventHandler); - ButtonMonitor(const ButtonMonitor & rhs); - virtual ~ButtonMonitor() { } - - /* IProcessable */ - virtual void Process(); - - /* ILoopable */ - virtual void OnStart(); - virtual void OnLoop(); - virtual bool IsDone(); - virtual void OnStop(); - -private: - frc::GenericHID * _gameCntrlr; - int _btnIdx; - IButtonPressEventHandler * _handler; - bool _isDown = false; -}; -} -} -} -#endif // CTR_INCLUDE_WPILIB_CLASSES or __FRC_ROBORIO__ diff --git a/include/ctre/phoenix/tasking/Schedulers/ConcurrentScheduler(1).h b/include/ctre/phoenix/tasking/Schedulers/ConcurrentScheduler(1).h deleted file mode 100644 index 676c8b8..0000000 --- a/include/ctre/phoenix/tasking/Schedulers/ConcurrentScheduler(1).h +++ /dev/null @@ -1,88 +0,0 @@ -#pragma once - -#include -#include "ctre/phoenix/tasking/ILoopable.h" -#include "ctre/phoenix/tasking/IProcessable.h" - -namespace ctre { -namespace phoenix { -/** tasking namespace */ -namespace tasking { -/** schedulers namespace */ -namespace schedulers { - -/** - * Scheduler that wil run its ILoopables in concurrency - */ -class ConcurrentScheduler: public ILoopable, public IProcessable { -public: - /** Should be private */ - std::vector _loops; - /** Should be private */ - std::vector _enabs; - - ConcurrentScheduler(); - virtual ~ConcurrentScheduler(); - /** - * Add ILoopable to schedule - * @param aLoop ILoopable to add to schedule - * @param enable Whether to enable ILoopable - */ - void Add(ILoopable *aLoop, bool enable = true); - /** - * Remove all ILoopables from scheduler - */ - void RemoveAll(); - /** - * Start an ILoopable - * @param toStart ILoopable to start - */ - void Start(ILoopable *toStart); - /** - * Stop an ILoopable - * @param toStop ILoopable to stop - */ - void Stop(ILoopable *toStop); - /** - * Start all ILoopables - */ - void StartAll(); - /** - * Stop all ILoopables - */ - void StopAll(); - - //IProcessable - /** - * Process every ILoopable - * - * Call this every loop - */ - void Process(); - - //ILoopable - /** - * @return false, this never iterates - */ - bool Iterated(); - /** - * Start all ILoopables - */ - void OnStart(); - /** - * Process all ILoopables - */ - void OnLoop(); - /** - * Stop all ILoopables - */ - void OnStop(); - /** - * @return false, this is never done - */ - bool IsDone(); -}; -} -} -} -} diff --git a/include/ctre/phoenix/tasking/Schedulers/SequentialScheduler(1).h b/include/ctre/phoenix/tasking/Schedulers/SequentialScheduler(1).h deleted file mode 100644 index edaa92c..0000000 --- a/include/ctre/phoenix/tasking/Schedulers/SequentialScheduler(1).h +++ /dev/null @@ -1,75 +0,0 @@ -#pragma once - -#include -#include "ctre/phoenix/tasking/ILoopable.h" -#include "ctre/phoenix/tasking/IProcessable.h" - -namespace ctre { namespace phoenix { namespace tasking { namespace schedulers { - -/** - * Scheduler that will run its ILoopables in sequence - */ -class SequentialScheduler: public ILoopable, public IProcessable{ -public: - /** should be private */ - bool _running = false; - /** should be private */ - std::vector _loops; - /** should be private */ - unsigned int _idx = 0; - /** should be private */ - bool _iterated = false; - - SequentialScheduler(); - virtual ~SequentialScheduler(); - - /** - * Add ILoopable to scheduler - * @param aLoop ILoopable to add - */ - void Add(ILoopable *aLoop); - /** - * Get the currently running ILoopable - * @return null, not implemented - */ - ILoopable * GetCurrent(); - /** - * Remove all ILoopables - */ - void RemoveAll(); - /** - * Start next ILoopable - */ - void Start(); - /** - * Stop every ILoopable - */ - void Stop(); - - //IProcessable - /** - * Process the currently active ILoopable - * - * Call this every loop - */ - void Process(); - - //ILoopable - /** - * Start next ILoopable - */ - void OnStart(); - /** - * Process currently active ILoopable - */ - void OnLoop(); - /** - * Stop all ILoopables - */ - void OnStop(); - /** - * @return true when no longer running - */ - bool IsDone(); -}; -}}}} diff --git a/include/ctre/phoenix/unmanaged/Unmanaged.h b/include/ctre/phoenix/unmanaged/Unmanaged.h index 0eaa195..9cc668e 100644 --- a/include/ctre/phoenix/unmanaged/Unmanaged.h +++ b/include/ctre/phoenix/unmanaged/Unmanaged.h @@ -1,37 +1,59 @@ #pragma once +namespace ctre { +namespace phoenix { +/** unmanaged namespace */ +namespace unmanaged { -#include +/** + * Handles enabling when used in a non-FRC manner + */ +class Unmanaged { +public: + /** + * Feed the enable frame. + * This function does nothing on a roborio during FRC use. + * + * If running an application in simulation, creating a WPI_* + * object automatically enables actuators. + * Otherwise, call this to enable actuators. + * + * @param timeoutMs Timeout before disabling + */ + static void FeedEnable(int timeoutMs); + /** + * @return true if enabled + */ + static bool GetEnableState(); + /** + * @return Phoenix version + */ + static int GetPhoenixVersion(); + /** + * Calling this function will load and start + * the Phoenix background tasks. + * + * This can be useful if you need the + * Enable/Disable functionality for CAN devices + * but aren't using any of the CAN device classes. + * + * This function does NOT need to be called if + * you are using any of the Phoenix CAN device classes. + */ + static void LoadPhoenix(); -namespace ctre { - namespace phoenix { - namespace unmanaged { - /** - * Feed the robot enable. - * This function does nothing on a roborio during FRC use. - * @param timeoutMs Timeout before disabling - */ - void FeedEnable(int timeoutMs); - /** - * @return true if enabled - */ - bool GetEnableState(); - /** - * Sets whether to enable transmitting - * This function does nothing on a roborio during FRC use. - * @param en True enables transmitting - */ - void SetTransmitEnable(bool en); - /** - * @return true if transmitting is enabled - */ - bool GetTransmitEnable(); - /** - * @return Phoenix version - */ - int GetPhoenixVersion(); - void LoadPhoenix(); + /** + * Sets the duration of the delay before starting + * the Phoenix diagnostics server. + * + * @param startTime Magnitude of the delay (in seconds) before + * starting the server. + * A value of 0 will start the server immediately. + * A negative value will signal the server + * to shutdown or never start. + */ + static void SetPhoenixDiagnosticsStartTime(int startTimeSeconds); +}; - int IoControl(uint32_t ioControlCode, uint64_t ioControlParam, char* inValue = 0, int inValueSize = 0, char* outValue = 0, int outValueSize = 0); - } - } +} +} } diff --git a/launch/ros_control_test.launch b/launch/ros_control_test.launch index 06a4d58..5b82473 100644 --- a/launch/ros_control_test.launch +++ b/launch/ros_control_test.launch @@ -3,8 +3,8 @@ - - \ No newline at end of file + diff --git a/lib/jetsontx/libCTRE_Phoenix.a b/lib/jetsontx/libCTRE_Phoenix.a deleted file mode 100644 index 7bb7701..0000000 Binary files a/lib/jetsontx/libCTRE_Phoenix.a and /dev/null differ diff --git a/lib/jetsontx/libCTRE_Phoenix.so b/lib/jetsontx/libCTRE_Phoenix.so new file mode 100644 index 0000000..963f205 Binary files /dev/null and b/lib/jetsontx/libCTRE_Phoenix.so differ diff --git a/lib/jetsontx/libCTRE_PhoenixCCI.a b/lib/jetsontx/libCTRE_PhoenixCCI.a deleted file mode 100644 index b530f88..0000000 Binary files a/lib/jetsontx/libCTRE_PhoenixCCI.a and /dev/null differ diff --git a/lib/jetsontx/libCTRE_PhoenixCCI.so b/lib/jetsontx/libCTRE_PhoenixCCI.so new file mode 100644 index 0000000..8219f3b Binary files /dev/null and b/lib/jetsontx/libCTRE_PhoenixCCI.so differ diff --git a/lib/jetsontx/libCTRE_PhoenixCanutils.a b/lib/jetsontx/libCTRE_PhoenixCanutils.a deleted file mode 100644 index 196f9f0..0000000 Binary files a/lib/jetsontx/libCTRE_PhoenixCanutils.a and /dev/null differ diff --git a/lib/jetsontx/libCTRE_PhoenixCore.a b/lib/jetsontx/libCTRE_PhoenixCore.a deleted file mode 100644 index a79bf4b..0000000 Binary files a/lib/jetsontx/libCTRE_PhoenixCore.a and /dev/null differ diff --git a/lib/jetsontx/libCTRE_PhoenixDiagnostics.a b/lib/jetsontx/libCTRE_PhoenixDiagnostics.a deleted file mode 100644 index e7162e3..0000000 Binary files a/lib/jetsontx/libCTRE_PhoenixDiagnostics.a and /dev/null differ diff --git a/lib/jetsontx/libCTRE_PhoenixPlatform_socketcan.a b/lib/jetsontx/libCTRE_PhoenixPlatform_socketcan.a deleted file mode 100644 index 4e37336..0000000 Binary files a/lib/jetsontx/libCTRE_PhoenixPlatform_socketcan.a and /dev/null differ diff --git a/lib/raspberry/libCTRE_Phoenix.a b/lib/raspberry/libCTRE_Phoenix.a deleted file mode 100644 index 8dcbc7a..0000000 Binary files a/lib/raspberry/libCTRE_Phoenix.a and /dev/null differ diff --git a/lib/raspberry/libCTRE_Phoenix.so b/lib/raspberry/libCTRE_Phoenix.so new file mode 100644 index 0000000..2f68353 Binary files /dev/null and b/lib/raspberry/libCTRE_Phoenix.so differ diff --git a/lib/raspberry/libCTRE_PhoenixCCI.a b/lib/raspberry/libCTRE_PhoenixCCI.a deleted file mode 100644 index 0df33c8..0000000 Binary files a/lib/raspberry/libCTRE_PhoenixCCI.a and /dev/null differ diff --git a/lib/raspberry/libCTRE_PhoenixCCI.so b/lib/raspberry/libCTRE_PhoenixCCI.so new file mode 100644 index 0000000..fa57136 Binary files /dev/null and b/lib/raspberry/libCTRE_PhoenixCCI.so differ diff --git a/lib/raspberry/libCTRE_PhoenixCanutils.a b/lib/raspberry/libCTRE_PhoenixCanutils.a deleted file mode 100644 index f91ea38..0000000 Binary files a/lib/raspberry/libCTRE_PhoenixCanutils.a and /dev/null differ diff --git a/lib/raspberry/libCTRE_PhoenixCore.a b/lib/raspberry/libCTRE_PhoenixCore.a deleted file mode 100644 index 50d8fd0..0000000 Binary files a/lib/raspberry/libCTRE_PhoenixCore.a and /dev/null differ diff --git a/lib/raspberry/libCTRE_PhoenixDiagnostics.a b/lib/raspberry/libCTRE_PhoenixDiagnostics.a deleted file mode 100644 index ac9d87e..0000000 Binary files a/lib/raspberry/libCTRE_PhoenixDiagnostics.a and /dev/null differ diff --git a/lib/raspberry/libCTRE_PhoenixPlatform_socketcan.a b/lib/raspberry/libCTRE_PhoenixPlatform_socketcan.a deleted file mode 100644 index 019e0b9..0000000 Binary files a/lib/raspberry/libCTRE_PhoenixPlatform_socketcan.a and /dev/null differ diff --git a/lib/x86-64/libCTRE_Phoenix.a b/lib/x86-64/libCTRE_Phoenix.a deleted file mode 100644 index 2434b88..0000000 Binary files a/lib/x86-64/libCTRE_Phoenix.a and /dev/null differ diff --git a/lib/x86-64/libCTRE_Phoenix.so b/lib/x86-64/libCTRE_Phoenix.so new file mode 100644 index 0000000..8cc1406 Binary files /dev/null and b/lib/x86-64/libCTRE_Phoenix.so differ diff --git a/lib/x86-64/libCTRE_PhoenixCCI.a b/lib/x86-64/libCTRE_PhoenixCCI.a deleted file mode 100644 index 79ec84a..0000000 Binary files a/lib/x86-64/libCTRE_PhoenixCCI.a and /dev/null differ diff --git a/lib/x86-64/libCTRE_PhoenixCCI.so b/lib/x86-64/libCTRE_PhoenixCCI.so new file mode 100644 index 0000000..7e394ac Binary files /dev/null and b/lib/x86-64/libCTRE_PhoenixCCI.so differ diff --git a/lib/x86-64/libCTRE_PhoenixCanutils.a b/lib/x86-64/libCTRE_PhoenixCanutils.a deleted file mode 100644 index 0c46f43..0000000 Binary files a/lib/x86-64/libCTRE_PhoenixCanutils.a and /dev/null differ diff --git a/lib/x86-64/libCTRE_PhoenixCore.a b/lib/x86-64/libCTRE_PhoenixCore.a deleted file mode 100644 index 2e1dbf7..0000000 Binary files a/lib/x86-64/libCTRE_PhoenixCore.a and /dev/null differ diff --git a/lib/x86-64/libCTRE_PhoenixDiagnostics.a b/lib/x86-64/libCTRE_PhoenixDiagnostics.a deleted file mode 100644 index e60caf5..0000000 Binary files a/lib/x86-64/libCTRE_PhoenixDiagnostics.a and /dev/null differ diff --git a/lib/x86-64/libCTRE_PhoenixPlatform_socketcan.a b/lib/x86-64/libCTRE_PhoenixPlatform_socketcan.a deleted file mode 100644 index 5709ca3..0000000 Binary files a/lib/x86-64/libCTRE_PhoenixPlatform_socketcan.a and /dev/null differ diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index b460308..f7e4f95 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(CalibrateMagnetometer) add_subdirectory(RawTalonTest) -add_subdirectory(RosControlTest) -add_subdirectory(MockMotors) \ No newline at end of file +add_subdirectory(RosPhoenix) +add_subdirectory(MockMotors) diff --git a/src/app/CalibrateMagnetometer/CMakeLists.txt b/src/app/CalibrateMagnetometer/CMakeLists.txt new file mode 100644 index 0000000..7c01563 --- /dev/null +++ b/src/app/CalibrateMagnetometer/CMakeLists.txt @@ -0,0 +1,7 @@ +add_executable(CalibrateMagnetometer) + +target_sources(CalibrateMagnetometer PRIVATE main.cpp) + +target_link_libraries(CalibrateMagnetometer PRIVATE hardware) + +MakeTalonTarget(CalibrateMagnetometer) diff --git a/src/app/CalibrateMagnetometer/main.cpp b/src/app/CalibrateMagnetometer/main.cpp new file mode 100644 index 0000000..db1b531 --- /dev/null +++ b/src/app/CalibrateMagnetometer/main.cpp @@ -0,0 +1,33 @@ +#include "PigeonIMU.h" +#include "ctre/phoenix/platform/can/PlatformCAN.h" +#include +#include +#include +#include +#include + +using Hardware::PigeonIMU; +using std::this_thread::sleep_for; + +constexpr int32_t PIGEON_CAN_ID{10}; +constexpr std::chrono::seconds LONG_WAIT{60}; + +auto main() -> int32_t { + + ctre::phoenix::platform::can::PlatformCAN::SetCANInterface("can0"); + std::cout << "Hardware setup" << std::endl; + + auto pigeon{std::make_shared(PIGEON_CAN_ID, "pigeon")}; + pigeon->enableCompass(false); + + std::cout << "Starting calibration" << std::endl; + + pigeon->startMagCal(); + + sleep_for(LONG_WAIT); + + std::cout << "Saving calibration" << std::endl; + + pigeon->endMagCal(true); + +} diff --git a/src/app/RawTalonTest/test.cpp b/src/app/RawTalonTest/test.cpp index 467785e..89bdac7 100644 --- a/src/app/RawTalonTest/test.cpp +++ b/src/app/RawTalonTest/test.cpp @@ -2,6 +2,7 @@ #include "Group.h" #include "Motor.h" #include "ctre/phoenix/platform/Platform.h" +#include "ctre/phoenix/platform/can/PlatformCAN.h" #include "ctre/phoenix/unmanaged/Unmanaged.h" #include #include @@ -26,9 +27,9 @@ auto main() -> int32_t { short int some_num = 0; - ctre::phoenix::platform::can::SetCANInterface("can0"); + ctre::phoenix::platform::can::PlatformCAN::SetCANInterface("can0"); std::cout << "Starting motor" << std::endl; - ctre::phoenix::unmanaged::FeedEnable(FEED_ENABLE_TIMEOUT_MILLISECONDS); + ctre::phoenix::unmanaged::Unmanaged::FeedEnable(FEED_ENABLE_TIMEOUT_MILLISECONDS); TalonFX mtr{1}; // mtr.Set(ctre::phoenix::motorcontrol::ControlMode::PercentOutput, 0.2); @@ -39,7 +40,7 @@ auto main() -> int32_t { std::shared_ptr testMotor2 = std::make_shared(MOTOR_2_ID, "MOTOR2"); Group testGroup1{"testGroup1"}; - std::cout << "Enable state: " << ctre::phoenix::unmanaged::GetEnableState() << std::endl; + std::cout << "Enable state: " << ctre::phoenix::unmanaged::Unmanaged::GetEnableState() << std::endl; testMotor1->setPower(0.5); testGroup1.addControlGroup(testMotor1); @@ -73,7 +74,7 @@ auto main() -> int32_t { testGroup1.clearGroup(); printControlGroup(testGroup1); -}; +} void printControlGroup(const ControlGroup &obj) { std::cout << "Motor Name: " << obj.getName() << std::endl; diff --git a/src/app/RosControlTest/CMakeLists.txt b/src/app/RosControlTest/CMakeLists.txt deleted file mode 100644 index a9831e3..0000000 --- a/src/app/RosControlTest/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -add_executable(RosControlTest) - -target_sources(RosControlTest PRIVATE main.cpp) - -target_link_libraries(RosControlTest PRIVATE hardware ros-handler) - -MakeROSTarget(RosControlTest) - -MakeTalonTarget(RosControlTest) \ No newline at end of file diff --git a/src/app/RosPhoenix/CMakeLists.txt b/src/app/RosPhoenix/CMakeLists.txt new file mode 100644 index 0000000..35c3a6b --- /dev/null +++ b/src/app/RosPhoenix/CMakeLists.txt @@ -0,0 +1,9 @@ +add_executable(RosPhoenix) + +target_sources(RosPhoenix PRIVATE main.cpp) + +target_link_libraries(RosPhoenix PRIVATE hardware ros-handler) + +MakeROSTarget(RosPhoenix) + +MakeTalonTarget(RosPhoenix) diff --git a/src/app/RosControlTest/main.cpp b/src/app/RosPhoenix/main.cpp similarity index 76% rename from src/app/RosControlTest/main.cpp rename to src/app/RosPhoenix/main.cpp index 83a720b..4c936d5 100644 --- a/src/app/RosControlTest/main.cpp +++ b/src/app/RosPhoenix/main.cpp @@ -2,6 +2,8 @@ #include "ControlGroupRosHandler.h" #include "Group.h" #include "Motor.h" +#include "PigeonIMU.h" +#include "PigeonRosHandler.h" #include "ros/node_handle.h" #include #include @@ -10,12 +12,13 @@ #include "ctre/phoenix/platform/Platform.h" +#include "ctre/phoenix/platform/can/PlatformCAN.h" #include "ctre/phoenix/unmanaged/Unmanaged.h" auto main(int32_t argc, char **argv) -> int32_t { // TODO (@Tzanccc): currently a magic string, consider changing it use command line arguments or some other equivalent - ctre::phoenix::platform::can::SetCANInterface("can0"); + ctre::phoenix::platform::can::PlatformCAN::SetCANInterface("can0"); std::cout << "wrevolution ROS test start..." << std::endl; @@ -39,6 +42,13 @@ auto main(int32_t argc, char **argv) -> int32_t { rightGroup->addControlGroup(motor5); rightGroup->addControlGroup(motor6); + leftGroup->setZeroPowerBehavior(Hardware::ZeroPowerBehavior::COAST); + rightGroup->setZeroPowerBehavior(Hardware::ZeroPowerBehavior::COAST); + + auto pigeonIMU{std::make_shared(10, "pigeon")}; + pigeonIMU->setOrientation(AxisDirection::NegativeX, AxisDirection::PositiveZ); + pigeonIMU->enableCompass(false); + std::cout << "Motor setup complete!" << std::endl; // Setup ROS Interface @@ -50,6 +60,7 @@ auto main(int32_t argc, char **argv) -> int32_t { auto leftHandler{std::make_unique(node, leftGroup)}; auto rightHandler{std::make_unique(node, rightGroup)}; + auto pigeonHandler{std::make_shared(node, pigeonIMU)}; std::cout << "ROS Setup complete!" << std::endl; diff --git a/src/app/RosControlTest/test_sinusoidal_power.py b/src/app/RosPhoenix/test_sinusoidal_power.py similarity index 85% rename from src/app/RosControlTest/test_sinusoidal_power.py rename to src/app/RosPhoenix/test_sinusoidal_power.py index beca755..53d409c 100755 --- a/src/app/RosControlTest/test_sinusoidal_power.py +++ b/src/app/RosPhoenix/test_sinusoidal_power.py @@ -1,14 +1,15 @@ #!/usr/bin/env python3 import rospy import std_msgs + rospy.init_node("temp_node") import math + pub = rospy.Publisher("/MOTOR_1/power", std_msgs.msg.Float64, queue_size=10) rate = rospy.Rate(20) t = 0 while not rospy.is_shutdown(): - p = math.sin(2*math.pi*t/(20*10)) + p = math.sin(2 * math.pi * t / (20 * 10)) t += 1 pub.publish(p) rate.sleep() - diff --git a/src/hardware/CMakeLists.txt b/src/hardware/CMakeLists.txt index 01abb9c..b77678b 100644 --- a/src/hardware/CMakeLists.txt +++ b/src/hardware/CMakeLists.txt @@ -5,10 +5,11 @@ target_sources(hardware src/Group.cpp src/Motor.cpp src/MockMotor.cpp + src/PigeonIMU.cpp ) target_include_directories(hardware PUBLIC include) MakeTalonTarget(hardware) # TODO (@bennowotny ): hardware should not depend on ROS -MakeROSTarget(hardware) \ No newline at end of file +MakeROSTarget(hardware) diff --git a/src/hardware/include/PigeonIMU.h b/src/hardware/include/PigeonIMU.h new file mode 100644 index 0000000..ad5d51d --- /dev/null +++ b/src/hardware/include/PigeonIMU.h @@ -0,0 +1,33 @@ +#ifndef PIGEON_H +#define PIGEON_H + +#include +#include + +#define Phoenix_No_WPI +#include "ctre/phoenix/sensors/Pigeon2.h" + +using ctre::phoenix::sensors::Pigeon2; +using ctre::phoenix::sensors::AxisDirection; + +namespace Hardware { +class PigeonIMU { +public: + explicit PigeonIMU(uint8_t canID, std::string friendlyName); + auto getName() const -> std::string; + [[nodiscard]] auto getYaw() const -> std::optional; + void setOrientation(AxisDirection forward, AxisDirection up); + void setYaw(double angleDeg); + void startMagCal(); + void endMagCal(bool saveMagCal); + void enableCompass(bool enable); + +private: + mutable std::mutex mutex; + std::unique_ptr imu; + uint8_t deviceID; + const std::string friendlyName; +}; +} // namespace Hardware + +#endif diff --git a/src/hardware/src/Motor.cpp b/src/hardware/src/Motor.cpp index 224eb47..cc752ed 100644 --- a/src/hardware/src/Motor.cpp +++ b/src/hardware/src/Motor.cpp @@ -36,7 +36,7 @@ Motor::Motor(uint8_t motorID, std::string friendlyName) void Motor::setPower(double power) { const std::lock_guard lock{mutex}; - ctre::phoenix::unmanaged::FeedEnable(5000); + ctre::phoenix::unmanaged::Unmanaged::FeedEnable(5000); motor->Set(ControlMode::PercentOutput, power); const auto err{motor->GetLastError()}; using std::string_literals::operator""s; diff --git a/src/hardware/src/PigeonIMU.cpp b/src/hardware/src/PigeonIMU.cpp new file mode 100644 index 0000000..a7a6407 --- /dev/null +++ b/src/hardware/src/PigeonIMU.cpp @@ -0,0 +1,61 @@ +#include +#include +#include +#include + +#include "PigeonIMU.h" +#include "ctre/phoenix/paramEnum.h" + +#define Phoenix_No_WPI +#include "ctre/phoenix/sensors/Pigeon2.h" + +namespace Hardware { + +PigeonIMU::PigeonIMU(uint8_t canID, std::string friendlyName) : + imu{std::make_unique(canID)}, + deviceID{canID}, + friendlyName{std::move(friendlyName)} { + + } + +auto PigeonIMU::getName() const -> std::string{ + const std::lock_guard lock{mutex}; + return friendlyName; +} + +void PigeonIMU::setOrientation(AxisDirection forward, AxisDirection up) { + imu->ConfigMountPose(forward, up); +} + +auto PigeonIMU::getYaw() const -> std::optional { + const std::lock_guard lock{mutex}; + double angle = std::fmod(imu->GetYaw(), 360); + angle = angle >= 0 ? angle : angle + 360; + return std::make_optional(angle); +} + +void PigeonIMU::setYaw(double angleDeg) { + const std::lock_guard lock{mutex}; + imu->SetYaw(angleDeg); +} + +void PigeonIMU::startMagCal() { + imu->ConfigSetParameter(ctre::phoenix::eMagCalRunning, 1, 0, 0); +} + +void PigeonIMU::endMagCal(bool saveMagCal) { + // Apply calibration + if (saveMagCal) { + imu->ConfigSetParameter(ctre::phoenix::eMagCal, 0, 0, 0); + } + imu->ConfigSetParameter(ctre::phoenix::eMagCalRunning, 0, 0, 0); +} + +void PigeonIMU::enableCompass(bool enable) { + imu->ConfigEnableCompass(enable); + if (enable) { + imu->SetYawToCompass(); + } +} + +} diff --git a/src/ros-handler/CMakeLists.txt b/src/ros-handler/CMakeLists.txt index 6552106..8f8b347 100644 --- a/src/ros-handler/CMakeLists.txt +++ b/src/ros-handler/CMakeLists.txt @@ -4,6 +4,7 @@ target_sources(ros-handler PRIVATE src/ros-handler-core/RosTimedAction.cpp src/ros-handler-core/ControlGroupRosTimedAction.cpp + src/ros-handler-core/PigeonRosTimedAction.cpp src/EncoderTimedAction.cpp src/ZeroPowerBehaviorServiceAction.cpp src/PowerSubscribedAction.cpp @@ -11,6 +12,9 @@ target_sources(ros-handler src/ResetSettingsServiceAction.cpp src/ResetEncoderServiceAction.cpp src/ReverseServiceAction.cpp + src/PigeonRosHandler.cpp + src/HeadingTimedAction.cpp + src/SetHeadingServiceAction.cpp ) target_link_libraries(ros-handler PRIVATE hardware) diff --git a/src/ros-handler/include/EncoderTimedAction.h b/src/ros-handler/include/EncoderTimedAction.h index 6ecfe18..34c0bf5 100644 --- a/src/ros-handler/include/EncoderTimedAction.h +++ b/src/ros-handler/include/EncoderTimedAction.h @@ -18,10 +18,10 @@ class EncoderTimedAction : public ControlGroupRosTimedAction { void onTimerEvent(const ros::TimerEvent &event) override; const ros::Publisher publisher; - static constexpr double ENCODER_PUBLISHING_RATE_HZ{50}; - static constexpr uint32_t ENCODER_PUBLISHING_BUFFER_SIZE{1}; + static constexpr double ENCODER_PUBLISHER_RATE_HZ{50}; + static constexpr uint32_t ENCODER_PUBLISHER_BUFFER_SIZE{1}; }; } // namespace RosHandler -#endif \ No newline at end of file +#endif diff --git a/src/ros-handler/include/HeadingTimedAction.h b/src/ros-handler/include/HeadingTimedAction.h new file mode 100644 index 0000000..2d1fc8d --- /dev/null +++ b/src/ros-handler/include/HeadingTimedAction.h @@ -0,0 +1,27 @@ +#ifndef HEADING_TIMED_ACTION_H +#define HEADING_TIMED_ACTION_H + +#include "PigeonIMU.h" +#include "ros-handler-core/PigeonRosTimedAction.h" +#include "ros-handler-core/RosTimedAction.h" + +namespace RosHandler { + +using Hardware::PigeonIMU; +using RosHandlerCore::PigeonRosTimedAction; + +class HeadingTimedAction : public PigeonRosTimedAction { +public: + HeadingTimedAction(ros::NodeHandle &node, const std::shared_ptr &pigeon); + +private: + void onTimerEvent(const ros::TimerEvent &event) override; + + const ros::Publisher publisher; + static constexpr double HEADING_PUBLISHER_RATE_HZ{50}; + static constexpr uint32_t HEADING_PUBLISHER_BUFFER_SIZE{1}; +}; + +} // namespace RosHandler + +#endif diff --git a/src/ros-handler/include/PigeonRosHandler.h b/src/ros-handler/include/PigeonRosHandler.h new file mode 100644 index 0000000..0d85a05 --- /dev/null +++ b/src/ros-handler/include/PigeonRosHandler.h @@ -0,0 +1,22 @@ +#ifndef PIGEON_ROS_HANDLER_H +#define PIGEON_ROS_HANDLER_H + +#include "HeadingTimedAction.h" +#include "PigeonIMU.h" +#include "SetHeadingServiceAction.h" +#include "ros/node_handle.h" + +namespace RosHandler { + +class PigeonRosHandler { +public: + PigeonRosHandler(ros::NodeHandle &node, const std::shared_ptr &pigeon); + +private: + const std::unique_ptr headingAction; + const std::unique_ptr setHeadingAction; +}; + +} // namespace RosHandler + +#endif diff --git a/src/ros-handler/include/SetHeadingServiceAction.h b/src/ros-handler/include/SetHeadingServiceAction.h new file mode 100644 index 0000000..e6403f1 --- /dev/null +++ b/src/ros-handler/include/SetHeadingServiceAction.h @@ -0,0 +1,25 @@ +#ifndef SET_HEADING_SERVICE_ACTION_H +#define SET_HEADING_SERVICE_ACTION_H + +#include "PigeonIMU.h" +#include "ros-handler-core/PigeonRosServiceAction.h" +#include "wrevolution/SetHeading.h" + +namespace RosHandler { + +using Hardware::PigeonIMU; +using RosHandlerCore::PigeonRosServiceAction; + +class SetHeadingServiceAction : public PigeonRosServiceAction { +public: + SetHeadingServiceAction(ros::NodeHandle &node, const std::shared_ptr &pigeon); + +private: + auto onServiceRequest(const wrevolution::SetHeading::Request &req, wrevolution::SetHeading::Response &resp) -> bool override; + + static constexpr double SET_HEADING_MAX_RESPONSE_DELAY_SECONDS{0.5}; +}; + +} // namespace RosHandler + +#endif diff --git a/src/ros-handler/include/ros-handler-core/PigeonRosServiceAction.h b/src/ros-handler/include/ros-handler-core/PigeonRosServiceAction.h new file mode 100644 index 0000000..49f3410 --- /dev/null +++ b/src/ros-handler/include/ros-handler-core/PigeonRosServiceAction.h @@ -0,0 +1,29 @@ +#ifndef PIGEON_ROS_SERVICE_ACTION_H +#define PIGEON_ROS_SERVICE_ACTION_H + +#include "PigeonIMU.h" +#include "RosConcepts.h" // IWYU pragma: keep; required concepts +#include "ros-handler-core/RosServiceAction.h" + +namespace RosHandler::RosHandlerCore { + +using Hardware::PigeonIMU; + +template +class PigeonRosServiceAction : public RosServiceAction { +public: + PigeonRosServiceAction( + ros::NodeHandle &node, + const std::shared_ptr &pigeon, + const std::string &serviceName, + const ros::Duration &maxResponseTime) + : RosServiceAction{node, pigeon->getName() + "/" + serviceName, maxResponseTime}, + pigeon{pigeon} {} + +protected: + const std::shared_ptr pigeon; +}; + +} // namespace RosHandler::RosHandlerCore + +#endif diff --git a/src/ros-handler/include/ros-handler-core/PigeonRosTimedAction.h b/src/ros-handler/include/ros-handler-core/PigeonRosTimedAction.h new file mode 100644 index 0000000..6f7de94 --- /dev/null +++ b/src/ros-handler/include/ros-handler-core/PigeonRosTimedAction.h @@ -0,0 +1,26 @@ +#ifndef PIGEON_ROS_TIMED_ACTION_H +#define PIGEON_ROS_TIMED_ACTION_H + +#include +#include "PigeonIMU.h" +#include "RosTimedAction.h" + +namespace RosHandler::RosHandlerCore { + +using Hardware::PigeonIMU; + +class PigeonRosTimedAction : public RosTimedAction { +public: + PigeonRosTimedAction( + const ros::NodeHandle &node, + const std::shared_ptr &pigeon, + const std::string &actionDescription, + const ros::Rate &rate); + +protected: + const std::shared_ptr pigeon; +}; + +} // namespace RosHandler::RosHandlerCore + +#endif diff --git a/src/ros-handler/src/EncoderTimedAction.cpp b/src/ros-handler/src/EncoderTimedAction.cpp index 5e333f2..acbba08 100644 --- a/src/ros-handler/src/EncoderTimedAction.cpp +++ b/src/ros-handler/src/EncoderTimedAction.cpp @@ -10,8 +10,8 @@ EncoderTimedAction::EncoderTimedAction(ros::NodeHandle &node, const std::shared_ : ControlGroupRosTimedAction(node, controlGroup, "Encoder Publisher", - ros::Rate{ENCODER_PUBLISHING_RATE_HZ}), - publisher{node.advertise(controlGroup->getName() + "/encoder", ENCODER_PUBLISHING_BUFFER_SIZE)} {} + ros::Rate{ENCODER_PUBLISHER_RATE_HZ}), + publisher{node.advertise(controlGroup->getName() + "/encoder", ENCODER_PUBLISHER_BUFFER_SIZE)} {} void EncoderTimedAction::onTimerEvent(const ros::TimerEvent &event) { std_msgs::Float64 msg; @@ -22,4 +22,4 @@ void EncoderTimedAction::onTimerEvent(const ros::TimerEvent &event) { } } -} // namespace RosHandler \ No newline at end of file +} // namespace RosHandler diff --git a/src/ros-handler/src/HeadingTimedAction.cpp b/src/ros-handler/src/HeadingTimedAction.cpp new file mode 100644 index 0000000..287bef0 --- /dev/null +++ b/src/ros-handler/src/HeadingTimedAction.cpp @@ -0,0 +1,25 @@ +#include "HeadingTimedAction.h" +#include "ros/forwards.h" +#include "std_msgs/Float64.h" + +namespace RosHandler { +using Hardware::PigeonIMU; + +HeadingTimedAction::HeadingTimedAction(ros::NodeHandle &node, const std::shared_ptr &pigeon) + : PigeonRosTimedAction(node, + pigeon, + "Heading Publisher", + ros::Rate{HEADING_PUBLISHER_RATE_HZ}), + publisher{node.advertise("/heading", HEADING_PUBLISHER_BUFFER_SIZE)} {} + + +void HeadingTimedAction::onTimerEvent(const ros::TimerEvent &event) { + std_msgs::Float64 msg; + auto yaw = pigeon->getYaw(); + if (yaw.has_value()) { + msg.data = *yaw; + publisher.publish(msg); + } +} + +} // namespace RosHandler diff --git a/src/ros-handler/src/PigeonRosHandler.cpp b/src/ros-handler/src/PigeonRosHandler.cpp new file mode 100644 index 0000000..9442000 --- /dev/null +++ b/src/ros-handler/src/PigeonRosHandler.cpp @@ -0,0 +1,13 @@ +#include "PigeonRosHandler.h" +#include "HeadingTimedAction.h" +#include "PigeonIMU.h" +#include "SetHeadingServiceAction.h" +#include + +namespace RosHandler { + +PigeonRosHandler::PigeonRosHandler(ros::NodeHandle &node, const std::shared_ptr &pigeon) + : headingAction{std::make_unique(node, pigeon)}, + setHeadingAction{std::make_unique(node, pigeon)} {} + +} // namespace RosHandler diff --git a/src/ros-handler/src/SetHeadingServiceAction.cpp b/src/ros-handler/src/SetHeadingServiceAction.cpp new file mode 100644 index 0000000..754b528 --- /dev/null +++ b/src/ros-handler/src/SetHeadingServiceAction.cpp @@ -0,0 +1,24 @@ +#include "SetHeadingServiceAction.h" +#include "PigeonIMU.h" +#include "ros-handler-core/PigeonRosServiceAction.h" +#include "wrevolution/SetHeading.h" + +namespace RosHandler { + +using Hardware::PigeonIMU; +using RosHandlerCore::PigeonRosServiceAction; +using wrevolution::SetHeading; + +SetHeadingServiceAction::SetHeadingServiceAction(ros::NodeHandle &node, const std::shared_ptr &pigeon) + : PigeonRosServiceAction(node, + pigeon, + "set_heading", + ros::Duration{SET_HEADING_MAX_RESPONSE_DELAY_SECONDS}) {} + +auto SetHeadingServiceAction::onServiceRequest(const SetHeading::Request &req, + SetHeading::Response &resp) -> bool { + pigeon->setYaw(req.heading); + return true; +} + +} // namespace RosHandler diff --git a/src/ros-handler/src/ros-handler-core/PigeonRosTimedAction.cpp b/src/ros-handler/src/ros-handler-core/PigeonRosTimedAction.cpp new file mode 100644 index 0000000..ed9acfa --- /dev/null +++ b/src/ros-handler/src/ros-handler-core/PigeonRosTimedAction.cpp @@ -0,0 +1,14 @@ +#include "ros-handler-core/PigeonRosTimedAction.h" +#include "ros-handler-core/RosTimedAction.h" + +namespace RosHandler::RosHandlerCore { + +PigeonRosTimedAction::PigeonRosTimedAction( + const ros::NodeHandle &node, + const std::shared_ptr &pigeon, + const std::string &actionDescription, + const ros::Rate &rate) + : RosTimedAction(rate, node, "'" + pigeon->getName() + "' - " + actionDescription), + pigeon{pigeon} {} + +} // namespace RosHandler::RosHandlerCore diff --git a/srv/SetHeading.srv b/srv/SetHeading.srv new file mode 100644 index 0000000..7cd76e6 --- /dev/null +++ b/srv/SetHeading.srv @@ -0,0 +1,2 @@ +float64 heading +---