mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-30 02:31:44 +00:00
Added Get/clear routine for IntegralAccumulator Added missing status check in GetFirmwareVersion(). I don't expect this to affect anything. JAVA Renamed getRampRate to getCloseLoopRampRate in java to match the set routines in java, and match all routines in cpp. Added GetFirmwareVersion to java to match cpp. Added Get/clear routine for IntegralAccumulator Retested all three routines in java. Change-Id: I4ce9d9c87a379b9d4a76aae226e2072876218688
319 lines
16 KiB
C++
319 lines
16 KiB
C++
/**
|
|
* @brief CAN TALON SRX driver.
|
|
*
|
|
* The TALON SRX is designed to instrument all runtime signals periodically. The default periods are chosen to support 16 TALONs
|
|
* with 10ms update rate for control (throttle or setpoint). However these can be overridden with SetStatusFrameRate. @see SetStatusFrameRate
|
|
* The getters for these unsolicited signals are auto generated at the bottom of this module.
|
|
*
|
|
* Likewise most control signals are sent periodically using the fire-and-forget CAN API.
|
|
* The setters for these unsolicited signals are auto generated at the bottom of this module.
|
|
*
|
|
* Signals that are not available in an unsolicited fashion are the Close Loop gains.
|
|
* For teams that have a single profile for their TALON close loop they can use either the webpage to configure their TALONs once
|
|
* or set the PIDF,Izone,CloseLoopRampRate,etc... once in the robot application. These parameters are saved to flash so once they are
|
|
* loaded in the TALON, they will persist through power cycles and mode changes.
|
|
*
|
|
* For teams that have one or two profiles to switch between, they can use the same strategy since there are two slots to choose from
|
|
* and the ProfileSlotSelect is periodically sent in the 10 ms control frame.
|
|
*
|
|
* For teams that require changing gains frequently, they can use the soliciting API to get and set those parameters. Most likely
|
|
* they will only need to set them in a periodic fashion as a function of what motion the application is attempting.
|
|
* If this API is used, be mindful of the CAN utilization reported in the driver station.
|
|
*
|
|
* Encoder position is measured in encoder edges. Every edge is counted (similar to roboRIO 4X mode).
|
|
* Analog position is 10 bits, meaning 1024 ticks per rotation (0V => 3.3V).
|
|
* Use SetFeedbackDeviceSelect to select which sensor type you need. Once you do that you can use GetSensorPosition()
|
|
* and GetSensorVelocity(). These signals are updated on CANBus every 20ms (by default).
|
|
* If a relative sensor is selected, you can zero (or change the current value) using SetSensorPosition.
|
|
*
|
|
* Analog Input and quadrature position (and velocity) are also explicitly reported in GetEncPosition, GetEncVel, GetAnalogInWithOv, GetAnalogInVel.
|
|
* These signals are available all the time, regardless of what sensor is selected at a rate of 100ms. This allows easy instrumentation
|
|
* for "in the pits" checking of all sensors regardless of modeselect. The 100ms rate is overridable for teams who want to acquire sensor
|
|
* data for processing, not just instrumentation. Or just select the sensor using SetFeedbackDeviceSelect to get it at 20ms.
|
|
*
|
|
* Velocity is in position ticks / 100ms.
|
|
*
|
|
* All output units are in respect to duty cycle (throttle) which is -1023(full reverse) to +1023 (full forward).
|
|
* This includes demand (which specifies duty cycle when in duty cycle mode) and rampRamp, which is in throttle units per 10ms (if nonzero).
|
|
*
|
|
* Pos and velocity close loops are calc'd as
|
|
* err = target - posOrVel.
|
|
* iErr += err;
|
|
* if( (IZone!=0) and abs(err) > IZone)
|
|
* ClearIaccum()
|
|
* output = P X err + I X iErr + D X dErr + F X target
|
|
* dErr = err - lastErr
|
|
* P, I,and D gains are always positive. F can be negative.
|
|
* Motor direction can be reversed using SetRevMotDuringCloseLoopEn if sensor and motor are out of phase.
|
|
* Similarly feedback sensor can also be reversed (multiplied by -1) if you prefer the sensor to be inverted.
|
|
*
|
|
* P gain is specified in throttle per error tick. For example, a value of 102 is ~9.9% (which is 102/1023) throttle per 1
|
|
* ADC unit(10bit) or 1 quadrature encoder edge depending on selected sensor.
|
|
*
|
|
* I gain is specified in throttle per integrated error. For example, a value of 10 equates to ~0.99% (which is 10/1023)
|
|
* for each accumulated ADC unit(10bit) or 1 quadrature encoder edge depending on selected sensor.
|
|
* Close loop and integral accumulator runs every 1ms.
|
|
*
|
|
* D gain is specified in throttle per derivative error. For example a value of 102 equates to ~9.9% (which is 102/1023)
|
|
* per change of 1 unit (ADC or encoder) per ms.
|
|
*
|
|
* I Zone is specified in the same units as sensor position (ADC units or quadrature edges). If pos/vel error is outside of
|
|
* this value, the integrated error will auto-clear...
|
|
* if( (IZone!=0) and abs(err) > IZone)
|
|
* ClearIaccum()
|
|
* ...this is very useful in preventing integral windup and is highly recommended if using full PID to keep stability low.
|
|
*
|
|
* CloseLoopRampRate ramps the target of the close loop. The units are in position per 1ms. Set to zero to disable ramping.
|
|
* So a value of 10 means allow the target input of the close loop to approach the user's demand by 10 units (ADC or encoder edges)
|
|
* per 1ms.
|
|
*
|
|
* auto generated using spreadsheet and WpiClassGen.csproj
|
|
* @link https://docs.google.com/spreadsheets/d/1OU_ZV7fZLGYUQ-Uhc8sVAmUmWTlT8XBFYK8lfjg_tac/edit#gid=1766046967
|
|
*/
|
|
#ifndef CanTalonSRX_H_
|
|
#define CanTalonSRX_H_
|
|
#include "ctre.h" //BIT Defines + Typedefs
|
|
#include "CtreCanNode.h"
|
|
#include <NetworkCommunication/CANSessionMux.h> //CAN Comm
|
|
#include <map>
|
|
class CanTalonSRX : public CtreCanNode
|
|
{
|
|
private:
|
|
|
|
/** just in case user wants to modify periods of certain status frames.
|
|
* Default the vars to match the firmware default. */
|
|
uint32_t _statusRateMs[4];
|
|
//---------------------- Vars for opening a CAN stream if caller needs signals that require soliciting */
|
|
uint32_t _can_h; //!< Session handle for catching response params.
|
|
int32_t _can_stat; //!< Session handle status.
|
|
struct tCANStreamMessage _msgBuff[20];
|
|
static int const kMsgCapacity = 20;
|
|
typedef std::map<uint32_t, uint32_t> sigs_t;
|
|
sigs_t _sigs; //!< Catches signal updates that are solicited. Expect this to be very few.
|
|
void OpenSessionIfNeedBe();
|
|
void ProcessStreamMessages();
|
|
/**
|
|
* Send a one shot frame to set an arbitrary signal.
|
|
* Most signals are in the control frame so avoid using this API unless you have to.
|
|
* Use this api for...
|
|
* -A motor controller profile signal eProfileParam_XXXs. These are backed up in flash. If you are gain-scheduling then call this periodically.
|
|
* -Default brake and limit switch signals... eOnBoot_XXXs. Avoid doing this, use the override signals in the control frame.
|
|
* Talon will automatically send a PARAM_RESPONSE after the set, so GetParamResponse will catch the latest value after a couple ms.
|
|
*/
|
|
CTR_Code SetParamRaw(uint32_t paramEnum, int32_t rawBits);
|
|
/**
|
|
* Checks cached CAN frames and updating solicited signals.
|
|
*/
|
|
CTR_Code GetParamResponseRaw(uint32_t paramEnum, int32_t & rawBits);
|
|
public:
|
|
static const int kDefaultControlPeriodMs = 10; //!< default control update rate is 10ms.
|
|
CanTalonSRX(int deviceNumber = 0,int controlPeriodMs = kDefaultControlPeriodMs);
|
|
~CanTalonSRX();
|
|
void Set(double value);
|
|
/* mode select enumerations */
|
|
static const int kMode_DutyCycle = 0; //!< Demand is 11bit signed duty cycle [-1023,1023].
|
|
static const int kMode_PositionCloseLoop = 1; //!< Position PIDF.
|
|
static const int kMode_VelocityCloseLoop = 2; //!< Velocity PIDF.
|
|
static const int kMode_CurrentCloseLoop = 3; //!< Current close loop - not done.
|
|
static const int kMode_VoltCompen = 4; //!< Voltage Compensation Mode - not done. Demand is fixed pt target 8.8 volts.
|
|
static const int kMode_SlaveFollower = 5; //!< Demand is the 6 bit Device ID of the 'master' TALON SRX.
|
|
static const int kMode_NoDrive = 15; //!< Zero the output (honors brake/coast) regardless of demand. Might be useful if we need to change modes but can't atomically change all the signals we want in between.
|
|
/* limit switch enumerations */
|
|
static const int kLimitSwitchOverride_UseDefaultsFromFlash = 1;
|
|
static const int kLimitSwitchOverride_DisableFwd_DisableRev = 4;
|
|
static const int kLimitSwitchOverride_DisableFwd_EnableRev = 5;
|
|
static const int kLimitSwitchOverride_EnableFwd_DisableRev = 6;
|
|
static const int kLimitSwitchOverride_EnableFwd_EnableRev = 7;
|
|
/* brake override enumerations */
|
|
static const int kBrakeOverride_UseDefaultsFromFlash = 0;
|
|
static const int kBrakeOverride_OverrideCoast = 1;
|
|
static const int kBrakeOverride_OverrideBrake = 2;
|
|
/* feedback device enumerations */
|
|
static const int kFeedbackDev_DigitalQuadEnc=0;
|
|
static const int kFeedbackDev_AnalogPot=2;
|
|
static const int kFeedbackDev_AnalogEncoder=3;
|
|
static const int kFeedbackDev_CountEveryRisingEdge=4;
|
|
static const int kFeedbackDev_CountEveryFallingEdge=5;
|
|
static const int kFeedbackDev_PosIsPulseWidth=8;
|
|
/* ProfileSlotSelect enumerations*/
|
|
static const int kProfileSlotSelect_Slot0 = 0;
|
|
static const int kProfileSlotSelect_Slot1 = 1;
|
|
/* status frame rate types */
|
|
static const int kStatusFrame_General = 0;
|
|
static const int kStatusFrame_Feedback = 1;
|
|
static const int kStatusFrame_Encoder = 2;
|
|
static const int kStatusFrame_AnalogTempVbat = 3;
|
|
/**
|
|
* Signal enumeration for generic signal access.
|
|
* Although every signal is enumerated, only use this for traffic that must be solicited.
|
|
* Use the auto generated getters/setters at bottom of this header as much as possible.
|
|
*/
|
|
typedef enum _param_t{
|
|
eProfileParamSlot0_P=1,
|
|
eProfileParamSlot0_I=2,
|
|
eProfileParamSlot0_D=3,
|
|
eProfileParamSlot0_F=4,
|
|
eProfileParamSlot0_IZone=5,
|
|
eProfileParamSlot0_CloseLoopRampRate=6,
|
|
eProfileParamSlot1_P=11,
|
|
eProfileParamSlot1_I=12,
|
|
eProfileParamSlot1_D=13,
|
|
eProfileParamSlot1_F=14,
|
|
eProfileParamSlot1_IZone=15,
|
|
eProfileParamSlot1_CloseLoopRampRate=16,
|
|
eProfileParamSoftLimitForThreshold=21,
|
|
eProfileParamSoftLimitRevThreshold=22,
|
|
eProfileParamSoftLimitForEnable=23,
|
|
eProfileParamSoftLimitRevEnable=24,
|
|
eOnBoot_BrakeMode=31,
|
|
eOnBoot_LimitSwitch_Forward_NormallyClosed=32,
|
|
eOnBoot_LimitSwitch_Reverse_NormallyClosed=33,
|
|
eOnBoot_LimitSwitch_Forward_Disable=34,
|
|
eOnBoot_LimitSwitch_Reverse_Disable=35,
|
|
eFault_OverTemp=41,
|
|
eFault_UnderVoltage=42,
|
|
eFault_ForLim=43,
|
|
eFault_RevLim=44,
|
|
eFault_HardwareFailure=45,
|
|
eFault_ForSoftLim=46,
|
|
eFault_RevSoftLim=47,
|
|
eStckyFault_OverTemp=48,
|
|
eStckyFault_UnderVoltage=49,
|
|
eStckyFault_ForLim=50,
|
|
eStckyFault_RevLim=51,
|
|
eStckyFault_ForSoftLim=52,
|
|
eStckyFault_RevSoftLim=53,
|
|
eAppliedThrottle=61,
|
|
eCloseLoopErr=62,
|
|
eFeedbackDeviceSelect=63,
|
|
eRevMotDuringCloseLoopEn=64,
|
|
eModeSelect=65,
|
|
eProfileSlotSelect=66,
|
|
eRampThrottle=67,
|
|
eRevFeedbackSensor=68,
|
|
eLimitSwitchEn=69,
|
|
eLimitSwitchClosedFor=70,
|
|
eLimitSwitchClosedRev=71,
|
|
eSensorPosition=73,
|
|
eSensorVelocity=74,
|
|
eCurrent=75,
|
|
eBrakeIsEnabled=76,
|
|
eEncPosition=77,
|
|
eEncVel=78,
|
|
eEncIndexRiseEvents=79,
|
|
eQuadApin=80,
|
|
eQuadBpin=81,
|
|
eQuadIdxpin=82,
|
|
eAnalogInWithOv=83,
|
|
eAnalogInVel=84,
|
|
eTemp=85,
|
|
eBatteryV=86,
|
|
eResetCount=87,
|
|
eResetFlags=88,
|
|
eFirmVers=89,
|
|
eSettingsChanged=90,
|
|
eQuadFilterEn=91,
|
|
ePidIaccum=93,
|
|
}param_t;
|
|
/*---------------------setters and getters that use the solicated param request/response-------------*//**
|
|
* Send a one shot frame to set an arbitrary signal.
|
|
* Most signals are in the control frame so avoid using this API unless you have to.
|
|
* Use this api for...
|
|
* -A motor controller profile signal eProfileParam_XXXs. These are backed up in flash. If you are gain-scheduling then call this periodically.
|
|
* -Default brake and limit switch signals... eOnBoot_XXXs. Avoid doing this, use the override signals in the control frame.
|
|
* Talon will automatically send a PARAM_RESPONSE after the set, so GetParamResponse will catch the latest value after a couple ms.
|
|
*/
|
|
CTR_Code SetParam(param_t paramEnum, double value);
|
|
/**
|
|
* Asks TALON to immedietely respond with signal value. This API is only used for signals that are not sent periodically.
|
|
* This can be useful for reading params that rarely change like Limit Switch settings and PIDF values.
|
|
* @param param to request.
|
|
*/
|
|
CTR_Code RequestParam(param_t paramEnum);
|
|
CTR_Code GetParamResponse(param_t paramEnum, double & value);
|
|
CTR_Code GetParamResponseInt32(param_t paramEnum, int & value);
|
|
/*----- getters and setters that use param request/response. These signals are backed up in flash and will survive a power cycle. ---------*/
|
|
/*----- If your application requires changing these values consider using both slots and switch between slot0 <=> slot1. ------------------*/
|
|
/*----- If your application requires changing these signals frequently then it makes sense to leverage this API. --------------------------*/
|
|
/*----- Getters don't block, so it may require several calls to get the latest value. --------------------------*/
|
|
CTR_Code SetPgain(unsigned slotIdx,double gain);
|
|
CTR_Code SetIgain(unsigned slotIdx,double gain);
|
|
CTR_Code SetDgain(unsigned slotIdx,double gain);
|
|
CTR_Code SetFgain(unsigned slotIdx,double gain);
|
|
CTR_Code SetIzone(unsigned slotIdx,int zone);
|
|
CTR_Code SetCloseLoopRampRate(unsigned slotIdx,int closeLoopRampRate);
|
|
CTR_Code SetSensorPosition(int pos);
|
|
CTR_Code SetForwardSoftLimit(int forwardLimit);
|
|
CTR_Code SetReverseSoftLimit(int reverseLimit);
|
|
CTR_Code SetForwardSoftEnable(int enable);
|
|
CTR_Code SetReverseSoftEnable(int enable);
|
|
CTR_Code GetPgain(unsigned slotIdx,double & gain);
|
|
CTR_Code GetIgain(unsigned slotIdx,double & gain);
|
|
CTR_Code GetDgain(unsigned slotIdx,double & gain);
|
|
CTR_Code GetFgain(unsigned slotIdx,double & gain);
|
|
CTR_Code GetIzone(unsigned slotIdx,int & zone);
|
|
CTR_Code GetCloseLoopRampRate(unsigned slotIdx,int & closeLoopRampRate);
|
|
CTR_Code GetForwardSoftLimit(int & forwardLimit);
|
|
CTR_Code GetReverseSoftLimit(int & reverseLimit);
|
|
CTR_Code GetForwardSoftEnable(int & enable);
|
|
CTR_Code GetReverseSoftEnable(int & enable);
|
|
/**
|
|
* Change the periodMs of a TALON's status frame. See kStatusFrame_* enums for what's available.
|
|
*/
|
|
CTR_Code SetStatusFrameRate(unsigned frameEnum, unsigned periodMs);
|
|
/**
|
|
* Clear all sticky faults in TALON.
|
|
*/
|
|
CTR_Code ClearStickyFaults();
|
|
/*------------------------ auto generated. This API is optimal since it uses the fire-and-forget CAN interface ----------------------*/
|
|
/*------------------------ These signals should cover the majority of all use cases. ----------------------------------*/
|
|
CTR_Code GetFault_OverTemp(int ¶m);
|
|
CTR_Code GetFault_UnderVoltage(int ¶m);
|
|
CTR_Code GetFault_ForLim(int ¶m);
|
|
CTR_Code GetFault_RevLim(int ¶m);
|
|
CTR_Code GetFault_HardwareFailure(int ¶m);
|
|
CTR_Code GetFault_ForSoftLim(int ¶m);
|
|
CTR_Code GetFault_RevSoftLim(int ¶m);
|
|
CTR_Code GetStckyFault_OverTemp(int ¶m);
|
|
CTR_Code GetStckyFault_UnderVoltage(int ¶m);
|
|
CTR_Code GetStckyFault_ForLim(int ¶m);
|
|
CTR_Code GetStckyFault_RevLim(int ¶m);
|
|
CTR_Code GetStckyFault_ForSoftLim(int ¶m);
|
|
CTR_Code GetStckyFault_RevSoftLim(int ¶m);
|
|
CTR_Code GetAppliedThrottle(int ¶m);
|
|
CTR_Code GetCloseLoopErr(int ¶m);
|
|
CTR_Code GetFeedbackDeviceSelect(int ¶m);
|
|
CTR_Code GetModeSelect(int ¶m);
|
|
CTR_Code GetLimitSwitchEn(int ¶m);
|
|
CTR_Code GetLimitSwitchClosedFor(int ¶m);
|
|
CTR_Code GetLimitSwitchClosedRev(int ¶m);
|
|
CTR_Code GetSensorPosition(int ¶m);
|
|
CTR_Code GetSensorVelocity(int ¶m);
|
|
CTR_Code GetCurrent(double ¶m);
|
|
CTR_Code GetBrakeIsEnabled(int ¶m);
|
|
CTR_Code GetEncPosition(int ¶m);
|
|
CTR_Code GetEncVel(int ¶m);
|
|
CTR_Code GetEncIndexRiseEvents(int ¶m);
|
|
CTR_Code GetQuadApin(int ¶m);
|
|
CTR_Code GetQuadBpin(int ¶m);
|
|
CTR_Code GetQuadIdxpin(int ¶m);
|
|
CTR_Code GetAnalogInWithOv(int ¶m);
|
|
CTR_Code GetAnalogInVel(int ¶m);
|
|
CTR_Code GetTemp(double ¶m);
|
|
CTR_Code GetBatteryV(double ¶m);
|
|
CTR_Code GetResetCount(int ¶m);
|
|
CTR_Code GetResetFlags(int ¶m);
|
|
CTR_Code GetFirmVers(int ¶m);
|
|
CTR_Code SetDemand(int param);
|
|
CTR_Code SetOverrideLimitSwitchEn(int param);
|
|
CTR_Code SetFeedbackDeviceSelect(int param);
|
|
CTR_Code SetRevMotDuringCloseLoopEn(int param);
|
|
CTR_Code SetOverrideBrakeType(int param);
|
|
CTR_Code SetModeSelect(int param);
|
|
CTR_Code SetProfileSlotSelect(int param);
|
|
CTR_Code SetRampThrottle(int param);
|
|
CTR_Code SetRevFeedbackSensor(int param);
|
|
};
|
|
#endif
|
|
|