Valkyrie 2026
Loading...
Searching...
No Matches
BaseController.h
1#pragma once
2
3#include <memory>
4#include <string>
5
6#include <ctre/phoenix6/CANBus.hpp>
7#include <ctre/phoenix6/CANcoder.hpp>
8#include <ctre/phoenix6/TalonFX.hpp>
9#include <frc/simulation/DCMotorSim.h>
10#include <frc/simulation/FlywheelSim.h>
11#include <frc/simulation/SingleJointedArmSim.h>
12#include <frc/smartdashboard/SmartDashboard.h>
13#include <frc/system/plant/DCMotor.h>
14#include <networktables/NetworkTable.h>
15#include <networktables/NetworkTableEntry.h>
16#include <networktables/NetworkTableInstance.h>
17#include <units/angle.h>
18#include <units/angular_velocity.h>
19#include <units/base.h>
20#include <units/current.h>
21#include <units/velocity.h>
22#include <units/voltage.h>
23
24#include "frc/smartdashboard/SendableChooser.h"
25#include "valkyrie/Loggable.h"
26#include "valkyrie/controllers/PIDF.h"
27#include "valkyrie/util/SendableChooser.h"
28#include "wpi/sendable/SendableRegistry.h"
29
30namespace valor {
31
35enum NeutralMode { Brake, Coast };
36
59 public:
60 using Output = std::variant<units::volt_t, units::ampere_t, units::scalar_t>;
61
65 explicit BaseController(frc::DCMotor _motorSpec)
66 : motorSpec{_motorSpec}, rotorToSensor(1), sensorToMech(1), voltageCompensation(units::volt_t{12.0}) {
67 for (TuningMode mode : magic_enum::enum_values<TuningMode>())
68 tuningModeChooser.AddOption(magic_enum::enum_name(mode), mode);
69 tuningModeChooser.SetDefaultOption(magic_enum::enum_name(TuningMode::Voltage));
70 opModeChooser.AddOption("Tuning", OperationalMode::Tuning);
71 opModeChooser.AddOption("Non Operational", OperationalMode::NonOperational);
72 opModeChooser.SetDefaultOption("Operational", OperationalMode::Operational);
73
74 LogChild("Tuning Mode", &tuningModeChooser);
75 LogChild("Operational Mode", &opModeChooser);
76 }
77
78 virtual ~BaseController() {
79 wpi::SendableRegistry::Remove(&tuningModeChooser);
80 wpi::SendableRegistry::Remove(&opModeChooser);
81 }
82
83 void OnLoggingStart() override {
84 WriteLog("Tuning Setpoint", 0.0);
85 WriteLog("Tune", false);
86 }
87
88 virtual void ApplyConfig() = 0;
89
90 enum class OperationalMode { NonOperational, Tuning, Operational };
91 enum class TuningMode { Voltage, Current, DutyCycle, Speed, Position };
92
93 inline OperationalMode GetOperationalMode() const { return opModeChooser.GetSelected(); }
94
95 inline TuningMode GetTuningMode() const { return tuningModeChooser.GetSelected(); }
96
103 constexpr units::turns_per_second_t GetMaxMechanismSpeed() { return motorSpec.freeSpeed / (rotorToSensor * sensorToMech); }
104
109 constexpr void SetVoltageCompensation(units::volt_t _voltageCompensation) { voltageCompensation = _voltageCompensation; }
110
111 constexpr units::volt_t GetVoltageCompensation() { return voltageCompensation; }
112
123 virtual constexpr void Reset() {}
124
132 virtual units::turn_t GetPosition() const = 0;
133
141 virtual units::ampere_t GetCurrent() const = 0;
142
150 virtual units::turns_per_second_t GetSpeed() const = 0;
151
152 virtual void SetEncoderPosition(units::turn_t position) = 0;
153
154 void SetPosition(units::turn_t position, Output feedforward = 0, int slot = 0) {
155 if (GetOperationalMode() == OperationalMode::Operational) {
156 WriteLog("Requested Position", position);
157 PositionSetter(position, feedforward, slot);
158 } else if (GetOperationalMode() == OperationalMode::Tuning && ReadLog<bool>("Tune"))
159 HandleTuningMode();
160 else
161 PowerSetter(0_V);
162 }
163
164 void SetSpeed(units::turns_per_second_t speed, Output feedforward = 0, int slot = 0) {
165 if (GetOperationalMode() == OperationalMode::Operational) {
166 WriteLog("Requested Speed", speed);
167 SpeedSetter(speed, feedforward, slot);
168 } else if (GetOperationalMode() == OperationalMode::Tuning && ReadLog<bool>("Tune"))
169 HandleTuningMode();
170 else
171 PowerSetter(0_V);
172 }
173
174 void SetPower(Output power) {
175 if (GetOperationalMode() == OperationalMode::Operational)
176 PowerSetter(power);
177 else if (GetOperationalMode() == OperationalMode::Tuning && ReadLog<bool>("Tune"))
178 HandleTuningMode();
179 else
180 PowerSetter(0_V);
181 }
182
195 virtual void SetupFollower(int canID, bool followerInverted = false) = 0;
196
208 virtual void SetPIDF(valor::PIDF<> pidf, int slot = 0, bool saveImmediately = false) = 0;
209
222 void SetLimits(units::turn_t reverse, units::turn_t forward, bool saveImmediately = false) {
223 SetForwardLimit(forward, saveImmediately);
224 SetReverseLimit(reverse, saveImmediately);
225 }
226
235 virtual void SetForwardLimit(units::turn_t forward, bool saveImmediately = false) = 0;
236
245 virtual void SetReverseLimit(units::turn_t reverse, bool saveImmediately = false) = 0;
246
253 virtual void SetNeutralMode(valor::NeutralMode mode, bool saveImmediately = false) = 0;
254
270 virtual void SetGearRatios(double rotorToSensor, double sensorToMech, bool saveImmediately = false) = 0;
271
272 virtual void SetOpenLoopRamp(units::second_t time, bool saveImmediately = false) = 0;
273
274 virtual units::turn_t GetAbsoluteEncoderPosition() const = 0;
275
276 virtual units::volt_t CalculateAppliedVoltage() = 0;
277 virtual void SetSimState(units::turn_t pos, units::turns_per_second_t vel, units::turns_per_second_squared_t accel) = 0;
278
279 virtual inline void SetSimState(frc::sim::DCMotorSim& sim) {
280 SetSimState(sim.GetAngularPosition(), sim.GetAngularVelocity(), sim.GetAngularAcceleration());
281 }
282
283 virtual inline void SetSimState(frc::sim::FlywheelSim& sim) {
284 SetSimState(0_tr, sim.GetAngularVelocity(), sim.GetAngularAcceleration());
285 }
286
287 virtual inline void SetSimState(frc::sim::SingleJointedArmSim& sim) { SetSimState(sim.GetAngle(), sim.GetVelocity(), 0_tr_per_s_sq); }
288
289 constexpr void SetDefaultTuningMode(TuningMode mode) { tuningModeChooser.SetDefaultOption(magic_enum::enum_name(mode)); };
290
291 frc::DCMotor motorSpec;
292 double rotorToSensor;
293 double sensorToMech;
294
295 protected:
308 virtual void PositionSetter(units::turn_t position, Output feedforward = 0, int slot = 0) = 0;
309
322 virtual void SpeedSetter(units::turns_per_second_t speed, Output feedforward = 0, int slot = 0) = 0;
323
324 virtual void PowerSetter(Output out) = 0;
325
326 units::volt_t voltageCompensation;
327
328 private:
329 void HandleTuningMode() {
330 double setpoint = ReadLog<double>("Tuning Setpoint");
331 switch (tuningModeChooser.GetSelected()) {
332 case TuningMode::Voltage:
333 return PowerSetter(units::volt_t{setpoint});
334 case TuningMode::Current:
335 return PowerSetter(units::ampere_t{setpoint});
336 case TuningMode::DutyCycle:
337 return PowerSetter(setpoint);
338 case TuningMode::Speed:
339 WriteLog("Requested Speed", units::turns_per_second_t{setpoint});
340 return SpeedSetter(units::turns_per_second_t{setpoint});
341 case TuningMode::Position:
342 WriteLog("Requested Position", units::turn_t{setpoint});
343 return PositionSetter(units::turn_t{setpoint});
344 }
345 }
346
347 valor::SendableChooser<TuningMode> tuningModeChooser;
349};
350} // namespace valor
Abstract class that all Valor controllers's should implement.
Definition BaseController.h:58
virtual units::ampere_t GetCurrent() const =0
Get the motors output current.
virtual void SetNeutralMode(valor::NeutralMode mode, bool saveImmediately=false)=0
Set the neutral mode of the motor.
virtual void SetForwardLimit(units::turn_t forward, bool saveImmediately=false)=0
Set the forward soft limit for the motor.
void SetLimits(units::turn_t reverse, units::turn_t forward, bool saveImmediately=false)
Set both soft limits for the motor.
Definition BaseController.h:222
virtual void SpeedSetter(units::turns_per_second_t speed, Output feedforward=0, int slot=0)=0
Send the motor to a specific speed.
virtual void SetPIDF(valor::PIDF<> pidf, int slot=0, bool saveImmediately=false)=0
Change the PIDF values for the motor.
constexpr units::turns_per_second_t GetMaxMechanismSpeed()
Get the mechanisms's maximum speed.
Definition BaseController.h:103
virtual void SetReverseLimit(units::turn_t reverse, bool saveImmediately=false)=0
Set the reverse soft limit for the motor.
BaseController(frc::DCMotor _motorSpec)
Construct a new Valor Controller object.
Definition BaseController.h:65
virtual void SetupFollower(int canID, bool followerInverted=false)=0
If a motor is paired with another motor, setup that other motor as a follower.
virtual units::turns_per_second_t GetSpeed() const =0
Get the motors speed.
virtual units::turn_t GetPosition() const =0
Get the motors position.
virtual void PositionSetter(units::turn_t position, Output feedforward=0, int slot=0)=0
Send the motor to a specific position.
virtual void SetGearRatios(double rotorToSensor, double sensorToMech, bool saveImmediately=false)=0
Set the gear ratios for the motor.
constexpr void SetVoltageCompensation(units::volt_t _voltageCompensation)
Setup the voltage compensation for the motor.
Definition BaseController.h:109
virtual constexpr void Reset()
Resets the motor and any state.
Definition BaseController.h:123
void OnLoggingStart() override
Hook invoked when logging is started for this object.
Definition BaseController.h:83
Base helper for publishing and subscribing values to NetworkTables.
Definition Loggable.h:218
T ReadLog(std::string_view field, const T &defaultValue={})
Read a value from NetworkTables for the given field.
Definition Loggable.h:362
T WriteLog(std::string_view field, const T &data, LogLevel level=LogLevel::Normal)
Publish a value to NetworkTables under the given field.
Definition Loggable.h:326
void LogChild(std::string_view name, Loggable *child)
Register a child Loggable under a named subtree.
Definition SendableChooser.h:7
Container to hold PID and feed forward values for the motor controller.
Definition PIDF.h:26