blob: 3fe3b76a3aaaa2a20e8f9f4019ab77094bc56679 [file] [log] [blame]
#include "aos/common/control_loop/Timing.h"
#include "aos/common/logging/logging.h"
#include "frc971/autonomous/shoot_action.q.h"
#include "frc971/control_loops/shooter/shooter.q.h"
#include "frc971/control_loops/claw/claw.q.h"
#include "frc971/constants.h"
namespace frc971 {
namespace actions {
class ShootAction {
public:
void Run() {
::frc971::actions::shoot_action.goal.FetchLatest();
while (!::frc971::actions::shoot_action.goal.get()) {
::frc971::actions::shoot_action.goal.FetchNextBlocking();
}
if (!::frc971::actions::shoot_action.status.MakeWithBuilder().running(false)
.Send()) {
LOG(ERROR, "Failed to send the status.\n");
}
while (true) {
while (!::frc971::actions::shoot_action.goal->run) {
LOG(INFO, "Waiting for an action request.\n");
::frc971::actions::shoot_action.goal.FetchNextBlocking();
}
LOG(INFO, "Starting action\n");
if (!::frc971::actions::shoot_action.status.MakeWithBuilder().running(
true).Send()) {
LOG(ERROR, "Failed to send the status.\n");
}
RunAction();
if (!::frc971::actions::shoot_action.status.MakeWithBuilder().running(
false).Send()) {
LOG(ERROR, "Failed to send the status.\n");
}
while (::frc971::actions::shoot_action.goal->run) {
LOG(INFO, "Waiting for the action to be stopped.\n");
::frc971::actions::shoot_action.goal.FetchNextBlocking();
}
}
}
// Actually execute the action of moving the claw and shooter into position
// and actually firing them.
void RunAction();
protected:
// Returns true if the action should be canceled.
bool ShouldCancel() {
shoot_action.goal.FetchLatest();
bool ans = !::frc971::actions::shoot_action.goal->run;
if (ans) {
LOG(INFO, "Time to exit auto mode\n");
}
return ans;
}
};
void ShootAction::RunAction() {
if (!control_loops::shooter_queue_group.goal.MakeWithBuilder().shot_power(
shoot_action.goal->shot_power).shot_requested(false)
.unload_requested(false).load_requested(false).Send()) {
LOG(ERROR, "Failed to send the shoot action\n");
return;
}
if (!control_loops::claw_queue_group.goal.MakeWithBuilder().bottom_angle(
shoot_action.goal->shot_angle).separation_angle(0.0).intake(2.0)
.centering(1.0).Send()) {
LOG(WARNING, "sending claw goal failed\n");
return;
}
// Make sure we have the latest statuses.
control_loops::shooter_queue_group.status.FetchLatest();
control_loops::claw_queue_group.status.FetchLatest();
while (true) {
// Make sure that both the shooter and claw have reached the necessary
// states.
if (control_loops::shooter_queue_group.status->ready &&
control_loops::claw_queue_group.status->done) {
LOG(INFO, "Claw and Shooter ready for shooting.\n");
// TODO(james): Get realer numbers for shooter_action.
break;
}
// Wait until we have a new status.
control_loops::shooter_queue_group.status.FetchNextBlocking();
control_loops::claw_queue_group.status.FetchNextBlocking();
if (ShouldCancel()) return;
}
const frc971::constants::Values &values = frc971::constants::GetValues();
// Open up the claw in preparation for shooting.
if (!control_loops::claw_queue_group.goal.MakeWithBuilder().bottom_angle(
shoot_action.goal->shot_angle)
.separation_angle(values.shooter_action.claw_separation_goal)
.intake(2.0).centering(1.0).Send()) {
LOG(WARNING, "sending claw goal failed\n");
return;
}
if (ShouldCancel()) return;
// Make sure we have the latest status.
control_loops::claw_queue_group.status.FetchLatest();
while (true) {
if (control_loops::claw_queue_group.status->separation > values.shooter_action.claw_shooting_separation) {
LOG(INFO, "Opened up enough to shoot.\n");
break;
}
// Wait until we have a new status.
control_loops::claw_queue_group.status.FetchNextBlocking();
if (ShouldCancel()) return;
}
// Shoot!
if (!control_loops::shooter_queue_group.goal.MakeWithBuilder().shot_power(
shoot_action.goal->shot_power).shot_requested(true)
.unload_requested(false).load_requested(false).Send()) {
LOG(WARNING, "sending shooter goal failed\n");
return;
}
if (ShouldCancel()) return;
// Make sure that we have the latest shooter status.
control_loops::shooter_queue_group.status.FetchLatest();
// Get the number of shots fired up to this point. This should not be updated
// again for another few cycles.
int previous_shots = control_loops::shooter_queue_group.status->shots;
while (true) {
if (control_loops::shooter_queue_group.status->shots > previous_shots) {
LOG(INFO, "Shot succeeded!\n");
break;
}
// Wait until we have a new status.
control_loops::shooter_queue_group.status.FetchNextBlocking();
if (ShouldCancel()) return;
}
return;
}
} // namespace actions
} // namespace frc971