Add 2022 joystick reader
Change-Id: I20a502c46a19c9b2e4170db3847eed740901e490
Signed-off-by: Henry Speiser <henry@speiser.net>
Signed-off-by: Milind Upadhyay <milind.upadhyay@gmail.com>
Signed-off-by: Ravago Jones <ravagojones@gmail.com>
diff --git a/y2022/joystick_reader.cc b/y2022/joystick_reader.cc
index 530de90..7170a1d 100644
--- a/y2022/joystick_reader.cc
+++ b/y2022/joystick_reader.cc
@@ -10,15 +10,21 @@
#include "aos/network/team_number.h"
#include "aos/util/log_interval.h"
#include "frc971/autonomous/base_autonomous_actor.h"
+#include "frc971/control_loops/drivetrain/localizer_generated.h"
#include "frc971/control_loops/profiled_subsystem_generated.h"
#include "frc971/input/action_joystick_input.h"
#include "frc971/input/driver_station_data.h"
#include "frc971/input/drivetrain_input.h"
#include "frc971/input/joystick_input.h"
+#include "frc971/zeroing/wrap.h"
+#include "y2022/constants.h"
#include "y2022/control_loops/drivetrain/drivetrain_base.h"
#include "y2022/control_loops/superstructure/superstructure_goal_generated.h"
#include "y2022/control_loops/superstructure/superstructure_status_generated.h"
+#include "y2022/setpoint_generated.h"
+using frc971::CreateProfileParameters;
+using frc971::control_loops::CreateStaticZeroingSingleDOFProfiledSubsystemGoal;
using frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal;
using frc971::input::driver_station::ButtonLocation;
using frc971::input::driver_station::ControlBit;
@@ -29,11 +35,24 @@
namespace input {
namespace joysticks {
-const ButtonLocation kCatapultPos(3, 3);
-const ButtonLocation kFire(3, 1);
-
namespace superstructure = y2022::control_loops::superstructure;
+// TODO(henry) put actually button locations here
+// TODO(milind): integrate with shooting statemachine and aimer
+const ButtonLocation kCatapultPos(3, 3);
+const ButtonLocation kFire(3, 2);
+const ButtonLocation kFixedTurret(3, 1);
+
+const ButtonLocation kIntakeFrontOut(4, 4);
+const ButtonLocation kIntakeBackOut(4, 3);
+
+const ButtonLocation kRedLocalizerReset(3, 13);
+const ButtonLocation kBlueLocalizerReset(3, 14);
+const ButtonLocation kLocalizerReset(3, 8);
+
+const ButtonLocation kClimberUpMidRung(10, 10);
+const ButtonLocation kClimberDown(11, 11);
+
class Reader : public ::frc971::input::ActionJoystickInput {
public:
Reader(::aos::EventLoop *event_loop)
@@ -43,9 +62,74 @@
::frc971::input::DrivetrainInputReader::InputType::kPistol, {}),
superstructure_goal_sender_(
event_loop->MakeSender<superstructure::Goal>("/superstructure")),
+ localizer_control_sender_(
+ event_loop->MakeSender<
+ ::frc971::control_loops::drivetrain::LocalizerControl>(
+ "/drivetrain")),
superstructure_status_fetcher_(
- event_loop->MakeFetcher<superstructure::Status>(
- "/superstructure")) {}
+ event_loop->MakeFetcher<superstructure::Status>("/superstructure")),
+ setpoint_fetcher_(
+ event_loop->MakeFetcher<Setpoint>("/superstructure")) {}
+
+ void BlueResetLocalizer() {
+ auto builder = localizer_control_sender_.MakeBuilder();
+
+ frc971::control_loops::drivetrain::LocalizerControl::Builder
+ localizer_control_builder = builder.MakeBuilder<
+ frc971::control_loops::drivetrain::LocalizerControl>();
+ localizer_control_builder.add_x(7.4);
+ localizer_control_builder.add_y(-1.7);
+ localizer_control_builder.add_theta_uncertainty(10.0);
+ localizer_control_builder.add_theta(0.0);
+ localizer_control_builder.add_keep_current_theta(false);
+ if (builder.Send(localizer_control_builder.Finish()) !=
+ aos::RawSender::Error::kOk) {
+ AOS_LOG(ERROR, "Failed to reset blue localizer.\n");
+ }
+ }
+
+ void RedResetLocalizer() {
+ auto builder = localizer_control_sender_.MakeBuilder();
+
+ frc971::control_loops::drivetrain::LocalizerControl::Builder
+ localizer_control_builder = builder.MakeBuilder<
+ frc971::control_loops::drivetrain::LocalizerControl>();
+ localizer_control_builder.add_x(-7.4);
+ localizer_control_builder.add_y(1.7);
+ localizer_control_builder.add_theta_uncertainty(10.0);
+ localizer_control_builder.add_theta(M_PI);
+ localizer_control_builder.add_keep_current_theta(false);
+ if (builder.Send(localizer_control_builder.Finish()) !=
+ aos::RawSender::Error::kOk) {
+ AOS_LOG(ERROR, "Failed to reset red localizer.\n");
+ }
+ }
+
+ void ResetLocalizer() {
+ const frc971::control_loops::drivetrain::Status *drivetrain_status =
+ this->drivetrain_status();
+ if (drivetrain_status == nullptr) {
+ return;
+ }
+ // Get the current position
+ // Snap to heading.
+ auto builder = localizer_control_sender_.MakeBuilder();
+
+ // TODO<Henry> Put our starting location here.
+ frc971::control_loops::drivetrain::LocalizerControl::Builder
+ localizer_control_builder = builder.MakeBuilder<
+ frc971::control_loops::drivetrain::LocalizerControl>();
+ localizer_control_builder.add_x(drivetrain_status->x());
+ localizer_control_builder.add_y(drivetrain_status->y());
+ const double new_theta =
+ frc971::zeroing::Wrap(drivetrain_status->theta(), 0, M_PI);
+ localizer_control_builder.add_theta(new_theta);
+ localizer_control_builder.add_theta_uncertainty(10.0);
+ if (builder.Send(localizer_control_builder.Finish()) !=
+ aos::RawSender::Error::kOk) {
+ AOS_LOG(ERROR, "Failed to reset localizer.\n");
+ }
+ }
void AutoEnded() override { AOS_LOG(INFO, "Auto ended.\n"); }
@@ -57,43 +141,169 @@
return;
}
- aos::Sender<superstructure::Goal>::Builder builder =
- superstructure_goal_sender_.MakeBuilder();
+ setpoint_fetcher_.Fetch();
- flatbuffers::Offset<frc971::ProfileParameters> catapult_profile =
- frc971::CreateProfileParameters(*builder.fbb(), 5.0, 30.0);
+ // Default to the intakes in
+ double intake_front_pos = constants::Values::kIntakeRange().lower;
+ double intake_back_pos = constants::Values::kIntakeRange().lower;
- StaticZeroingSingleDOFProfiledSubsystemGoal::Builder
- catapult_return_builder =
- builder.MakeBuilder<StaticZeroingSingleDOFProfiledSubsystemGoal>();
- catapult_return_builder.add_unsafe_goal(
- data.IsPressed(kCatapultPos) ? 0.3 : -0.85);
- catapult_return_builder.add_profile_params(catapult_profile);
- flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
- catapult_return_offset = catapult_return_builder.Finish();
+ double roller_front_speed = 0.0;
+ double roller_back_speed = 0.0;
+ bool roller_speed_compensation = false;
- superstructure::CatapultGoal::Builder catapult_builder =
- builder.MakeBuilder<superstructure::CatapultGoal>();
- catapult_builder.add_return_position(catapult_return_offset);
- catapult_builder.add_shot_position(0.3);
- catapult_builder.add_shot_velocity(15.0);
- flatbuffers::Offset<superstructure::CatapultGoal> catapult_offset =
- catapult_builder.Finish();
+ double turret_pos = 0.0;
- superstructure::Goal::Builder goal_builder =
- builder.MakeBuilder<superstructure::Goal>();
- goal_builder.add_catapult(catapult_offset);
- goal_builder.add_fire(data.IsPressed(kFire));
+ double catapult_pos = 0.0;
+ double catapult_return_pos = 0.0;
+ double catapult_speed = 0.0;
+ bool fire = false;
- if (builder.Send(goal_builder.Finish()) != aos::RawSender::Error::kOk) {
- AOS_LOG(ERROR, "Sending superstructure goal failed.\n");
+ if (data.IsPressed(kFire)) {
+ fire = true;
+ }
+
+ // Use setpoints for shooting if present
+ if (setpoint_fetcher_.get()) {
+ turret_pos = setpoint_fetcher_->turret();
+
+ catapult_pos = setpoint_fetcher_->catapult_position();
+ catapult_speed = setpoint_fetcher_->catapult_velocity();
+ } else {
+ turret_pos = 0.0;
+
+ catapult_pos = constants::Values::kDefaultCatapultShotPosition();
+ catapult_speed = constants::Values::kDefaultCatapultShotVelocity();
+ }
+
+ // Keep the catapult return position at the shot one if kCatapultPos is
+ // pressed
+ if (data.IsPressed(kCatapultPos)) {
+ catapult_return_pos = catapult_pos;
+ } else {
+ catapult_return_pos = constants::Values::kCatapultReturnPosition();
+ }
+
+ // If either intake is out by enough, always spin the rollers
+ if (superstructure_status_fetcher_.get() &&
+ superstructure_status_fetcher_->intake_front()->zeroed() &&
+ superstructure_status_fetcher_->intake_front()->position() >
+ constants::Values::kIntakeSlightlyOutPosition()) {
+ roller_front_speed =
+ std::max(roller_front_speed,
+ constants::Values::kMinIntakeSlightlyOutRollerSpeed());
+ roller_speed_compensation = true;
+ }
+ if (superstructure_status_fetcher_.get() &&
+ superstructure_status_fetcher_->intake_back()->zeroed() &&
+ superstructure_status_fetcher_->intake_back()->position() >
+ constants::Values::kIntakeSlightlyOutPosition()) {
+ roller_back_speed =
+ std::max(roller_back_speed,
+ constants::Values::kMinIntakeSlightlyOutRollerSpeed());
+ roller_speed_compensation = true;
+ }
+
+ // Extend the intakes and spin the rollers
+ if (data.IsPressed(kIntakeFrontOut)) {
+ intake_front_pos = constants::Values::kIntakeOutPosition();
+ roller_front_speed = constants::Values::kIntakeOutRollerSpeed();
+ roller_speed_compensation = true;
+ }
+ if (data.IsPressed(kIntakeBackOut)) {
+ intake_back_pos = constants::Values::kIntakeOutPosition();
+ roller_back_speed = constants::Values::kIntakeOutRollerSpeed();
+ roller_speed_compensation = true;
+ }
+
+ // Position climber to climb on mid rung
+ if (data.IsPressed(kClimberUpMidRung)) {
+ climber_pos_ = constants::Values::kClimberMidRungHeight();
+ } else if (data.IsPressed(kClimberDown)) {
+ climber_pos_ = 0.0;
+ }
+
+ if (data.PosEdge(kLocalizerReset)) {
+ ResetLocalizer();
+ }
+
+ if (data.PosEdge(kRedLocalizerReset)) {
+ RedResetLocalizer();
+ }
+ if (data.PosEdge(kBlueLocalizerReset)) {
+ BlueResetLocalizer();
+ }
+
+ {
+ auto builder = superstructure_goal_sender_.MakeBuilder();
+
+ flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
+ intake_front_offset =
+ CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
+ *builder.fbb(), intake_front_pos,
+ CreateProfileParameters(*builder.fbb(), 20.0, 70.0));
+ flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
+ intake_back_offset =
+ CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
+ *builder.fbb(), intake_back_pos,
+ CreateProfileParameters(*builder.fbb(), 20.0, 70.0));
+
+ flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
+ turret_offset = CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
+ *builder.fbb(), turret_pos,
+ CreateProfileParameters(*builder.fbb(), 6.0, 20.0));
+
+ flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
+ climber_offset = CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
+ *builder.fbb(), climber_pos_,
+ CreateProfileParameters(*builder.fbb(), 6.0, 20.0));
+
+ flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
+ catapult_return_offset =
+ CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
+ *builder.fbb(), catapult_return_pos,
+ frc971::CreateProfileParameters(*builder.fbb(), 5.0, 30.0));
+
+ superstructure::CatapultGoal::Builder catapult_builder =
+ builder.MakeBuilder<superstructure::CatapultGoal>();
+ catapult_builder.add_return_position(catapult_return_offset);
+ catapult_builder.add_shot_position(catapult_pos);
+ catapult_builder.add_shot_velocity(catapult_speed);
+ flatbuffers::Offset<superstructure::CatapultGoal> catapult_offset =
+ catapult_builder.Finish();
+
+ superstructure::Goal::Builder superstructure_goal_builder =
+ builder.MakeBuilder<superstructure::Goal>();
+
+ superstructure_goal_builder.add_intake_front(intake_front_offset);
+ superstructure_goal_builder.add_intake_back(intake_back_offset);
+ superstructure_goal_builder.add_turret(turret_offset);
+ superstructure_goal_builder.add_climber(climber_offset);
+ superstructure_goal_builder.add_catapult(catapult_offset);
+ superstructure_goal_builder.add_fire(fire);
+
+ superstructure_goal_builder.add_roller_speed_front(roller_front_speed);
+ superstructure_goal_builder.add_roller_speed_back(roller_back_speed);
+ superstructure_goal_builder.add_roller_speed_compensation(
+ roller_speed_compensation ? 1.5 : 0.0f);
+
+ if (builder.Send(superstructure_goal_builder.Finish()) !=
+ aos::RawSender::Error::kOk) {
+ AOS_LOG(ERROR, "Sending superstructure goal failed.\n");
+ }
}
}
private:
+ double climber_pos_ = 0.0;
+
::aos::Sender<superstructure::Goal> superstructure_goal_sender_;
+ ::aos::Sender<frc971::control_loops::drivetrain::LocalizerControl>
+ localizer_control_sender_;
+
::aos::Fetcher<superstructure::Status> superstructure_status_fetcher_;
+
+ ::aos::Fetcher<Setpoint> setpoint_fetcher_;
};
} // namespace joysticks