Remove Encoder from Climber

Signed-off-by: Niko Sohmers <nikolai@sohmers.com>
Change-Id: Ia219b303a500c46fdd72aad592053fe81e807f2b
diff --git a/y2024/autonomous/autonomous_actor.cc b/y2024/autonomous/autonomous_actor.cc
index f50e8f6..bde0d4b 100644
--- a/y2024/autonomous/autonomous_actor.cc
+++ b/y2024/autonomous/autonomous_actor.cc
@@ -459,8 +459,6 @@
   }
   goal_builder->set_note_goal(note_goal_);
   goal_builder->set_fire(fire_);
-  goal_builder->set_climber_goal(
-      control_loops::superstructure::ClimberGoal::STOWED);
 
   control_loops::superstructure::ShooterGoalStatic *shooter_goal =
       goal_builder->add_shooter_goal();
diff --git a/y2024/constants.h b/y2024/constants.h
index 9923660..4cb5378 100644
--- a/y2024/constants.h
+++ b/y2024/constants.h
@@ -71,32 +71,16 @@
            kIntakePivotEncoderCountsPerRevolution();
   }
 
-  static constexpr double kClimberEncoderCountsPerRevolution() {
-    return 4096.0;
-  }
-
-  static constexpr double kClimberEncoderRatio() { return (16.0 / 60.0); }
-
   static constexpr double kClimberPotMetersPerRevolution() {
     return 16 * 0.25 * 0.0254;
   }
 
-  static constexpr double kClimberEncoderMetersPerRadian() {
-    return kClimberEncoderRatio() * kClimberPotMetersPerRevolution() / 2.0 /
-           M_PI;
-  }
-
   static constexpr double kClimberPotMetersPerVolt() {
     return kClimberPotMetersPerRevolution() * (10.0 /*turns*/ / 5.0 /*volts*/);
   }
 
-  static constexpr double kMaxClimberEncoderPulsesPerSecond() {
-    return control_loops::superstructure::climber::kFreeSpeed / (2.0 * M_PI) *
-           control_loops::superstructure::climber::kOutputRatio /
-           kClimberEncoderRatio() * kClimberEncoderCountsPerRevolution();
-  }
-
   static constexpr double kExtendEncoderCountsPerRevolution() { return 4096.0; }
+
   // TODO: (niko) add the gear ratios for the intake once we have them
   static constexpr double kCatapultEncoderCountsPerRevolution() {
     return 4096.0;
@@ -241,6 +225,13 @@
         ::frc971::zeroing::AbsoluteEncoderZeroingEstimator>
         subsystem_params;
   };
+
+  struct PotConstants {
+    ::frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemParams<
+        ::frc971::zeroing::RelativeEncoderZeroingEstimator>
+        subsystem_params;
+    double potentiometer_offset;
+  };
 };
 
 // Creates and returns a Values instance for the constants.
diff --git a/y2024/constants/7971.json b/y2024/constants/7971.json
index 6e72615..85eb141 100644
--- a/y2024/constants/7971.json
+++ b/y2024/constants/7971.json
@@ -27,15 +27,7 @@
       }
     ) %}
     "intake_constants":  {{ intake_pivot_zero | tojson(indent=2)}},
-    "climber_constants": {
-      {% set _ = climber_zero.update(
-          {
-              "measured_absolute_position" : 0.0
-          }
-      ) %}
-      "zeroing_constants": {{ climber_zero | tojson(indent=2)}},
-      "potentiometer_offset": 0.0
-    },
+    "climber_potentiometer_offset": 0.0,
     "catapult_constants": {
       {% set _ = catapult_zero.update(
           {
diff --git a/y2024/constants/971.json b/y2024/constants/971.json
index a8512c3..a875255 100644
--- a/y2024/constants/971.json
+++ b/y2024/constants/971.json
@@ -27,15 +27,7 @@
       }
     ) %}
     "intake_constants":  {{ intake_pivot_zero | tojson(indent=2)}},
-    "climber_constants": {
-      {% set _ = climber_zero.update(
-          {
-              "measured_absolute_position" :  0.00861798094474761
-          }
-      ) %}
-      "zeroing_constants": {{ climber_zero | tojson(indent=2)}},
-      "potentiometer_offset": {{ -0.935529777248618 + 1.83632555414775 + 0.0431080619919798 - 0.493015437796464 + 0.001602382648064  +0.00194716776942403 - 0.030467594535944}}
-    },
+    "climber_potentiometer_offset": 0.0,
     "catapult_constants": {
       {% set _ = catapult_zero.update(
           {
diff --git a/y2024/constants/9971.json b/y2024/constants/9971.json
index 755b56a..0cde2ad 100644
--- a/y2024/constants/9971.json
+++ b/y2024/constants/9971.json
@@ -27,15 +27,7 @@
       }
     ) %}
     "intake_constants":  {{ intake_pivot_zero | tojson(indent=2)}},
-    "climber_constants": {
-      {% set _ = climber_zero.update(
-          {
-              "measured_absolute_position" : 0.0
-          }
-      ) %}
-      "zeroing_constants": {{ climber_zero | tojson(indent=2)}},
-      "potentiometer_offset": 0.0
-    },
+    "climber_potentiometer_offset": 0.0,
     "catapult_constants": {
       {% set _ = catapult_zero.update(
           {
diff --git a/y2024/constants/common.jinja2 b/y2024/constants/common.jinja2
index 27f28ac..d01b45a 100644
--- a/y2024/constants/common.jinja2
+++ b/y2024/constants/common.jinja2
@@ -32,18 +32,6 @@
 }
 %}
 
-{% set climber_encoder_ratio = (16.0 / 60.0) %}
-{% set climber_circumference = 16.0 * 0.25 * 0.0254 %}
-{%
-set climber_zero = {
-    "average_filter_size": zeroing_sample_size,
-    "one_revolution_distance": climber_encoder_ratio * climber_circumference,
-    "zeroing_threshold": 0.0005,
-    "moving_buffer_size": 20,
-    "allowable_encoder_error": 0.9
-}
-%}
-
 {# Catapult #}
 {% set catapult_encoder_ratio = (12.0 / 24.0) %}
 
diff --git a/y2024/constants/common.json b/y2024/constants/common.json
index 8a59b64..8fec134 100644
--- a/y2024/constants/common.json
+++ b/y2024/constants/common.json
@@ -126,30 +126,6 @@
     "scoring": 6.0,
     "reversing": -4.0
   },
-  "climber_set_points": {
-    "full_extend": -0.005,
-    "stowed": -0.442,
-    "retract": -0.472
-  },
-  "climber": {
-    "zeroing_voltage": 3.0,
-    "operating_voltage": 12.0,
-    "zeroing_profile_params": {
-      "max_velocity": 0.5,
-      "max_acceleration": 3.0
-    },
-    "default_profile_params":{
-      "max_velocity": 0.05,
-      "max_acceleration": 3.0
-    },
-    "range": {
-        "lower_hard": -0.495,
-        "upper_hard": 0.005,
-        "lower": -0.492,
-        "upper": -0.005
-    },
-    "loop": {% include 'y2024/control_loops/superstructure/climber/integral_climber_plant.json' %}
-  },
   "catapult": {
     "zeroing_voltage": 3.0,
     "operating_voltage": 12.0,
diff --git a/y2024/constants/constants.fbs b/y2024/constants/constants.fbs
index 626a13a..f652b22 100644
--- a/y2024/constants/constants.fbs
+++ b/y2024/constants/constants.fbs
@@ -129,7 +129,9 @@
 
 table RobotConstants {
   intake_constants:frc971.zeroing.AbsoluteEncoderZeroingConstants (id: 0);
-  climber_constants:PotAndAbsEncoderConstants (id: 1);
+  // Deprecated since climber no longer has an encoder
+  climber_constants:PotAndAbsEncoderConstants (id: 1, deprecated);
+  climber_potentiometer_offset:double (id: 8);
   catapult_constants:PotAndAbsEncoderConstants (id: 2);
   altitude_constants:PotAndAbsEncoderConstants (id: 3);
   turret_constants:PotAndAbsEncoderConstants (id: 4);
@@ -178,8 +180,8 @@
   drivetrain:frc971.control_loops.drivetrain.fbs.DrivetrainConfig (id: 5);
   current_limits:CurrentLimits (id: 6);
   transfer_roller_voltages:TransferRollerVoltages (id: 7);
-  climber:frc971.control_loops.StaticZeroingSingleDOFProfiledSubsystemCommonParams (id: 8);
-  climber_set_points:ClimberSetPoints (id: 9);
+  climber:frc971.control_loops.StaticZeroingSingleDOFProfiledSubsystemCommonParams (id: 8, deprecated);
+  climber_set_points:ClimberSetPoints (id: 9, deprecated);
   turret_loading_position: double (id: 10);
   catapult_return_position: double (id: 11);
   catapult:frc971.control_loops.StaticZeroingSingleDOFProfiledSubsystemCommonParams (id: 12);
diff --git a/y2024/constants/test_data/test_team.json b/y2024/constants/test_data/test_team.json
index 37d9de1..9d40027 100644
--- a/y2024/constants/test_data/test_team.json
+++ b/y2024/constants/test_data/test_team.json
@@ -27,15 +27,7 @@
       }
     ) %}
     "intake_constants":  {{ intake_pivot_zero | tojson(indent=2)}},
-    "climber_constants": {
-      {% set _ = climber_zero.update(
-          {
-              "measured_absolute_position" : 0.0
-          }
-      ) %}
-      "zeroing_constants": {{ climber_zero | tojson(indent=2)}},
-      "potentiometer_offset": 0.0
-    },
+    "climber_potentiometer_offset": 0.0,
     "catapult_constants": {
       {% set _ = catapult_zero.update(
           {
diff --git a/y2024/control_loops/superstructure/superstructure.cc b/y2024/control_loops/superstructure/superstructure.cc
index daede87..6412c27 100644
--- a/y2024/control_loops/superstructure/superstructure.cc
+++ b/y2024/control_loops/superstructure/superstructure.cc
@@ -43,9 +43,6 @@
           event_loop->MakeFetcher<aos::JoystickState>("/aos")),
       intake_pivot_(robot_constants_->common()->intake_pivot(),
                     robot_constants_->robot()->intake_constants()),
-      climber_(
-          robot_constants_->common()->climber(),
-          robot_constants_->robot()->climber_constants()->zeroing_constants()),
       shooter_(event_loop, robot_constants_),
       extend_(
           robot_constants_->common()->extend(),
@@ -71,7 +68,6 @@
   if (WasReset()) {
     AOS_LOG(ERROR, "WPILib reset, restarting\n");
     intake_pivot_.Reset();
-    climber_.Reset();
     shooter_.Reset();
     extend_.Reset();
   }
@@ -84,45 +80,6 @@
   transfer_debouncer_.Update(position->transfer_beambreak(), timestamp);
   const bool transfer_beambreak = transfer_debouncer_.state();
 
-  // Handle Climber Goal separately from main superstructure state machine
-  double climber_position =
-      robot_constants_->common()->climber_set_points()->retract();
-
-  double climber_velocity = robot_constants_->common()
-                                ->climber()
-                                ->default_profile_params()
-                                ->max_velocity();
-  const double climber_accel = robot_constants_->common()
-                                   ->climber()
-                                   ->default_profile_params()
-                                   ->max_acceleration();
-
-  if (unsafe_goal != nullptr) {
-    switch (unsafe_goal->climber_goal()) {
-      case ClimberGoal::FULL_EXTEND:
-        climber_position =
-            robot_constants_->common()->climber_set_points()->full_extend();
-        // The climber can go reasonably fast when extending out.
-        climber_velocity = 0.5;
-
-        if (unsafe_goal->slow_climber()) {
-          climber_velocity = 0.01;
-        }
-        break;
-      case ClimberGoal::RETRACT:
-        climber_position =
-            robot_constants_->common()->climber_set_points()->retract();
-        // Keep the climber slower while retracting.
-        climber_velocity = 0.1;
-        break;
-      case ClimberGoal::STOWED:
-        climber_position =
-            robot_constants_->common()->climber_set_points()->stowed();
-        // Keep the climber slower while retracting.
-        climber_velocity = 0.1;
-    }
-  }
-
   // If we started off preloaded, skip to the ready state.
   if (unsafe_goal != nullptr && unsafe_goal->shooter_goal() &&
       unsafe_goal->shooter_goal()->preloaded()) {
@@ -554,31 +511,6 @@
                               : 0.0),
   });
 
-  aos::FlatbufferFixedAllocatorArray<
-      frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal, 512>
-      climber_goal_buffer;
-
-  {
-    flatbuffers::FlatBufferBuilder *climber_fbb = climber_goal_buffer.fbb();
-    flatbuffers::Offset<frc971::ProfileParameters> climber_profile =
-        frc971::CreateProfileParameters(*climber_fbb, climber_velocity,
-                                        climber_accel);
-
-    climber_goal_buffer.Finish(
-        frc971::control_loops::
-            CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
-                *climber_fbb, climber_position, climber_profile));
-  }
-
-  const frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal
-      *climber_goal = &climber_goal_buffer.message();
-
-  const flatbuffers::Offset<PotAndAbsoluteEncoderProfiledJointStatus>
-      climber_status_offset = climber_.Iterate(
-          climber_goal, position->climber(),
-          output != nullptr ? &output_struct.climber_voltage : nullptr,
-          status->fbb());
-
   double max_intake_pivot_position = 0;
   double min_intake_pivot_position = 0;
   double max_extend_position = 0;
@@ -663,10 +595,11 @@
     output_struct.extend_voltage = 0.0;
   }
 
-  // Zero out climber voltage if "disable_climber" is true
-  if (robot_constants_->robot()->disable_climber()) {
-    output_struct.climber_voltage = 0.0;
-  }
+  // Ignore climber voltage goal if "disable_climber" is true
+  output_struct.climber_voltage =
+      (!robot_constants_->robot()->disable_climber() && unsafe_goal != nullptr)
+          ? unsafe_goal->climber_goal_voltage()
+          : 0.0;
 
   if (output) {
     output->CheckOk(output->Send(Output::Pack(*output->fbb(), &output_struct)));
@@ -674,17 +607,16 @@
 
   Status::Builder status_builder = status->MakeBuilder<Status>();
 
-  const bool zeroed = intake_pivot_.zeroed() && climber_.zeroed() &&
-                      shooter_.zeroed() && extend_.zeroed();
-  const bool estopped = intake_pivot_.estopped() || climber_.estopped() ||
-                        shooter_.estopped() || extend_.estopped();
+  const bool zeroed =
+      intake_pivot_.zeroed() && shooter_.zeroed() && extend_.zeroed();
+  const bool estopped =
+      intake_pivot_.estopped() || shooter_.estopped() || extend_.estopped();
 
   status_builder.add_zeroed(zeroed);
   status_builder.add_estopped(estopped);
   status_builder.add_intake_roller(intake_roller_state);
   status_builder.add_intake_pivot(intake_pivot_status_offset);
   status_builder.add_transfer_roller(transfer_roller_status);
-  status_builder.add_climber(climber_status_offset);
   status_builder.add_shooter(shooter_status_offset);
   status_builder.add_collided(collided);
   status_builder.add_extend_roller(extend_roller_status);
diff --git a/y2024/control_loops/superstructure/superstructure.h b/y2024/control_loops/superstructure/superstructure.h
index a1bf841..6286615 100644
--- a/y2024/control_loops/superstructure/superstructure.h
+++ b/y2024/control_loops/superstructure/superstructure.h
@@ -40,10 +40,6 @@
     return intake_pivot_;
   }
 
-  inline const PotAndAbsoluteEncoderSubsystem &climber() const {
-    return climber_;
-  }
-
   inline const Shooter &shooter() const { return shooter_; }
   inline const PotAndAbsoluteEncoderSubsystem &extend() const {
     return extend_;
@@ -86,7 +82,6 @@
       aos::monotonic_clock::time_point::min();
 
   AbsoluteEncoderSubsystem intake_pivot_;
-  PotAndAbsoluteEncoderSubsystem climber_;
 
   Shooter shooter_;
 
diff --git a/y2024/control_loops/superstructure/superstructure_goal.fbs b/y2024/control_loops/superstructure/superstructure_goal.fbs
index abfd405..c217bcc 100644
--- a/y2024/control_loops/superstructure/superstructure_goal.fbs
+++ b/y2024/control_loops/superstructure/superstructure_goal.fbs
@@ -60,13 +60,23 @@
 table Goal {
     intake_goal:IntakeGoal = NONE (id: 0);
     intake_pivot:IntakePivotGoal = UP (id: 5);
+
+    // Deprecated since climber no longer has an encoder
     climber_goal:ClimberGoal (id: 1);
+
+    // Voltage we want to give to climber
+    // Positive voltage is for climber up
+    // Negative voltage is for climber down
+    climber_goal_voltage:double = 0.0 (id: 8);
+
     shooter_goal:ShooterGoal (id: 2);
     note_goal:NoteGoal (id: 3);
     fire: bool (id: 4);
 
     // Tells the climber to go absurdly slow on FULL_EXTEND
-    slow_climber: bool = false (id: 6);
+    // Deprecated now because we take care of this through 
+    // climber_goal_voltage
+    slow_climber: bool = false (id: 6, deprecated);
 
     // Spit on the extend motors
     spit_extend: bool = false (id: 7);
diff --git a/y2024/control_loops/superstructure/superstructure_lib_test.cc b/y2024/control_loops/superstructure/superstructure_lib_test.cc
index a4e47d7..5544fc0 100644
--- a/y2024/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2024/control_loops/superstructure/superstructure_lib_test.cc
@@ -15,7 +15,6 @@
 #include "y2024/control_loops/drivetrain/drivetrain_dog_motor_plant.h"
 #include "y2024/control_loops/superstructure/altitude/altitude_plant.h"
 #include "y2024/control_loops/superstructure/catapult/catapult_plant.h"
-#include "y2024/control_loops/superstructure/climber/climber_plant.h"
 #include "y2024/control_loops/superstructure/extend/extend_plant.h"
 #include "y2024/control_loops/superstructure/intake_pivot/intake_pivot_plant.h"
 #include "y2024/control_loops/superstructure/superstructure.h"
@@ -81,26 +80,6 @@
                 ->intake_constants()
                 ->measured_absolute_position(),
             dt_),
-        climber_(new CappedTestPlant(climber::MakeClimberPlant()),
-                 PositionSensorSimulator(simulated_robot_constants->robot()
-                                             ->climber_constants()
-                                             ->zeroing_constants()
-                                             ->one_revolution_distance()),
-                 {.subsystem_params =
-                      {simulated_robot_constants->common()->climber(),
-                       simulated_robot_constants->robot()
-                           ->climber_constants()
-                           ->zeroing_constants()},
-                  .potentiometer_offset = simulated_robot_constants->robot()
-                                              ->climber_constants()
-                                              ->potentiometer_offset()},
-                 frc971::constants::Range::FromFlatbuffer(
-                     simulated_robot_constants->common()->climber()->range()),
-                 simulated_robot_constants->robot()
-                     ->climber_constants()
-                     ->zeroing_constants()
-                     ->measured_absolute_position(),
-                 dt_),
         catapult_(new CappedTestPlant(catapult::MakeCatapultPlant()),
                   PositionSensorSimulator(simulated_robot_constants->robot()
                                               ->catapult_constants()
@@ -185,10 +164,6 @@
         frc971::constants::Range::FromFlatbuffer(
             simulated_robot_constants->common()->intake_pivot()->range())
             .middle());
-    climber_.InitializePosition(
-        frc971::constants::Range::FromFlatbuffer(
-            simulated_robot_constants->common()->climber()->range())
-            .middle());
     catapult_.InitializePosition(
         frc971::constants::Range::FromFlatbuffer(
             simulated_robot_constants->common()->catapult()->range())
@@ -213,8 +188,6 @@
                 superstructure_output_fetcher_->intake_pivot_voltage(),
                 superstructure_status_fetcher_->intake_pivot());
 
-            climber_.Simulate(superstructure_output_fetcher_->climber_voltage(),
-                              superstructure_status_fetcher_->climber());
             catapult_.Simulate(
                 superstructure_output_fetcher_->catapult_voltage(),
                 superstructure_status_fetcher_->shooter()->catapult());
@@ -246,14 +219,8 @@
     flatbuffers::Offset<frc971::AbsolutePosition> intake_pivot_offset =
         intake_pivot_.encoder()->GetSensorValues(&intake_pivot_builder);
 
-    frc971::PotAndAbsolutePosition::Builder climber_builder =
-        builder.MakeBuilder<frc971::PotAndAbsolutePosition>();
-
-    flatbuffers::Offset<frc971::PotAndAbsolutePosition> climber_offset =
-        climber_.encoder()->GetSensorValues(&climber_builder);
     frc971::PotAndAbsolutePosition::Builder catapult_builder =
         builder.MakeBuilder<frc971::PotAndAbsolutePosition>();
-
     flatbuffers::Offset<frc971::PotAndAbsolutePosition> catapult_offset =
         catapult_.encoder()->GetSensorValues(&catapult_builder);
 
@@ -281,7 +248,6 @@
     position_builder.add_catapult(catapult_offset);
     position_builder.add_altitude(altitude_offset);
     position_builder.add_turret(turret_offset);
-    position_builder.add_climber(climber_offset);
     position_builder.add_extend(extend_offset);
 
     CHECK_EQ(builder.Send(position_builder.Finish()),
@@ -302,7 +268,6 @@
   PotAndAbsoluteEncoderSimulator *catapult() { return &catapult_; }
   PotAndAbsoluteEncoderSimulator *altitude() { return &altitude_; }
   PotAndAbsoluteEncoderSimulator *turret() { return &turret_; }
-  PotAndAbsoluteEncoderSimulator *climber() { return &climber_; }
 
   PotAndAbsoluteEncoderSimulator *extend() { return &extend_; }
 
@@ -321,7 +286,6 @@
   bool transfer_beambreak_;
 
   AbsoluteEncoderSimulator intake_pivot_;
-  PotAndAbsoluteEncoderSimulator climber_;
   PotAndAbsoluteEncoderSimulator catapult_;
   PotAndAbsoluteEncoderSimulator altitude_;
   PotAndAbsoluteEncoderSimulator turret_;
@@ -459,26 +423,6 @@
       EXPECT_EQ(superstructure_output_fetcher_->intake_roller_voltage(), 0.0);
     }
 
-    if (superstructure_goal_fetcher_->has_climber_goal()) {
-      double set_point =
-          simulated_robot_constants_->common()->climber_set_points()->retract();
-
-      if (superstructure_goal_fetcher_->climber_goal() ==
-          ClimberGoal::FULL_EXTEND) {
-        set_point = simulated_robot_constants_->common()
-                        ->climber_set_points()
-                        ->full_extend();
-      }
-
-      if (superstructure_goal_fetcher_->climber_goal() == ClimberGoal::STOWED) {
-        set_point = simulated_robot_constants_->common()
-                        ->climber_set_points()
-                        ->stowed();
-      }
-      EXPECT_NEAR(set_point,
-                  superstructure_status_fetcher_->climber()->position(), 0.001);
-    }
-
     if (superstructure_status_fetcher_->has_uncompleted_note_goal()) {
       double set_point = simulated_robot_constants_->common()
                              ->extend_set_points()
@@ -623,7 +567,6 @@
         shooter_goal_builder.Finish();
 
     Goal::Builder goal_builder = builder.MakeBuilder<Goal>();
-    goal_builder.add_climber_goal(ClimberGoal::RETRACT);
     goal_builder.add_shooter_goal(shooter_goal_offset);
     goal_builder.add_intake_goal(IntakeGoal::NONE);
     goal_builder.add_intake_pivot(IntakePivotGoal::UP);
@@ -675,7 +618,6 @@
 
     Goal::Builder goal_builder = builder.MakeBuilder<Goal>();
     goal_builder.add_intake_pivot(IntakePivotGoal::DOWN);
-    goal_builder.add_climber_goal(ClimberGoal::FULL_EXTEND);
     goal_builder.add_shooter_goal(shooter_goal_offset);
     goal_builder.add_note_goal(NoteGoal::NONE);
 
@@ -726,7 +668,6 @@
 
     Goal::Builder goal_builder = builder.MakeBuilder<Goal>();
     goal_builder.add_intake_goal(IntakeGoal::INTAKE);
-    goal_builder.add_climber_goal(ClimberGoal::FULL_EXTEND);
     goal_builder.add_shooter_goal(shooter_goal_offset);
     goal_builder.add_note_goal(NoteGoal::AMP);
 
@@ -772,7 +713,6 @@
 
     Goal::Builder goal_builder = builder.MakeBuilder<Goal>();
     goal_builder.add_intake_goal(IntakeGoal::NONE);
-    goal_builder.add_climber_goal(ClimberGoal::RETRACT);
     goal_builder.add_shooter_goal(shooter_goal_offset);
     goal_builder.add_note_goal(NoteGoal::NONE);
 
@@ -798,9 +738,6 @@
             superstructure_.intake_pivot().state());
 
   EXPECT_EQ(PotAndAbsoluteEncoderSubsystem::State::RUNNING,
-            superstructure_.climber().state());
-
-  EXPECT_EQ(PotAndAbsoluteEncoderSubsystem::State::RUNNING,
             superstructure_.shooter().turret().state());
 
   EXPECT_EQ(PotAndAbsoluteEncoderSubsystem::State::RUNNING,
@@ -1661,8 +1598,6 @@
 
     Goal::Builder goal_builder = builder.MakeBuilder<Goal>();
 
-    goal_builder.add_climber_goal(ClimberGoal::STOWED);
-
     ASSERT_EQ(builder.Send(goal_builder.Finish()), aos::RawSender::Error::kOk);
   }
 
@@ -1675,8 +1610,6 @@
 
     Goal::Builder goal_builder = builder.MakeBuilder<Goal>();
 
-    goal_builder.add_climber_goal(ClimberGoal::FULL_EXTEND);
-
     ASSERT_EQ(builder.Send(goal_builder.Finish()), aos::RawSender::Error::kOk);
   }
 
@@ -1689,8 +1622,6 @@
 
     Goal::Builder goal_builder = builder.MakeBuilder<Goal>();
 
-    goal_builder.add_climber_goal(ClimberGoal::RETRACT);
-
     ASSERT_EQ(builder.Send(goal_builder.Finish()), aos::RawSender::Error::kOk);
   }
 
diff --git a/y2024/control_loops/superstructure/superstructure_position.fbs b/y2024/control_loops/superstructure/superstructure_position.fbs
index b1facba..6905fcf 100644
--- a/y2024/control_loops/superstructure/superstructure_position.fbs
+++ b/y2024/control_loops/superstructure/superstructure_position.fbs
@@ -28,11 +28,14 @@
     // True means there is a game piece in the transfer.
     transfer_beambreak:bool (id: 4);
 
-    // Values of the encoder and potentiometer at the climber.
+    // Deprecated since climber no longer has an encoder
+    deprecated_climber:frc971.PotAndAbsolutePosition (id: 5, deprecated);
+
+    // Value of the potentiometer at the climber.
     // Zero is fully extended, with top of the highest slider aligned with the
     // caps on the tubes for the climber.
     // Positive is more extended.
-    climber:frc971.PotAndAbsolutePosition (id: 5);
+    climber:frc971.RelativePosition (id: 9);
 
     // True if there is a game piece in the catapult
     catapult_beambreak:bool (id: 6);
diff --git a/y2024/control_loops/superstructure/superstructure_status.fbs b/y2024/control_loops/superstructure/superstructure_status.fbs
index 0b30edd..7a508dd 100644
--- a/y2024/control_loops/superstructure/superstructure_status.fbs
+++ b/y2024/control_loops/superstructure/superstructure_status.fbs
@@ -140,7 +140,9 @@
   transfer_roller:TransferRollerStatus (id: 5);
 
   // Estimated angle and angular velocitiy of the climber.
-  climber:frc971.control_loops.PotAndAbsoluteEncoderProfiledJointStatus (id: 6);
+  // Deprecated now because climber no longer has an encoder 
+  // and climber status is not used
+  climber:frc971.control_loops.PotAndAbsoluteEncoderProfiledJointStatus (id: 6, deprecated);
 
   // Status of the subsytems involved in the shooter
   shooter:ShooterStatus (id: 7);
diff --git a/y2024/joystick_reader.cc b/y2024/joystick_reader.cc
index 293e57e..5b2fc74 100644
--- a/y2024/joystick_reader.cc
+++ b/y2024/joystick_reader.cc
@@ -58,8 +58,7 @@
 const ButtonLocation kAimPodium(0, 0);
 const ButtonLocation kShoot(0, 0);
 const ButtonLocation kRaiseClimber(3, 2);
-const ButtonLocation kSlowClimber(3, 1);
-const ButtonLocation kRetractClimber(2, 3);
+const ButtonLocation kRaiseFastClimber(3, 1);
 const ButtonLocation kExtraButtonOne(0, 0);
 const ButtonLocation kExtraButtonTwo(0, 0);
 const ButtonLocation kExtraButtonThree(0, 0);
@@ -163,21 +162,10 @@
     superstructure_goal_builder->set_fire(data.IsPressed(kFire) ||
                                           data.IsPressed(kDriverFire));
 
-    if (data.IsPressed(kRetractClimber)) {
-      superstructure_goal_builder->set_climber_goal(
-          superstructure::ClimberGoal::RETRACT);
-    } else if (data.IsPressed(kRaiseClimber)) {
-      superstructure_goal_builder->set_climber_goal(
-          superstructure::ClimberGoal::FULL_EXTEND);
-    } else {
-      superstructure_goal_builder->set_climber_goal(
-          superstructure::ClimberGoal::STOWED);
-    }
-
-    if (data.IsPressed(kSlowClimber)) {
-      superstructure_goal_builder->set_slow_climber(true);
-    } else {
-      superstructure_goal_builder->set_slow_climber(false);
+    if (data.IsPressed(kRaiseClimber)) {
+      superstructure_goal_builder->set_climber_goal_voltage(4.0);
+    } else if (data.IsPressed(kRaiseFastClimber)) {
+      superstructure_goal_builder->set_climber_goal_voltage(6.0);
     }
 
     superstructure_goal_builder.CheckOk(superstructure_goal_builder.Send());
diff --git a/y2024/wpilib_interface.cc b/y2024/wpilib_interface.cc
index eb419e6..0abedec 100644
--- a/y2024/wpilib_interface.cc
+++ b/y2024/wpilib_interface.cc
@@ -79,7 +79,7 @@
 constexpr double kMaxBringupPower = 12.0;
 
 double climber_pot_translate(double voltage) {
-  return -1 * voltage * Values::kClimberPotMetersPerVolt();
+  return voltage * Values::kClimberPotMetersPerVolt();
 }
 
 double extend_pot_translate(double voltage) {
@@ -108,7 +108,6 @@
 constexpr double kMaxFastEncoderPulsesPerSecond = std::max({
     Values::kMaxDrivetrainEncoderPulsesPerSecond(),
     Values::kMaxIntakePivotEncoderPulsesPerSecond(),
-    Values::kMaxClimberEncoderPulsesPerSecond(),
     Values::kMaxExtendEncoderPulsesPerSecond(),
     Values::kMaxCatapultEncoderPulsesPerSecond(),
 });
@@ -167,13 +166,9 @@
                    Values::kIntakePivotEncoderCountsPerRevolution(),
                    Values::kIntakePivotEncoderRatio(), /* reversed: */ false);
 
-      CopyPosition(climber_encoder_, builder->add_climber(),
-                   Values::kClimberEncoderCountsPerRevolution(),
-                   Values::kClimberEncoderMetersPerRadian(),
+      CopyPosition(*climber_potentiometer_, builder->add_climber(),
                    climber_pot_translate, false,
-                   robot_constants_->robot()
-                       ->climber_constants()
-                       ->potentiometer_offset());
+                   robot_constants_->robot()->climber_potentiometer_offset());
 
       CopyPosition(extend_encoder_, builder->add_extend(),
                    Values::kExtendEncoderCountsPerRevolution(),
@@ -266,6 +261,11 @@
     }
   }
 
+  void set_climber_potentiometer(
+      ::std::unique_ptr<frc::AnalogInput> potentiometer) {
+    climber_potentiometer_ = ::std::move(potentiometer);
+  }
+
   void set_intake_pivot(::std::unique_ptr<frc::Encoder> encoder,
                         ::std::unique_ptr<frc::DigitalInput> absolute_pwm) {
     fast_encoder_filter_.Add(encoder.get());
@@ -285,15 +285,6 @@
     catapult_beam_break_ = ::std::move(sensor);
   }
 
-  void set_climber(::std::unique_ptr<frc::Encoder> encoder,
-                   ::std::unique_ptr<frc::DigitalInput> absolute_pwm,
-                   ::std::unique_ptr<frc::AnalogInput> potentiometer) {
-    fast_encoder_filter_.Add(encoder.get());
-    climber_encoder_.set_encoder(::std::move(encoder));
-    climber_encoder_.set_absolute_pwm(::std::move(absolute_pwm));
-    climber_encoder_.set_potentiometer(::std::move(potentiometer));
-  }
-
   void set_extend(::std::unique_ptr<frc::Encoder> encoder,
                   ::std::unique_ptr<frc::DigitalInput> absolute_pwm,
                   ::std::unique_ptr<frc::AnalogInput> potentiometer) {
@@ -344,9 +335,11 @@
   std::unique_ptr<frc::DigitalInput> imu_yaw_rate_input_, transfer_beam_break_,
       extend_beam_break_, catapult_beam_break_;
 
+  std::unique_ptr<frc::AnalogInput> climber_potentiometer_;
+
   frc971::wpilib::AbsoluteEncoder intake_pivot_encoder_;
-  frc971::wpilib::AbsoluteEncoderAndPotentiometer climber_encoder_,
-      catapult_encoder_, extend_encoder_;
+  frc971::wpilib::AbsoluteEncoderAndPotentiometer catapult_encoder_,
+      extend_encoder_;
 
   frc971::wpilib::DMAPulseWidthReader imu_yaw_rate_reader_;
 
@@ -437,10 +430,7 @@
       sensor_reader.set_transfer_beambreak(make_unique<frc::DigitalInput>(23));
       sensor_reader.set_extend_beambreak(make_unique<frc::DigitalInput>(24));
       sensor_reader.set_catapult_beambreak(make_unique<frc::DigitalInput>(22));
-
-      sensor_reader.set_climber(make_encoder(4),
-                                make_unique<frc::DigitalInput>(4),
-                                make_unique<frc::AnalogInput>(4));
+      sensor_reader.set_climber_potentiometer(make_unique<frc::AnalogInput>(4));
       sensor_reader.set_extend(make_encoder(5),
                                make_unique<frc::DigitalInput>(5),
                                make_unique<frc::AnalogInput>(5));
diff --git a/y2024/www/field.html b/y2024/www/field.html
index ebb03e5..a7809ae 100644
--- a/y2024/www/field.html
+++ b/y2024/www/field.html
@@ -163,20 +163,6 @@
           <td id="intake_pivot_abs"> NA </td>
         </tr>
         <tr>
-          <th colspan="2">Climber</th>
-        </tr>
-        <tr>
-          <td>Position</td>
-          <td id="climber"> NA </td>
-        </tr>
-        <tr>
-          <td>Absolute Position</td>
-          <td id="climber_abs"> NA </td>
-        </tr>
-        <tr>
-          <td>Pot Position</td>
-          <td id="climber_pot"> NA </td>
-        </tr>
         <tr>
           <th colspan="2">Extend</th>
         </tr>
diff --git a/y2024/www/field_handler.ts b/y2024/www/field_handler.ts
index 7b5e0f4..298615f 100644
--- a/y2024/www/field_handler.ts
+++ b/y2024/www/field_handler.ts
@@ -105,13 +105,6 @@
   private intakePivotAbs: HTMLElement =
     (document.getElementById('intake_pivot_abs') as HTMLElement);
 
-  private climber: HTMLElement =
-    (document.getElementById('climber') as HTMLElement);
-  private climberAbs: HTMLElement =
-    (document.getElementById('climber_abs') as HTMLElement);
-  private climberPot: HTMLElement =
-    (document.getElementById('climber_pot') as HTMLElement);
-
   private extend: HTMLElement =
     (document.getElementById('extend') as HTMLElement);
   private extendAbs: HTMLElement =
@@ -568,22 +561,6 @@
 
       this.intakePivotAbs.innerHTML = this.superstructureStatus.intakePivot().estimatorState().absolutePosition().toString();
 
-      if (!this.superstructureStatus.climber() ||
-          !this.superstructureStatus.climber().zeroed()) {
-        this.setZeroing(this.climber);
-      } else if (this.superstructureStatus.climber().estopped()) {
-        this.setEstopped(this.climber);
-      } else {
-        this.setTargetValue(
-            this.climber,
-            this.superstructureStatus.climber().unprofiledGoalPosition(),
-            this.superstructureStatus.climber().estimatorState().position(),
-            1e-3);
-      }
-
-      this.climberAbs.innerHTML = this.superstructureStatus.climber().estimatorState().absolutePosition().toString();
-      this.climberPot.innerHTML = this.superstructureStatus.climber().estimatorState().potPosition().toString();
-
       if (!this.superstructureStatus.extend() ||
           !this.superstructureStatus.extend().zeroed()) {
         this.setZeroing(this.extend);
@@ -660,14 +637,6 @@
             '<br/>';
       }
       zeroingErrors += '<br/>' +
-          'Climber Errors:' +
-          '<br/>';
-      for (let i = 0; i < this.superstructureStatus.climber().estimatorState().errorsLength();
-           i++) {
-        zeroingErrors += ZeroingError[this.superstructureStatus.climber().estimatorState().errors(i)] +
-            '<br/>';
-      }
-      zeroingErrors += '<br/>' +
           'Extend Errors:' +
           '<br/>';
       for (let i = 0; i < this.superstructureStatus.extend().estimatorState().errorsLength();