2023-Robot
Robot code for 2023 FRC season by Argos, FRC team #1756
Loading...
Searching...
No Matches
talonsrx_config.h
Go to the documentation of this file.
1
4
5#pragma once
6
7#include <units/current.h>
8#include <units/time.h>
9#include <units/voltage.h>
10
13#include "ctre/Phoenix.h"
14#include "status_frame_config.h"
15
16namespace argos_lib {
17 namespace talonsrx_config {
18
19 HAS_MEMBER(inverted)
20 HAS_MEMBER(neutralMode)
21 HAS_MEMBER(pid0_allowableError)
22 HAS_MEMBER(pid0_iZone)
23 HAS_MEMBER(pid0_kD)
24 HAS_MEMBER(pid0_kF)
25 HAS_MEMBER(pid0_kI)
26 HAS_MEMBER(pid0_kP)
27 HAS_MEMBER(pid0_selectedSensor)
28 HAS_MEMBER(remoteFilter0_addr)
29 HAS_MEMBER(remoteFilter0_type)
30 HAS_MEMBER(sensorPhase)
31 HAS_MEMBER(voltCompSat)
32 HAS_MEMBER(statusFrameMotorMode)
33 HAS_MEMBER(peakCurrentLimit)
34 HAS_MEMBER(peakCurrentDuration)
35 HAS_MEMBER(continuousCurrentLimit)
36 HAS_MEMBER(peakOutputForward)
37 HAS_MEMBER(peakOutputReverse)
67 template <typename T>
68 bool TalonSRXConfig(WPI_TalonSRX& motorController, units::millisecond_t configTimeout) {
69 TalonSRXConfiguration config;
70 auto timeout = configTimeout.to<int>();
71
72 if constexpr (has_inverted<T>{}) {
73 motorController.SetInverted(T::inverted);
74 }
75 if constexpr (has_sensorPhase<T>{}) {
76 motorController.SetSensorPhase(T::sensorPhase);
77 }
78 if constexpr (has_neutralMode<T>{}) {
79 motorController.SetNeutralMode(T::neutralMode);
80 }
81 if constexpr (has_voltCompSat<T>{}) {
82 constexpr units::volt_t voltage = T::voltCompSat;
83 config.voltageCompSaturation = voltage.to<double>();
84 motorController.EnableVoltageCompensation(true);
85 } else {
86 motorController.EnableVoltageCompensation(false);
87 }
89 ctre::phoenix::motorcontrol::can::FilterConfiguration filterConfig;
90 filterConfig.remoteSensorDeviceID = T::remoteFilter0_addr.address;
91 filterConfig.remoteSensorSource = T::remoteFilter0_type;
92 config.remoteFilter0 = filterConfig;
93 }
94 if constexpr (has_pid0_selectedSensor<T>{}) {
95 config.primaryPID.selectedFeedbackSensor = T::pid0_selectedSensor;
96 }
97 if constexpr (has_pid0_kP<T>{}) {
98 config.slot0.kP = T::pid0_kP;
99 }
100 if constexpr (has_pid0_kI<T>{}) {
101 config.slot0.kI = T::pid0_kI;
102 }
103 if constexpr (has_pid0_kD<T>{}) {
104 config.slot0.kD = T::pid0_kD;
105 }
106 if constexpr (has_pid0_kF<T>{}) {
107 config.slot0.kF = T::pid0_kF;
108 }
109 if constexpr (has_pid0_iZone<T>{}) {
110 config.slot0.integralZone = T::pid0_iZone;
111 }
112 if constexpr (has_pid0_allowableError<T>{}) {
113 config.slot0.allowableClosedloopError = T::pid0_allowableError;
114 }
115 if constexpr (has_peakCurrentLimit<T>()) {
116 constexpr units::ampere_t currentLimit = T::peakCurrentLimit;
117 static_assert(currentLimit.to<double>() > 0, "Current limit must be positive");
118 config.peakCurrentLimit = std::round(currentLimit.to<double>());
119 }
120 if constexpr (has_peakCurrentDuration<T>()) {
121 constexpr units::millisecond_t currentDuration = T::peakCurrentDuration;
122 static_assert(currentDuration.to<double>() > 0, "Current duration must be positive");
123 config.peakCurrentDuration = std::round(currentDuration.to<double>());
124 }
125 if constexpr (has_continuousCurrentLimit<T>()) {
126 constexpr units::ampere_t currentLimit = T::continuousCurrentLimit;
127 static_assert(currentLimit.to<double>() > 0, "Current limit must be positive");
128 config.continuousCurrentLimit = std::round(currentLimit.to<double>());
129 }
130 if constexpr (has_peakOutputForward<T>()) {
131 config.peakOutputForward = T::peakOutputForward;
132 }
133 if constexpr (has_peakOutputReverse<T>()) {
134 config.peakOutputReverse = T::peakOutputReverse;
135 }
136
137 if constexpr (has_statusFrameMotorMode<T>()) {
138 argos_lib::status_frame_config::SetMotorStatusFrameRates(motorController, T::statusFrameMotorMode);
139 }
140
141 // enable current limiting if any current limiting option is set, disable if none are
143 motorController.EnableCurrentLimit(true);
144 } else {
145 motorController.EnableCurrentLimit(false);
146 }
147
148 // ensure using single threshold if peakCurrentLimit is not set but continuousCurrentLimit is
150 config.peakCurrentLimit = 0;
151 }
152
153 return 0 != motorController.ConfigAllSettings(config, timeout);
154 }
155
167 template <typename CompetitionConfig, typename PracticeConfig>
168 bool TalonSRXConfig(WPI_TalonSRX& motorController,
169 units::millisecond_t configTimeout,
170 argos_lib::RobotInstance instance) {
171 switch (instance) {
173 return TalonSRXConfig<CompetitionConfig>(motorController, configTimeout);
174 break;
176 return TalonSRXConfig<PracticeConfig>(motorController, configTimeout);
177 break;
178 }
179 return false;
180 }
181
182 } // namespace talonsrx_config
183} // namespace argos_lib
#define HAS_MEMBER(X)
Helper function generator to detect if a namespace has a member defined.
Definition compile_time_member_check.h:14
void SetMotorStatusFrameRates(BaseTalon &motor, MotorPresetMode motorMode)
Set motor controller status frame update periods based on the motor preset.
Definition status_frame_config.cpp:7
bool TalonSRXConfig(WPI_TalonSRX &motorController, units::millisecond_t configTimeout)
Configures a CTRE TalonSRX with only the fields provided. All other fields are given the factory defa...
Definition talonsrx_config.h:68
Definition swap_controllers_command.h:12
RobotInstance
Differentiates between practice robot and competition robot.
Definition config_types.h:13
@ Competition
Competition robot.
@ Practice
Practice robot.
Definition custom_units.h:11
Definition talonsrx_config.h:19
Definition talonsrx_config.h:20
Definition talonsrx_config.h:22
Definition talonsrx_config.h:23
Definition talonsrx_config.h:24
Definition talonsrx_config.h:25
Definition talonsrx_config.h:26
Definition talonsrx_config.h:30
Definition talonsrx_config.h:31