107 TalonFXConfiguration config;
108 auto timeout = configTimeout.to<
int>();
111 motorController.SetInverted(T::inverted);
114 motorController.SetSensorPhase(T::sensorPhase);
117 motorController.SetNeutralMode(T::neutralMode);
120 constexpr units::volt_t voltage = T::voltCompSat;
121 config.voltageCompSaturation = voltage.to<
double>();
122 motorController.EnableVoltageCompensation(
true);
124 motorController.EnableVoltageCompensation(
false);
127 ctre::phoenix::motorcontrol::can::FilterConfiguration filterConfig;
128 filterConfig.remoteSensorDeviceID = T::remoteFilter0_addr.address;
129 filterConfig.remoteSensorSource = T::remoteFilter0_type;
130 config.remoteFilter0 = filterConfig;
133 config.nominalOutputForward = T::nominalOutputForward;
136 config.nominalOutputReverse = T::nominalOutputReverse;
139 config.peakOutputForward = T::peakOutputForward;
142 config.peakOutputReverse = T::peakOutputReverse;
145 config.primaryPID.selectedFeedbackSensor = T::pid0_selectedSensor;
148 config.slot0.kP = T::pid0_kP;
151 config.slot0.kI = T::pid0_kI;
154 config.slot0.kD = T::pid0_kD;
157 config.slot0.kF = T::pid0_kF;
160 config.slot0.integralZone = T::pid0_iZone;
163 config.slot0.allowableClosedloopError = T::pid0_allowableError;
166 config.slot1.kP = T::pid1_kP;
169 config.slot1.kI = T::pid1_kI;
172 config.slot1.kD = T::pid1_kD;
175 config.slot1.kF = T::pid1_kF;
178 config.slot1.integralZone = T::pid1_iZone;
181 config.slot1.allowableClosedloopError = T::pid1_allowableError;
185 config.supplyCurrLimit.enable =
true;
187 constexpr units::ampere_t currentLimit = T::supplyCurrentLimit;
188 static_assert(currentLimit.to<
double>() > 0,
"Supply current limit must be positive");
189 config.supplyCurrLimit.currentLimit = currentLimit.to<
double>();
192 constexpr units::ampere_t currentThreshold = T::supplyCurrentThreshold;
193 static_assert(currentThreshold.to<
double>() > 0,
"Supply current threshold must be positive");
194 config.supplyCurrLimit.triggerThresholdCurrent = currentThreshold.to<
double>();
197 constexpr units::second_t currentThresholdTime = T::supplyCurrentThresholdTime;
198 static_assert(currentThresholdTime.to<
double>() >= 0,
"Supply current threshold time must be non-negative");
199 config.supplyCurrLimit.triggerThresholdTime = currentThresholdTime.to<
double>();
204 config.statorCurrLimit.enable =
true;
206 constexpr units::ampere_t currentLimit = T::statorCurrentLimit;
207 static_assert(currentLimit.to<
double>() > 0,
"Stator current limit must be positive");
208 config.statorCurrLimit.currentLimit = currentLimit.to<
double>();
211 constexpr units::ampere_t currentThreshold = T::statorCurrentThreshold;
212 static_assert(currentThreshold.to<
double>() > 0,
"Stator current threshold must be positive");
213 config.statorCurrLimit.triggerThresholdCurrent = currentThreshold.to<
double>();
216 constexpr units::second_t currentThresholdTime = T::statorCurrentThresholdTime;
217 static_assert(currentThresholdTime.to<
double>() >= 0,
"Stator current threshold time must be non-negative");
218 config.statorCurrLimit.triggerThresholdTime = currentThresholdTime.to<
double>();
224 constexpr ctre::phoenix::motorcontrol::LimitSwitchSource source = T::forwardLimit_source;
225 if constexpr (source != ctre::phoenix::motorcontrol::LimitSwitchSource_Deactivated &&
226 source != ctre::phoenix::motorcontrol::LimitSwitchSource_FeedbackConnector) {
229 if constexpr (source != ctre::phoenix::motorcontrol::LimitSwitchSource_Deactivated) {
231 T::forwardLimit_normalState != ctre::phoenix::motorcontrol::LimitSwitchNormal_Disabled,
232 "Forward limit switch configuration requires both source and normal state");
234 config.forwardLimitSwitchSource = T::forwardLimit_source;
238 T::forwardLimit_source != ctre::phoenix::motorcontrol::LimitSwitchSource_Deactivated &&
239 T::forwardLimit_source != ctre::phoenix::motorcontrol::LimitSwitchSource_FeedbackConnector,
240 "Forward limit switch device ID has no effect when limit source is not remote");
241 config.forwardLimitSwitchDeviceID = T::forwardLimit_deviceID;
244 if constexpr (T::forwardLimit_normalState != ctre::phoenix::motorcontrol::LimitSwitchNormal_Disabled) {
247 config.forwardLimitSwitchNormal = T::forwardLimit_normalState;
253 constexpr ctre::phoenix::motorcontrol::LimitSwitchSource source = T::reverseLimit_source;
254 if constexpr (source != ctre::phoenix::motorcontrol::LimitSwitchSource_Deactivated &&
255 source != ctre::phoenix::motorcontrol::LimitSwitchSource_FeedbackConnector) {
258 if constexpr (source != ctre::phoenix::motorcontrol::LimitSwitchSource_Deactivated) {
260 T::reverseLimit_normalState != ctre::phoenix::motorcontrol::LimitSwitchNormal_Disabled,
261 "Reverse limit switch configuration requires both source and normal state");
263 config.reverseLimitSwitchSource = T::reverseLimit_source;
267 T::reverseLimit_source != ctre::phoenix::motorcontrol::LimitSwitchSource_Deactivated &&
268 T::reverseLimit_source != ctre::phoenix::motorcontrol::LimitSwitchSource_FeedbackConnector,
269 "Reverse limit switch device ID has no effect when limit source is not remote");
270 config.reverseLimitSwitchDeviceID = T::reverseLimit_deviceID;
273 if constexpr (T::reverseLimit_normalState != ctre::phoenix::motorcontrol::LimitSwitchNormal_Disabled) {
276 config.reverseLimitSwitchNormal = T::reverseLimit_normalState;
280 static_assert(T::neutralDeadband >= 0.001,
"Neutral deadband must be greater than 0.001 (0.1%)");
281 static_assert(T::neutralDeadband <= 0.25,
"Neutral deadband must be less than 0.25 (25%)");
282 config.neutralDeadband = T::neutralDeadband;
289 auto retVal = motorController.ConfigAllSettings(config, timeout);
291 std::cout <<
"Error code (" << motorController.GetDeviceID() <<
"): " << retVal <<
'\n';