Daniel Petti | aece37f | 2014-10-25 17:13:44 -0700 | [diff] [blame] | 1 | #include <stdio.h> |
| 2 | |
| 3 | #include <memory> |
| 4 | |
| 5 | #include "aos/common/util/phased_loop.h" |
| 6 | #include "aos/common/time.h" |
| 7 | #include "aos/common/util/trapezoid_profile.h" |
| 8 | #include "aos/common/logging/logging.h" |
Daniel Petti | aece37f | 2014-10-25 17:13:44 -0700 | [diff] [blame] | 9 | |
Daniel Petti | b0733be | 2014-11-14 22:44:03 -0800 | [diff] [blame] | 10 | #include "bot3/actions/drivetrain_action.h" |
Daniel Petti | aece37f | 2014-10-25 17:13:44 -0700 | [diff] [blame] | 11 | #include "bot3/control_loops/drivetrain/drivetrain.q.h" |
Daniel Petti | b0733be | 2014-11-14 22:44:03 -0800 | [diff] [blame] | 12 | #include "bot3/control_loops/drivetrain/drivetrain_constants.h" |
| 13 | #include "bot3/control_loops/rollers/rollers.q.h" |
| 14 | #include "frc971/actions/action_client.h" |
| 15 | #include "frc971/actions/drivetrain_action.q.h" |
Daniel Petti | aece37f | 2014-10-25 17:13:44 -0700 | [diff] [blame] | 16 | #include "frc971/autonomous/auto.q.h" |
| 17 | #include "frc971/queues/other_sensors.q.h" |
| 18 | |
| 19 | using ::aos::time::Time; |
| 20 | |
| 21 | namespace bot3 { |
| 22 | namespace autonomous { |
| 23 | |
| 24 | namespace time = ::aos::time; |
| 25 | |
| 26 | static double left_initial_position, right_initial_position; |
| 27 | |
| 28 | bool ShouldExitAuto() { |
| 29 | ::frc971::autonomous::autonomous.FetchLatest(); |
| 30 | bool ans = !::frc971::autonomous::autonomous->run_auto; |
| 31 | if (ans) { |
| 32 | LOG(INFO, "Time to exit auto mode\n"); |
| 33 | } |
| 34 | return ans; |
| 35 | } |
| 36 | |
| 37 | void StopDrivetrain() { |
| 38 | LOG(INFO, "Stopping the drivetrain\n"); |
| 39 | control_loops::drivetrain.goal.MakeWithBuilder() |
| 40 | .control_loop_driving(true) |
| 41 | .left_goal(left_initial_position) |
| 42 | .left_velocity_goal(0) |
| 43 | .right_goal(right_initial_position) |
| 44 | .right_velocity_goal(0) |
| 45 | .quickturn(false) |
| 46 | .Send(); |
| 47 | } |
| 48 | |
| 49 | void ResetDrivetrain() { |
| 50 | LOG(INFO, "resetting the drivetrain\n"); |
| 51 | control_loops::drivetrain.goal.MakeWithBuilder() |
| 52 | .control_loop_driving(false) |
| 53 | .highgear(false) |
| 54 | .steering(0.0) |
| 55 | .throttle(0.0) |
| 56 | .left_goal(left_initial_position) |
| 57 | .left_velocity_goal(0) |
| 58 | .right_goal(right_initial_position) |
| 59 | .right_velocity_goal(0) |
| 60 | .Send(); |
| 61 | } |
| 62 | |
Daniel Petti | b0733be | 2014-11-14 22:44:03 -0800 | [diff] [blame] | 63 | void WaitUntilDoneOrCanceled(::frc971::Action *action) { |
Daniel Petti | aece37f | 2014-10-25 17:13:44 -0700 | [diff] [blame] | 64 | while (true) { |
Daniel Petti | b0733be | 2014-11-14 22:44:03 -0800 | [diff] [blame] | 65 | // Poll the running bit and auto done bits. |
| 66 | ::aos::time::PhasedLoop10MS(5000); |
| 67 | if (!action->Running() || ShouldExitAuto()) { |
| 68 | return; |
| 69 | } |
Daniel Petti | aece37f | 2014-10-25 17:13:44 -0700 | [diff] [blame] | 70 | } |
Daniel Petti | b0733be | 2014-11-14 22:44:03 -0800 | [diff] [blame] | 71 | } |
| 72 | |
| 73 | ::std::unique_ptr<::frc971::TypedAction |
| 74 | < ::frc971::actions::DrivetrainActionQueueGroup>> |
| 75 | SetDriveGoal(double distance, bool slow_acceleration, |
| 76 | double maximum_velocity = 1.7, double theta = 0) { |
| 77 | LOG(INFO, "Driving to %f\n", distance); |
| 78 | auto drivetrain_action = actions::MakeDrivetrainAction(); |
| 79 | drivetrain_action->GetGoal()->left_initial_position = left_initial_position; |
| 80 | drivetrain_action->GetGoal()->right_initial_position = right_initial_position; |
| 81 | drivetrain_action->GetGoal()->y_offset = distance; |
| 82 | drivetrain_action->GetGoal()->theta_offset = theta; |
| 83 | drivetrain_action->GetGoal()->maximum_velocity = maximum_velocity; |
| 84 | drivetrain_action->GetGoal()->maximum_acceleration = |
| 85 | slow_acceleration ? 2.5 : 3.0; |
| 86 | drivetrain_action->Start(); |
| 87 | left_initial_position += |
| 88 | distance - theta * control_loops::kBot3TurnWidth / 2.0; |
| 89 | right_initial_position += |
| 90 | distance + theta * control_loops::kBot3TurnWidth / 2.0; |
| 91 | return ::std::move(drivetrain_action); |
Daniel Petti | aece37f | 2014-10-25 17:13:44 -0700 | [diff] [blame] | 92 | } |
| 93 | |
| 94 | void InitializeEncoders() { |
| 95 | control_loops::drivetrain.status.FetchLatest(); |
| 96 | while (!control_loops::drivetrain.status.get()) { |
| 97 | LOG(WARNING, |
| 98 | "No previous drivetrain position packet, trying to fetch again\n"); |
| 99 | control_loops::drivetrain.status.FetchNextBlocking(); |
| 100 | } |
| 101 | left_initial_position = |
| 102 | control_loops::drivetrain.status->filtered_left_position; |
| 103 | right_initial_position = |
| 104 | control_loops::drivetrain.status->filtered_right_position; |
| 105 | |
| 106 | } |
| 107 | |
Daniel Petti | b0733be | 2014-11-14 22:44:03 -0800 | [diff] [blame] | 108 | void StopRollers() { |
| 109 | control_loops::rollers.goal.MakeWithBuilder() |
| 110 | .intake(0) |
| 111 | .low_spit(0) |
| 112 | .human_player(false) |
| 113 | .Send(); |
| 114 | } |
| 115 | |
| 116 | void SpitBallFront() { |
| 117 | control_loops::rollers.goal.MakeWithBuilder() |
| 118 | .intake(0) |
| 119 | .low_spit(1) |
| 120 | .human_player(false) |
| 121 | .Send(); |
| 122 | time::SleepFor(time::Time::InSeconds(1)); |
| 123 | StopRollers(); |
| 124 | } |
| 125 | |
| 126 | void IntakeBallBack() { |
| 127 | control_loops::rollers.goal.MakeWithBuilder() |
| 128 | .intake(-1) |
| 129 | .low_spit(0) |
| 130 | .human_player(false) |
| 131 | .Send(); |
| 132 | time::SleepFor(time::Time::InSeconds(1.5)); |
| 133 | StopRollers(); |
| 134 | } |
| 135 | |
| 136 | void ScoreBall(const double distance, const double velocity) { |
| 137 | // Drive to the goal, score, and drive back. |
| 138 | { |
| 139 | // Drive forward. |
| 140 | auto drivetrain_action = SetDriveGoal(distance, |
| 141 | false, velocity); |
| 142 | LOG(INFO, "Waiting until drivetrain is finished.\n"); |
| 143 | WaitUntilDoneOrCanceled(drivetrain_action.get()); |
| 144 | time::SleepFor(time::Time::InSeconds(0.5)); |
| 145 | if (ShouldExitAuto()) return; |
| 146 | } |
| 147 | { |
| 148 | LOG(INFO, "Spitting ball.\n"); |
| 149 | SpitBallFront(); |
| 150 | time::SleepFor(time::Time::InSeconds(0.5)); |
| 151 | if (ShouldExitAuto()) return; |
| 152 | } |
| 153 | { |
| 154 | // Drive back. |
| 155 | LOG(INFO, "Driving back.\n"); |
| 156 | auto drivetrain_action = SetDriveGoal(-distance, |
| 157 | false, velocity); |
| 158 | LOG(INFO, "Waiting until drivetrain is finished.\n"); |
| 159 | WaitUntilDoneOrCanceled(drivetrain_action.get()); |
| 160 | if (ShouldExitAuto()) return; |
| 161 | } |
| 162 | } |
| 163 | |
Daniel Petti | aece37f | 2014-10-25 17:13:44 -0700 | [diff] [blame] | 164 | void HandleAuto() { |
Daniel Petti | b0733be | 2014-11-14 22:44:03 -0800 | [diff] [blame] | 165 | constexpr double kDriveDistance = 4.86; |
| 166 | constexpr double kAutoVelocity = 2.5; |
| 167 | |
| 168 | if (ShouldExitAuto()) return; |
| 169 | ResetDrivetrain(); |
| 170 | InitializeEncoders(); |
| 171 | if (ShouldExitAuto()) return; |
| 172 | |
| 173 | ScoreBall(kDriveDistance, kAutoVelocity); |
Daniel Petti | aece37f | 2014-10-25 17:13:44 -0700 | [diff] [blame] | 174 | } |
| 175 | |
| 176 | } // namespace autonomous |
| 177 | } // namespace bot3 |