blob: 840ce5323f3c29a821b2c55dd33615ee77a1096d [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
4#include "frc971/zeroing/zeroing.h"
5#include "y2018/constants.h"
6#include "y2018/control_loops/superstructure/arm/dynamics.h"
7#include "y2018/control_loops/superstructure/arm/ekf.h"
8#include "y2018/control_loops/superstructure/arm/graph.h"
9#include "y2018/control_loops/superstructure/arm/trajectory.h"
10#include "y2018/control_loops/superstructure/superstructure.q.h"
11
12namespace y2018 {
13namespace control_loops {
14namespace superstructure {
15namespace arm {
16
Austin Schuhcb091712018-02-21 20:01:55 -080017class Arm {
18 public:
19 Arm();
20
Austin Schuh7a090402018-03-04 01:16:45 -080021 // If true, tune down all the constants for testing.
Austin Schuhb874fd32018-03-05 00:27:10 -080022 static constexpr bool kGrannyMode() { return false; }
Austin Schuh7a090402018-03-04 01:16:45 -080023
Austin Schuhcb091712018-02-21 20:01:55 -080024 // The operating voltage.
Austin Schuh7a090402018-03-04 01:16:45 -080025 static constexpr double kOperatingVoltage() {
Austin Schuh96341532018-03-09 21:17:24 -080026 return kGrannyMode() ? 4.0 : 12.0;
Austin Schuh7a090402018-03-04 01:16:45 -080027 }
Austin Schuhcb091712018-02-21 20:01:55 -080028 static constexpr double kDt() { return 0.00505; }
Austin Schuhef978fc2018-03-21 20:38:06 -070029 static constexpr double kAlpha0Max() { return kGrannyMode() ? 10.0 : 10.0; }
30 static constexpr double kAlpha1Max() { return kGrannyMode() ? 10.0 : 10.0; }
Austin Schuhb874fd32018-03-05 00:27:10 -080031
32 static constexpr double kVMax() { return kGrannyMode() ? 5.0 : 11.5; }
33 static constexpr double kPathlessVMax() { return 5.0; }
Austin Schuh345a3732018-03-21 20:49:32 -070034 static constexpr double kGotoPathVMax() { return 12.0; }
Austin Schuhcb091712018-02-21 20:01:55 -080035
Austin Schuh96341532018-03-09 21:17:24 -080036 void Iterate(const uint32_t *unsafe_goal, bool grab_box, bool open_claw,
Austin Schuhcb091712018-02-21 20:01:55 -080037 const control_loops::ArmPosition *position,
Austin Schuh96341532018-03-09 21:17:24 -080038 const bool claw_beambreak_triggered,
39 const bool box_back_beambreak_triggered,
40 const bool intake_clear_of_box, double *proximal_output,
41 double *distal_output, bool *release_arm_brake,
Austin Schuh17e484e2018-03-11 01:11:36 -080042 bool *claw_closed, control_loops::ArmStatus *status,
43 bool suicide);
Austin Schuhcb091712018-02-21 20:01:55 -080044
45 void Reset();
46
47 enum class State : int32_t {
48 UNINITIALIZED,
49 ZEROING,
Austin Schuh96341532018-03-09 21:17:24 -080050 DISABLED,
51 GOTO_PATH,
Austin Schuhcb091712018-02-21 20:01:55 -080052 RUNNING,
Austin Schuh17e484e2018-03-11 01:11:36 -080053 PREP_CLIMB,
Austin Schuhcb091712018-02-21 20:01:55 -080054 ESTOP,
55 };
56
Austin Schuh96341532018-03-09 21:17:24 -080057 enum class GrabState : int32_t {
58 NORMAL,
59 WAIT_FOR_BOX,
60 TALL_BOX,
61 SHORT_BOX,
62 CLAW_CLOSE,
63 OPEN_INTAKE,
64 };
65
Austin Schuhcb091712018-02-21 20:01:55 -080066 State state() const { return state_; }
Austin Schuh96341532018-03-09 21:17:24 -080067 GrabState grab_state() const { return grab_state_; }
68
69 // Returns the maximum position for the intake. This is used to override the
70 // intake position to release the box when the state machine is lifting.
71 double max_intake_override() const { return max_intake_override_; }
Austin Schuhcb091712018-02-21 20:01:55 -080072
73 private:
Austin Schuh96341532018-03-09 21:17:24 -080074 bool AtState(uint32_t state) const { return current_node_ == state; }
Austin Schuh83cdd8a2018-03-21 20:49:02 -070075 bool NearEnd(double threshold = 0.03) const {
Austin Schuh96341532018-03-09 21:17:24 -080076 return ::std::abs(arm_ekf_.X_hat(0) - follower_.theta(0)) <= threshold &&
77 ::std::abs(arm_ekf_.X_hat(2) - follower_.theta(1)) <= threshold &&
78 follower_.path_distance_to_go() < 1e-3;
79 }
80
Austin Schuhcb091712018-02-21 20:01:55 -080081 State state_ = State::UNINITIALIZED;
82
Austin Schuh96341532018-03-09 21:17:24 -080083 GrabState grab_state_ = GrabState::NORMAL;
84
85 ::aos::monotonic_clock::time_point claw_close_start_time_ =
Austin Schuhcb091712018-02-21 20:01:55 -080086 ::aos::monotonic_clock::min_time;
87
88 ::frc971::zeroing::PotAndAbsEncoderZeroingEstimator proximal_zeroing_estimator_;
89 ::frc971::zeroing::PotAndAbsEncoderZeroingEstimator distal_zeroing_estimator_;
90
91 double proximal_offset_ = 0.0;
92 double distal_offset_ = 0.0;
93
Austin Schuh96341532018-03-09 21:17:24 -080094 bool claw_closed_ = true;
95 double max_intake_override_ = 1000.0;
96
Austin Schuhcb091712018-02-21 20:01:55 -080097 const ::Eigen::Matrix<double, 2, 2> alpha_unitizer_;
98
Austin Schuh7dfccf62018-03-03 21:28:14 -080099 ::std::vector<Trajectory> trajectories_;
Austin Schuhcb091712018-02-21 20:01:55 -0800100 SearchGraph search_graph_;
101
102 bool close_enough_for_full_power_ = false;
103
Austin Schuh17e484e2018-03-11 01:11:36 -0800104 int32_t climb_count_ = 0;
105
Austin Schuhcb091712018-02-21 20:01:55 -0800106 EKF arm_ekf_;
107 TrajectoryFollower follower_;
108
Austin Schuhb874fd32018-03-05 00:27:10 -0800109 const ::std::vector<::Eigen::Matrix<double, 2, 1>> points_;
110
Austin Schuhcb091712018-02-21 20:01:55 -0800111 // Start at the 0th index.
112 uint32_t current_node_ = 0;
113
114 EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
115};
116
117} // namespace arm
118} // namespace superstructure
119} // namespace control_loops
120} // namespace y2018
121
122#endif // Y2018_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_ARM_H_