Merge "Use event_loop to set realtime priority on y2019 SolenoidWriter"
diff --git a/aos/network/BUILD b/aos/network/BUILD
index e6ff5af..067ae35 100644
--- a/aos/network/BUILD
+++ b/aos/network/BUILD
@@ -105,8 +105,8 @@
     ],
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
-        "//aos/util:string_to_num",
         "@com_github_google_glog//:glog",
+        "@com_google_absl//absl/strings",
     ],
 )
 
diff --git a/aos/network/team_number.cc b/aos/network/team_number.cc
index 1f71946..0bd0cf7 100644
--- a/aos/network/team_number.cc
+++ b/aos/network/team_number.cc
@@ -5,7 +5,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 
-#include "aos/util/string_to_num.h"
+#include "absl/strings/numbers.h"
 
 DEFINE_string(
     override_hostname, "",
@@ -16,16 +16,17 @@
 namespace network {
 namespace team_number_internal {
 
-std::optional<uint16_t> ParseRoborioTeamNumber(const std::string &hostname) {
+std::optional<uint16_t> ParseRoborioTeamNumber(
+    const std::string_view hostname) {
   for (size_t i = 0; i < hostname.size(); i++) {
     if (hostname[i] == '-') {
-      const std::string num_as_s =
+      const std::string_view num_as_s =
           hostname[hostname.size() - 1] == 'C'
               ? hostname.substr(i + 1, hostname.size() - 5 - i)
               : hostname.substr(i + 1);
 
       int num;
-      if (!::aos::util::StringToNumber(num_as_s, &num)) {
+      if (!absl::SimpleAtoi(num_as_s, &num)) {
         return std::nullopt;
       }
       if (hostname.substr(0, i) == "roboRIO" &&
@@ -38,7 +39,7 @@
   return std::nullopt;
 }
 
-std::optional<uint16_t> ParsePiTeamNumber(const std::string &hostname) {
+std::optional<uint16_t> ParsePiTeamNumber(const std::string_view hostname) {
   if (hostname.substr(0, 3) != "pi-") {
     return std::nullopt;
   }
@@ -52,10 +53,10 @@
   if (second_separator == hostname.npos) {
     return std::nullopt;
   }
-  const std::string number_string =
+  const std::string_view number_string =
       hostname.substr(first_separator, second_separator - first_separator);
   int number;
-  if (!util::StringToNumber(number_string, &number)) {
+  if (!absl::SimpleAtoi(number_string, &number)) {
     return std::nullopt;
   }
   return number;
@@ -74,8 +75,8 @@
 
   const char *override_number = getenv("AOS_TEAM_NUMBER");
   if (override_number != nullptr) {
-    uint16_t result;
-    if (!::aos::util::StringToNumber(override_number, &result)) {
+    uint32_t result;
+    if (!absl::SimpleAtoi(override_number, &result)) {
       LOG(FATAL) << "Error parsing AOS_TEAM_NUMBER: " << override_number;
     }
     LOG(WARNING)
@@ -121,7 +122,7 @@
 
 void OverrideTeamNumber(uint16_t team) { override_team = team; }
 
-std::optional<uint16_t> ParsePiNumber(const std::string &hostname) {
+std::optional<uint16_t> ParsePiNumber(const std::string_view hostname) {
   if (hostname.substr(0, 3) != "pi-") {
     return std::nullopt;
   }
@@ -135,14 +136,14 @@
   if (second_separator == hostname.npos) {
     return std::nullopt;
   }
-  const std::string number_string = hostname.substr(
+  const std::string_view number_string = hostname.substr(
       second_separator + 1, hostname.size() - second_separator - 1);
   if (number_string.size() == 0) {
     return std::nullopt;
   }
 
   int number;
-  if (!util::StringToNumber(number_string, &number)) {
+  if (!absl::SimpleAtoi(number_string, &number)) {
     return std::nullopt;
   }
   return number;
diff --git a/aos/network/team_number.h b/aos/network/team_number.h
index c2954b6..8effc27 100644
--- a/aos/network/team_number.h
+++ b/aos/network/team_number.h
@@ -4,7 +4,7 @@
 #include <stdint.h>
 
 #include <optional>
-#include <string>
+#include <string_view>
 
 #include "glog/logging.h"
 
@@ -29,14 +29,14 @@
 void OverrideTeamNumber(uint16_t team);
 
 // Returns the pi number for a pi formated hostname.  pi-team#-pi# (pi-971-5)
-std::optional<uint16_t> ParsePiNumber(const std::string &hostname);
+std::optional<uint16_t> ParsePiNumber(const std::string_view hostname);
 
 namespace team_number_internal {
 
-std::optional<uint16_t> ParseRoborioTeamNumber(const std::string &hostname);
+std::optional<uint16_t> ParseRoborioTeamNumber(const std::string_view hostname);
 
 // Returns the team number for a pi formated hostname.  pi-team#-pi#
-std::optional<uint16_t> ParsePiTeamNumber(const std::string &hostname);
+std::optional<uint16_t> ParsePiTeamNumber(const std::string_view hostname);
 
 }  // namespace team_number_internal
 }  // namespace network
diff --git a/aos/starter/starter_cmd.cc b/aos/starter/starter_cmd.cc
index e9b6ed5..3cf6636 100644
--- a/aos/starter/starter_cmd.cc
+++ b/aos/starter/starter_cmd.cc
@@ -24,8 +24,7 @@
                         {"restart", aos::starter::Command::RESTART}};
 
 void PrintKey() {
-  absl::PrintF("%-30s %-30s %s\n\n", "Name", "Time since last started",
-               "State");
+  absl::PrintF("%-30s %-10s %s\n\n", "Name", "Uptime", "State");
 }
 
 void PrintApplicationStatus(const aos::starter::ApplicationStatus *app_status,
@@ -34,7 +33,7 @@
       chrono::nanoseconds(app_status->last_start_time()));
   const auto time_running =
       chrono::duration_cast<chrono::seconds>(time - last_start_time);
-  absl::PrintF("%-30s %-30s %s\n", app_status->name()->string_view(),
+  absl::PrintF("%-30s %-10s %s\n", app_status->name()->string_view(),
                std::to_string(time_running.count()) + 's',
                aos::starter::EnumNameState(app_status->state()));
 }
diff --git a/aos/util/BUILD b/aos/util/BUILD
index 7c5052c..59dec18 100644
--- a/aos/util/BUILD
+++ b/aos/util/BUILD
@@ -119,26 +119,6 @@
 )
 
 cc_library(
-    name = "string_to_num",
-    hdrs = [
-        "string_to_num.h",
-    ],
-    target_compatible_with = ["@platforms//os:linux"],
-)
-
-cc_test(
-    name = "string_to_num_test",
-    srcs = [
-        "string_to_num_test.cc",
-    ],
-    target_compatible_with = ["@platforms//os:linux"],
-    deps = [
-        ":string_to_num",
-        "//aos/testing:googletest",
-    ],
-)
-
-cc_library(
     name = "trapezoid_profile",
     srcs = [
         "trapezoid_profile.cc",
diff --git a/aos/util/string_to_num.h b/aos/util/string_to_num.h
deleted file mode 100644
index 86210ca..0000000
--- a/aos/util/string_to_num.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef AOS_UTIL_STRING_TO_NUM_H_
-#define AOS_UTIL_STRING_TO_NUM_H_
-
-#include <sstream>
-#include <string>
-
-namespace aos {
-namespace util {
-
-// Converts a string into a specified numeric type. If it can't be converted
-// completely or at all, or if the converted number would overflow the
-// specified type, it returns false.
-template<typename T>
-inline bool StringToNumber(const ::std::string &input, T *out_num) {
-  ::std::istringstream stream(input);
-  stream >> *out_num;
-
-  if (stream.fail() || !stream.eof()) {
-    return false;
-  }
-
-  return true;
-}
-
-
-}  // util
-}  // aos
-
-#endif
diff --git a/aos/util/string_to_num_test.cc b/aos/util/string_to_num_test.cc
deleted file mode 100644
index 3f467cf..0000000
--- a/aos/util/string_to_num_test.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-#include <stdint.h>
-
-#include <string>
-
-#include "gtest/gtest.h"
-
-#include "aos/util/string_to_num.h"
-
-namespace aos {
-namespace util {
-namespace testing {
-
-TEST(StringToNumTest, CorrectNumber) {
-  int result;
-  ASSERT_TRUE(StringToNumber<int>(::std::string("42"), &result));
-  EXPECT_EQ(result, 42);
-}
-
-TEST(StringToNumTest, NegativeTest) {
-  int result;
-  ASSERT_TRUE(StringToNumber<int>(::std::string("-42"), &result));
-  EXPECT_EQ(result, -42);
-}
-
-TEST(StringToNumTest, NonNumber) {
-  int result;
-  ASSERT_FALSE(StringToNumber<int>(::std::string("Daniel"), &result));
-}
-
-TEST(StringToNumTest, NumberWithText) {
-  int result;
-  ASSERT_FALSE(StringToNumber<int>(::std::string("42Daniel"), &result));
-}
-
-TEST(StringToNumTest, OverflowTest) {
-  uint32_t result;
-  // 2 << 32 should overflow.
-  ASSERT_FALSE(StringToNumber<uint32_t>(::std::string("4294967296"), &result));
-}
-
-TEST(StringToNumTest, FloatingPointTest) {
-  double result;
-  ASSERT_TRUE(StringToNumber<double>(::std::string("3.1415927"), &result));
-  EXPECT_EQ(result, 3.1415927);
-}
-
-}  // testing
-}  // util
-}  // aos
diff --git a/frc971/wpilib/ADIS16448.cc b/frc971/wpilib/ADIS16448.cc
index 2ce45e9..b104840 100644
--- a/frc971/wpilib/ADIS16448.cc
+++ b/frc971/wpilib/ADIS16448.cc
@@ -119,7 +119,7 @@
                      frc::DigitalInput *dio1)
     : event_loop_(event_loop),
       imu_values_sender_(
-          event_loop_->MakeSender<::frc971::IMUValues>("/drivetrain")),
+          event_loop_->MakeSender<::frc971::IMUValuesBatch>("/drivetrain")),
       spi_(new frc::SPI(port)),
       dio1_(dio1) {
   // 1MHz is the maximum supported for burst reads, but we
@@ -276,7 +276,15 @@
         ConvertValue(&to_receive[24], kTemperatureLsbDegree) +
         kTemperatureZero);
 
-    if (!builder.Send(imu_builder.Finish())) {
+    flatbuffers::Offset<IMUValues> imu_offset = imu_builder.Finish();
+
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<IMUValues>>>
+        readings_offset = builder.fbb()->CreateVector(&imu_offset, 1);
+
+    IMUValuesBatch::Builder imu_values_batch_builder =
+        builder.MakeBuilder<IMUValuesBatch>();
+    imu_values_batch_builder.add_readings(readings_offset);
+    if (!builder.Send(imu_values_batch_builder.Finish())) {
       AOS_LOG(WARNING, "sending queue message failed\n");
     }
 
diff --git a/frc971/wpilib/ADIS16448.h b/frc971/wpilib/ADIS16448.h
index 04d1712..59f9aa8 100644
--- a/frc971/wpilib/ADIS16448.h
+++ b/frc971/wpilib/ADIS16448.h
@@ -14,6 +14,7 @@
 #include "aos/events/shm_event_loop.h"
 #include "aos/logging/logging.h"
 #include "frc971/wpilib/fpga_time_conversion.h"
+#include "frc971/wpilib/imu_batch_generated.h"
 #include "frc971/wpilib/imu_generated.h"
 #include "frc971/wpilib/spi_rx_clearer.h"
 
@@ -85,7 +86,7 @@
   bool Initialize();
 
   ::aos::EventLoop *event_loop_;
-  ::aos::Sender<::frc971::IMUValues> imu_values_sender_;
+  ::aos::Sender<::frc971::IMUValuesBatch> imu_values_sender_;
 
   // TODO(Brian): This object has no business owning these ones.
   const ::std::unique_ptr<frc::SPI> spi_;
diff --git a/frc971/wpilib/BUILD b/frc971/wpilib/BUILD
index 4f8bca0..10e8462 100644
--- a/frc971/wpilib/BUILD
+++ b/frc971/wpilib/BUILD
@@ -115,9 +115,9 @@
         "//aos/events:event_loop",
         "//aos/events:shm_event_loop",
         "//aos/logging",
-        "//frc971/input:robot_state_fbs",
         "//aos/time",
         "//aos/util:phased_loop",
+        "//frc971/input:robot_state_fbs",
         "//frc971/queues:gyro_fbs",
         "//frc971/queues:gyro_uid_fbs",
         "//frc971/zeroing:averager",
@@ -167,10 +167,10 @@
     deps = [
         "//aos:init",
         "//aos/events:event_loop",
-        "//frc971/input:robot_state_fbs",
         "//aos/scoped:scoped_fd",
         "//aos/time",
         "//aos/util:log_interval",
+        "//frc971/input:robot_state_fbs",
     ],
 )
 
@@ -204,8 +204,8 @@
     deps = [
         "//aos:init",
         "//aos/events:shm_event_loop",
-        "//frc971/input:driver_station_data",
         "//aos/network:team_number",
+        "//frc971/input:driver_station_data",
         "//frc971/input:joystick_state_fbs",
         "//third_party:wpilib",
     ],
@@ -331,6 +331,7 @@
     target_compatible_with = ["//tools/platforms/hardware:roborio"],
     deps = [
         ":fpga_time_conversion",
+        ":imu_batch_fbs",
         ":imu_fbs",
         ":spi_rx_clearer",
         "//aos:init",
diff --git a/y2012/control_loops/drivetrain/drivetrain_main.cc b/y2012/control_loops/drivetrain/drivetrain_main.cc
index 050f00e..8665e91 100644
--- a/y2012/control_loops/drivetrain/drivetrain_main.cc
+++ b/y2012/control_loops/drivetrain/drivetrain_main.cc
@@ -1,6 +1,7 @@
-#include "aos/init.h"
+#include <memory>
 
 #include "aos/events/shm_event_loop.h"
+#include "aos/init.h"
 #include "frc971/control_loops/drivetrain/drivetrain.h"
 #include "y2012/control_loops/drivetrain/drivetrain_base.h"
 
@@ -15,7 +16,7 @@
   ::aos::ShmEventLoop event_loop(&config.message());
   ::frc971::control_loops::drivetrain::DeadReckonEkf localizer(
       &event_loop, ::y2012::control_loops::drivetrain::GetDrivetrainConfig());
-  DrivetrainLoop drivetrain(
+  std::unique_ptr<DrivetrainLoop> drivetrain = std::make_unique<DrivetrainLoop>(
       ::y2012::control_loops::drivetrain::GetDrivetrainConfig(), &event_loop,
       &localizer);
 
diff --git a/y2014/control_loops/drivetrain/drivetrain_main.cc b/y2014/control_loops/drivetrain/drivetrain_main.cc
index 8367ec1..19b8e70 100644
--- a/y2014/control_loops/drivetrain/drivetrain_main.cc
+++ b/y2014/control_loops/drivetrain/drivetrain_main.cc
@@ -1,6 +1,7 @@
-#include "aos/init.h"
+#include <memory>
 
 #include "aos/events/shm_event_loop.h"
+#include "aos/init.h"
 #include "frc971/control_loops/drivetrain/drivetrain.h"
 #include "y2014/control_loops/drivetrain/drivetrain_base.h"
 
@@ -15,8 +16,8 @@
   ::aos::ShmEventLoop event_loop(&config.message());
   ::frc971::control_loops::drivetrain::DeadReckonEkf localizer(
       &event_loop, ::y2014::control_loops::GetDrivetrainConfig());
-  DrivetrainLoop drivetrain(::y2014::control_loops::GetDrivetrainConfig(),
-                            &event_loop, &localizer);
+  std::unique_ptr<DrivetrainLoop> drivetrain = std::make_unique<DrivetrainLoop>(
+      ::y2014::control_loops::GetDrivetrainConfig(), &event_loop, &localizer);
 
   event_loop.Run();
 
diff --git a/y2014_bot3/control_loops/drivetrain/drivetrain_main.cc b/y2014_bot3/control_loops/drivetrain/drivetrain_main.cc
index 1b7bda1..7c1486d 100644
--- a/y2014_bot3/control_loops/drivetrain/drivetrain_main.cc
+++ b/y2014_bot3/control_loops/drivetrain/drivetrain_main.cc
@@ -1,6 +1,7 @@
-#include "aos/init.h"
+#include <memory>
 
 #include "aos/events/shm_event_loop.h"
+#include "aos/init.h"
 #include "frc971/control_loops/drivetrain/drivetrain.h"
 #include "y2014_bot3/control_loops/drivetrain/drivetrain_base.h"
 
@@ -16,7 +17,7 @@
   ::frc971::control_loops::drivetrain::DeadReckonEkf localizer(
       &event_loop,
       ::y2014_bot3::control_loops::drivetrain::GetDrivetrainConfig());
-  DrivetrainLoop drivetrain(
+  std::unique_ptr<DrivetrainLoop> drivetrain = std::make_unique<DrivetrainLoop>(
       ::y2014_bot3::control_loops::drivetrain::GetDrivetrainConfig(),
       &event_loop, &localizer);
 
diff --git a/y2016/control_loops/drivetrain/drivetrain_main.cc b/y2016/control_loops/drivetrain/drivetrain_main.cc
index 3c60a63..7edcde5 100644
--- a/y2016/control_loops/drivetrain/drivetrain_main.cc
+++ b/y2016/control_loops/drivetrain/drivetrain_main.cc
@@ -1,6 +1,7 @@
-#include "aos/init.h"
+#include <memory>
 
 #include "aos/events/shm_event_loop.h"
+#include "aos/init.h"
 #include "frc971/control_loops/drivetrain/drivetrain.h"
 #include "y2016/control_loops/drivetrain/drivetrain_base.h"
 
@@ -15,7 +16,7 @@
   ::aos::ShmEventLoop event_loop(&config.message());
   ::frc971::control_loops::drivetrain::DeadReckonEkf localizer(
       &event_loop, ::y2016::control_loops::drivetrain::GetDrivetrainConfig());
-  DrivetrainLoop drivetrain(
+  std::unique_ptr<DrivetrainLoop> drivetrain = std::make_unique<DrivetrainLoop>(
       ::y2016::control_loops::drivetrain::GetDrivetrainConfig(), &event_loop,
       &localizer);
 
diff --git a/y2017/control_loops/drivetrain/drivetrain_main.cc b/y2017/control_loops/drivetrain/drivetrain_main.cc
index 444838c..4db7b95 100644
--- a/y2017/control_loops/drivetrain/drivetrain_main.cc
+++ b/y2017/control_loops/drivetrain/drivetrain_main.cc
@@ -1,6 +1,7 @@
-#include "aos/init.h"
+#include <memory>
 
 #include "aos/events/shm_event_loop.h"
+#include "aos/init.h"
 #include "frc971/control_loops/drivetrain/drivetrain.h"
 #include "y2017/control_loops/drivetrain/drivetrain_base.h"
 
@@ -15,7 +16,7 @@
   ::aos::ShmEventLoop event_loop(&config.message());
   ::frc971::control_loops::drivetrain::DeadReckonEkf localizer(
       &event_loop, ::y2017::control_loops::drivetrain::GetDrivetrainConfig());
-  DrivetrainLoop drivetrain(
+  std::unique_ptr<DrivetrainLoop> drivetrain = std::make_unique<DrivetrainLoop>(
       ::y2017::control_loops::drivetrain::GetDrivetrainConfig(), &event_loop,
       &localizer);
 
diff --git a/y2018/control_loops/drivetrain/drivetrain_main.cc b/y2018/control_loops/drivetrain/drivetrain_main.cc
index ad1d9bd..461fd34 100644
--- a/y2018/control_loops/drivetrain/drivetrain_main.cc
+++ b/y2018/control_loops/drivetrain/drivetrain_main.cc
@@ -1,6 +1,7 @@
-#include "aos/init.h"
+#include <memory>
 
 #include "aos/events/shm_event_loop.h"
+#include "aos/init.h"
 #include "frc971/control_loops/drivetrain/drivetrain.h"
 #include "y2018/control_loops/drivetrain/drivetrain_base.h"
 
@@ -15,7 +16,7 @@
   ::aos::ShmEventLoop event_loop(&config.message());
   ::frc971::control_loops::drivetrain::DeadReckonEkf localizer(
       &event_loop, ::y2018::control_loops::drivetrain::GetDrivetrainConfig());
-  DrivetrainLoop drivetrain(
+  std::unique_ptr<DrivetrainLoop> drivetrain = std::make_unique<DrivetrainLoop>(
       ::y2018::control_loops::drivetrain::GetDrivetrainConfig(), &event_loop,
       &localizer);
 
diff --git a/y2019/constants.cc b/y2019/constants.cc
index b14ac3e..0a56ca5 100644
--- a/y2019/constants.cc
+++ b/y2019/constants.cc
@@ -181,7 +181,8 @@
       intake->zeroing_constants.measured_absolute_position = 1.273143;
 
       wrist_params->zeroing_constants.measured_absolute_position = 0.155868;
-      wrist->potentiometer_offset = -4.257454 - 0.058039 + 0.270233 - 0.661464;
+      wrist->potentiometer_offset =
+          -4.257454 - 0.058039 + 0.270233 - 0.661464 + 0.872911951453577;
 
       stilts_params->zeroing_constants.measured_absolute_position = 0.066843;
       stilts->potentiometer_offset = -0.015760 + 0.011604 - 0.061213 + 0.006690;
diff --git a/y2019/control_loops/drivetrain/drivetrain_main.cc b/y2019/control_loops/drivetrain/drivetrain_main.cc
index 5641d1d..a45db0c 100644
--- a/y2019/control_loops/drivetrain/drivetrain_main.cc
+++ b/y2019/control_loops/drivetrain/drivetrain_main.cc
@@ -1,6 +1,7 @@
-#include "aos/init.h"
+#include <memory>
 
 #include "aos/events/shm_event_loop.h"
+#include "aos/init.h"
 #include "frc971/control_loops/drivetrain/drivetrain.h"
 #include "y2019/control_loops/drivetrain/drivetrain_base.h"
 #include "y2019/control_loops/drivetrain/event_loop_localizer.h"
@@ -16,7 +17,7 @@
   ::aos::ShmEventLoop event_loop(&config.message());
   ::y2019::control_loops::drivetrain::EventLoopLocalizer localizer(
       &event_loop, ::y2019::control_loops::drivetrain::GetDrivetrainConfig());
-  DrivetrainLoop drivetrain(
+  std::unique_ptr<DrivetrainLoop> drivetrain = std::make_unique<DrivetrainLoop>(
       ::y2019::control_loops::drivetrain::GetDrivetrainConfig(), &event_loop,
       &localizer);
 
diff --git a/y2019/y2019.json b/y2019/y2019.json
index 7a30be4..719925c 100644
--- a/y2019/y2019.json
+++ b/y2019/y2019.json
@@ -43,7 +43,36 @@
   ],
   "applications": [
     {
-      "name": "drivetrain"
+      "name": "drivetrain",
+      "executable_name": "drivetrain.stripped"
+    },
+    {
+      "name": "trajectory_generator",
+      "executable_name": "trajectory_generator.stripped"
+    },
+    {
+      "name": "superstructure",
+      "executable_name": "superstructure.stripped"
+    },
+    {
+      "name": "server",
+      "executable_name": "server.stripped"
+    },
+    {
+      "name": "logger_main",
+      "executable_name": "logger_main.stripped"
+    },
+    {
+      "name": "joystick_reader",
+      "executable_name": "joystick_reader.stripped"
+    },
+    {
+      "name": "autonomous_action",
+      "executable_name": "autonomous_action.stripped"
+    },
+    {
+      "name": "wpilib_interface",
+      "executable_name": "wpilib_interface.stripped"
     }
   ],
   "imports": [
diff --git a/y2020/control_loops/drivetrain/drivetrain_main.cc b/y2020/control_loops/drivetrain/drivetrain_main.cc
index e73c023..dec9118 100644
--- a/y2020/control_loops/drivetrain/drivetrain_main.cc
+++ b/y2020/control_loops/drivetrain/drivetrain_main.cc
@@ -1,3 +1,5 @@
+#include <memory>
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "frc971/control_loops/drivetrain/drivetrain.h"
@@ -15,7 +17,7 @@
   ::aos::ShmEventLoop event_loop(&config.message());
   ::y2020::control_loops::drivetrain::Localizer localizer(
       &event_loop, ::y2020::control_loops::drivetrain::GetDrivetrainConfig());
-  DrivetrainLoop drivetrain(
+  std::unique_ptr<DrivetrainLoop> drivetrain = std::make_unique<DrivetrainLoop>(
       ::y2020::control_loops::drivetrain::GetDrivetrainConfig(), &event_loop,
       &localizer);
 
diff --git a/y2020/vision/rootfs/modify_rootfs.sh b/y2020/vision/rootfs/modify_rootfs.sh
index f08e635..ae1e493 100755
--- a/y2020/vision/rootfs/modify_rootfs.sh
+++ b/y2020/vision/rootfs/modify_rootfs.sh
@@ -44,7 +44,7 @@
 else
   OFFSET="$(/sbin/fdisk -lu "${IMAGE}" | grep "${IMAGE}2" | awk '{print 512*$2}')"
 
-  if [[ "$(stat -c %s "${IMAGE}")" < 3000000000 ]]; then
+  if [[ "$(stat -c %s "${IMAGE}")" < 2000000000 ]]; then
     echo "Growing image"
     dd if=/dev/zero bs=1G count=1 >> "${IMAGE}"
     START="$(/sbin/fdisk -lu "${IMAGE}" | grep "${IMAGE}2" | awk '{print $2}')"
diff --git a/y2020/vision/rootfs/target_configure.sh b/y2020/vision/rootfs/target_configure.sh
index 11b8cc8..e36a940 100755
--- a/y2020/vision/rootfs/target_configure.sh
+++ b/y2020/vision/rootfs/target_configure.sh
@@ -38,23 +38,9 @@
   libopencv-videostab3.2 \
   libopencv-viz3.2 \
   python3-opencv \
-  python3-matplotlib \
-  gstreamer1.0-plugins-bad \
-  gstreamer1.0-plugins-base \
-  gstreamer1.0-plugins-good \
-  gstreamer1.0-plugins-ugly \
-  gstreamer1.0-x \
-  gstreamer1.0-nice \
-  gstreamer1.0-gl \
-  libgstreamer-plugins-bad1.0-0 \
-  libgstreamer-plugins-base1.0-0 \
-  libgstreamer1.0-0 \
-  libgstreamer-gl1.0-0 \
   libnice10 \
   libnice-dev
 
-python3 -m pip install glog
-
 echo 'GOVERNOR="performance"' > /etc/default/cpufrequtils
 
 # Add a .bashrc and friends for root.
diff --git a/y2021_bot3/control_loops/drivetrain/drivetrain_main.cc b/y2021_bot3/control_loops/drivetrain/drivetrain_main.cc
index 0fef75f..f79846e 100644
--- a/y2021_bot3/control_loops/drivetrain/drivetrain_main.cc
+++ b/y2021_bot3/control_loops/drivetrain/drivetrain_main.cc
@@ -1,3 +1,5 @@
+#include <memory>
+
 #include "aos/events/shm_event_loop.h"
 #include "aos/init.h"
 #include "frc971/control_loops/drivetrain/drivetrain.h"
@@ -15,7 +17,7 @@
   ::frc971::control_loops::drivetrain::DeadReckonEkf localizer(
       &event_loop,
       ::y2021_bot3::control_loops::drivetrain::GetDrivetrainConfig());
-  DrivetrainLoop drivetrain(
+  std::unique_ptr<DrivetrainLoop> drivetrain = std::make_unique<DrivetrainLoop>(
       ::y2021_bot3::control_loops::drivetrain::GetDrivetrainConfig(),
       &event_loop, &localizer);