blob: a33ff2239fbd666deeea43d54cbf7b3bdffc4660 [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
16enum class ShifterType : int32_t {
17 HALL_EFFECT_SHIFTER = 0, // Detect when inbetween gears.
Adam Snaider18f44172016-10-22 15:30:21 -070018 SIMPLE_SHIFTER = 1, // Switch gears without speedmatch logic.
19 NO_SHIFTER = 2, // Only one gear ratio.
Comran Morshed5323ecb2015-12-26 20:50:55 +000020};
21
Comran Morshed76ca8f52016-02-21 17:26:28 +000022enum class LoopType : int32_t {
Adam Snaider18f44172016-10-22 15:30:21 -070023 OPEN_LOOP = 0, // Only use open loop logic.
Comran Morshed76ca8f52016-02-21 17:26:28 +000024 CLOSED_LOOP = 1, // Add in closed loop calculation.
25};
26
Campbell Crowley2527ed22017-02-17 21:10:02 -080027enum class GyroType : int32_t {
28 SPARTAN_GYRO = 0, // Use the gyro on the spartan board.
29 IMU_X_GYRO = 1, // Use the x-axis of the gyro on the IMU.
30 IMU_Y_GYRO = 2, // Use the y-axis of the gyro on the IMU.
31 IMU_Z_GYRO = 3, // Use the z-axis of the gyro on the IMU.
32 FLIPPED_SPARTAN_GYRO = 4, // Use the gyro on the spartan board.
Austin Schuh90b43b42019-01-04 07:45:05 +110033 FLIPPED_IMU_Z_GYRO = 5, // Use the flipped z-axis of the gyro on the IMU.
Campbell Crowley2527ed22017-02-17 21:10:02 -080034};
35
Diana Burgessd0180f12018-03-21 21:24:17 -070036enum class IMUType : int32_t {
Austin Schuhe7f6ddf2019-03-22 20:29:49 -070037 IMU_X = 0, // Use the x-axis of the IMU.
38 IMU_Y = 1, // Use the y-axis of the IMU.
39 IMU_FLIPPED_X = 2, // Use the flipped x-axis of the IMU.
James Kuszmaul7f55f072020-03-01 10:21:26 -080040 IMU_Z = 3, // Use the z-axis of the IMU.
Diana Burgessd0180f12018-03-21 21:24:17 -070041};
42
Austin Schuhbcce26a2018-03-26 23:41:24 -070043template <typename Scalar = double>
Comran Morshed5323ecb2015-12-26 20:50:55 +000044struct DrivetrainConfig {
45 // Shifting method we are using.
46 ShifterType shifter_type;
47
Comran Morshed76ca8f52016-02-21 17:26:28 +000048 // Type of loop to use.
49 LoopType loop_type;
50
Campbell Crowley2527ed22017-02-17 21:10:02 -080051 // Type of gyro to use.
52 GyroType gyro_type;
53
Diana Burgessd0180f12018-03-21 21:24:17 -070054 // Type of IMU to use.
55 IMUType imu_type;
56
Comran Morshed5323ecb2015-12-26 20:50:55 +000057 // Polydrivetrain functions returning various controller loops with plants.
Austin Schuhbcce26a2018-03-26 23:41:24 -070058 ::std::function<StateFeedbackLoop<4, 2, 2, Scalar>()> make_drivetrain_loop;
59 ::std::function<StateFeedbackLoop<2, 2, 2, Scalar>()> make_v_drivetrain_loop;
60 ::std::function<StateFeedbackLoop<7, 2, 4, Scalar>()> make_kf_drivetrain_loop;
Austin Schuha062edb2019-01-03 13:17:13 -080061#if defined(__linux__)
62 ::std::function<
63 StateFeedbackLoop<2, 2, 2, Scalar, StateFeedbackHybridPlant<2, 2, 2>,
64 HybridKalman<2, 2, 2>>()>
65 make_hybrid_drivetrain_velocity_loop;
66#endif
Comran Morshed5323ecb2015-12-26 20:50:55 +000067
Austin Schuhbb735b72019-01-03 12:58:41 -080068 ::std::chrono::nanoseconds dt; // Control loop time step.
69 Scalar robot_radius; // Robot radius, in meters.
70 Scalar wheel_radius; // Wheel radius, in meters.
71 Scalar v; // Motor velocity constant.
Comran Morshed5323ecb2015-12-26 20:50:55 +000072
Austin Schuh09fa9bb2016-02-16 11:47:40 -080073 // Gear ratios, from wheel to motor shaft.
Austin Schuhbcce26a2018-03-26 23:41:24 -070074 Scalar high_gear_ratio;
75 Scalar low_gear_ratio;
Comran Morshed5323ecb2015-12-26 20:50:55 +000076
Austin Schuhe6a9fdf2019-01-12 16:05:43 -080077 // Moment of inertia and mass.
78 Scalar J;
79 Scalar mass;
80
Comran Morshed5323ecb2015-12-26 20:50:55 +000081 // Hall effect constants. Unused if not applicable to shifter type.
82 constants::ShifterHallEffect left_drive;
83 constants::ShifterHallEffect right_drive;
Adam Snaiderbc918b62016-02-27 21:03:39 -080084
85 // Variable that holds the default gear ratio. We use this in ZeroOutputs().
86 // (ie. true means high gear is default).
87 bool default_high_gear;
Austin Schuh889fee82016-04-13 22:16:36 -070088
Austin Schuhbcce26a2018-03-26 23:41:24 -070089 Scalar down_offset;
Adam Snaider94a52372016-10-19 20:06:01 -070090
Austin Schuhbcce26a2018-03-26 23:41:24 -070091 Scalar wheel_non_linearity;
Adam Snaider94a52372016-10-19 20:06:01 -070092
Austin Schuhbcce26a2018-03-26 23:41:24 -070093 Scalar quickturn_wheel_multiplier;
Austin Schuhd91c0d22016-10-15 21:24:28 -070094
Austin Schuhbcce26a2018-03-26 23:41:24 -070095 Scalar wheel_multiplier;
Austin Schuhe8a54c02018-03-05 00:25:58 -080096
James Kuszmaul8bad2412019-03-10 10:47:56 -070097 // Whether the shift button on the pistol grip enables line following mode.
98 bool pistol_grip_shift_enables_line_follow = false;
99
James Kuszmaul2215d922020-02-11 17:17:26 -0800100 // Rotation matrix from the IMU's coordinate frame to the robot's coordinate
101 // frame.
102 // I.e., imu_transform * imu_readings will give the imu readings in the
103 // robot frame.
104 Eigen::Matrix<double, 3, 3> imu_transform =
105 Eigen::Matrix<double, 3, 3>::Identity();
106
107 // True if we are running a simulated drivetrain.
108 bool is_simulated = false;
109
Austin Schuhd91c0d22016-10-15 21:24:28 -0700110 // Converts the robot state to a linear distance position, velocity.
Austin Schuhbcce26a2018-03-26 23:41:24 -0700111 static Eigen::Matrix<Scalar, 2, 1> LeftRightToLinear(
112 const Eigen::Matrix<Scalar, 7, 1> &left_right) {
113 Eigen::Matrix<Scalar, 2, 1> linear;
Austin Schuhd91c0d22016-10-15 21:24:28 -0700114 linear(0, 0) = (left_right(0, 0) + left_right(2, 0)) / 2.0;
115 linear(1, 0) = (left_right(1, 0) + left_right(3, 0)) / 2.0;
116 return linear;
117 }
118 // Converts the robot state to an anglular distance, velocity.
Austin Schuhbcce26a2018-03-26 23:41:24 -0700119 Eigen::Matrix<Scalar, 2, 1> LeftRightToAngular(
120 const Eigen::Matrix<Scalar, 7, 1> &left_right) const {
121 Eigen::Matrix<Scalar, 2, 1> angular;
Austin Schuhd91c0d22016-10-15 21:24:28 -0700122 angular(0, 0) =
123 (left_right(2, 0) - left_right(0, 0)) / (this->robot_radius * 2.0);
124 angular(1, 0) =
125 (left_right(3, 0) - left_right(1, 0)) / (this->robot_radius * 2.0);
126 return angular;
127 }
128
Alex Perrye32eabc2019-02-08 19:51:19 -0800129 Eigen::Matrix<Scalar, 2, 2> Tlr_to_la() const {
130 return (::Eigen::Matrix<Scalar, 2, 2>() << 0.5, 0.5,
131 -1.0 / (2 * robot_radius), 1.0 / (2 * robot_radius)).finished();
132 }
133
134 Eigen::Matrix<Scalar, 2, 2> Tla_to_lr() const {
135 return Tlr_to_la().inverse();
136 }
137
Austin Schuhd91c0d22016-10-15 21:24:28 -0700138 // Converts the linear and angular position, velocity to the top 4 states of
139 // the robot state.
Austin Schuhbcce26a2018-03-26 23:41:24 -0700140 Eigen::Matrix<Scalar, 4, 1> AngularLinearToLeftRight(
141 const Eigen::Matrix<Scalar, 2, 1> &linear,
142 const Eigen::Matrix<Scalar, 2, 1> &angular) const {
143 Eigen::Matrix<Scalar, 2, 1> scaled_angle =
Austin Schuhd91c0d22016-10-15 21:24:28 -0700144 angular * this->robot_radius;
Austin Schuhbcce26a2018-03-26 23:41:24 -0700145 Eigen::Matrix<Scalar, 4, 1> state;
Austin Schuhd91c0d22016-10-15 21:24:28 -0700146 state(0, 0) = linear(0, 0) - scaled_angle(0, 0);
147 state(1, 0) = linear(1, 0) - scaled_angle(1, 0);
148 state(2, 0) = linear(0, 0) + scaled_angle(0, 0);
149 state(3, 0) = linear(1, 0) + scaled_angle(1, 0);
150 return state;
151 }
Comran Morshed5323ecb2015-12-26 20:50:55 +0000152};
Comran Morshed5323ecb2015-12-26 20:50:55 +0000153} // namespace drivetrain
154} // namespace control_loops
155} // namespace frc971
156
157#endif // FRC971_CONTROL_LOOPS_DRIVETRAIN_CONSTANTS_H_