Add second transfer roller motor

Still use same behavior of always sending opposite voltages

Signed-off-by: Milind Upadhyay <milind.upadhyay@gmail.com>
Change-Id: If6bcf617db37b40924556d59dcfa23e7d43bdef1
diff --git a/y2022/actors/autonomous_actor.cc b/y2022/actors/autonomous_actor.cc
index ed1a9ee..67156dd 100644
--- a/y2022/actors/autonomous_actor.cc
+++ b/y2022/actors/autonomous_actor.cc
@@ -214,7 +214,10 @@
   superstructure_builder.add_roller_speed_compensation(1.5);
   superstructure_builder.add_roller_speed_front(roller_front_voltage_);
   superstructure_builder.add_roller_speed_back(roller_back_voltage_);
-  superstructure_builder.add_transfer_roller_speed(transfer_roller_voltage_);
+  superstructure_builder.add_transfer_roller_speed_front(
+      transfer_roller_front_voltage_);
+  superstructure_builder.add_transfer_roller_speed_back(
+      transfer_roller_back_voltage_);
   superstructure_builder.add_catapult(catapult_goal_offset);
   superstructure_builder.add_fire(fire_);
   superstructure_builder.add_auto_aim(true);
@@ -228,28 +231,32 @@
 void AutonomousActor::ExtendFrontIntake() {
   set_intake_front_goal(kExtendIntakeGoal);
   set_roller_front_voltage(kRollerVoltage);
-  set_transfer_roller_voltage(kRollerVoltage);
+  set_transfer_roller_front_voltage(kRollerVoltage);
+  set_transfer_roller_back_voltage(-kRollerVoltage);
   SendSuperstructureGoal();
 }
 
 void AutonomousActor::RetractFrontIntake() {
   set_intake_front_goal(kRetractIntakeGoal);
   set_roller_front_voltage(kRollerVoltage);
-  set_transfer_roller_voltage(0.0);
+  set_transfer_roller_front_voltage(0.0);
+  set_transfer_roller_back_voltage(0.0);
   SendSuperstructureGoal();
 }
 
 void AutonomousActor::ExtendBackIntake() {
   set_intake_back_goal(kExtendIntakeGoal);
   set_roller_back_voltage(kRollerVoltage);
-  set_transfer_roller_voltage(-kRollerVoltage);
+  set_transfer_roller_back_voltage(kRollerVoltage);
+  set_transfer_roller_front_voltage(-kRollerVoltage);
   SendSuperstructureGoal();
 }
 
 void AutonomousActor::RetractBackIntake() {
   set_intake_back_goal(kRetractIntakeGoal);
   set_roller_back_voltage(kRollerVoltage);
-  set_transfer_roller_voltage(0.0);
+  set_transfer_roller_front_voltage(0.0);
+  set_transfer_roller_back_voltage(0.0);
   SendSuperstructureGoal();
 }
 
diff --git a/y2022/actors/autonomous_actor.h b/y2022/actors/autonomous_actor.h
index f01da02..37a8cdb 100644
--- a/y2022/actors/autonomous_actor.h
+++ b/y2022/actors/autonomous_actor.h
@@ -40,8 +40,11 @@
   void set_roller_back_voltage(double roller_back_voltage) {
     roller_back_voltage_ = roller_back_voltage;
   }
-  void set_transfer_roller_voltage(double voltage) {
-    transfer_roller_voltage_ = voltage;
+  void set_transfer_roller_front_voltage(double voltage) {
+    transfer_roller_front_voltage_ = voltage;
+  }
+  void set_transfer_roller_back_voltage(double voltage) {
+    transfer_roller_back_voltage_ = voltage;
   }
 
   void set_fire_at_will(bool fire) { fire_ = fire; }
@@ -62,7 +65,8 @@
   double intake_back_goal_ = 0.0;
   double roller_front_voltage_ = 0.0;
   double roller_back_voltage_ = 0.0;
-  double transfer_roller_voltage_ = 0.0;
+  double transfer_roller_front_voltage_ = 0.0;
+  double transfer_roller_back_voltage_ = 0.0;
   bool fire_ = false;
 
   aos::Sender<frc971::control_loops::drivetrain::LocalizerControl>
diff --git a/y2022/constants.h b/y2022/constants.h
index 494ca3d..865a0e6 100644
--- a/y2022/constants.h
+++ b/y2022/constants.h
@@ -108,18 +108,11 @@
   static constexpr double kIntakeRollerStatorCurrentLimit() { return 60.0; }
 
   // Transfer rollers
-  // Positive voltage means front transfer rollers pull in and back spits out,
-  // and vice versa
-  static constexpr double kTransferRollerFrontVoltage() { return 12.0; }
-  static constexpr double kTransferRollerBackVoltage() {
-    return -kTransferRollerFrontVoltage();
-  }
+  static constexpr double kTransferRollerVoltage() { return 12.0; }
 
   // Voltage to wiggle the transfer rollers and keep a ball in.
-  static constexpr double kTransferRollerFrontWiggleVoltage() { return 3.0; }
-  static constexpr double kTransferRollerBackWiggleVoltage() {
-    return -kTransferRollerFrontWiggleVoltage();
-  }
+  static constexpr double kTransferRollerWiggleVoltage() { return 3.0; }
+
   // Minimum roller speed when the intake is slightly out
   static constexpr double kMinIntakeSlightlyOutRollerSpeed() { return 6.0; }
   // Roller speeds when intake is out
diff --git a/y2022/control_loops/superstructure/superstructure.cc b/y2022/control_loops/superstructure/superstructure.cc
index b25d074..a5b4df9 100644
--- a/y2022/control_loops/superstructure/superstructure.cc
+++ b/y2022/control_loops/superstructure/superstructure.cc
@@ -66,7 +66,8 @@
       *turret_goal = nullptr;
   double roller_speed_compensated_front = 0.0;
   double roller_speed_compensated_back = 0.0;
-  double transfer_roller_speed = 0.0;
+  double transfer_roller_speed_front = 0.0;
+  double transfer_roller_speed_back = 0.0;
   double flipper_arms_voltage = 0.0;
 
   if (unsafe_goal != nullptr) {
@@ -78,7 +79,8 @@
         unsafe_goal->roller_speed_back() -
         std::min(velocity * unsafe_goal->roller_speed_compensation(), 0.0);
 
-    transfer_roller_speed = unsafe_goal->transfer_roller_speed();
+    transfer_roller_speed_front = unsafe_goal->transfer_roller_speed_front();
+    transfer_roller_speed_back = unsafe_goal->transfer_roller_speed_back();
 
     turret_goal =
         unsafe_goal->auto_aim() ? auto_aim_goal : unsafe_goal->turret();
@@ -112,9 +114,9 @@
   // to IDLE.
 
   const bool is_spitting = ((intake_state_ == IntakeState::INTAKE_FRONT_BALL &&
-                             transfer_roller_speed < 0) ||
+                             transfer_roller_speed_front < 0) ||
                             (intake_state_ == IntakeState::INTAKE_BACK_BALL &&
-                             transfer_roller_speed > 0));
+                             transfer_roller_speed_back < 0));
 
   // Intake handling should happen regardless of the turret state
   if (position->intake_beambreak_front() || position->intake_beambreak_back()) {
@@ -135,23 +137,29 @@
   }
 
   if (intake_state_ != IntakeState::NO_BALL) {
-    // Block intaking in
     roller_speed_compensated_front = 0.0;
     roller_speed_compensated_back = 0.0;
 
     const double wiggle_voltage =
-        (intake_state_ == IntakeState::INTAKE_FRONT_BALL
-             ? constants::Values::kTransferRollerFrontWiggleVoltage()
-             : constants::Values::kTransferRollerBackWiggleVoltage());
+        constants::Values::kTransferRollerWiggleVoltage();
     // Wiggle transfer rollers: send the ball back and forth while waiting
     // for the turret or waiting for another shot to be completed
-    if ((intake_state_ == IntakeState::INTAKE_FRONT_BALL &&
-         position->intake_beambreak_front()) ||
-        (intake_state_ == IntakeState::INTAKE_BACK_BALL &&
-         position->intake_beambreak_back())) {
-      transfer_roller_speed = -wiggle_voltage;
+    if (intake_state_ == IntakeState::INTAKE_FRONT_BALL) {
+      if (position->intake_beambreak_front()) {
+        transfer_roller_speed_front = -wiggle_voltage;
+        transfer_roller_speed_back = wiggle_voltage;
+      } else {
+        transfer_roller_speed_front = wiggle_voltage;
+        transfer_roller_speed_back = -wiggle_voltage;
+      }
     } else {
-      transfer_roller_speed = wiggle_voltage;
+      if (position->intake_beambreak_back()) {
+        transfer_roller_speed_back = -wiggle_voltage;
+        transfer_roller_speed_front = wiggle_voltage;
+      } else {
+        transfer_roller_speed_back = wiggle_voltage;
+        transfer_roller_speed_front = -wiggle_voltage;
+      }
     }
   }
 
@@ -198,10 +206,17 @@
       }
 
       // Transfer rollers and flipper arm belt on
-      transfer_roller_speed =
-          (intake_state_ == IntakeState::INTAKE_FRONT_BALL
-               ? constants::Values::kTransferRollerFrontVoltage()
-               : constants::Values::kTransferRollerBackVoltage());
+      if (intake_state_ == IntakeState::INTAKE_FRONT_BALL) {
+        transfer_roller_speed_front =
+            constants::Values::kTransferRollerVoltage();
+        transfer_roller_speed_back =
+            -constants::Values::kTransferRollerVoltage();
+      } else {
+        transfer_roller_speed_back =
+            constants::Values::kTransferRollerVoltage();
+        transfer_roller_speed_front =
+            -constants::Values::kTransferRollerVoltage();
+      }
       flipper_arms_voltage = constants::Values::kFlipperFeedVoltage();
 
       // Ball is in catapult
@@ -373,7 +388,8 @@
   if (output != nullptr) {
     output_struct.roller_voltage_front = roller_speed_compensated_front;
     output_struct.roller_voltage_back = roller_speed_compensated_back;
-    output_struct.transfer_roller_voltage = transfer_roller_speed;
+    output_struct.transfer_roller_voltage_front = transfer_roller_speed_front;
+    output_struct.transfer_roller_voltage_back = transfer_roller_speed_back;
     output_struct.flipper_arms_voltage = flipper_arms_voltage;
 
     output->CheckOk(output->Send(Output::Pack(*output->fbb(), &output_struct)));
diff --git a/y2022/control_loops/superstructure/superstructure_goal.fbs b/y2022/control_loops/superstructure/superstructure_goal.fbs
index c86f338..6266b3c 100644
--- a/y2022/control_loops/superstructure/superstructure_goal.fbs
+++ b/y2022/control_loops/superstructure/superstructure_goal.fbs
@@ -28,8 +28,8 @@
   // Positive is rollers intaking.
   roller_speed_front:double (id: 3);
   roller_speed_back:double (id: 4);
-  // One transfer motor for both sides
-  transfer_roller_speed:double (id: 5);
+  transfer_roller_speed_front:double (id: 5);
+  transfer_roller_speed_back:double (id: 12);
 
   // Factor to multiply robot velocity by and add to roller voltage.
   roller_speed_compensation:double (id: 6);
diff --git a/y2022/control_loops/superstructure/superstructure_lib_test.cc b/y2022/control_loops/superstructure/superstructure_lib_test.cc
index 2f73370..af2ba53 100644
--- a/y2022/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2022/control_loops/superstructure/superstructure_lib_test.cc
@@ -473,20 +473,6 @@
     EXPECT_EQ(superstructure_output_fetcher_->roller_voltage_back(), expected);
   }
 
-  void TestTransferRoller(double transfer_roller_speed,
-                          double roller_speed_compensation, double expected) {
-    auto builder = superstructure_goal_sender_.MakeBuilder();
-    Goal::Builder goal_builder = builder.MakeBuilder<Goal>();
-    goal_builder.add_transfer_roller_speed(transfer_roller_speed);
-    goal_builder.add_roller_speed_compensation(roller_speed_compensation);
-    builder.CheckOk(builder.Send(goal_builder.Finish()));
-    RunFor(dt() * 2);
-    ASSERT_TRUE(superstructure_output_fetcher_.Fetch());
-    ASSERT_TRUE(superstructure_status_fetcher_.Fetch());
-    EXPECT_EQ(superstructure_output_fetcher_->transfer_roller_voltage(),
-              expected);
-  }
-
   std::shared_ptr<const constants::Values> values_;
 
   const aos::Node *const roborio_;
@@ -760,10 +746,6 @@
   TestRollerBack(-12.0, 1.5, -7.5);
   TestRollerBack(12.0, 1.5, 16.5);
   TestRollerBack(0.0, 1.5, 4.5);
-
-  TestTransferRoller(-12.0, 1.5, -12.0);
-  TestTransferRoller(12.0, 1.5, 12.0);
-  TestTransferRoller(0.0, 1.5, 0.0);
 }
 
 // Tests the whole shooting statemachine - from loading to shooting
@@ -794,7 +776,10 @@
   ASSERT_TRUE(superstructure_status_fetcher_.Fetch());
   EXPECT_EQ(superstructure_output_fetcher_->roller_voltage_front(), 12.0);
   EXPECT_EQ(superstructure_output_fetcher_->roller_voltage_back(), 12.0);
-  EXPECT_EQ(superstructure_output_fetcher_->transfer_roller_voltage(), 0.0);
+  EXPECT_EQ(superstructure_output_fetcher_->transfer_roller_voltage_front(),
+            0.0);
+  EXPECT_EQ(superstructure_output_fetcher_->transfer_roller_voltage_back(),
+            0.0);
   EXPECT_EQ(superstructure_status_fetcher_->state(), SuperstructureState::IDLE);
   EXPECT_EQ(superstructure_status_fetcher_->intake_state(),
             IntakeState::NO_BALL);
@@ -833,8 +818,10 @@
             IntakeState::INTAKE_FRONT_BALL);
   EXPECT_EQ(superstructure_output_fetcher_->flipper_arms_voltage(),
             constants::Values::kFlipperFeedVoltage());
-  EXPECT_EQ(superstructure_output_fetcher_->transfer_roller_voltage(),
-            constants::Values::kTransferRollerFrontVoltage());
+  EXPECT_EQ(superstructure_output_fetcher_->transfer_roller_voltage_front(),
+            constants::Values::kTransferRollerVoltage());
+  EXPECT_EQ(superstructure_output_fetcher_->transfer_roller_voltage_back(),
+            -constants::Values::kTransferRollerVoltage());
   EXPECT_NEAR(superstructure_status_fetcher_->turret()->position(),
               constants::Values::kTurretFrontIntakePos(), 0.001);
   EXPECT_EQ(superstructure_status_fetcher_->shot_count(), 0);
@@ -852,7 +839,10 @@
   ASSERT_TRUE(superstructure_status_fetcher_.Fetch());
   EXPECT_EQ(superstructure_output_fetcher_->roller_voltage_front(), 12.0);
   EXPECT_EQ(superstructure_output_fetcher_->roller_voltage_back(), 12.0);
-  EXPECT_EQ(superstructure_output_fetcher_->transfer_roller_voltage(), 0.0);
+  EXPECT_EQ(superstructure_output_fetcher_->transfer_roller_voltage_front(),
+            0.0);
+  EXPECT_EQ(superstructure_output_fetcher_->transfer_roller_voltage_back(),
+            0.0);
   EXPECT_EQ(superstructure_status_fetcher_->state(),
             SuperstructureState::LOADING);
   EXPECT_EQ(superstructure_status_fetcher_->intake_state(),
@@ -871,7 +861,10 @@
   ASSERT_TRUE(superstructure_status_fetcher_.Fetch());
   EXPECT_EQ(superstructure_output_fetcher_->roller_voltage_front(), 12.0);
   EXPECT_EQ(superstructure_output_fetcher_->roller_voltage_back(), 12.0);
-  EXPECT_EQ(superstructure_output_fetcher_->transfer_roller_voltage(), 0.0);
+  EXPECT_EQ(superstructure_output_fetcher_->transfer_roller_voltage_front(),
+            0.0);
+  EXPECT_EQ(superstructure_output_fetcher_->transfer_roller_voltage_back(),
+            0.0);
   EXPECT_EQ(superstructure_status_fetcher_->state(),
             SuperstructureState::LOADED);
   EXPECT_EQ(superstructure_status_fetcher_->intake_state(),
@@ -887,7 +880,10 @@
   ASSERT_TRUE(superstructure_status_fetcher_.Fetch());
   EXPECT_EQ(superstructure_output_fetcher_->roller_voltage_front(), 12.0);
   EXPECT_EQ(superstructure_output_fetcher_->roller_voltage_back(), 12.0);
-  EXPECT_EQ(superstructure_output_fetcher_->transfer_roller_voltage(), 0.0);
+  EXPECT_EQ(superstructure_output_fetcher_->transfer_roller_voltage_front(),
+            0.0);
+  EXPECT_EQ(superstructure_output_fetcher_->transfer_roller_voltage_back(),
+            0.0);
   EXPECT_EQ(superstructure_status_fetcher_->state(),
             SuperstructureState::LOADED);
   EXPECT_EQ(superstructure_status_fetcher_->intake_state(),
@@ -908,13 +904,14 @@
   ASSERT_TRUE(superstructure_output_fetcher_.Fetch());
   EXPECT_EQ(superstructure_output_fetcher_->roller_voltage_front(), 0.0);
   EXPECT_EQ(superstructure_output_fetcher_->roller_voltage_back(), 0.0);
-  LOG(INFO) << superstructure_output_fetcher_->transfer_roller_voltage();
-  EXPECT_TRUE(superstructure_output_fetcher_->transfer_roller_voltage() !=
+  EXPECT_TRUE(superstructure_output_fetcher_->transfer_roller_voltage_front() !=
                   0.0 &&
-              superstructure_output_fetcher_->transfer_roller_voltage() <=
-                  constants::Values::kTransferRollerFrontWiggleVoltage() &&
-              superstructure_output_fetcher_->transfer_roller_voltage() >=
-                  -constants::Values::kTransferRollerFrontWiggleVoltage());
+              superstructure_output_fetcher_->transfer_roller_voltage_front() <=
+                  constants::Values::kTransferRollerWiggleVoltage() &&
+              superstructure_output_fetcher_->transfer_roller_voltage_front() >=
+                  -constants::Values::kTransferRollerWiggleVoltage());
+  EXPECT_EQ(superstructure_output_fetcher_->transfer_roller_voltage_back(),
+            -superstructure_output_fetcher_->transfer_roller_voltage_front());
   EXPECT_EQ(superstructure_status_fetcher_->state(),
             SuperstructureState::LOADED);
   EXPECT_EQ(superstructure_status_fetcher_->intake_state(),
@@ -960,12 +957,14 @@
   ASSERT_TRUE(superstructure_status_fetcher_.Fetch());
   EXPECT_EQ(superstructure_output_fetcher_->roller_voltage_front(), 0.0);
   EXPECT_EQ(superstructure_output_fetcher_->roller_voltage_back(), 0.0);
-  EXPECT_TRUE(superstructure_output_fetcher_->transfer_roller_voltage() !=
+  EXPECT_TRUE(superstructure_output_fetcher_->transfer_roller_voltage_back() !=
                   0.0 &&
-              superstructure_output_fetcher_->transfer_roller_voltage() <=
-                  constants::Values::kTransferRollerFrontWiggleVoltage() &&
-              superstructure_output_fetcher_->transfer_roller_voltage() >=
-                  -constants::Values::kTransferRollerFrontWiggleVoltage());
+              superstructure_output_fetcher_->transfer_roller_voltage_back() <=
+                  constants::Values::kTransferRollerWiggleVoltage() &&
+              superstructure_output_fetcher_->transfer_roller_voltage_back() >=
+                  -constants::Values::kTransferRollerWiggleVoltage());
+  EXPECT_EQ(superstructure_output_fetcher_->transfer_roller_voltage_front(),
+            -superstructure_output_fetcher_->transfer_roller_voltage_back());
   EXPECT_EQ(superstructure_status_fetcher_->state(),
             SuperstructureState::SHOOTING);
   EXPECT_EQ(superstructure_status_fetcher_->intake_state(),
diff --git a/y2022/control_loops/superstructure/superstructure_output.fbs b/y2022/control_loops/superstructure/superstructure_output.fbs
index 8fa992e..af6c292 100644
--- a/y2022/control_loops/superstructure/superstructure_output.fbs
+++ b/y2022/control_loops/superstructure/superstructure_output.fbs
@@ -26,8 +26,8 @@
   // positive is pulling into the robot
   roller_voltage_front:double (id: 6);
   roller_voltage_back:double (id: 7);
-  // One transfer motor for both sides
-  transfer_roller_voltage:double (id: 8);
+  transfer_roller_voltage_front:double (id: 8);
+  transfer_roller_voltage_back:double (id: 9);
 }
 
 root_type Output;
diff --git a/y2022/joystick_reader.cc b/y2022/joystick_reader.cc
index 0065db7..ce5c755 100644
--- a/y2022/joystick_reader.cc
+++ b/y2022/joystick_reader.cc
@@ -157,7 +157,8 @@
     // Default to the intakes in
     double intake_front_pos = 1.47;
     double intake_back_pos = 1.47;
-    double transfer_roller_speed = 0.0;
+    double transfer_roller_front_speed = 0.0;
+    double transfer_roller_back_speed = 0.0;
 
     double roller_front_speed = 0.0;
     double roller_back_speed = 0.0;
@@ -198,11 +199,13 @@
     if (data.IsPressed(kIntakeFrontOut)) {
       intake_front_pos = 0.0;
       roller_front_speed = 12.0;
-      transfer_roller_speed = 12.0;
+      transfer_roller_front_speed = 12.0;
+      transfer_roller_back_speed = -transfer_roller_front_speed;
     } else if (data.IsPressed(kIntakeBackOut)) {
       roller_back_speed = 12.0;
       intake_back_pos = 0.0;
-      transfer_roller_speed = -12.0;
+      transfer_roller_back_speed = 12.0;
+      transfer_roller_front_speed = -transfer_roller_back_speed;
     }
 
     if (data.IsPressed(kFire)) {
@@ -253,7 +256,10 @@
 
       superstructure_goal_builder.add_roller_speed_front(roller_front_speed);
       superstructure_goal_builder.add_roller_speed_back(roller_back_speed);
-      superstructure_goal_builder.add_transfer_roller_speed(transfer_roller_speed);
+      superstructure_goal_builder.add_transfer_roller_speed_front(
+          transfer_roller_front_speed);
+      superstructure_goal_builder.add_transfer_roller_speed_back(
+          transfer_roller_front_speed);
 
       if (builder.Send(superstructure_goal_builder.Finish()) !=
           aos::RawSender::Error::kOk) {
diff --git a/y2022/wpilib_interface.cc b/y2022/wpilib_interface.cc
index a694211..2294cda 100644
--- a/y2022/wpilib_interface.cc
+++ b/y2022/wpilib_interface.cc
@@ -215,8 +215,7 @@
       frc971::PotAndAbsolutePositionT intake_back;
       CopyPosition(intake_encoder_back_, &intake_back,
                    Values::kIntakeEncoderCountsPerRevolution(),
-                   Values::kIntakeEncoderRatio(),
-                   intake_pot_translate, true,
+                   Values::kIntakeEncoderRatio(), intake_pot_translate, true,
                    values_->intake_back.potentiometer_offset);
       frc971::PotAndAbsolutePositionT turret;
       CopyPosition(turret_encoder_, &turret,
@@ -484,8 +483,12 @@
     return flipper_arms_falcon_;
   }
 
-  void set_transfer_roller_victor(::std::unique_ptr<::frc::VictorSP> t) {
-    transfer_roller_victor_ = ::std::move(t);
+  void set_transfer_roller_victor_front(::std::unique_ptr<::frc::VictorSP> t) {
+    transfer_roller_victor_front_ = ::std::move(t);
+  }
+
+  void set_transfer_roller_victor_back(::std::unique_ptr<::frc::VictorSP> t) {
+    transfer_roller_victor_back_ = ::std::move(t);
   }
 
  private:
@@ -500,7 +503,8 @@
         ctre::phoenix::motorcontrol::ControlMode::Disabled, 0);
     intake_falcon_front_->SetDisabled();
     intake_falcon_back_->SetDisabled();
-    transfer_roller_victor_->SetDisabled();
+    transfer_roller_victor_front_->SetDisabled();
+    transfer_roller_victor_back_->SetDisabled();
     catapult_falcon_1_->SetDisabled();
     turret_falcon_->SetDisabled();
   }
@@ -512,7 +516,10 @@
     WritePwm(output.intake_voltage_back(), intake_falcon_back_.get());
     WriteCan(output.roller_voltage_front(), roller_falcon_front_.get());
     WriteCan(output.roller_voltage_back(), roller_falcon_back_.get());
-    WritePwm(output.transfer_roller_voltage(), transfer_roller_victor_.get());
+    WritePwm(output.transfer_roller_voltage_front(),
+             transfer_roller_victor_front_.get());
+    WritePwm(output.transfer_roller_voltage_back(),
+             transfer_roller_victor_back_.get());
 
     WriteCan(-output.flipper_arms_voltage(), flipper_arms_falcon_.get());
 
@@ -544,7 +551,8 @@
 
   ::std::unique_ptr<::frc::TalonFX> turret_falcon_, catapult_falcon_1_,
       climber_falcon_;
-  ::std::unique_ptr<::frc::VictorSP> transfer_roller_victor_;
+  ::std::unique_ptr<::frc::VictorSP> transfer_roller_victor_front_,
+      transfer_roller_victor_back_;
 };
 
 class CANSensorReader {
@@ -614,7 +622,7 @@
     // Thread 2.
     ::aos::ShmEventLoop pdp_fetcher_event_loop(&config.message());
     ::frc971::wpilib::PDPFetcher pdp_fetcher(&pdp_fetcher_event_loop);
-    ;AddLoop(&pdp_fetcher_event_loop);
+    AddLoop(&pdp_fetcher_event_loop);
 
     // Thread 3.
     ::aos::ShmEventLoop sensor_reader_event_loop(&config.message());
@@ -639,8 +647,7 @@
     sensor_reader.set_turret_potentiometer(make_unique<frc::AnalogInput>(5));
 
     // TODO(milind): correct intake beambreak ports once set
-    sensor_reader.set_intake_beambreak_front(
-        make_unique<frc::DigitalInput>(1));
+    sensor_reader.set_intake_beambreak_front(make_unique<frc::DigitalInput>(1));
     sensor_reader.set_intake_beambreak_back(make_unique<frc::DigitalInput>(6));
     sensor_reader.set_turret_beambreak(make_unique<frc::DigitalInput>(7));
 
@@ -679,8 +686,9 @@
     superstructure_writer.set_roller_falcon_back(
         make_unique<::ctre::phoenix::motorcontrol::can::TalonFX>(1));
 
-    // TODO(milind): correct port
-    superstructure_writer.set_transfer_roller_victor(
+    superstructure_writer.set_transfer_roller_victor_front(
+        make_unique<::frc::VictorSP>(6));
+    superstructure_writer.set_transfer_roller_victor_back(
         make_unique<::frc::VictorSP>(5));
 
     superstructure_writer.set_intake_falcon_front(make_unique<frc::TalonFX>(2));