blob: a9cf61415fad3ac4fcbf004e2ec82b368db0ad98 [file] [log] [blame]
Austin Schuhcb091712018-02-21 20:01:55 -08001#ifndef Y2018_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_ARM_H_
2#define Y2018_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_ARM_H_
3
Alex Perrycb7da4b2019-08-28 19:35:56 -07004#include "aos/time/time.h"
Maxwell Henderson8f0e07f2023-02-08 21:10:58 -08005#include "frc971/control_loops/double_jointed_arm/dynamics.h"
6#include "frc971/control_loops/double_jointed_arm/ekf.h"
Maxwell Henderson8f0e07f2023-02-08 21:10:58 -08007#include "frc971/control_loops/double_jointed_arm/graph.h"
8#include "frc971/control_loops/double_jointed_arm/trajectory.h"
James Kuszmaulec635d22023-08-12 18:39:24 -07009#include "frc971/zeroing/pot_and_absolute_encoder.h"
Philipp Schrader790cb542023-07-05 21:06:52 -070010#include "frc971/zeroing/zeroing.h"
11#include "y2018/constants.h"
12#include "y2018/control_loops/superstructure/arm/generated_graph.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070013#include "y2018/control_loops/superstructure/superstructure_position_generated.h"
14#include "y2018/control_loops/superstructure/superstructure_status_generated.h"
Austin Schuhcb091712018-02-21 20:01:55 -080015
Maxwell Henderson8f0e07f2023-02-08 21:10:58 -080016using frc971::control_loops::arm::EKF;
Philipp Schrader790cb542023-07-05 21:06:52 -070017using frc971::control_loops::arm::TrajectoryFollower;
Maxwell Henderson8f0e07f2023-02-08 21:10:58 -080018
Austin Schuhcb091712018-02-21 20:01:55 -080019namespace y2018 {
20namespace control_loops {
21namespace superstructure {
22namespace arm {
23
Austin Schuhcb091712018-02-21 20:01:55 -080024class Arm {
25 public:
26 Arm();
27
Austin Schuh7a090402018-03-04 01:16:45 -080028 // If true, tune down all the constants for testing.
Austin Schuhb874fd32018-03-05 00:27:10 -080029 static constexpr bool kGrannyMode() { return false; }
Austin Schuh7a090402018-03-04 01:16:45 -080030
Austin Schuhcb091712018-02-21 20:01:55 -080031 // The operating voltage.
Austin Schuh7a090402018-03-04 01:16:45 -080032 static constexpr double kOperatingVoltage() {
Austin Schuh41c71e42018-04-04 20:11:20 -070033 return kGrannyMode() ? 5.0 : 12.0;
Austin Schuh7a090402018-03-04 01:16:45 -080034 }
Austin Schuhcb091712018-02-21 20:01:55 -080035 static constexpr double kDt() { return 0.00505; }
Austin Schuh41c71e42018-04-04 20:11:20 -070036 static constexpr double kAlpha0Max() { return kGrannyMode() ? 5.0 : 15.0; }
37 static constexpr double kAlpha1Max() { return kGrannyMode() ? 5.0 : 15.0; }
Austin Schuhb874fd32018-03-05 00:27:10 -080038
39 static constexpr double kVMax() { return kGrannyMode() ? 5.0 : 11.5; }
40 static constexpr double kPathlessVMax() { return 5.0; }
Austin Schuh41c71e42018-04-04 20:11:20 -070041 static constexpr double kGotoPathVMax() { return 6.0; }
Austin Schuhcb091712018-02-21 20:01:55 -080042
Alex Perrycb7da4b2019-08-28 19:35:56 -070043 flatbuffers::Offset<superstructure::ArmStatus> Iterate(
44 const ::aos::monotonic_clock::time_point monotonic_now,
45 const uint32_t *unsafe_goal, bool grab_box, bool open_claw,
46 bool close_claw, const superstructure::ArmPosition *position,
47 const bool claw_beambreak_triggered,
48 const bool box_back_beambreak_triggered, const bool intake_clear_of_box,
49 bool suicide, bool trajectory_override, double *proximal_output,
50 double *distal_output, bool *release_arm_brake, bool *claw_closed,
51 flatbuffers::FlatBufferBuilder *fbb);
Austin Schuhcb091712018-02-21 20:01:55 -080052
53 void Reset();
54
55 enum class State : int32_t {
56 UNINITIALIZED,
57 ZEROING,
Austin Schuh96341532018-03-09 21:17:24 -080058 DISABLED,
59 GOTO_PATH,
Austin Schuhcb091712018-02-21 20:01:55 -080060 RUNNING,
Austin Schuh17e484e2018-03-11 01:11:36 -080061 PREP_CLIMB,
Austin Schuhcb091712018-02-21 20:01:55 -080062 ESTOP,
63 };
64
Austin Schuh96341532018-03-09 21:17:24 -080065 enum class GrabState : int32_t {
Austin Schuhede47322018-07-08 16:04:36 -070066 NORMAL = 0,
67 WAIT_FOR_BOX = 1,
68 TALL_BOX = 2,
69 SHORT_BOX = 3,
70 CLAW_CLOSE = 4,
71 OPEN_INTAKE = 5,
Austin Schuh96341532018-03-09 21:17:24 -080072 };
73
Austin Schuhcb091712018-02-21 20:01:55 -080074 State state() const { return state_; }
Austin Schuh96341532018-03-09 21:17:24 -080075 GrabState grab_state() const { return grab_state_; }
76
Alex Perrycb7da4b2019-08-28 19:35:56 -070077 bool estopped() const { return state_ == State::ESTOP; }
78 bool zeroed() const {
79 return (proximal_zeroing_estimator_.zeroed() &&
80 distal_zeroing_estimator_.zeroed());
81 }
82
Austin Schuh96341532018-03-09 21:17:24 -080083 // Returns the maximum position for the intake. This is used to override the
84 // intake position to release the box when the state machine is lifting.
85 double max_intake_override() const { return max_intake_override_; }
Austin Schuhcb091712018-02-21 20:01:55 -080086
Austin Schuhd76546a2018-07-08 16:05:14 -070087 uint32_t current_node() const { return current_node_; }
88
89 double path_distance_to_go() { return follower_.path_distance_to_go(); }
90
Austin Schuhcb091712018-02-21 20:01:55 -080091 private:
Austin Schuh96341532018-03-09 21:17:24 -080092 bool AtState(uint32_t state) const { return current_node_ == state; }
Austin Schuh83cdd8a2018-03-21 20:49:02 -070093 bool NearEnd(double threshold = 0.03) const {
Austin Schuh96341532018-03-09 21:17:24 -080094 return ::std::abs(arm_ekf_.X_hat(0) - follower_.theta(0)) <= threshold &&
95 ::std::abs(arm_ekf_.X_hat(2) - follower_.theta(1)) <= threshold &&
96 follower_.path_distance_to_go() < 1e-3;
97 }
98
Austin Schuhcb091712018-02-21 20:01:55 -080099 State state_ = State::UNINITIALIZED;
100
Austin Schuh96341532018-03-09 21:17:24 -0800101 GrabState grab_state_ = GrabState::NORMAL;
102
103 ::aos::monotonic_clock::time_point claw_close_start_time_ =
Austin Schuhcb091712018-02-21 20:01:55 -0800104 ::aos::monotonic_clock::min_time;
105
Austin Schuh72db9a12019-01-21 18:02:51 -0800106 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator
107 proximal_zeroing_estimator_;
108 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator
109 distal_zeroing_estimator_;
Austin Schuhcb091712018-02-21 20:01:55 -0800110
111 double proximal_offset_ = 0.0;
112 double distal_offset_ = 0.0;
113
Austin Schuh96341532018-03-09 21:17:24 -0800114 bool claw_closed_ = true;
115 double max_intake_override_ = 1000.0;
116
Austin Schuhcb091712018-02-21 20:01:55 -0800117 const ::Eigen::Matrix<double, 2, 2> alpha_unitizer_;
118
Austin Schuh41c71e42018-04-04 20:11:20 -0700119 double vmax_ = kVMax();
120
Maxwell Henderson8f0e07f2023-02-08 21:10:58 -0800121 frc971::control_loops::arm::Dynamics dynamics_;
122
Austin Schuh41c71e42018-04-04 20:11:20 -0700123 ::std::vector<TrajectoryAndParams> trajectories_;
Austin Schuhcb091712018-02-21 20:01:55 -0800124 SearchGraph search_graph_;
125
126 bool close_enough_for_full_power_ = false;
127
Austin Schuh17e484e2018-03-11 01:11:36 -0800128 int32_t climb_count_ = 0;
Austin Schuh7afcc232018-09-16 16:33:47 -0700129 int32_t brownout_count_ = 0;
Austin Schuh17e484e2018-03-11 01:11:36 -0800130
Austin Schuhcb091712018-02-21 20:01:55 -0800131 EKF arm_ekf_;
132 TrajectoryFollower follower_;
133
Austin Schuhb874fd32018-03-05 00:27:10 -0800134 const ::std::vector<::Eigen::Matrix<double, 2, 1>> points_;
135
Austin Schuhcb091712018-02-21 20:01:55 -0800136 // Start at the 0th index.
137 uint32_t current_node_ = 0;
138
Neil Balchba9cbba2018-04-06 22:26:38 -0700139 uint32_t claw_closed_count_ = 0;
140
Austin Schuhcb091712018-02-21 20:01:55 -0800141 EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
142};
143
144} // namespace arm
145} // namespace superstructure
146} // namespace control_loops
147} // namespace y2018
148
149#endif // Y2018_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_ARM_H_