Merge "Use newer log in balls shot replay test"
diff --git a/aos/BUILD b/aos/BUILD
index cd1f133..9049e08 100644
--- a/aos/BUILD
+++ b/aos/BUILD
@@ -153,9 +153,8 @@
     ],
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
-        "//aos/logging",
-        "//aos/logging:implementations",
         "//aos/time",
+        "@com_github_google_glog//:glog",
     ],
 )
 
diff --git a/aos/dump_rtprio.cc b/aos/dump_rtprio.cc
index 5ab402f..a017137 100644
--- a/aos/dump_rtprio.cc
+++ b/aos/dump_rtprio.cc
@@ -16,9 +16,8 @@
 #include <cstdlib>
 #include <string>
 
-#include "aos/logging/implementations.h"
-#include "aos/logging/logging.h"
 #include "aos/time/time.h"
+#include "glog/logging.h"
 
 namespace {
 
@@ -54,19 +53,16 @@
 int find_pid_max() {
   int r;
   FILE *pid_max_file = fopen("/proc/sys/kernel/pid_max", "r");
-  if (pid_max_file == nullptr) {
-    AOS_PLOG(FATAL, "fopen(\"/proc/sys/kernel/pid_max\")");
-  }
-  AOS_CHECK_EQ(1, fscanf(pid_max_file, "%d", &r));
-  AOS_PCHECK(fclose(pid_max_file));
+  PCHECK(pid_max_file != nullptr)
+      << ": Failed to open /proc/sys/kernel/pid_max";
+  CHECK_EQ(1, fscanf(pid_max_file, "%d", &r));
+  PCHECK(fclose(pid_max_file) == 0);
   return r;
 }
 
 cpu_set_t find_all_cpus() {
   long nproc = sysconf(_SC_NPROCESSORS_CONF);
-  if (nproc == -1) {
-    AOS_PLOG(FATAL, "sysconf(_SC_NPROCESSORS_CONF)");
-  }
+  PCHECK(nproc != -1);
   cpu_set_t r;
   CPU_ZERO(&r);
   for (long i = 0; i < nproc; ++i) {
@@ -82,9 +78,7 @@
     *not_there = true;
     return cpu_set_t();
   }
-  if (result != 0) {
-    AOS_PLOG(FATAL, "sched_getaffinity(%d, %zu, %p)", process, sizeof(r), &r);
-  }
+  PCHECK(result == 0) << ": sched_getaffinity of " << process;
   return r;
 }
 
@@ -95,9 +89,7 @@
     *not_there = true;
     return sched_param();
   }
-  if (result != 0) {
-    AOS_PLOG(FATAL, "sched_getparam(%d)", process);
-  }
+  PCHECK(result == 0) << ": sched_getparam of " << process;
   return r;
 }
 
@@ -107,9 +99,7 @@
     *not_there = true;
     return 0;
   }
-  if (scheduler == -1) {
-    AOS_PLOG(FATAL, "sched_getscheduler(%d)", process);
-  }
+  PCHECK(scheduler != -1) << ": sched_getscheduler of " << process;
   return scheduler;
 }
 
@@ -125,10 +115,8 @@
       *not_there = true;
       return "";
     }
-    if (exe_size == -1) {
-      AOS_PLOG(FATAL, "readlink(%s, %p, %zu)", exe_filename.c_str(), exe_buffer,
-               sizeof(exe_buffer));
-    }
+    PCHECK(exe_size != -1) << ": readlink " << exe_filename
+                           << " into buffer of size " << sizeof(exe_buffer);
     return ::std::string(exe_buffer, exe_size);
   }
 }
@@ -140,9 +128,7 @@
     *not_there = true;
     return 0;
   }
-  if (errno != 0) {
-    AOS_PLOG(FATAL, "getpriority(PRIO_PROCESS, %d)", process);
-  }
+  PCHECK(errno == 0) << "getpriority of " << process;
   return nice_value;
 }
 
@@ -153,9 +139,7 @@
     *not_there = true;
     return;
   }
-  if (stat == nullptr) {
-    AOS_PLOG(FATAL, "fopen(%s, \"r\")", stat_filename.c_str());
-  }
+  PCHECK(stat != nullptr) << ": Failed to open " << stat_filename;
 
   char buffer[2048];
   if (fgets(buffer, sizeof(buffer), stat) == nullptr) {
@@ -164,7 +148,8 @@
         *not_there = true;
         return;
       }
-      AOS_PLOG(FATAL, "fgets(%p, %zu, %p)", buffer, sizeof(buffer), stat);
+      PLOG(FATAL) << "reading from " << stat_filename << " into buffer of size "
+                  << sizeof(buffer);
     }
   }
 
@@ -197,12 +182,12 @@
       field_start = i + 1;
     }
   }
-  AOS_PCHECK(fclose(stat));
+  PCHECK(fclose(stat) == 0);
 
   if (field < 4) {
-    AOS_LOG(FATAL, "couldn't get fields from /proc/%d/stat\n", process);
+    LOG(FATAL) << "couldn't get fields from /proc/" << process << "/stat";
   }
-  AOS_CHECK_EQ(pid, process);
+  CHECK_EQ(pid, process);
 }
 
 void read_status(int process, int ppid, int *pgrp, ::std::string *name,
@@ -214,16 +199,15 @@
     *not_there = true;
     return;
   }
-  if (status == nullptr) {
-    AOS_PLOG(FATAL, "fopen(%s, \"r\")", status_filename.c_str());
-  }
+  PCHECK(status != nullptr) << ": Failed to open " << status_filename;
 
   int pid = 0, status_ppid = 0;
   while (true) {
     char buffer[1024];
     if (fgets(buffer, sizeof(buffer), status) == nullptr) {
       if (ferror(status)) {
-        AOS_PLOG(FATAL, "fgets(%p, %zu, %p)", buffer, sizeof(buffer), status);
+        PLOG(FATAL) << "reading from " << status_filename
+                    << " into buffer of size " << sizeof(buffer);
       } else {
         break;
       }
@@ -239,9 +223,9 @@
       *pgrp = ::std::stoi(strip_string_prefix(5, line));
     }
   }
-  AOS_PCHECK(fclose(status));
-  AOS_CHECK_EQ(pid, process);
-  AOS_CHECK_EQ(status_ppid, ppid);
+  PCHECK(fclose(status) == 0);
+  CHECK_EQ(pid, process);
+  CHECK_EQ(status_ppid, ppid);
 }
 
 }  // namespace
diff --git a/aos/ftrace.cc b/aos/ftrace.cc
index f159a76..0afbcf5 100644
--- a/aos/ftrace.cc
+++ b/aos/ftrace.cc
@@ -3,8 +3,20 @@
 #include <cstdarg>
 #include <cstdio>
 
+DEFINE_bool(
+    enable_ftrace, false,
+    "If false, disable logging to /sys/kernel/debug/tracing/trace_marker");
+
 namespace aos {
 
+Ftrace::Ftrace()
+    : message_fd_(FLAGS_enable_ftrace
+                      ? open("/sys/kernel/debug/tracing/trace_marker", O_WRONLY)
+                      : -1),
+      on_fd_(FLAGS_enable_ftrace
+                 ? open("/sys/kernel/debug/tracing/tracing_on", O_WRONLY)
+                 : -1) {}
+
 Ftrace::~Ftrace() {
   if (message_fd_ != -1) {
     PCHECK(close(message_fd_) == 0);
diff --git a/aos/ftrace.h b/aos/ftrace.h
index 42147ad..3b5326f 100644
--- a/aos/ftrace.h
+++ b/aos/ftrace.h
@@ -17,9 +17,7 @@
 // continue working in that case.
 class Ftrace {
  public:
-  Ftrace()
-      : message_fd_(open("/sys/kernel/debug/tracing/trace_marker", O_WRONLY)),
-        on_fd_(open("/sys/kernel/debug/tracing/tracing_on", O_WRONLY)) {}
+  Ftrace();
   ~Ftrace();
 
   // Writes a message with a printf-style format.
diff --git a/aos/network/web_proxy.cc b/aos/network/web_proxy.cc
index a486b94..3806973 100644
--- a/aos/network/web_proxy.cc
+++ b/aos/network/web_proxy.cc
@@ -17,7 +17,7 @@
 struct list *tmrl_get(void);
 }
 
-DEFINE_int32(proxy_port, 8080, "Port to use for the web proxy server.");
+DEFINE_int32(proxy_port, 1180, "Port to use for the web proxy server.");
 
 namespace aos {
 namespace web_proxy {
@@ -140,7 +140,7 @@
   epoll->BeforeWait([]() {
     const uint64_t to = tmr_next_timeout(tmrl_get());
     if (to != 0) {
-      VLOG(1) << "Next timeout " << to;
+      VLOG(3) << "Next timeout " << to;
     }
     // Note: this only works because we are spinning on it...
     // TODO(austin): If we choose to actually sleep, use a timerfd reserved just
diff --git a/aos/seasocks/BUILD b/aos/seasocks/BUILD
index e9a98c7..7f5d25a 100644
--- a/aos/seasocks/BUILD
+++ b/aos/seasocks/BUILD
@@ -14,7 +14,7 @@
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
-        "//aos/logging",
         "//third_party/seasocks",
+        "@com_github_google_glog//:glog",
     ],
 )
diff --git a/aos/seasocks/seasocks_logger.cc b/aos/seasocks/seasocks_logger.cc
index 53d05e8..3cf3bd9 100644
--- a/aos/seasocks/seasocks_logger.cc
+++ b/aos/seasocks/seasocks_logger.cc
@@ -1,32 +1,35 @@
 #include "aos/seasocks/seasocks_logger.h"
 
-#include "aos/logging/logging.h"
+#include "glog/logging.h"
 #include "seasocks/PrintfLogger.h"
 
 namespace aos {
 namespace seasocks {
 
 void SeasocksLogger::log(::seasocks::Logger::Level level, const char *message) {
-  // Convert Seasocks error codes to AOS.
-  log_level aos_level;
+  // Convert Seasocks error codes to glog.
+  int glog_level;
   switch (level) {
     case ::seasocks::Logger::Level::Info:
-      aos_level = INFO;
+      glog_level = google::INFO;
       break;
     case ::seasocks::Logger::Level::Warning:
-      aos_level = WARNING;
+      glog_level = google::WARNING;
       break;
     case ::seasocks::Logger::Level::Error:
     case ::seasocks::Logger::Level::Severe:
-      aos_level = ERROR;
+      glog_level = google::ERROR;
       break;
     case ::seasocks::Logger::Level::Debug:
     case ::seasocks::Logger::Level::Access:
     default:
-      aos_level = DEBUG;
+      if (!VLOG_IS_ON(1)) {
+        return;
+      }
+      glog_level = google::INFO;
       break;
   }
-  AOS_LOG(aos_level, "Seasocks: %s\n", message);
+  LOG_AT_LEVEL(glog_level) << "Seasocks: " << message;
 }
 
 }  // namespace seasocks
diff --git a/frc971/control_loops/static_zeroing_single_dof_profiled_subsystem.h b/frc971/control_loops/static_zeroing_single_dof_profiled_subsystem.h
index dd64111..c1bfe8c 100644
--- a/frc971/control_loops/static_zeroing_single_dof_profiled_subsystem.h
+++ b/frc971/control_loops/static_zeroing_single_dof_profiled_subsystem.h
@@ -223,11 +223,11 @@
 
         double safe_goal = goal->unsafe_goal();
         if (safe_goal < min_position_) {
-          AOS_LOG(DEBUG, "Limiting to %f from %f\n", min_position_, safe_goal);
+          VLOG(1) << "Limiting to " << min_position_ << " from " << safe_goal;
           safe_goal = min_position_;
         }
         if (safe_goal > max_position_) {
-          AOS_LOG(DEBUG, "Limiting to %f from %f\n", max_position_, safe_goal);
+          VLOG(1) << "Limiting to " << max_position_ << " from " << safe_goal;
           safe_goal = max_position_;
         }
         if (goal->has_ignore_profile()) {
diff --git a/frc971/wpilib/ADIS16448.cc b/frc971/wpilib/ADIS16448.cc
index b479970..c047cf9 100644
--- a/frc971/wpilib/ADIS16448.cc
+++ b/frc971/wpilib/ADIS16448.cc
@@ -137,9 +137,9 @@
 
   // NI's SPI driver defaults to SCHED_OTHER.  Find it's PID with ps, and change
   // it to a RT priority of 33.
-  AOS_PCHECK(system("busybox ps -ef | grep '\\[spi0\\]' | awk '{print $1}' | "
-                    "xargs chrt -f -p "
-                    "33") == 0);
+  PCHECK(system("busybox ps -ef | grep '\\[spi0\\]' | awk '{print $1}' | "
+                "xargs chrt -f -p "
+                "33") == 0);
 
   event_loop->set_name("IMU");
   event_loop_->SetRuntimeRealtimePriority(33);
diff --git a/frc971/wpilib/sensor_reader.cc b/frc971/wpilib/sensor_reader.cc
index 2a40128..f476e71 100644
--- a/frc971/wpilib/sensor_reader.cc
+++ b/frc971/wpilib/sensor_reader.cc
@@ -6,6 +6,7 @@
 
 #include "aos/init.h"
 #include "aos/logging/logging.h"
+#include "aos/realtime.h"
 #include "aos/util/compiler_memory_barrier.h"
 #include "frc971/wpilib/ahal/DigitalInput.h"
 #include "frc971/wpilib/ahal/DriverStation.h"
@@ -27,6 +28,10 @@
   ds_ = &::frc::DriverStation::GetInstance();
 
   event_loop->SetRuntimeRealtimePriority(40);
+  // The timer interrupt fires on CPU1.  Since nothing else is pinned, it will
+  // be cheapest to pin this there so it transitions directly and doesn't
+  // need to ever migrate.
+  event_loop->SetRuntimeAffinity(aos::MakeCpusetFromCpus({1}));
 
   // Fill in the no pwm trigger defaults.
   timer_handler_ = event_loop_->AddTimer([this]() { Loop(); });
diff --git a/frc971/wpilib/wpilib_robot_base.h b/frc971/wpilib/wpilib_robot_base.h
index 33a17bc..bcde100 100644
--- a/frc971/wpilib/wpilib_robot_base.h
+++ b/frc971/wpilib/wpilib_robot_base.h
@@ -54,6 +54,12 @@
     // it. This is in here instead of starter.sh because starter.sh doesn't run
     // with permissions on a roboRIO.
     PCHECK(system("echo 0 > /proc/sys/vm/overcommit_memory") == 0);
+    PCHECK(system("busybox ps -ef | grep '\\[ktimersoftd/0\\]' | awk '{print "
+                  "$1}' | xargs chrt -f -p 70") == 0);
+    PCHECK(system("busybox ps -ef | grep '\\[ktimersoftd/1\\]' | awk '{print "
+                  "$1}' | xargs chrt -f -p 70") == 0);
+    PCHECK(system("busybox ps -ef | grep '\\[irq/54-eth0\\]' | awk '{print "
+                  "$1}' | xargs chrt -f -p 17") == 0);
 
     // Configure throttling so we reserve 5% of the CPU for non-rt work.
     // This makes things significantly more stable when work explodes.
diff --git a/y2014/BUILD b/y2014/BUILD
index d483883..cb718a6 100644
--- a/y2014/BUILD
+++ b/y2014/BUILD
@@ -12,12 +12,12 @@
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
-        "//aos/logging",
         "//aos/network:team_number",
         "//aos/stl_mutex",
         "//frc971:shifter_hall_effect",
         "//frc971/control_loops:state_feedback_loop",
         "//y2014/control_loops/drivetrain:polydrivetrain_plants",
+        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
     ],
 )
diff --git a/y2014/constants.cc b/y2014/constants.cc
index d6a8e5d..70f70fe 100644
--- a/y2014/constants.cc
+++ b/y2014/constants.cc
@@ -10,9 +10,9 @@
 #endif
 
 #include "absl/base/call_once.h"
-#include "aos/logging/logging.h"
 #include "aos/network/team_number.h"
 #include "aos/stl_mutex/stl_mutex.h"
+#include "glog/logging.h"
 #include "y2014/control_loops/drivetrain/drivetrain_dog_motor_plant.h"
 #include "y2014/control_loops/drivetrain/polydrivetrain_dog_motor_plant.h"
 
@@ -223,13 +223,13 @@
       };
       break;
     default:
-      AOS_LOG(FATAL, "unknown team #%" PRIu16 "\n", team);
+      LOG(FATAL) << "unknown team: " << team;
   }
 }
 
 void DoGetValues(const Values **result) {
   uint16_t team = ::aos::network::GetTeamNumber();
-  AOS_LOG(INFO, "creating a Constants for team %" PRIu16 "\n", team);
+  LOG(INFO) << "creating a Constants for team: " << team;
   *result = DoGetValuesForTeam(team);
   return;
 }
diff --git a/y2016/BUILD b/y2016/BUILD
index bf3919d..260a305 100644
--- a/y2016/BUILD
+++ b/y2016/BUILD
@@ -12,13 +12,13 @@
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
-        "//aos/logging",
         "//aos/network:team_number",
         "//aos/stl_mutex",
         "//frc971:constants",
         "//frc971:shifter_hall_effect",
         "//frc971/control_loops:state_feedback_loop",
         "//y2016/control_loops/drivetrain:polydrivetrain_plants",
+        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
     ],
 )
diff --git a/y2016/constants.cc b/y2016/constants.cc
index 363ef26..1ca3ef2 100644
--- a/y2016/constants.cc
+++ b/y2016/constants.cc
@@ -10,9 +10,9 @@
 #endif
 
 #include "absl/base/call_once.h"
-#include "aos/logging/logging.h"
 #include "aos/network/team_number.h"
 #include "aos/stl_mutex/stl_mutex.h"
+#include "glog/logging.h"
 #include "y2016/control_loops/drivetrain/drivetrain_dog_motor_plant.h"
 #include "y2016/control_loops/drivetrain/polydrivetrain_dog_motor_plant.h"
 
@@ -146,13 +146,13 @@
       };
       break;
     default:
-      AOS_LOG(FATAL, "unknown team #%" PRIu16 "\n", team);
+      LOG(FATAL) << "unknown team: " << team;
   }
 }
 
 void DoGetValues(const Values **result) {
   uint16_t team = ::aos::network::GetTeamNumber();
-  AOS_LOG(INFO, "creating a Constants for team %" PRIu16 "\n", team);
+  LOG(INFO) << "creating a Constants for team: " << team;
   *result = DoGetValuesForTeam(team);
   return;
 }
diff --git a/y2017/BUILD b/y2017/BUILD
index 12a585b..df1fd4b 100644
--- a/y2017/BUILD
+++ b/y2017/BUILD
@@ -12,7 +12,6 @@
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
-        "//aos/logging",
         "//aos/network:team_number",
         "//aos/stl_mutex",
         "//frc971:constants",
@@ -22,6 +21,7 @@
         "//y2017/control_loops/superstructure/hood:hood_plants",
         "//y2017/control_loops/superstructure/intake:intake_plants",
         "//y2017/control_loops/superstructure/shooter:shooter_plants",
+        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
     ],
 )
diff --git a/y2017/constants.cc b/y2017/constants.cc
index 654edf8..1594de7 100644
--- a/y2017/constants.cc
+++ b/y2017/constants.cc
@@ -10,9 +10,9 @@
 #endif
 
 #include "absl/base/call_once.h"
-#include "aos/logging/logging.h"
 #include "aos/network/team_number.h"
 #include "aos/stl_mutex/stl_mutex.h"
+#include "glog/logging.h"
 #include "y2017/control_loops/drivetrain/drivetrain_dog_motor_plant.h"
 #include "y2017/control_loops/drivetrain/polydrivetrain_dog_motor_plant.h"
 
@@ -145,7 +145,7 @@
       break;
 
     default:
-      AOS_LOG(FATAL, "unknown team #%" PRIu16 "\n", team);
+      LOG(FATAL) << "unknown team: " << team;
   }
 
   return r;
@@ -153,7 +153,7 @@
 
 void DoGetValues(const Values **result) {
   uint16_t team = ::aos::network::GetTeamNumber();
-  AOS_LOG(INFO, "creating a Constants for team %" PRIu16 "\n", team);
+  LOG(INFO) << "creating a Constants for team: " << team;
   *result = DoGetValuesForTeam(team);
 }
 
diff --git a/y2018/BUILD b/y2018/BUILD
index 0d0cb5d..9c845fd 100644
--- a/y2018/BUILD
+++ b/y2018/BUILD
@@ -54,7 +54,6 @@
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
-        "//aos/logging",
         "//aos/network:team_number",
         "//aos/stl_mutex",
         "//frc971:constants",
@@ -62,6 +61,7 @@
         "//y2018/control_loops/drivetrain:polydrivetrain_plants",
         "//y2018/control_loops/superstructure/arm:dynamics",
         "//y2018/control_loops/superstructure/intake:intake_plants",
+        "@com_github_google_glog//:glog",
     ],
 )
 
diff --git a/y2018/constants.cc b/y2018/constants.cc
index e6951cc..5a180ef 100644
--- a/y2018/constants.cc
+++ b/y2018/constants.cc
@@ -9,9 +9,9 @@
 #include "sanitizer/lsan_interface.h"
 #endif
 
-#include "aos/logging/logging.h"
 #include "aos/network/team_number.h"
 #include "aos/stl_mutex/stl_mutex.h"
+#include "glog/logging.h"
 #include "y2018/control_loops/drivetrain/drivetrain_dog_motor_plant.h"
 #include "y2018/control_loops/drivetrain/polydrivetrain_dog_motor_plant.h"
 
@@ -128,7 +128,7 @@
       break;
 
     default:
-      AOS_LOG(FATAL, "unknown team #%" PRIu16 "\n", team);
+      LOG(FATAL) << "unknown team: " << team;
   }
 
   return r;
@@ -136,7 +136,7 @@
 
 const Values &DoGetValues() {
   const uint16_t team = ::aos::network::GetTeamNumber();
-  AOS_LOG(INFO, "creating a Constants for team %" PRIu16 "\n", team);
+  LOG(INFO) << "creating a Constants for team: " << team;
   return GetValuesForTeam(team);
 }
 
diff --git a/y2019/BUILD b/y2019/BUILD
index b5f42cd..8c250e0 100644
--- a/y2019/BUILD
+++ b/y2019/BUILD
@@ -33,7 +33,6 @@
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
-        "//aos/logging",
         "//aos/network:team_number",
         "//aos/stl_mutex",
         "//frc971:constants",
@@ -46,6 +45,7 @@
         "//y2019/control_loops/superstructure/stilts:stilts_plants",
         "//y2019/control_loops/superstructure/wrist:wrist_plants",
         "//y2019/vision:constants",
+        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
     ],
 )
diff --git a/y2019/constants.cc b/y2019/constants.cc
index f86110c..cc81f53 100644
--- a/y2019/constants.cc
+++ b/y2019/constants.cc
@@ -8,9 +8,9 @@
 #endif
 
 #include "absl/base/call_once.h"
-#include "aos/logging/logging.h"
 #include "aos/network/team_number.h"
 #include "aos/stl_mutex/stl_mutex.h"
+#include "glog/logging.h"
 #include "y2019/control_loops/superstructure/elevator/integral_elevator_plant.h"
 #include "y2019/control_loops/superstructure/intake/integral_intake_plant.h"
 #include "y2019/control_loops/superstructure/stilts/integral_stilts_plant.h"
@@ -224,7 +224,7 @@
       break;
 
     default:
-      AOS_LOG(FATAL, "unknown team #%" PRIu16 "\n", team);
+      LOG(FATAL) << "unknown team: " << team;
   }
 
   return r;
@@ -232,7 +232,7 @@
 
 void DoGetValues(const Values **result) {
   uint16_t team = ::aos::network::GetTeamNumber();
-  AOS_LOG(INFO, "creating a Constants for team %" PRIu16 "\n", team);
+  LOG(INFO) << "creating a Constants for team: " << team;
   *result = DoGetValuesForTeam(team);
 }
 
diff --git a/y2020/BUILD b/y2020/BUILD
index 61987c9..7da0bc7 100644
--- a/y2020/BUILD
+++ b/y2020/BUILD
@@ -63,7 +63,6 @@
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
-        "//aos/logging",
         "//aos/network:team_number",
         "//aos/stl_mutex",
         "//frc971:constants",
@@ -76,6 +75,7 @@
         "//y2020/control_loops/superstructure/hood:hood_plants",
         "//y2020/control_loops/superstructure/intake:intake_plants",
         "//y2020/control_loops/superstructure/turret:turret_plants",
+        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
     ],
 )
diff --git a/y2020/constants.cc b/y2020/constants.cc
index e418831..0b1b50a 100644
--- a/y2020/constants.cc
+++ b/y2020/constants.cc
@@ -8,9 +8,9 @@
 #endif
 
 #include "absl/base/call_once.h"
-#include "aos/logging/logging.h"
 #include "aos/network/team_number.h"
 #include "aos/stl_mutex/stl_mutex.h"
+#include "glog/logging.h"
 #include "y2020/control_loops/superstructure/control_panel/integral_control_panel_plant.h"
 #include "y2020/control_loops/superstructure/hood/integral_hood_plant.h"
 #include "y2020/control_loops/superstructure/intake/integral_intake_plant.h"
@@ -162,7 +162,7 @@
     case Values::kPracticeTeamNumber:
       hood->zeroing_constants.measured_absolute_position = 0.0;
 
-      intake->zeroing_constants.measured_absolute_position = 0.347;
+      intake->zeroing_constants.measured_absolute_position = 0.205469223604347;
 
       turret->potentiometer_offset = 5.3931926228241;
       turret_params->zeroing_constants.measured_absolute_position = 4.22;
@@ -178,7 +178,7 @@
       break;
 
     default:
-      AOS_LOG(FATAL, "unknown team #%" PRIu16 "\n", team);
+      LOG(FATAL) << "unknown team: " << team;
   }
 
   return r;
@@ -188,7 +188,7 @@
 
 void DoGetValues() {
   uint16_t team = ::aos::network::GetTeamNumber();
-  AOS_LOG(INFO, "creating a Constants for team %" PRIu16 "\n", team);
+  LOG(INFO) << "creating a Constants for team: " << team;
   values = DoGetValuesForTeam(team);
 }
 
diff --git a/y2020/constants.h b/y2020/constants.h
index d1689a7..01cd177 100644
--- a/y2020/constants.h
+++ b/y2020/constants.h
@@ -69,9 +69,9 @@
   static constexpr ::frc971::constants::Range kHoodRange() {
     return ::frc971::constants::Range{
         -0.01,  // Back Hard
-        0.65,   // Front Hard
+        0.675,   // Front Hard
         0.00,   // Back Soft
-        0.63    // Front Soft
+        0.67    // Front Soft
     };
   }
 
diff --git a/y2020/control_loops/superstructure/shooter/shooter.cc b/y2020/control_loops/superstructure/shooter/shooter.cc
index 9f4edb2..99854fe 100644
--- a/y2020/control_loops/superstructure/shooter/shooter.cc
+++ b/y2020/control_loops/superstructure/shooter/shooter.cc
@@ -23,12 +23,13 @@
       accelerator_right_(accelerator::MakeIntegralAcceleratorLoop(),
                          accelerator::kBemf, accelerator::kResistance) {}
 
-bool Shooter::UpToSpeed(const ShooterGoal *goal) {
+void Shooter::UpToSpeed(const ShooterGoal *goal) {
   finisher_ready_ =
       (std::abs(goal->velocity_finisher() - finisher_.avg_angular_velocity()) <
            kVelocityToleranceFinisher &&
        std::abs(goal->velocity_finisher() - finisher_.velocity()) <
-           kVelocityToleranceFinisher);
+           kVelocityToleranceFinisher &&
+       goal->velocity_finisher() > kVelocityToleranceFinisher);
   accelerator_ready_ =
       (std::abs(goal->velocity_accelerator() -
                 accelerator_left_.avg_angular_velocity()) <
@@ -39,8 +40,8 @@
        std::abs(goal->velocity_accelerator() - accelerator_left_.velocity()) <
            kVelocityToleranceAccelerator &&
        std::abs(goal->velocity_accelerator() - accelerator_right_.velocity()) <
-           kVelocityToleranceAccelerator);
-  return (finisher_ready_ && accelerator_ready_);
+           kVelocityToleranceAccelerator &&
+       goal->velocity_accelerator() > kVelocityToleranceAccelerator);
 }
 
 flatbuffers::Offset<ShooterStatus> Shooter::RunIteration(
@@ -74,15 +75,7 @@
   accelerator_right_.Update(output == nullptr);
 
   if (goal) {
-    if (UpToSpeed(goal) &&
-        goal->velocity_finisher() > kVelocityToleranceFinisher &&
-        goal->velocity_accelerator() > kVelocityToleranceAccelerator) {
-      ready_ = true;
-    } else {
-      ready_ = false;
-      finisher_ready_ = false;
-      accelerator_ready_ = false;
-    }
+    UpToSpeed(goal);
   }
 
   flatbuffers::Offset<FlywheelControllerStatus> finisher_status_offset =
diff --git a/y2020/control_loops/superstructure/shooter/shooter.h b/y2020/control_loops/superstructure/shooter/shooter.h
index 2520df6..ccbb326 100644
--- a/y2020/control_loops/superstructure/shooter/shooter.h
+++ b/y2020/control_loops/superstructure/shooter/shooter.h
@@ -27,7 +27,7 @@
       flatbuffers::FlatBufferBuilder *fbb, OutputT *output,
       const aos::monotonic_clock::time_point position_timestamp);
 
-  bool ready() const { return ready_; }
+  bool ready() const { return finisher_ready() && accelerator_ready(); }
   bool finisher_ready() const { return finisher_ready_; }
   bool accelerator_ready() const { return accelerator_ready_; }
 
@@ -44,10 +44,9 @@
 
   FlywheelController finisher_, accelerator_left_, accelerator_right_;
 
-  bool UpToSpeed(const ShooterGoal *goal);
+  void UpToSpeed(const ShooterGoal *goal);
   bool finisher_ready_ = false;
   bool accelerator_ready_ = false;
-  bool ready_ = false;
 
   int balls_shot_ = 0;
   bool finisher_goal_changed_ = false;
diff --git a/y2020/control_loops/superstructure/superstructure.cc b/y2020/control_loops/superstructure/superstructure.cc
index d3c2464..ae79e76 100644
--- a/y2020/control_loops/superstructure/superstructure.cc
+++ b/y2020/control_loops/superstructure/superstructure.cc
@@ -2,6 +2,7 @@
 
 #include "aos/containers/sized_array.h"
 #include "aos/events/event_loop.h"
+#include "aos/network/team_number.h"
 
 namespace y2020 {
 namespace control_loops {
@@ -22,7 +23,8 @@
           event_loop->MakeFetcher<frc971::control_loops::drivetrain::Status>(
               "/drivetrain")),
       joystick_state_fetcher_(
-          event_loop->MakeFetcher<aos::JoystickState>("/aos")) {
+          event_loop->MakeFetcher<aos::JoystickState>("/aos")),
+      has_turret_(::aos::network::GetTeamNumber() != 9971) {
   event_loop->SetRuntimeRealtimePriority(30);
 }
 
@@ -199,7 +201,7 @@
   flatbuffers::Offset<flatbuffers::Vector<Subsystem>>
       subsystems_not_ready_offset;
   const bool turret_ready =
-      (std::abs(turret_.goal(0) - turret_.position()) < 0.025);
+      (std::abs(turret_.goal(0) - turret_.position()) < 0.025) || !has_turret_;
   if (unsafe_goal && unsafe_goal->shooting() &&
       (!shooter_.ready() || !turret_ready)) {
     aos::SizedArray<Subsystem, 3> subsystems_not_ready;
@@ -270,7 +272,9 @@
       }
 
       if (unsafe_goal->shooting()) {
-        if (shooter_.ready() && turret_ready) {
+        if ((shooter_.ready() ||
+             (!has_turret_ && shooter_.accelerator_ready())) &&
+            turret_ready) {
           output_struct.feeder_voltage = 12.0;
         }
         output_struct.washing_machine_spinner_voltage = 5.0;
diff --git a/y2020/control_loops/superstructure/superstructure.h b/y2020/control_loops/superstructure/superstructure.h
index 07b7575..7f565cf 100644
--- a/y2020/control_loops/superstructure/superstructure.h
+++ b/y2020/control_loops/superstructure/superstructure.h
@@ -78,6 +78,8 @@
   aos::monotonic_clock::time_point preloading_backpower_timeout_ =
       aos::monotonic_clock::min_time;
 
+  bool has_turret_ = true;
+
   DISALLOW_COPY_AND_ASSIGN(Superstructure);
 };
 
diff --git a/y2020/joystick_reader.cc b/y2020/joystick_reader.cc
index b92126a..b101337 100644
--- a/y2020/joystick_reader.cc
+++ b/y2020/joystick_reader.cc
@@ -42,6 +42,7 @@
 const ButtonLocation kAutoTrack(3, 3);
 const ButtonLocation kAutoNoHood(3, 5);
 const ButtonLocation kHood(3, 2);
+const ButtonLocation kShootSlow(4, 2);
 const ButtonLocation kFixedTurret(3, 1);
 const ButtonLocation kFeed(4, 1);
 const ButtonLocation kFeedDriver(1, 2);
@@ -137,8 +138,6 @@
     }
   }
 
-  bool latched_climbing_ = false;
-
   void HandleTeleop(
       const ::frc971::input::driver_station::Data &data) override {
     superstructure_status_fetcher_.Fetch();
@@ -153,7 +152,7 @@
     double intake_pos = -0.89;
     double turret_pos = 0.0;
     float roller_speed = 0.0f;
-    float roller_speed_compensation = 0.0f;
+    bool roller_speed_compensation = false;
     double accelerator_speed = 0.0;
     double finisher_speed = 0.0;
     double climber_speed = 0.0;
@@ -187,12 +186,15 @@
         accelerator_speed = setpoint_fetcher_->accelerator();
         finisher_speed = setpoint_fetcher_->finisher();
       }
+    } else if (data.IsPressed(kShootSlow)) {
+      accelerator_speed = 150.0;
+      finisher_speed = 200.0;
     }
 
     if (data.IsPressed(kIntakeExtend) || data.IsPressed(kIntakeExtendDriver)) {
-      intake_pos = 1.2;
+      intake_pos = 1.24;
       roller_speed = 7.0f;
-      roller_speed_compensation = 2.0f;
+      roller_speed_compensation = true;
       preload_intake = true;
     }
 
@@ -200,12 +202,12 @@
         superstructure_status_fetcher_->intake()->zeroed() &&
         superstructure_status_fetcher_->intake()->position() > -0.5) {
       roller_speed = std::max(roller_speed, 6.0f);
-      roller_speed_compensation = 2.0f;
+      roller_speed_compensation = true;
     }
 
     if (data.IsPressed(kIntakeIn)) {
-      roller_speed = 6.0f;
-      roller_speed_compensation = 2.0f;
+      roller_speed = 5.0f;
+      roller_speed_compensation = true;
       preload_intake = true;
     } else if (data.IsPressed(kSpit)) {
       roller_speed = -6.0f;
@@ -216,17 +218,31 @@
     }
 
     if (data.IsPressed(kWinch)) {
+      ++winch_counter_;
+    } else {
+      winch_counter_ = 0;
+    }
+
+    if (winch_counter_ > 5 || (winch_counter_ > 0 && latched_climbing_)) {
       climber_speed = 12.0f;
       latched_climbing_ = true;
     }
 
     if (data.IsPressed(kUnWinch)) {
+      ++unwinch_counter_;
+    } else {
+      unwinch_counter_ = 0;
+    }
+
+    if (unwinch_counter_ > 10 || (unwinch_counter_ > 0 && latched_climbing_)) {
       climber_speed = -12.0f;
       latched_climbing_ = true;
     }
 
     if (data.IsPressed(kWinch) && data.IsPressed(kUnWinch)) {
       latched_climbing_ = false;
+      unwinch_counter_ = 0;
+      winch_counter_ = 0;
     }
 
     if (latched_climbing_) {
@@ -276,7 +292,7 @@
       superstructure_goal_builder.add_turret(turret_offset);
       superstructure_goal_builder.add_roller_voltage(roller_speed);
       superstructure_goal_builder.add_roller_speed_compensation(
-          roller_speed_compensation);
+          roller_speed_compensation ? 1.5f : 0.0f);
       superstructure_goal_builder.add_shooter(shooter_offset);
       superstructure_goal_builder.add_shooting(data.IsPressed(kFeed) ||
                                                data.IsPressed(kFeedDriver));
@@ -306,6 +322,11 @@
   ::aos::Fetcher<superstructure::Status> superstructure_status_fetcher_;
 
   ::aos::Fetcher<y2020::joysticks::Setpoint> setpoint_fetcher_;
+
+  bool latched_climbing_ = false;
+
+  size_t winch_counter_ = 0;
+  size_t unwinch_counter_ = 0;
 };
 
 }  // namespace joysticks
diff --git a/y2020/vision/viewer.cc b/y2020/vision/viewer.cc
index 5da2dbe..c141e3c 100644
--- a/y2020/vision/viewer.cc
+++ b/y2020/vision/viewer.cc
@@ -15,6 +15,9 @@
 DEFINE_bool(show_features, true, "Show the SIFT features that matched.");
 DEFINE_string(channel, "/camera", "Channel name for the image.");
 
+DEFINE_string(capture, "",
+              "If set, capture a single image and save it to this filename.");
+
 namespace frc971 {
 namespace vision {
 namespace {
@@ -68,6 +71,11 @@
   cv::Mat rgb_image(cv::Size(image->cols(), image->rows()), CV_8UC3);
   cv::cvtColor(image_color_mat, rgb_image, CV_YUV2BGR_YUYV);
 
+  if (!FLAGS_capture.empty()) {
+    cv::imwrite(FLAGS_capture, rgb_image);
+    return false;
+  }
+
   if (matching_image_found) {
     // Draw whatever matches we have
     if (match->camera_poses() != nullptr && match->camera_poses()->size() > 0) {
@@ -154,6 +162,9 @@
       ::std::chrono::milliseconds(100));
 
   event_loop.Run();
+
+  image_fetcher = aos::Fetcher<CameraImage>();
+  match_fetcher = aos::Fetcher<sift::ImageMatchResult>();
 }
 
 }  // namespace
diff --git a/y2020/y2020_roborio.json b/y2020/y2020_roborio.json
index 3176d41..5417302 100644
--- a/y2020/y2020_roborio.json
+++ b/y2020/y2020_roborio.json
@@ -377,7 +377,7 @@
     {
       "name": "message_bridge_client",
       "executable_name": "message_bridge_client",
-      "args": ["--rt_priority=5"],
+      "args": ["--rt_priority=16"],
       "nodes": [
         "roborio"
       ]
@@ -385,7 +385,7 @@
     {
       "name": "message_bridge_server",
       "executable_name": "message_bridge_server",
-      "args": ["--rt_priority=5"],
+      "args": ["--rt_priority=16"],
       "nodes": [
         "roborio"
       ]
diff --git a/y2021_bot3/BUILD b/y2021_bot3/BUILD
index 949820a..f068dbe 100644
--- a/y2021_bot3/BUILD
+++ b/y2021_bot3/BUILD
@@ -26,13 +26,13 @@
     ],
     visibility = ["//visibility:public"],
     deps = [
-        "//aos/logging",
         "//aos/mutex",
         "//aos/network:team_number",
         "//frc971:constants",
         "//frc971/control_loops:pose",
         "//frc971/control_loops:static_zeroing_single_dof_profiled_subsystem",
         "//y2021_bot3/control_loops/drivetrain:polydrivetrain_plants",
+        "@com_github_google_glog//:glog",
         "@com_google_absl//absl/base",
     ],
 )
diff --git a/y2021_bot3/constants.cc b/y2021_bot3/constants.cc
index 707ecd6..82e3808 100644
--- a/y2021_bot3/constants.cc
+++ b/y2021_bot3/constants.cc
@@ -8,9 +8,9 @@
 #endif
 
 #include "absl/base/call_once.h"
-#include "aos/logging/logging.h"
 #include "aos/mutex/mutex.h"
 #include "aos/network/team_number.h"
+#include "glog/logging.h"
 
 namespace y2021_bot3 {
 namespace constants {
@@ -41,7 +41,7 @@
       break;
 
     default:
-      AOS_LOG(FATAL, "unknown team #%" PRIu16 "\n", team);
+      LOG(FATAL) << "unknown team: " << team;
   }
 
   return r;
@@ -49,7 +49,7 @@
 
 void DoGetValues(const Values **result) {
   uint16_t team = ::aos::network::GetTeamNumber();
-  AOS_LOG(INFO, "creating a Constants for team %" PRIu16 "\n", team);
+  LOG(INFO) << "creating a Constants for team: " << team;
   *result = DoGetValuesForTeam(team);
 }