Valkyrie 2026
Loading...
Searching...
No Matches
PIDF.h
1#pragma once
2
3#include <optional>
4#include <ratio>
5#include <type_traits>
6
7#include <units/acceleration.h>
8#include <units/angle.h>
9#include <units/angular_acceleration.h>
10#include <units/angular_jerk.h>
11#include <units/angular_velocity.h>
12#include <units/base.h>
13#include <units/time.h>
14#include <units/velocity.h>
15
16namespace valor {
17
18enum class GravityFFType { LINEAR, CIRCULAR };
19
23
24template <typename INPUT = units::dimensionless::dimensionless, typename OUTPUT = units::dimensionless::dimensionless>
25 requires units::traits::is_unit_v<INPUT> && units::traits::is_unit_v<OUTPUT>
26struct PIDF {
27 using TagTraits = units::traits::unit_traits<INPUT>;
28 using BaseUnits = typename TagTraits::base_unit_type;
29 using TimeRatio = typename BaseUnits::second_ratio;
30 using TimeCorrectionUnit =
31 units::unit<std::ratio<1>,
32 units::base_unit<std::ratio<0>, std::ratio<0>, std::ratio<-TimeRatio::num, TimeRatio::den>, std::ratio<0>>>;
33
34 using Position = units::compound_unit<INPUT, TimeCorrectionUnit>;
35 using Velocity = units::compound_unit<units::inverse<units::second>, Position>;
36 using Acceleration = units::compound_unit<units::inverse<units::second>, Velocity>;
37 using Jerk = units::compound_unit<units::inverse<units::second>, Acceleration>;
38
39 using Velocity_t = units::unit_t<Velocity>;
40 using Acceleration_t = units::unit_t<Acceleration>;
41 using Jerk_t = units::unit_t<Jerk>;
42
43 using ProportionalGain = units::compound_unit<OUTPUT, units::inverse<INPUT>>;
44 using IntegralGain = units::compound_unit<ProportionalGain, units::inverse<units::second>>;
45 using DerivativeGain = units::compound_unit<ProportionalGain, units::second>;
46
47 using ProportionalGain_t = units::unit_t<ProportionalGain>;
48 using IntegralGain_t = units::unit_t<IntegralGain>;
49 using DerivativeGain_t = units::unit_t<DerivativeGain>;
50
51 using Input_t = units::unit_t<INPUT>;
52 using Output_t = units::unit_t<OUTPUT>;
53
54 using kV_t = units::unit_t<units::compound_unit<OUTPUT, units::inverse<Velocity>>>;
55 using kA_t = units::unit_t<units::compound_unit<OUTPUT, units::inverse<Acceleration>>>;
56
57 ProportionalGain_t P{0};
58 IntegralGain_t I{0};
59 DerivativeGain_t D{0};
60
61 Velocity_t maxVelocity{0};
62 Acceleration_t maxAcceleration{0};
63 Jerk_t maxJerk{0};
64
65 Input_t error{0};
66 Input_t errorThreshold{0};
67
68 Output_t kS{0};
69 Output_t kG{0};
70
71 std::optional<kV_t> kV = std::nullopt;
72 std::optional<kA_t> kA = std::nullopt;
73
74 units::turn_t GTarget = 0_deg;
75 GravityFFType GType = GravityFFType::LINEAR;
76
78
79 operator DimensionlessPIDF_t() const
80 requires(!std::is_same_v<PIDF, DimensionlessPIDF_t>)
81 {
82 return DimensionlessPIDF_t{
83 .P = typename DimensionlessPIDF_t::ProportionalGain_t{P.value()},
84 .I = typename DimensionlessPIDF_t::IntegralGain_t{I.value()},
85 .D = typename DimensionlessPIDF_t::DerivativeGain_t{D.value()},
86 .maxVelocity = typename DimensionlessPIDF_t::Velocity_t{maxVelocity.value()},
87 .maxAcceleration = typename DimensionlessPIDF_t::Acceleration_t{maxAcceleration.value()},
88 .maxJerk = typename DimensionlessPIDF_t::Jerk_t{maxJerk.value()},
89 .error = typename DimensionlessPIDF_t::Input_t{error.value()},
90 .errorThreshold = typename DimensionlessPIDF_t::Input_t{errorThreshold.value()},
91 .kS = typename DimensionlessPIDF_t::Output_t{kS.value()},
92 .kG = typename DimensionlessPIDF_t::Output_t{kG.value()},
93 .kV = kV.has_value() ? std::make_optional(typename DimensionlessPIDF_t::kV_t{kV->value()}) : std::nullopt,
94 .kA = kA.has_value() ? std::make_optional(typename DimensionlessPIDF_t::kA_t{kA->value()}) : std::nullopt,
95 .GTarget = GTarget,
96 .GType = GType,
97 };
98 };
99};
100} // namespace valor
Container to hold PID and feed forward values for the motor controller.
Definition PIDF.h:26