Add 3 game piece auto
Change-Id: I3ee12fe6f253705e825774620d16b00c266db30d
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
diff --git a/y2023/autonomous/autonomous_actor.cc b/y2023/autonomous/autonomous_actor.cc
index 77965e4..c3ba65b 100644
--- a/y2023/autonomous/autonomous_actor.cc
+++ b/y2023/autonomous/autonomous_actor.cc
@@ -12,14 +12,27 @@
#include "y2023/control_loops/drivetrain/drivetrain_base.h"
#include "y2023/control_loops/superstructure/arm/generated_graph.h"
-DEFINE_bool(spline_auto, true, "Run simple test S-spline auto mode.");
+DEFINE_bool(spline_auto, false, "Run simple test S-spline auto mode.");
DEFINE_bool(charged_up, true, "If true run charged up autonomous mode");
namespace y2023 {
namespace autonomous {
-using ::aos::monotonic_clock;
using ::frc971::ProfileParametersT;
+
+ProfileParametersT MakeProfileParameters(float max_velocity,
+ float max_acceleration) {
+ ProfileParametersT result;
+ result.max_velocity = max_velocity;
+ result.max_acceleration = max_acceleration;
+ return result;
+}
+
+using ::aos::monotonic_clock;
+using frc971::CreateProfileParameters;
+using ::frc971::ProfileParametersT;
+using frc971::control_loops::CreateStaticZeroingSingleDOFProfiledSubsystemGoal;
+using frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal;
using frc971::control_loops::drivetrain::LocalizerControl;
namespace chrono = ::std::chrono;
@@ -34,8 +47,16 @@
event_loop->MakeFetcher<aos::JoystickState>("/aos")),
robot_state_fetcher_(event_loop->MakeFetcher<aos::RobotState>("/aos")),
auto_splines_(),
- arm_goal_position_(control_loops::superstructure::arm::NeutralIndex()),
+ arm_goal_position_(control_loops::superstructure::arm::StartingIndex()),
+ superstructure_goal_sender_(
+ event_loop->MakeSender<::y2023::control_loops::superstructure::Goal>(
+ "/superstructure")),
+ superstructure_status_fetcher_(
+ event_loop
+ ->MakeFetcher<::y2023::control_loops::superstructure::Status>(
+ "/superstructure")),
points_(control_loops::superstructure::arm::PointList()) {
+ drivetrain_status_fetcher_.Fetch();
replan_timer_ = event_loop->AddTimer([this]() { Replan(); });
event_loop->OnRun([this, event_loop]() {
@@ -74,6 +95,12 @@
}
void AutonomousActor::Replan() {
+ if (!drivetrain_status_fetcher_.Fetch()) {
+ replan_timer_->Setup(event_loop()->monotonic_now() + chrono::seconds(1));
+ AOS_LOG(INFO, "Drivetrain not up, replanning in 1 second");
+ return;
+ }
+
if (alliance_ == aos::Alliance::kInvalid) {
return;
}
@@ -86,6 +113,7 @@
starting_position_ = test_spline_->starting_position();
} else if (FLAGS_charged_up) {
+ AOS_LOG(INFO, "Charged up replanning!");
charged_up_splines_ = {
PlanSpline(std::bind(&AutonomousSplines::Spline1, &auto_splines_,
std::placeholders::_1, alliance_),
@@ -99,9 +127,6 @@
PlanSpline(std::bind(&AutonomousSplines::Spline4, &auto_splines_,
std::placeholders::_1, alliance_),
SplineDirection::kForward),
- PlanSpline(std::bind(&AutonomousSplines::Spline5, &auto_splines_,
- std::placeholders::_1, alliance_),
- SplineDirection::kBackward),
};
starting_position_ = charged_up_splines_.value()[0].starting_position();
@@ -129,6 +154,12 @@
CHECK(joystick_state_fetcher_.get() != nullptr)
<< "Expect at least one JoystickState message before running auto...";
alliance_ = joystick_state_fetcher_->alliance();
+
+ wrist_goal_ = 0.0;
+ roller_goal_ = control_loops::superstructure::RollerGoal::IDLE;
+ arm_goal_position_ = control_loops::superstructure::arm::StartingIndex();
+ preloaded_ = false;
+ SendSuperstructureGoal();
}
bool AutonomousActor::RunAction(
@@ -155,6 +186,8 @@
}
if (FLAGS_spline_auto) {
SplineAuto();
+ } else if (FLAGS_charged_up) {
+ ChargedUp();
} else {
AOS_LOG(WARNING, "No auto mode selected.");
}
@@ -197,15 +230,21 @@
auto &splines = *charged_up_splines_;
+ AOS_LOG(INFO, "Going to preload");
+
// Tell the superstructure a cone was preloaded
if (!WaitForPreloaded()) return;
+ AOS_LOG(INFO, "Moving arm");
// Place first cone on mid level
MidConeScore();
// Wait until the arm is at the goal to spit
- if (!WaitForArmGoal()) return;
+ if (!WaitForArmGoal(0.10)) return;
Spit();
+ if (!WaitForArmGoal(0.01)) return;
+
+ std::this_thread::sleep_for(chrono::milliseconds(100));
AOS_LOG(
INFO, "Placed first cone %lf s\n",
@@ -217,21 +256,49 @@
// Move arm into position to pickup a cube and start cube intake
PickupCube();
+
+ std::this_thread::sleep_for(chrono::milliseconds(500));
+
IntakeCube();
+ AOS_LOG(
+ INFO, "Turning on rollers %lf s\n",
+ aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+
if (!splines[0].WaitForSplineDistanceRemaining(0.02)) return;
+ AOS_LOG(
+ INFO, "Got there %lf s\n",
+ aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+
// Drive back to grid and place cube on high level
if (!splines[1].WaitForPlan()) return;
splines[1].Start();
+ std::this_thread::sleep_for(chrono::milliseconds(300));
HighCubeScore();
- if (!splines[1].WaitForSplineDistanceRemaining(0.02)) return;
+ if (!splines[1].WaitForSplineDistanceRemaining(0.08)) return;
+ AOS_LOG(
+ INFO, "Back for first cube %lf s\n",
+ aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
- if (!WaitForArmGoal()) return;
+ if (!WaitForArmGoal(0.10)) return;
+
+ AOS_LOG(
+ INFO, "Arm in place for first cube %lf s\n",
+ aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+
Spit();
+ if (!splines[1].WaitForSplineDistanceRemaining(0.08)) return;
+
+ AOS_LOG(
+ INFO, "Finished spline back %lf s\n",
+ aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+
+ if (!WaitForArmGoal(0.05)) return;
+
AOS_LOG(
INFO, "Placed first cube %lf s\n",
aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
@@ -240,43 +307,110 @@
if (!splines[2].WaitForPlan()) return;
splines[2].Start();
+ std::this_thread::sleep_for(chrono::milliseconds(200));
PickupCube();
+
+ std::this_thread::sleep_for(chrono::milliseconds(500));
IntakeCube();
- if (!splines[2].WaitForSplineDistanceRemaining(0.02)) return;
+ if (!splines[2].WaitForSplineDistanceRemaining(0.05)) return;
+ AOS_LOG(
+ INFO, "Picked up second cube %lf s\n",
+ aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
// Drive back to grid and place object on mid level
if (!splines[3].WaitForPlan()) return;
splines[3].Start();
+ AOS_LOG(
+ INFO, "Driving back %lf s\n",
+ aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+
MidCubeScore();
- if (!splines[3].WaitForSplineDistanceRemaining(0.02)) return;
+ if (!splines[3].WaitForSplineDistanceRemaining(0.05)) return;
+ AOS_LOG(
+ INFO, "Got back from second cube at %lf s\n",
+ aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
- if (!WaitForArmGoal()) return;
+ if (!WaitForArmGoal(0.05)) return;
+
+ if (!splines[3].WaitForSplineDistanceRemaining(0.05)) return;
Spit();
+ if (!splines[3].WaitForSplineDistanceRemaining(0.02)) return;
+
AOS_LOG(
INFO, "Placed second cube %lf s\n",
aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+ InitializeEncoders();
- // Drive onto charging station
- if (!splines[4].WaitForPlan()) return;
- splines[4].Start();
+ const ProfileParametersT kDrive = MakeProfileParameters(2.0, 4.0);
+ const ProfileParametersT kTurn = MakeProfileParameters(3.0, 4.5);
+ StartDrive(0.0, 0.0, kDrive, kTurn);
- if (!splines[4].WaitForSplineDistanceRemaining(0.02)) return;
+ {
+ double side_scalar = (alliance_ == aos::Alliance::kRed) ? 1.0 : -1.0;
+ StartDrive(6.33 - std::abs(X()), 0.0, kDrive, kTurn);
+ if (!WaitForDriveProfileNear(0.01)) return;
+
+ AOS_LOG(
+ INFO, "Done backing up %lf s\n",
+ aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+
+ const ProfileParametersT kInPlaceTurn = MakeProfileParameters(2.0, 4.5);
+ StartDrive(0.0, aos::math::NormalizeAngle(M_PI / 2.0 - Theta()), kDrive,
+ kInPlaceTurn);
+
+ std::this_thread::sleep_for(chrono::milliseconds(400));
+ StopSpitting();
+
+ AOS_LOG(
+ INFO, "Roller off %lf s\n",
+ aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+
+ Balance();
+ if (!WaitForTurnProfileNear(0.03)) return;
+
+ AOS_LOG(
+ INFO, "Done turning %lf s\n",
+ aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+
+ const ProfileParametersT kDrive = MakeProfileParameters(1.4, 3.0);
+ const ProfileParametersT kFinalTurn = MakeProfileParameters(3.0, 4.5);
+ const double kDriveDistance = 3.12;
+ StartDrive(-kDriveDistance, 0.0, kDrive, kFinalTurn);
+
+ const ProfileParametersT kFastTurn = MakeProfileParameters(5.0, 8.0);
+ if (!WaitForDriveProfileNear(kDriveDistance - 0.4)) return;
+
+ AOS_LOG(
+ INFO, "Turning %lf s\n",
+ aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+ StartDrive(0.0, -side_scalar * M_PI / 2.0, kDrive, kFastTurn);
+ if (!WaitForDriveProfileDone()) return;
+ if (!WaitForTurnProfileDone()) return;
+ AOS_LOG(
+ INFO, "Done %lf s\n",
+ aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+ }
}
void AutonomousActor::SendSuperstructureGoal() {
auto builder = superstructure_goal_sender_.MakeBuilder();
+ flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
+ wrist_offset = CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
+ *builder.fbb(), wrist_goal_,
+ CreateProfileParameters(*builder.fbb(), 12.0, 90.0));
+
control_loops::superstructure::Goal::Builder superstructure_builder =
builder.MakeBuilder<control_loops::superstructure::Goal>();
superstructure_builder.add_arm_goal_position(arm_goal_position_);
superstructure_builder.add_preloaded_with_cone(preloaded_);
superstructure_builder.add_roller_goal(roller_goal_);
- superstructure_builder.add_wrist(wrist_goal_);
+ superstructure_builder.add_wrist(wrist_offset);
if (builder.Send(superstructure_builder.Finish()) !=
aos::RawSender::Error::kOk) {
@@ -314,8 +448,21 @@
void AutonomousActor::MidConeScore() {
set_arm_goal_position(
- control_loops::superstructure::arm::ScoreFrontMidConeUpIndex());
- set_wrist_goal(0.05);
+ control_loops::superstructure::arm::ScoreFrontMidConeUpAutoIndex());
+ set_wrist_goal(0.0);
+ SendSuperstructureGoal();
+}
+
+void AutonomousActor::Neutral() {
+ set_arm_goal_position(control_loops::superstructure::arm::NeutralIndex());
+ set_wrist_goal(0.0);
+ SendSuperstructureGoal();
+}
+
+void AutonomousActor::Balance() {
+ set_arm_goal_position(
+ control_loops::superstructure::arm::GroundPickupFrontConeUpIndex());
+ set_wrist_goal(0.0);
SendSuperstructureGoal();
}
@@ -329,14 +476,14 @@
void AutonomousActor::MidCubeScore() {
set_arm_goal_position(
control_loops::superstructure::arm::ScoreFrontMidCubeIndex());
- set_wrist_goal(0.6);
+ set_wrist_goal(1.0);
SendSuperstructureGoal();
}
void AutonomousActor::PickupCube() {
set_arm_goal_position(
control_loops::superstructure::arm::GroundPickupBackCubeIndex());
- set_wrist_goal(0.6);
+ set_wrist_goal(1.0);
SendSuperstructureGoal();
}
@@ -345,13 +492,18 @@
SendSuperstructureGoal();
}
+void AutonomousActor::StopSpitting() {
+ set_roller_goal(control_loops::superstructure::RollerGoal::IDLE);
+ SendSuperstructureGoal();
+}
+
void AutonomousActor::IntakeCube() {
set_roller_goal(control_loops::superstructure::RollerGoal::INTAKE_CUBE);
SendSuperstructureGoal();
}
-[[nodiscard]] bool AutonomousActor::WaitForArmGoal() {
- constexpr double kEpsTheta = 0.01;
+[[nodiscard]] bool AutonomousActor::WaitForArmGoal(double distance_to_go) {
+ constexpr double kEpsTheta = 0.10;
::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
event_loop()->monotonic_now(),
@@ -367,24 +519,15 @@
superstructure_status_fetcher_.Fetch();
CHECK(superstructure_status_fetcher_.get() != nullptr);
- // Check that the status had the right goal
- at_goal = (std::abs(points_[arm_goal_position_](0) -
- superstructure_status_fetcher_->arm()->theta0()) <
- kEpsTheta &&
- std::abs(points_[arm_goal_position_](1) -
- superstructure_status_fetcher_->arm()->theta1()) <
- kEpsTheta &&
- std::abs(points_[arm_goal_position_](2) -
- superstructure_status_fetcher_->arm()->theta2()) <
- kEpsTheta) &&
+ at_goal = (arm_goal_position_ ==
+ superstructure_status_fetcher_->arm()->current_node() &&
+ superstructure_status_fetcher_->arm()->path_distance_to_go() <
+ distance_to_go) &&
(std::abs(wrist_goal_ -
superstructure_status_fetcher_->wrist()->position()) <
kEpsTheta);
}
- set_preloaded(false);
- SendSuperstructureGoal();
-
return true;
}