blob: 4a579430102011c884187b5762515f9b02880a05 [file] [log] [blame]
Brian Silverman17f503e2015-08-02 18:17:18 -07001#include "y2014/actors/shoot_actor.h"
2
3#include <functional>
4
John Park33858a32018-09-28 23:05:48 -07005#include "aos/logging/logging.h"
Brian Silverman17f503e2015-08-02 18:17:18 -07006
Comran Morshed5323ecb2015-12-26 20:50:55 +00007#include "frc971/control_loops/drivetrain/drivetrain.q.h"
Austin Schuhb2461f42019-06-29 18:17:06 -07008#include "y2014/constants.h"
9#include "y2014/control_loops/claw/claw.q.h"
10#include "y2014/control_loops/shooter/shooter.q.h"
Brian Silverman17f503e2015-08-02 18:17:18 -070011
Brian Silvermanb601d892015-12-20 18:24:38 -050012namespace y2014 {
Brian Silverman17f503e2015-08-02 18:17:18 -070013namespace actors {
Brian Silverman17f503e2015-08-02 18:17:18 -070014
15constexpr double ShootActor::kOffsetRadians;
16constexpr double ShootActor::kClawShootingSeparation;
17constexpr double ShootActor::kClawShootingSeparationGoal;
18
Austin Schuh1bf8a212019-05-26 22:13:14 -070019ShootActor::ShootActor(::aos::EventLoop *event_loop)
20 : ::aos::common::actions::ActorBase<actors::ShootActionQueueGroup>(
Austin Schuhb2461f42019-06-29 18:17:06 -070021 event_loop, ".y2014.actors.shoot_action"),
22 claw_goal_fetcher_(
23 event_loop->MakeFetcher<::y2014::control_loops::ClawQueue::Goal>(
24 ".y2014.control_loops.claw_queue.goal")),
25 claw_status_fetcher_(
26 event_loop->MakeFetcher<::y2014::control_loops::ClawQueue::Status>(
27 ".y2014.control_loops.claw_queue.status")),
28 claw_goal_sender_(
29 event_loop->MakeSender<::y2014::control_loops::ClawQueue::Goal>(
30 ".y2014.control_loops.claw_queue.goal")) {}
Brian Silverman17f503e2015-08-02 18:17:18 -070031
32double ShootActor::SpeedToAngleOffset(double speed) {
Austin Schuhb2461f42019-06-29 18:17:06 -070033 const constants::Values &values = constants::GetValues();
Brian Silverman17f503e2015-08-02 18:17:18 -070034 // scale speed to a [0.0-1.0] on something close to the max
35 return (speed / values.drivetrain_max_speed) * kOffsetRadians;
36}
37
Austin Schuhb2461f42019-06-29 18:17:06 -070038bool ShootActor::IntakeOff() {
39 claw_goal_fetcher_.Fetch();
40 if (!claw_goal_fetcher_.get()) {
41 LOG(WARNING, "no claw goal\n");
42 // If it doesn't have a goal, then the intake isn't on so we don't have to
43 // turn it off.
44 return true;
45 } else {
46 auto goal_message = claw_goal_sender_.MakeMessage();
47
48 goal_message->bottom_angle = claw_goal_fetcher_->bottom_angle;
49 goal_message->separation_angle = claw_goal_fetcher_->separation_angle;
50 goal_message->intake = 0.0;
51 goal_message->centering = 0.0;
52
53 if (!goal_message.Send()) {
54 LOG(WARNING, "sending claw goal failed\n");
55 return false;
56 }
57 }
58 return true;
59}
60
Brian Silverman17f503e2015-08-02 18:17:18 -070061bool ShootActor::RunAction(const double&) {
62 InnerRunAction();
63
64 // Now do our 'finally' block and make sure that we aren't requesting shots
65 // continually.
66 control_loops::shooter_queue.goal.FetchLatest();
67 if (control_loops::shooter_queue.goal.get() == nullptr) {
68 return true;
69 }
70 if (!control_loops::shooter_queue.goal.MakeWithBuilder()
71 .shot_power(control_loops::shooter_queue.goal->shot_power)
72 .shot_requested(false)
73 .unload_requested(false)
74 .load_requested(false)
75 .Send()) {
76 LOG(WARNING, "sending shooter goal failed\n");
77 return false;
78 }
79
80 LOG(INFO, "finished\n");
81 return true;
82}
83
84void ShootActor::InnerRunAction() {
85 LOG(INFO, "Shooting at the current angle and power.\n");
86
87 // wait for claw to be ready
88 if (WaitUntil(::std::bind(&ShootActor::DoneSetupShot, this))) {
89 return;
90 }
91
92 if (!IntakeOff()) return;
93
94 // Make sure that we have the latest shooter status.
95 control_loops::shooter_queue.status.FetchLatest();
96 // Get the number of shots fired up to this point. This should not be updated
97 // again for another few cycles.
98 previous_shots_ = control_loops::shooter_queue.status->shots;
99 // Shoot!
100 if (!control_loops::shooter_queue.goal.MakeWithBuilder()
101 .shot_power(control_loops::shooter_queue.goal->shot_power)
102 .shot_requested(true)
103 .unload_requested(false)
104 .load_requested(false)
105 .Send()) {
106 LOG(WARNING, "sending shooter goal failed\n");
107 return;
108 }
109
110 // wait for record of shot having been fired
111 if (WaitUntil(::std::bind(&ShootActor::DoneShot, this))) return;
112
113 if (!IntakeOff()) return;
114}
115
Austin Schuhb2461f42019-06-29 18:17:06 -0700116bool ShootActor::ClawIsReady() {
117 claw_goal_fetcher_.Fetch();
Brian Silverman17f503e2015-08-02 18:17:18 -0700118
Austin Schuhb2461f42019-06-29 18:17:06 -0700119 bool ans = claw_status_fetcher_->zeroed &&
120 (::std::abs(claw_status_fetcher_->bottom_velocity) < 0.5) &&
121 (::std::abs(claw_status_fetcher_->bottom -
122 claw_goal_fetcher_->bottom_angle) < 0.10) &&
123 (::std::abs(claw_status_fetcher_->separation -
124 claw_goal_fetcher_->separation_angle) < 0.4);
Brian Silverman17f503e2015-08-02 18:17:18 -0700125 LOG(DEBUG, "Claw is %sready zeroed %d bottom_velocity %f bottom %f sep %f\n",
Austin Schuhb2461f42019-06-29 18:17:06 -0700126 ans ? "" : "not ", claw_status_fetcher_->zeroed,
127 ::std::abs(claw_status_fetcher_->bottom_velocity),
128 ::std::abs(claw_status_fetcher_->bottom -
129 claw_goal_fetcher_->bottom_angle),
130 ::std::abs(claw_status_fetcher_->separation -
131 claw_goal_fetcher_->separation_angle));
Brian Silverman17f503e2015-08-02 18:17:18 -0700132 return ans;
133}
134
135bool ShooterIsReady() {
136 control_loops::shooter_queue.goal.FetchLatest();
137
138 LOG(DEBUG, "Power error is %f - %f -> %f, ready %d\n",
139 control_loops::shooter_queue.status->hard_stop_power,
140 control_loops::shooter_queue.goal->shot_power,
141 ::std::abs(control_loops::shooter_queue.status->hard_stop_power -
142 control_loops::shooter_queue.goal->shot_power),
143 control_loops::shooter_queue.status->ready);
144 return (::std::abs(control_loops::shooter_queue.status->hard_stop_power -
145 control_loops::shooter_queue.goal->shot_power) < 1.0) &&
146 control_loops::shooter_queue.status->ready;
147}
148
149bool ShootActor::DoneSetupShot() {
150 control_loops::shooter_queue.status.FetchAnother();
Austin Schuhb2461f42019-06-29 18:17:06 -0700151 claw_status_fetcher_.Fetch();
Brian Silverman17f503e2015-08-02 18:17:18 -0700152 // Make sure that both the shooter and claw have reached the necessary
153 // states.
154 if (ShooterIsReady() && ClawIsReady()) {
155 LOG(INFO, "Claw and Shooter ready for shooting.\n");
156 return true;
157 }
158
159 return false;
160}
161
162bool ShootActor::DonePreShotOpen() {
Austin Schuhb2461f42019-06-29 18:17:06 -0700163 claw_status_fetcher_.Fetch();
164 if (claw_status_fetcher_->separation > kClawShootingSeparation) {
Brian Silverman17f503e2015-08-02 18:17:18 -0700165 LOG(INFO, "Opened up enough to shoot.\n");
166 return true;
167 }
168 return false;
169}
170
171bool ShootActor::DoneShot() {
172 control_loops::shooter_queue.status.FetchAnother();
173 if (control_loops::shooter_queue.status->shots > previous_shots_) {
174 LOG(INFO, "Shot succeeded!\n");
175 return true;
176 }
177 return false;
178}
179
Brian Silverman17f503e2015-08-02 18:17:18 -0700180} // namespace actors
Brian Silvermanb601d892015-12-20 18:24:38 -0500181} // namespace y2014