WPILibC++ 2024.1.1-beta-4
LinearSystemId.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <concepts>
8#include <stdexcept>
9
10#include <wpi/SymbolExports.h>
11
14#include "units/acceleration.h"
17#include "units/length.h"
19#include "units/velocity.h"
20#include "units/voltage.h"
21
22namespace frc {
24 public:
25 template <typename Distance>
28
29 template <typename Distance>
33
34 /**
35 * Create a state-space model of the elevator system. The states of the system
36 * are [position, velocity], inputs are [voltage], and outputs are [position].
37 *
38 * @param motor The motor (or gearbox) attached to the carriage.
39 * @param mass The mass of the elevator carriage, in kilograms.
40 * @param radius The radius of the elevator's driving drum, in meters.
41 * @param gearing Gear ratio from motor to carriage.
42 * @throws std::domain_error if mass <= 0, radius <= 0, or gearing <= 0.
43 */
45 units::kilogram_t mass,
46 units::meter_t radius,
47 double gearing);
48
49 /**
50 * Create a state-space model of a single-jointed arm system.The states of the
51 * system are [angle, angular velocity], inputs are [voltage], and outputs are
52 * [angle].
53 *
54 * @param motor The motor (or gearbox) attached to the arm.
55 * @param J The moment of inertia J of the arm.
56 * @param gearing Gear ratio from motor to arm.
57 * @throws std::domain_error if J <= 0 or gearing <= 0.
58 */
60 DCMotor motor, units::kilogram_square_meter_t J, double gearing);
61
62 /**
63 * Create a state-space model for a 1 DOF velocity system from its kV
64 * (volts/(unit/sec)) and kA (volts/(unit/sec²)). These constants can be
65 * found using SysId. The states of the system are [velocity], inputs are
66 * [voltage], and outputs are [velocity].
67 *
68 * You MUST use an SI unit (i.e. meters or radians) for the Distance template
69 * argument. You may still use non-SI units (such as feet or inches) for the
70 * actual method arguments; they will automatically be converted to SI
71 * internally.
72 *
73 * The parameters provided by the user are from this feedforward model:
74 *
75 * u = K_v v + K_a a
76 *
77 * @param kV The velocity gain, in volts/(unit/sec).
78 * @param kA The acceleration gain, in volts/(unit/sec²).
79 * @throws std::domain_error if kV <= 0 or kA <= 0.
80 * @see <a
81 * href="https://github.com/wpilibsuite/sysid">https://github.com/wpilibsuite/sysid</a>
82 */
83 template <typename Distance>
84 requires std::same_as<units::meter, Distance> ||
85 std::same_as<units::radian, Distance>
87 decltype(1_V / Velocity_t<Distance>(1)) kV,
88 decltype(1_V / Acceleration_t<Distance>(1)) kA) {
89 if (kV <= decltype(kV){0}) {
90 throw std::domain_error("Kv must be greater than zero.");
91 }
92 if (kA <= decltype(kA){0}) {
93 throw std::domain_error("Ka must be greater than zero.");
94 }
95
96 Matrixd<1, 1> A{-kV.value() / kA.value()};
97 Matrixd<1, 1> B{1.0 / kA.value()};
98 Matrixd<1, 1> C{1.0};
99 Matrixd<1, 1> D{0.0};
100
101 return LinearSystem<1, 1, 1>(A, B, C, D);
102 }
103
104 /**
105 * Create a state-space model for a 1 DOF position system from its kV
106 * (volts/(unit/sec)) and kA (volts/(unit/sec²)). These constants can be
107 * found using SysId. the states of the system are [position, velocity],
108 * inputs are [voltage], and outputs are [position].
109 *
110 * You MUST use an SI unit (i.e. meters or radians) for the Distance template
111 * argument. You may still use non-SI units (such as feet or inches) for the
112 * actual method arguments; they will automatically be converted to SI
113 * internally.
114 *
115 * The parameters provided by the user are from this feedforward model:
116 *
117 * u = K_v v + K_a a
118 *
119 * @param kV The velocity gain, in volts/(unit/sec).
120 * @param kA The acceleration gain, in volts/(unit/sec²).
121 *
122 * @throws std::domain_error if kV <= 0 or kA <= 0.
123 * @see <a
124 * href="https://github.com/wpilibsuite/sysid">https://github.com/wpilibsuite/sysid</a>
125 */
126 template <typename Distance>
127 requires std::same_as<units::meter, Distance> ||
128 std::same_as<units::radian, Distance>
130 decltype(1_V / Velocity_t<Distance>(1)) kV,
131 decltype(1_V / Acceleration_t<Distance>(1)) kA) {
132 if (kV <= decltype(kV){0}) {
133 throw std::domain_error("Kv must be greater than zero.");
134 }
135 if (kA <= decltype(kA){0}) {
136 throw std::domain_error("Ka must be greater than zero.");
137 }
138
139 Matrixd<2, 2> A{{0.0, 1.0}, {0.0, -kV.value() / kA.value()}};
140 Matrixd<2, 1> B{0.0, 1.0 / kA.value()};
141 Matrixd<1, 2> C{1.0, 0.0};
142 Matrixd<1, 1> D{0.0};
143
144 return LinearSystem<2, 1, 1>(A, B, C, D);
145 }
146
147 /**
148 * Identify a differential drive drivetrain given the drivetrain's kV and kA
149 * in both linear {(volts/(meter/sec), (volts/(meter/sec²))} and angular
150 * {(volts/(radian/sec), (volts/(radian/sec²))} cases. These constants can be
151 * found using SysId.
152 *
153 * States: [[left velocity], [right velocity]]<br>
154 * Inputs: [[left voltage], [right voltage]]<br>
155 * Outputs: [[left velocity], [right velocity]]
156 *
157 * @param kVLinear The linear velocity gain in volts per (meters per second).
158 * @param kALinear The linear acceleration gain in volts per (meters per
159 * second squared).
160 * @param kVAngular The angular velocity gain in volts per (meters per
161 * second).
162 * @param kAAngular The angular acceleration gain in volts per (meters per
163 * second squared).
164 * @throws domain_error if kVLinear <= 0, kALinear <= 0, kVAngular <= 0,
165 * or kAAngular <= 0.
166 * @see <a
167 * href="https://github.com/wpilibsuite/sysid">https://github.com/wpilibsuite/sysid</a>
168 */
170 decltype(1_V / 1_mps) kVLinear, decltype(1_V / 1_mps_sq) kALinear,
171 decltype(1_V / 1_mps) kVAngular, decltype(1_V / 1_mps_sq) kAAngular);
172
173 /**
174 * Identify a differential drive drivetrain given the drivetrain's kV and kA
175 * in both linear {(volts/(meter/sec)), (volts/(meter/sec²))} and angular
176 * {(volts/(radian/sec)), (volts/(radian/sec²))} cases. This can be found
177 * using SysId.
178 *
179 * States: [[left velocity], [right velocity]]<br>
180 * Inputs: [[left voltage], [right voltage]]<br>
181 * Outputs: [[left velocity], [right velocity]]
182 *
183 * @param kVLinear The linear velocity gain in volts per (meters per
184 * second).
185 * @param kALinear The linear acceleration gain in volts per (meters per
186 * second squared).
187 * @param kVAngular The angular velocity gain in volts per (radians per
188 * second).
189 * @param kAAngular The angular acceleration gain in volts per (radians per
190 * second squared).
191 * @param trackwidth The distance between the differential drive's left and
192 * right wheels, in meters.
193 * @throws domain_error if kVLinear <= 0, kALinear <= 0, kVAngular <= 0,
194 * kAAngular <= 0, or trackwidth <= 0.
195 * @see <a
196 * href="https://github.com/wpilibsuite/sysid">https://github.com/wpilibsuite/sysid</a>
197 */
199 decltype(1_V / 1_mps) kVLinear, decltype(1_V / 1_mps_sq) kALinear,
200 decltype(1_V / 1_rad_per_s) kVAngular,
201 decltype(1_V / 1_rad_per_s_sq) kAAngular, units::meter_t trackwidth);
202
203 /**
204 * Create a state-space model of a flywheel system, the states of the system
205 * are [angular velocity], inputs are [voltage], and outputs are [angular
206 * velocity].
207 *
208 * @param motor The motor (or gearbox) attached to the flywheel.
209 * @param J The moment of inertia J of the flywheel.
210 * @param gearing Gear ratio from motor to flywheel.
211 * @throws std::domain_error if J <= 0 or gearing <= 0.
212 */
214 units::kilogram_square_meter_t J,
215 double gearing);
216
217 /**
218 * Create a state-space model of a DC motor system. The states of the system
219 * are [angular position, angular velocity], inputs are [voltage], and outputs
220 * are [angular position, angular velocity].
221 *
222 * @param motor The motor (or gearbox) attached to the system.
223 * @param J the moment of inertia J of the DC motor.
224 * @param gearing Gear ratio from motor to output.
225 * @throws std::domain_error if J <= 0 or gearing <= 0.
226 * @see <a
227 * href="https://github.com/wpilibsuite/sysid">https://github.com/wpilibsuite/sysid</a>
228 */
230 units::kilogram_square_meter_t J,
231 double gearing);
232
233 /**
234 * Create a state-space model of a DC motor system from its kV
235 * (volts/(unit/sec)) and kA (volts/(unit/sec²)). These constants can be
236 * found using SysId. the states of the system are [position, velocity],
237 * inputs are [voltage], and outputs are [position].
238 *
239 * You MUST use an SI unit (i.e. meters or radians) for the Distance template
240 * argument. You may still use non-SI units (such as feet or inches) for the
241 * actual method arguments; they will automatically be converted to SI
242 * internally.
243 *
244 * The parameters provided by the user are from this feedforward model:
245 *
246 * u = K_v v + K_a a
247 *
248 * @param kV The velocity gain, in volts/(unit/sec).
249 * @param kA The acceleration gain, in volts/(unit/sec²).
250 *
251 * @throws std::domain_error if kV <= 0 or kA <= 0.
252 */
253 template <typename Distance>
254 requires std::same_as<units::meter, Distance> ||
255 std::same_as<units::radian, Distance>
257 decltype(1_V / Velocity_t<Distance>(1)) kV,
258 decltype(1_V / Acceleration_t<Distance>(1)) kA) {
259 if (kV <= decltype(kV){0}) {
260 throw std::domain_error("Kv must be greater than zero.");
261 }
262 if (kA <= decltype(kA){0}) {
263 throw std::domain_error("Ka must be greater than zero.");
264 }
265
266 Matrixd<2, 2> A{{0.0, 1.0}, {0.0, -kV.value() / kA.value()}};
267 Matrixd<2, 1> B{0.0, 1.0 / kA.value()};
268 Matrixd<2, 2> C{{1.0, 0.0}, {0.0, 1.0}};
269 Matrixd<2, 1> D{{0.0}, {0.0}};
270
271 return LinearSystem<2, 1, 2>(A, B, C, D);
272 }
273
274 /**
275 * Create a state-space model of differential drive drivetrain. In this model,
276 * the states are [left velocity, right velocity], the inputs are [left
277 * voltage, right voltage], and the outputs are [left velocity, right
278 * velocity]
279 *
280 * @param motor The motor (or gearbox) driving the drivetrain.
281 * @param mass The mass of the robot in kilograms.
282 * @param r The radius of the wheels in meters.
283 * @param rb The radius of the base (half of the track width), in meters.
284 * @param J The moment of inertia of the robot.
285 * @param gearing Gear ratio from motor to wheel.
286 * @throws std::domain_error if mass <= 0, r <= 0, rb <= 0, J <= 0, or
287 * gearing <= 0.
288 */
290 const DCMotor& motor, units::kilogram_t mass, units::meter_t r,
291 units::meter_t rb, units::kilogram_square_meter_t J, double gearing);
292};
293
294} // namespace frc
#define WPILIB_DLLEXPORT
Definition: SymbolExports.h:36
Holds the constants for a DC motor.
Definition: DCMotor.h:20
A plant defined using state-space notation.
Definition: LinearSystem.h:31
Definition: LinearSystemId.h:23
static LinearSystem< 2, 1, 2 > DCMotorSystem(DCMotor motor, units::kilogram_square_meter_t J, double gearing)
Create a state-space model of a DC motor system.
static LinearSystem< 2, 2, 2 > DrivetrainVelocitySystem(const DCMotor &motor, units::kilogram_t mass, units::meter_t r, units::meter_t rb, units::kilogram_square_meter_t J, double gearing)
Create a state-space model of differential drive drivetrain.
static LinearSystem< 1, 1, 1 > FlywheelSystem(DCMotor motor, units::kilogram_square_meter_t J, double gearing)
Create a state-space model of a flywheel system, the states of the system are [angular velocity],...
static LinearSystem< 2, 1, 1 > IdentifyPositionSystem(decltype(1_V/Velocity_t< Distance >(1)) kV, decltype(1_V/Acceleration_t< Distance >(1)) kA)
Create a state-space model for a 1 DOF position system from its kV (volts/(unit/sec)) and kA (volts/(...
Definition: LinearSystemId.h:129
static LinearSystem< 2, 1, 2 > DCMotorSystem(decltype(1_V/Velocity_t< Distance >(1)) kV, decltype(1_V/Acceleration_t< Distance >(1)) kA)
Create a state-space model of a DC motor system from its kV (volts/(unit/sec)) and kA (volts/(unit/se...
Definition: LinearSystemId.h:256
static LinearSystem< 1, 1, 1 > IdentifyVelocitySystem(decltype(1_V/Velocity_t< Distance >(1)) kV, decltype(1_V/Acceleration_t< Distance >(1)) kA)
Create a state-space model for a 1 DOF velocity system from its kV (volts/(unit/sec)) and kA (volts/(...
Definition: LinearSystemId.h:86
static LinearSystem< 2, 1, 1 > ElevatorSystem(DCMotor motor, units::kilogram_t mass, units::meter_t radius, double gearing)
Create a state-space model of the elevator system.
static LinearSystem< 2, 2, 2 > IdentifyDrivetrainSystem(decltype(1_V/1_mps) kVLinear, decltype(1_V/1_mps_sq) kALinear, decltype(1_V/1_rad_per_s) kVAngular, decltype(1_V/1_rad_per_s_sq) kAAngular, units::meter_t trackwidth)
Identify a differential drive drivetrain given the drivetrain's kV and kA in both linear {(volts/(met...
static LinearSystem< 2, 1, 1 > SingleJointedArmSystem(DCMotor motor, units::kilogram_square_meter_t J, double gearing)
Create a state-space model of a single-jointed arm system.The states of the system are [angle,...
static LinearSystem< 2, 2, 2 > IdentifyDrivetrainSystem(decltype(1_V/1_mps) kVLinear, decltype(1_V/1_mps_sq) kALinear, decltype(1_V/1_mps) kVAngular, decltype(1_V/1_mps_sq) kAAngular)
Identify a differential drive drivetrain given the drivetrain's kV and kA in both linear {(volts/(met...
Container for values which represent quantities of a given unit.
Definition: base.h:1938
typename units::detail::inverse_impl< U >::type inverse
represents the inverse unit type of class U.
Definition: base.h:1146
typename units::detail::compound_impl< U, Us... >::type compound_unit
Represents a unit type made up from other units.
Definition: base.h:1446
Definition: AprilTagPoseEstimator.h:15
Eigen::Matrix< double, Rows, Cols, Options, MaxRows, MaxCols > Matrixd
Definition: EigenCore.h:21