blob: 9c17fc804978794707602169954a2e63cd536c4f [file] [log] [blame]
Comran Morshed5323ecb2015-12-26 20:50:55 +00001#ifndef FRC971_CONTROL_LOOPS_DRIVETRAIN_CONSTANTS_H_
2#define FRC971_CONTROL_LOOPS_DRIVETRAIN_CONSTANTS_H_
3
4#include <functional>
5
Austin Schuha062edb2019-01-03 13:17:13 -08006#if defined(__linux__)
7#include "frc971/control_loops/hybrid_state_feedback_loop.h"
8#endif
Comran Morshed5323ecb2015-12-26 20:50:55 +00009#include "frc971/control_loops/state_feedback_loop.h"
Austin Schuha062edb2019-01-03 13:17:13 -080010#include "frc971/shifter_hall_effect.h"
Comran Morshed5323ecb2015-12-26 20:50:55 +000011
12namespace frc971 {
13namespace control_loops {
14namespace drivetrain {
15
Maxwell Henderson24f89f32023-03-25 15:55:46 -070016// What to use the top two buttons for on the pistol grip.
17enum class PistolTopButtonUse {
18 // Normal shifting.
19 kShift,
20 // Line following (currently just uses top button).
21 kLineFollow,
22 // Don't use the top button
23 kNone,
24};
25
26enum class PistolSecondButtonUse {
27 kTurn1,
28 kShiftLow,
29 kNone,
30};
31
32enum class PistolBottomButtonUse {
33 kControlLoopDriving,
34 kSlowDown,
35 kNone,
36};
37
Comran Morshed5323ecb2015-12-26 20:50:55 +000038enum class ShifterType : int32_t {
39 HALL_EFFECT_SHIFTER = 0, // Detect when inbetween gears.
Adam Snaider18f44172016-10-22 15:30:21 -070040 SIMPLE_SHIFTER = 1, // Switch gears without speedmatch logic.
41 NO_SHIFTER = 2, // Only one gear ratio.
Comran Morshed5323ecb2015-12-26 20:50:55 +000042};
43
Comran Morshed76ca8f52016-02-21 17:26:28 +000044enum class LoopType : int32_t {
Adam Snaider18f44172016-10-22 15:30:21 -070045 OPEN_LOOP = 0, // Only use open loop logic.
Comran Morshed76ca8f52016-02-21 17:26:28 +000046 CLOSED_LOOP = 1, // Add in closed loop calculation.
47};
48
Campbell Crowley2527ed22017-02-17 21:10:02 -080049enum class GyroType : int32_t {
Austin Schuhd749d932020-12-30 21:38:40 -080050 SPARTAN_GYRO = 0, // Use the gyro on the spartan board.
51 IMU_X_GYRO = 1, // Use the x-axis of the gyro on the IMU.
52 IMU_Y_GYRO = 2, // Use the y-axis of the gyro on the IMU.
53 IMU_Z_GYRO = 3, // Use the z-axis of the gyro on the IMU.
54 FLIPPED_SPARTAN_GYRO = 4, // Use the gyro on the spartan board.
55 FLIPPED_IMU_Z_GYRO = 5, // Use the flipped z-axis of the gyro on the IMU.
Campbell Crowley2527ed22017-02-17 21:10:02 -080056};
57
Diana Burgessd0180f12018-03-21 21:24:17 -070058enum class IMUType : int32_t {
Austin Schuhe7f6ddf2019-03-22 20:29:49 -070059 IMU_X = 0, // Use the x-axis of the IMU.
60 IMU_Y = 1, // Use the y-axis of the IMU.
61 IMU_FLIPPED_X = 2, // Use the flipped x-axis of the IMU.
James Kuszmaul7f55f072020-03-01 10:21:26 -080062 IMU_Z = 3, // Use the z-axis of the IMU.
Diana Burgessd0180f12018-03-21 21:24:17 -070063};
64
James Kuszmaul207ae322022-02-25 21:15:31 -080065struct DownEstimatorConfig {
66 // Threshold, in g's, to use for detecting whether we are stopped in the down
67 // estimator.
68 double gravity_threshold = 0.025;
69 // Number of cycles of being still to require before taking accelerometer
70 // corrections.
71 int do_accel_corrections = 50;
72};
73
James Kuszmaulc29f4572023-02-25 17:02:33 -080074// Configuration for line-following mode.
75struct LineFollowConfig {
76 // The line-following uses an LQR controller with states of [theta,
77 // linear_velocity, angular_velocity] and inputs of [left_voltage,
78 // right_voltage].
79 // These Q and R matrices are the costs for state and input respectively.
80 Eigen::Matrix3d Q =
81 Eigen::Matrix3d((::Eigen::DiagonalMatrix<double, 3>().diagonal()
82 << 1.0 / ::std::pow(0.1, 2),
83 1.0 / ::std::pow(1.0, 2), 1.0 / ::std::pow(1.0, 2))
84 .finished()
85 .asDiagonal());
86 Eigen::Matrix2d R =
87 Eigen::Matrix2d((::Eigen::DiagonalMatrix<double, 2>().diagonal()
88 << 1.0 / ::std::pow(12.0, 2),
89 1.0 / ::std::pow(12.0, 2))
90 .finished()
91 .asDiagonal());
92
93 // The driver can use their steering controller to adjust where we attempt to
94 // place things laterally. This specifies how much range on either side of
95 // zero we allow them, in meters.
96 double max_controllable_offset = 0.1;
97};
98
Austin Schuhbcce26a2018-03-26 23:41:24 -070099template <typename Scalar = double>
Comran Morshed5323ecb2015-12-26 20:50:55 +0000100struct DrivetrainConfig {
101 // Shifting method we are using.
102 ShifterType shifter_type;
103
Comran Morshed76ca8f52016-02-21 17:26:28 +0000104 // Type of loop to use.
105 LoopType loop_type;
106
Campbell Crowley2527ed22017-02-17 21:10:02 -0800107 // Type of gyro to use.
108 GyroType gyro_type;
109
Diana Burgessd0180f12018-03-21 21:24:17 -0700110 // Type of IMU to use.
111 IMUType imu_type;
112
Comran Morshed5323ecb2015-12-26 20:50:55 +0000113 // Polydrivetrain functions returning various controller loops with plants.
Austin Schuhbcce26a2018-03-26 23:41:24 -0700114 ::std::function<StateFeedbackLoop<4, 2, 2, Scalar>()> make_drivetrain_loop;
115 ::std::function<StateFeedbackLoop<2, 2, 2, Scalar>()> make_v_drivetrain_loop;
116 ::std::function<StateFeedbackLoop<7, 2, 4, Scalar>()> make_kf_drivetrain_loop;
Austin Schuha062edb2019-01-03 13:17:13 -0800117#if defined(__linux__)
118 ::std::function<
119 StateFeedbackLoop<2, 2, 2, Scalar, StateFeedbackHybridPlant<2, 2, 2>,
120 HybridKalman<2, 2, 2>>()>
121 make_hybrid_drivetrain_velocity_loop;
122#endif
Comran Morshed5323ecb2015-12-26 20:50:55 +0000123
Austin Schuhbb735b72019-01-03 12:58:41 -0800124 ::std::chrono::nanoseconds dt; // Control loop time step.
125 Scalar robot_radius; // Robot radius, in meters.
126 Scalar wheel_radius; // Wheel radius, in meters.
127 Scalar v; // Motor velocity constant.
Comran Morshed5323ecb2015-12-26 20:50:55 +0000128
Austin Schuh09fa9bb2016-02-16 11:47:40 -0800129 // Gear ratios, from wheel to motor shaft.
Austin Schuhbcce26a2018-03-26 23:41:24 -0700130 Scalar high_gear_ratio;
131 Scalar low_gear_ratio;
Comran Morshed5323ecb2015-12-26 20:50:55 +0000132
Austin Schuhe6a9fdf2019-01-12 16:05:43 -0800133 // Moment of inertia and mass.
134 Scalar J;
135 Scalar mass;
136
Comran Morshed5323ecb2015-12-26 20:50:55 +0000137 // Hall effect constants. Unused if not applicable to shifter type.
138 constants::ShifterHallEffect left_drive;
139 constants::ShifterHallEffect right_drive;
Adam Snaiderbc918b62016-02-27 21:03:39 -0800140
141 // Variable that holds the default gear ratio. We use this in ZeroOutputs().
142 // (ie. true means high gear is default).
143 bool default_high_gear;
Austin Schuh889fee82016-04-13 22:16:36 -0700144
Austin Schuhbcce26a2018-03-26 23:41:24 -0700145 Scalar down_offset;
Adam Snaider94a52372016-10-19 20:06:01 -0700146
Austin Schuhbcce26a2018-03-26 23:41:24 -0700147 Scalar wheel_non_linearity;
Adam Snaider94a52372016-10-19 20:06:01 -0700148
Austin Schuhbcce26a2018-03-26 23:41:24 -0700149 Scalar quickturn_wheel_multiplier;
Austin Schuhd91c0d22016-10-15 21:24:28 -0700150
Austin Schuhbcce26a2018-03-26 23:41:24 -0700151 Scalar wheel_multiplier;
Austin Schuhe8a54c02018-03-05 00:25:58 -0800152
James Kuszmaul8bad2412019-03-10 10:47:56 -0700153 // Whether the shift button on the pistol grip enables line following mode.
154 bool pistol_grip_shift_enables_line_follow = false;
155
James Kuszmaul2215d922020-02-11 17:17:26 -0800156 // Rotation matrix from the IMU's coordinate frame to the robot's coordinate
157 // frame.
158 // I.e., imu_transform * imu_readings will give the imu readings in the
159 // robot frame.
James Kuszmauld478f872020-03-16 20:54:27 -0700160 Eigen::Matrix<Scalar, 3, 3> imu_transform =
161 Eigen::Matrix<Scalar, 3, 3>::Identity();
James Kuszmaul2215d922020-02-11 17:17:26 -0800162
163 // True if we are running a simulated drivetrain.
164 bool is_simulated = false;
165
James Kuszmaul207ae322022-02-25 21:15:31 -0800166 DownEstimatorConfig down_estimator_config{};
167
James Kuszmaulc29f4572023-02-25 17:02:33 -0800168 LineFollowConfig line_follow_config{};
169
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700170 PistolTopButtonUse top_button_use = PistolTopButtonUse::kShift;
171 PistolSecondButtonUse second_button_use = PistolSecondButtonUse::kShiftLow;
172 PistolBottomButtonUse bottom_button_use = PistolBottomButtonUse::kSlowDown;
173
Austin Schuhd91c0d22016-10-15 21:24:28 -0700174 // Converts the robot state to a linear distance position, velocity.
Austin Schuhbcce26a2018-03-26 23:41:24 -0700175 static Eigen::Matrix<Scalar, 2, 1> LeftRightToLinear(
176 const Eigen::Matrix<Scalar, 7, 1> &left_right) {
177 Eigen::Matrix<Scalar, 2, 1> linear;
Austin Schuhd91c0d22016-10-15 21:24:28 -0700178 linear(0, 0) = (left_right(0, 0) + left_right(2, 0)) / 2.0;
179 linear(1, 0) = (left_right(1, 0) + left_right(3, 0)) / 2.0;
180 return linear;
181 }
182 // Converts the robot state to an anglular distance, velocity.
Austin Schuhbcce26a2018-03-26 23:41:24 -0700183 Eigen::Matrix<Scalar, 2, 1> LeftRightToAngular(
184 const Eigen::Matrix<Scalar, 7, 1> &left_right) const {
185 Eigen::Matrix<Scalar, 2, 1> angular;
Austin Schuhd91c0d22016-10-15 21:24:28 -0700186 angular(0, 0) =
187 (left_right(2, 0) - left_right(0, 0)) / (this->robot_radius * 2.0);
188 angular(1, 0) =
189 (left_right(3, 0) - left_right(1, 0)) / (this->robot_radius * 2.0);
190 return angular;
191 }
192
Alex Perrye32eabc2019-02-08 19:51:19 -0800193 Eigen::Matrix<Scalar, 2, 2> Tlr_to_la() const {
194 return (::Eigen::Matrix<Scalar, 2, 2>() << 0.5, 0.5,
Austin Schuhd749d932020-12-30 21:38:40 -0800195 -1.0 / (2 * robot_radius), 1.0 / (2 * robot_radius))
196 .finished();
Alex Perrye32eabc2019-02-08 19:51:19 -0800197 }
198
199 Eigen::Matrix<Scalar, 2, 2> Tla_to_lr() const {
200 return Tlr_to_la().inverse();
201 }
202
Austin Schuhd91c0d22016-10-15 21:24:28 -0700203 // Converts the linear and angular position, velocity to the top 4 states of
204 // the robot state.
Austin Schuhbcce26a2018-03-26 23:41:24 -0700205 Eigen::Matrix<Scalar, 4, 1> AngularLinearToLeftRight(
206 const Eigen::Matrix<Scalar, 2, 1> &linear,
207 const Eigen::Matrix<Scalar, 2, 1> &angular) const {
Austin Schuhd749d932020-12-30 21:38:40 -0800208 Eigen::Matrix<Scalar, 2, 1> scaled_angle = angular * this->robot_radius;
Austin Schuhbcce26a2018-03-26 23:41:24 -0700209 Eigen::Matrix<Scalar, 4, 1> state;
Austin Schuhd91c0d22016-10-15 21:24:28 -0700210 state(0, 0) = linear(0, 0) - scaled_angle(0, 0);
211 state(1, 0) = linear(1, 0) - scaled_angle(1, 0);
212 state(2, 0) = linear(0, 0) + scaled_angle(0, 0);
213 state(3, 0) = linear(1, 0) + scaled_angle(1, 0);
214 return state;
215 }
Comran Morshed5323ecb2015-12-26 20:50:55 +0000216};
Comran Morshed5323ecb2015-12-26 20:50:55 +0000217} // namespace drivetrain
218} // namespace control_loops
219} // namespace frc971
220
221#endif // FRC971_CONTROL_LOOPS_DRIVETRAIN_CONSTANTS_H_