Merge "Sandbox javascript build further"
diff --git a/.bazelrc b/.bazelrc
index 3a3c729..6642c31 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -100,6 +100,7 @@
 build --strategy=TsProject=sandboxed
 build --strategy=CopyFile=standalone
 build --strategy=CopyDirectory=standalone
+build --strategy=CopyToDirectory=standalone
 
 # Honor the setting of `skipLibCheck` in the tsconfig.json file.
 # https://www.typescriptlang.org/tsconfig#skipLibCheck
@@ -136,8 +137,13 @@
 # NOTE: Explicitly disable -Werror because the `-external/.*` filter does not work
 build --per_file_copt=third_party/.*,external/.*@-Wno-sign-compare,-Wno-cast-align,-Wno-error,-Wno-unused-parameter,-Wno-cast-qual,-Wno-format-nonliteral,-Wno-tautological-type-limit-compare,-Wno-missing-field-initializers,-Wno-unused-function,-Wno-cast-function-type,-Wno-comment,-Wno-typedef-redefinition,-Wno-tautological-unsigned-enum-zero-compare,-Wno-extra,-Wno-type-limits,-Wno-attributes,-Wno-deprecated
 
+# bzlmod breaks our code base right now, deal with this later.
+common --enable_bzlmod=false
+
+# Disable warnings about using directories in Bazel.
+startup --host_jvm_args=-DBAZEL_TRACK_SOURCE_DIRECTORIES=1
+
 # Load a local file that users can use to customize bazel invocations.  This
 # should stay the last line in this file so users can override things when they
 # want.
 try-import %workspace%/.bazelrc.user
-
diff --git a/BUILD b/BUILD
index 219495d..87de71b 100644
--- a/BUILD
+++ b/BUILD
@@ -1,8 +1,8 @@
-load("@bazel_gazelle//:def.bzl", "gazelle")
-load("@aspect_rules_ts//ts:defs.bzl", "ts_config")
-load("@npm//:defs.bzl", "npm_link_all_packages")
 load("@aspect_rules_js//npm:defs.bzl", "npm_link_package")
+load("@aspect_rules_ts//ts:defs.bzl", "ts_config")
+load("@bazel_gazelle//:def.bzl", "gazelle")
 load("@hedron_compile_commands//:refresh_compile_commands.bzl", "refresh_compile_commands")
+load("@npm//:defs.bzl", "npm_link_all_packages")
 
 # Link npm packages
 npm_link_all_packages(name = "node_modules")
diff --git a/WORKSPACE b/WORKSPACE
index 42756e2..371829f 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -11,9 +11,11 @@
 
 http_archive(
     name = "platforms",
-    sha256 = "2c8d8347427e6bb0ba7cf9f933c08fe2be2b62ff2454546ad852f7bf267aad87",
-    strip_prefix = "platforms-e658a6af526089406d0057160542597501ba65d7",
-    url = "https://github.com/bazelbuild/platforms/archive/e658a6af526089406d0057160542597501ba65d7.zip",
+    sha256 = "218efe8ee736d26a3572663b374a253c012b716d8af0c07e842e82f238a0a7ee",
+    urls = [
+        "https://mirror.bazel.build/github.com/bazelbuild/platforms/releases/download/0.0.10/platforms-0.0.10.tar.gz",
+        "https://github.com/bazelbuild/platforms/releases/download/0.0.10/platforms-0.0.10.tar.gz",
+    ],
 )
 
 http_archive(
@@ -31,9 +33,9 @@
 
 http_archive(
     name = "aspect_bazel_lib",
-    sha256 = "979667bb7276ee8fcf2c114c9be9932b9a3052a64a647e0dcaacfb9c0016f0a3",
-    strip_prefix = "bazel-lib-2.4.1",
-    url = "https://github.com/aspect-build/bazel-lib/releases/download/v2.4.1/bazel-lib-v2.4.1.tar.gz",
+    sha256 = "a8a92645e7298bbf538aa880131c6adb4cf6239bbd27230f077a00414d58e4ce",
+    strip_prefix = "bazel-lib-2.7.2",
+    url = "https://github.com/aspect-build/bazel-lib/releases/download/v2.7.2/bazel-lib-v2.7.2.tar.gz",
 )
 
 load("@aspect_bazel_lib//lib:repositories.bzl", "aspect_bazel_lib_dependencies", "aspect_bazel_lib_register_toolchains", "register_jq_toolchains")
@@ -117,64 +119,20 @@
     apache2_debs = "files",
 )
 load(
-    "//debian:postgresql_amd64.bzl",
-    postgresql_amd64_debs = "files",
-)
-load(
-    "//debian:patch.bzl",
-    patch_debs = "files",
-)
-load(
-    "//debian:rsync.bzl",
-    rsync_debs = "files",
-)
-load(
-    "//debian:ssh.bzl",
-    ssh_debs = "files",
-)
-load(
-    "//debian:pandoc.bzl",
-    pandoc_debs = "files",
-)
-load(
-    "//debian:libusb.bzl",
-    libusb_debs = "files",
-)
-load(
-    "//debian:mingw_compiler.bzl",
-    mingw_compiler_debs = "files",
-)
-load(
-    "//debian:patchelf.bzl",
-    patchelf_debs = "files",
-)
-load(
     "//debian:arm_frc_gnueabi_deps.bzl",
     arm_frc_gnueabi_deps_debs = "files",
 )
 load(
-    "//debian:gtk_runtime.bzl",
-    gtk_runtime_debs = "files",
-)
-load(
-    "//debian:opencv_amd64.bzl",
-    opencv_amd64_debs = "files",
+    "//debian:clang_amd64.bzl",
+    clang_amd64_debs = "files",
 )
 load(
     "//debian:gstreamer_amd64.bzl",
     gstreamer_amd64_debs = "files",
 )
 load(
-    "//debian:m4.bzl",
-    m4_debs = "files",
-)
-load(
-    "//debian:lzma_amd64.bzl",
-    lzma_amd64_debs = "files",
-)
-load(
-    "//debian:lzma_arm64.bzl",
-    lzma_arm64_debs = "files",
+    "//debian:gtk_runtime.bzl",
+    gtk_runtime_debs = "files",
 )
 load(
     "//debian:libtinfo5_amd64.bzl",
@@ -185,14 +143,58 @@
     libtinfo5_arm64_debs = "files",
 )
 load(
+    "//debian:libusb.bzl",
+    libusb_debs = "files",
+)
+load(
+    "//debian:lzma_amd64.bzl",
+    lzma_amd64_debs = "files",
+)
+load(
+    "//debian:lzma_arm64.bzl",
+    lzma_arm64_debs = "files",
+)
+load(
+    "//debian:m4.bzl",
+    m4_debs = "files",
+)
+load(
+    "//debian:mingw_compiler.bzl",
+    mingw_compiler_debs = "files",
+)
+load(
+    "//debian:opencv_amd64.bzl",
+    opencv_amd64_debs = "files",
+)
+load("//debian:packages.bzl", "generate_repositories_for_debs")
+load(
+    "//debian:pandoc.bzl",
+    pandoc_debs = "files",
+)
+load(
+    "//debian:patch.bzl",
+    patch_debs = "files",
+)
+load(
+    "//debian:patchelf.bzl",
+    patchelf_debs = "files",
+)
+load(
+    "//debian:postgresql_amd64.bzl",
+    postgresql_amd64_debs = "files",
+)
+load(
+    "//debian:rsync.bzl",
+    rsync_debs = "files",
+)
+load(
+    "//debian:ssh.bzl",
+    ssh_debs = "files",
+)
+load(
     "//debian:xvfb_amd64.bzl",
     xvfb_amd64_debs = "files",
 )
-load(
-    "//debian:clang_amd64.bzl",
-    clang_amd64_debs = "files",
-)
-load("//debian:packages.bzl", "generate_repositories_for_debs")
 
 generate_repositories_for_debs(rsync_debs)
 
@@ -379,9 +381,9 @@
     name = "com_google_absl",
     patch_args = ["-p1"],
     patches = ["//third_party/abseil:abseil.patch"],
-    sha256 = "ea1d31db00eb37e607bfda17ffac09064670ddf05da067944c4766f517876390",
-    strip_prefix = "abseil-cpp-c2435f8342c2d0ed8101cb43adfd605fdc52dca2",
-    url = "https://github.com/abseil/abseil-cpp/archive/c2435f8342c2d0ed8101cb43adfd605fdc52dca2.zip",
+    sha256 = "733726b8c3a6d39a4120d7e45ea8b41a434cdacde401cba500f14236c49b39dc",
+    strip_prefix = "abseil-cpp-20240116.2",
+    url = "https://github.com/abseil/abseil-cpp/archive/refs/tags/20240116.2.tar.gz",
 )
 
 local_repository(
@@ -869,9 +871,15 @@
 
 http_archive(
     name = "aspect_rules_js",
-    sha256 = "630a71aba66c4023a5b16ab3efafaeed8b1a2865ccd168a34611eb73876b3fc4",
-    strip_prefix = "rules_js-1.37.1",
-    url = "https://github.com/aspect-build/rules_js/releases/download/v1.37.1/rules_js-v1.37.1.tar.gz",
+    patch_args = [
+        "-p1",
+    ],
+    patches = [
+        "//third_party:rules_js/0001-Fix-package-permissions.patch",
+    ],
+    sha256 = "bc9b4a01ef8eb050d8a7a050eedde8ffb1e45a56b0e4094e26f06c17d5fcf1d5",
+    strip_prefix = "rules_js-1.41.2",
+    url = "https://github.com/aspect-build/rules_js/releases/download/v1.41.2/rules_js-v1.41.2.tar.gz",
 )
 
 load("@aspect_rules_js//js:repositories.bzl", "rules_js_dependencies")
@@ -1319,10 +1327,10 @@
     patches = [
         "@//third_party:rules_go/0001-Disable-warnings-for-external-repositories.patch",
     ],
-    sha256 = "dd926a88a564a9246713a9c00b35315f54cbd46b31a26d5d8fb264c07045f05d",
+    sha256 = "af47f30e9cbd70ae34e49866e201b3f77069abb111183f2c0297e7e74ba6bbc0",
     urls = [
-        "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.38.1/rules_go-v0.38.1.zip",
-        "https://github.com/bazelbuild/rules_go/releases/download/v0.38.1/rules_go-v0.38.1.zip",
+        "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.47.0/rules_go-v0.47.0.zip",
+        "https://github.com/bazelbuild/rules_go/releases/download/v0.47.0/rules_go-v0.47.0.zip",
     ],
 )
 
@@ -1334,10 +1342,10 @@
     patches = [
         "@//third_party:bazel-gazelle/0001-Fix-visibility-of-gazelle-runner.patch",
     ],
-    sha256 = "ecba0f04f96b4960a5b250c8e8eeec42281035970aa8852dda73098274d14a1d",
+    sha256 = "75df288c4b31c81eb50f51e2e14f4763cb7548daae126817247064637fd9ea62",
     urls = [
-        "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz",
-        "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz",
+        "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.36.0/bazel-gazelle-v0.36.0.tar.gz",
+        "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.36.0/bazel-gazelle-v0.36.0.tar.gz",
     ],
 )
 
@@ -1360,18 +1368,18 @@
 
 http_archive(
     name = "com_google_protobuf",
-    sha256 = "ace0abf35274ee0f08d5564635505ed55a0bc346a6534413d3c5b040fc926332",
-    strip_prefix = "protobuf-24.3",
-    url = "https://github.com/protocolbuffers/protobuf/archive/refs/tags/v24.3.zip",
+    sha256 = "4fc5ff1b2c339fb86cd3a25f0b5311478ab081e65ad258c6789359cd84d421f8",
+    strip_prefix = "protobuf-26.1",
+    url = "https://github.com/protocolbuffers/protobuf/archive/refs/tags/v26.1.tar.gz",
 )
 
 http_archive(
     name = "com_github_grpc_grpc",
     patch_args = ["-p1"],
     patches = ["//debian:grpc.patch"],
-    sha256 = "a3a65f0129c4922c5d7f4c11dcd40083a12ca54076fd3a927bcd63c53b7e44a5",
-    strip_prefix = "grpc-1.59.2",
-    url = "https://github.com/grpc/grpc/archive/refs/tags/v1.59.2.tar.gz",
+    sha256 = "493d9905aa09124c2f44268b66205dd013f3925a7e82995f36745974e97af609",
+    strip_prefix = "grpc-1.63.0",
+    url = "https://github.com/grpc/grpc/archive/refs/tags/v1.63.0.tar.gz",
 )
 
 load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
@@ -1472,17 +1480,15 @@
 )
 
 # This one is tricky to get an archive because it has recursive submodules. These semi-automated steps do work though:
-# git clone -b 1.10.34 --recurse-submodules --depth=1 https://github.com/aws/aws-sdk-cpp
+# git clone -b 1.11.321 --recurse-submodules --depth=1 https://github.com/aws/aws-sdk-cpp
 # cd aws-sdk-cpp
 # echo bsdtar -a -cf aws_sdk-version.tar.gz --ignore-zeros @\<\(git archive HEAD\) $(git submodule foreach --recursive --quiet 'echo @\<\(cd $displaypath \&\& git archive HEAD --prefix=$displaypath/\)')
 # Now run the command that printed, and the output will be at aws_sdk-version.tar.gz.
 http_archive(
     name = "aws_sdk",
     build_file = "//debian:aws_sdk.BUILD",
-    patch_args = ["-p1"],
-    patches = ["//debian:aws_sdk.patch"],
-    sha256 = "de6570d10c246189fd8c02100f7f0d9af8499a3ef94a131eeb85619f3bd6c604",
-    url = "https://software.frc971.org/Build-Dependencies/aws_sdk-1.10.34.tar.gz",
+    sha256 = "08856b91139d209f7423e60dd8f74a14ab6d053ca40088fcb42fd02484003e95",
+    url = "https://software.frc971.org/Build-Dependencies/aws_sdk-1.11.321.tar.gz",
 )
 
 # Source code of LZ4 (files under lib/) are under BSD 2-Clause.
diff --git a/aos/BUILD b/aos/BUILD
index 1f2d975..e67b593 100644
--- a/aos/BUILD
+++ b/aos/BUILD
@@ -1,7 +1,7 @@
 load("@com_github_google_flatbuffers//:build_defs.bzl", "flatbuffer_cc_library", "flatbuffer_py_library")
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 load("//aos:flatbuffers.bzl", "cc_static_flatbuffer")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//tools/build_rules:autocxx.bzl", "autocxx_library")
 load("//tools/rust:defs.bzl", "flatbuffer_rust_library", "rust_library")
 
diff --git a/aos/actions/BUILD b/aos/actions/BUILD
index 2127547..9f88d89 100644
--- a/aos/actions/BUILD
+++ b/aos/actions/BUILD
@@ -1,5 +1,5 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//aos:config.bzl", "aos_config")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 
 package(default_visibility = ["//visibility:public"])
 
diff --git a/aos/analysis/BUILD b/aos/analysis/BUILD
index 63f2d57..1e3b2fa 100644
--- a/aos/analysis/BUILD
+++ b/aos/analysis/BUILD
@@ -1,7 +1,7 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
-load("//tools/build_rules:js.bzl", "ts_project")
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 load("//aos:config.bzl", "aos_config")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
+load("//tools/build_rules:js.bzl", "ts_project")
 
 package(default_visibility = ["//visibility:public"])
 
diff --git a/aos/events/BUILD b/aos/events/BUILD
index e82fdde..e500417 100644
--- a/aos/events/BUILD
+++ b/aos/events/BUILD
@@ -1,7 +1,7 @@
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
-load("//aos:flatbuffers.bzl", "cc_static_flatbuffer")
 load("//aos:config.bzl", "aos_config")
+load("//aos:flatbuffers.bzl", "cc_static_flatbuffer")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//tools/build_rules:autocxx.bzl", "autocxx_library")
 load("//tools/rust:defs.bzl", "flatbuffer_rust_library", "rust_binary", "rust_library", "rust_test")
 
diff --git a/aos/events/logging/BUILD b/aos/events/logging/BUILD
index c914d1d..a8979ee 100644
--- a/aos/events/logging/BUILD
+++ b/aos/events/logging/BUILD
@@ -1,6 +1,6 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//aos:config.bzl", "aos_config")
 load("//aos:flatbuffers.bzl", "cc_static_flatbuffer")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 
 static_flatbuffer(
     name = "logger_fbs",
@@ -201,9 +201,9 @@
         "@com_google_absl//absl/types:span",
     ] + select({
         "//tools:cpu_k8": [
+            ":lzma_encoder",
             ":s3_fetcher",
             ":s3_file_operations",
-            ":lzma_encoder",
         ],
         "//tools:cpu_arm64": [":lzma_encoder"],
         "//conditions:default": [],
diff --git a/aos/flatbuffers/generate.bzl b/aos/flatbuffers/generate.bzl
index 288b281..52627bc 100644
--- a/aos/flatbuffers/generate.bzl
+++ b/aos/flatbuffers/generate.bzl
@@ -1,5 +1,5 @@
-load("@com_github_google_flatbuffers//:build_defs.bzl", "flatbuffer_cc_library")
 load("@aspect_bazel_lib//lib:run_binary.bzl", "run_binary")
+load("@com_github_google_flatbuffers//:build_defs.bzl", "flatbuffer_cc_library")
 
 def static_flatbuffer(name, visibility = None, deps = [], srcs = [], **kwargs):
     """Generates the code for the static C++ flatbuffer API for the specified fbs file.
diff --git a/aos/logging/BUILD b/aos/logging/BUILD
index 9bd4807..5f56a50 100644
--- a/aos/logging/BUILD
+++ b/aos/logging/BUILD
@@ -1,5 +1,5 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//aos:flatbuffers.bzl", "cc_static_flatbuffer")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 
 # The primary client logging interface.
 cc_library(
diff --git a/aos/network/BUILD b/aos/network/BUILD
index cd31731..db62286 100644
--- a/aos/network/BUILD
+++ b/aos/network/BUILD
@@ -1,12 +1,12 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
-load("//aos/seasocks:gen_embedded.bzl", "gen_embedded")
-load("//aos:config.bzl", "aos_config")
-load("//aos:flatbuffers.bzl", "cc_static_flatbuffer")
 load("@com_github_google_flatbuffers//:build_defs.bzl", "flatbuffer_cc_library")
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 load("@com_github_grpc_grpc//bazel:cc_grpc_library.bzl", "cc_grpc_library")
 load("@rules_cc//cc:defs.bzl", "cc_proto_library")
 load("@rules_proto//proto:defs.bzl", "proto_library")
+load("//aos:config.bzl", "aos_config")
+load("//aos:flatbuffers.bzl", "cc_static_flatbuffer")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
+load("//aos/seasocks:gen_embedded.bzl", "gen_embedded")
 
 package(default_visibility = ["//visibility:public"])
 
diff --git a/aos/network/www/BUILD b/aos/network/www/BUILD
index 8cccfa6..4f21778 100644
--- a/aos/network/www/BUILD
+++ b/aos/network/www/BUILD
@@ -1,5 +1,5 @@
-load("//tools/build_rules:js.bzl", "rollup_bundle", "ts_project")
 load("//aos:config.bzl", "aos_config")
+load("//tools/build_rules:js.bzl", "rollup_bundle", "ts_project")
 
 exports_files(["styles.css"])
 
diff --git a/aos/starter/BUILD b/aos/starter/BUILD
index 0ebe0f5..9d359d4 100644
--- a/aos/starter/BUILD
+++ b/aos/starter/BUILD
@@ -1,6 +1,6 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
-load("//aos:config.bzl", "aos_config")
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
+load("//aos:config.bzl", "aos_config")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 
 exports_files(["roborio_irq_config.json"])
 
diff --git a/aos/util/BUILD b/aos/util/BUILD
index 206bd8f..fa73d5e 100644
--- a/aos/util/BUILD
+++ b/aos/util/BUILD
@@ -1,7 +1,7 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
-load("//aos:flatbuffers.bzl", "cc_static_flatbuffer")
-load("config_validator_macro.bzl", "config_validator_test")
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
+load("//aos:flatbuffers.bzl", "cc_static_flatbuffer")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
+load("config_validator_macro.bzl", "config_validator_test")
 
 package(default_visibility = ["//visibility:public"])
 
diff --git a/build_tests/BUILD b/build_tests/BUILD
index 282365e..1eaf737 100644
--- a/build_tests/BUILD
+++ b/build_tests/BUILD
@@ -1,11 +1,11 @@
-load("//tools/build_rules:js.bzl", "ts_project")
-load("@rules_cc//cc:defs.bzl", "cc_proto_library")
-load("@rules_proto//proto:defs.bzl", "proto_library")
 load("@com_github_google_flatbuffers//:build_defs.bzl", "flatbuffer_go_library", "flatbuffer_py_library")
 load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
-load("//tools/build_rules:apache.bzl", "apache_wrapper")
+load("@rules_cc//cc:defs.bzl", "cc_proto_library")
+load("@rules_proto//proto:defs.bzl", "proto_library")
 load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_library")
+load("//tools/build_rules:apache.bzl", "apache_wrapper")
 load("//tools/build_rules:autocxx.bzl", "autocxx_library")
+load("//tools/build_rules:js.bzl", "ts_project")
 
 cc_test(
     name = "gflags_build_test",
diff --git a/debian/BUILD b/debian/BUILD
index a7b3b97..3aa05a3 100644
--- a/debian/BUILD
+++ b/debian/BUILD
@@ -3,60 +3,20 @@
     apache2_debs = "files",
 )
 load(
-    ":postgresql_amd64.bzl",
-    postgresql_amd64_debs = "files",
-)
-load(
-    ":patch.bzl",
-    patch_debs = "files",
-)
-load(
-    ":rsync.bzl",
-    rsync_debs = "files",
-)
-load(
-    ":ssh.bzl",
-    ssh_debs = "files",
-)
-load(
-    ":pandoc.bzl",
-    pandoc_debs = "files",
-)
-load(
-    ":libusb.bzl",
-    libusb_debs = "files",
-)
-load(
-    ":mingw_compiler.bzl",
-    mingw_compiler_debs = "files",
-)
-load(
-    ":patchelf.bzl",
-    patchelf_debs = "files",
-)
-load(
     ":arm_frc_gnueabi_deps.bzl",
     arm_frc_gnueabi_deps_debs = "files",
 )
 load(
-    ":gtk_runtime.bzl",
-    gtk_runtime_debs = "files",
-)
-load(
-    ":opencv_amd64.bzl",
-    opencv_amd64_debs = "files",
+    ":clang_amd64.bzl",
+    clang_amd64_debs = "files",
 )
 load(
     ":gstreamer_amd64.bzl",
     gstreamer_amd64_debs = "files",
 )
 load(
-    ":lzma_amd64.bzl",
-    lzma_amd64_debs = "files",
-)
-load(
-    ":lzma_arm64.bzl",
-    lzma_arm64_debs = "files",
+    ":gtk_runtime.bzl",
+    gtk_runtime_debs = "files",
 )
 load(
     ":libtinfo5_amd64.bzl",
@@ -67,14 +27,54 @@
     libtinfo5_arm64_debs = "files",
 )
 load(
+    ":libusb.bzl",
+    libusb_debs = "files",
+)
+load(
+    ":lzma_amd64.bzl",
+    lzma_amd64_debs = "files",
+)
+load(
+    ":lzma_arm64.bzl",
+    lzma_arm64_debs = "files",
+)
+load(
+    ":mingw_compiler.bzl",
+    mingw_compiler_debs = "files",
+)
+load(
+    ":opencv_amd64.bzl",
+    opencv_amd64_debs = "files",
+)
+load(":packages.bzl", "download_packages", "generate_deb_tarball")
+load(
+    ":pandoc.bzl",
+    pandoc_debs = "files",
+)
+load(
+    ":patch.bzl",
+    patch_debs = "files",
+)
+load(
+    ":patchelf.bzl",
+    patchelf_debs = "files",
+)
+load(
+    ":postgresql_amd64.bzl",
+    postgresql_amd64_debs = "files",
+)
+load(
+    ":rsync.bzl",
+    rsync_debs = "files",
+)
+load(
+    ":ssh.bzl",
+    ssh_debs = "files",
+)
+load(
     ":xvfb_amd64.bzl",
     xvfb_amd64_debs = "files",
 )
-load(
-    ":clang_amd64.bzl",
-    clang_amd64_debs = "files",
-)
-load(":packages.bzl", "download_packages", "generate_deb_tarball")
 
 package(default_visibility = ["//visibility:public"])
 
diff --git a/debian/aws_sdk.BUILD b/debian/aws_sdk.BUILD
index 46ac375..b5b2619 100644
--- a/debian/aws_sdk.BUILD
+++ b/debian/aws_sdk.BUILD
@@ -1,10 +1,18 @@
 load("@org_frc971//tools/build_rules:select.bzl", "compiler_select")
 
+common_copts = [
+    "-DPLATFORM_LINUX",
+    "-DINTEL_NO_ITTNOTIFY_API",
+    "-Wno-cast-align",
+    "-Wno-cast-qual",
+]
+
 cc_library(
     name = "s3",
-    srcs = glob(["aws-cpp-sdk-s3/source/**/*.cpp"]),
-    hdrs = glob(["aws-cpp-sdk-s3/include/**/*.h"]),
-    includes = ["aws-cpp-sdk-s3/include"],
+    srcs = glob(["generated/src/aws-cpp-sdk-s3/source/**/*.cpp"]),
+    hdrs = glob(["generated/src/aws-cpp-sdk-s3/include/**/*.h"]),
+    copts = common_copts,
+    includes = ["generated/src/aws-cpp-sdk-s3/include"],
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
@@ -15,7 +23,7 @@
 
 genrule(
     name = "gen_SDKConfig",
-    outs = ["aws-cpp-sdk-core/include/aws/core/SDKConfig.h"],
+    outs = ["src/aws-cpp-sdk-core/include/aws/core/SDKConfig.h"],
     cmd = "echo '#undef USE_AWS_MEMORY_MANAGEMENT' > $@",
     target_compatible_with = ["@platforms//os:linux"],
 )
@@ -23,43 +31,41 @@
 cc_library(
     name = "core",
     srcs = glob(
-        include = ["aws-cpp-sdk-core/source/**/*.cpp"],
+        include = ["src/aws-cpp-sdk-core/source/**/*.cpp"],
         exclude = [
-            "aws-cpp-sdk-core/source/utils/crypto/*/*.cpp",
-            "aws-cpp-sdk-core/source/platform/**/*.cpp",
-            "aws-cpp-sdk-core/source/platform/windows/**/*.cpp",
+            "src/aws-cpp-sdk-core/source/utils/crypto/*/*.cpp",
+            "src/aws-cpp-sdk-core/source/platform/**/*.cpp",
+            "src/aws-cpp-sdk-core/source/platform/windows/**/*.cpp",
             # net/*.cpp is for not-(linux or windows), so exclude everything in there.
-            "aws-cpp-sdk-core/source/net/**/*.cpp",
-            "aws-cpp-sdk-core/source/http/windows/**/*.cpp",
+            "src/aws-cpp-sdk-core/source/net/**/*.cpp",
+            "src/aws-cpp-sdk-core/source/http/windows/**/*.cpp",
         ],
     ) + glob([
-        "aws-cpp-sdk-core/source/utils/crypto/openssl/*.cpp",
-        "aws-cpp-sdk-core/source/utils/crypto/factory/*.cpp",
-        "aws-cpp-sdk-core/source/platform/linux-shared/**/*.cpp",
-        "aws-cpp-sdk-core/source/net/linux-shared/*.cpp",
+        "src/aws-cpp-sdk-core/source/utils/crypto/openssl/*.cpp",
+        "src/aws-cpp-sdk-core/source/utils/crypto/factory/*.cpp",
+        "src/aws-cpp-sdk-core/source/platform/linux-shared/**/*.cpp",
+        "src/aws-cpp-sdk-core/source/net/linux-shared/*.cpp",
     ]) + [
         ":gen_SDKConfig",
     ],
     hdrs = glob(
-        include = ["aws-cpp-sdk-core/include/**/*.h"],
+        include = ["src/aws-cpp-sdk-core/include/**/*.h"],
         exclude = [
-            "aws-cpp-sdk-core/include/aws/core/utils/crypto/*/*.h",
-            "aws-cpp-sdk-core/include/aws/core/http/windows/**/*.h",
+            "src/aws-cpp-sdk-core/include/aws/core/utils/crypto/*/*.h",
+            "src/aws-cpp-sdk-core/include/aws/core/http/windows/**/*.h",
         ],
     ) + glob([
-        "aws-cpp-sdk-core/include/aws/core/utils/crypto/openssl/*.h",
+        "src/aws-cpp-sdk-core/include/aws/core/utils/crypto/openssl/*.h",
     ]),
-    copts = [
+    copts = common_copts + [
         "-DAWS_SDK_VERSION_MAJOR=10",
         "-DAWS_SDK_VERSION_MINOR=34",
         "-DAWS_SDK_VERSION_PATCH=\"\\\"BRT\"\\\"",
         "-DENABLE_OPENSSL_ENCRYPTION",
         "-DENABLE_CURL_CLIENT",
-        "-Wno-cast-align",
-        "-Wno-cast-qual",
         "-Wno-format-nonliteral",
     ],
-    includes = ["aws-cpp-sdk-core/include"],
+    includes = ["src/aws-cpp-sdk-core/include"],
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
@@ -69,13 +75,22 @@
         ":crt",
         "@boringssl//:crypto",
         "@com_github_curl_curl//:curl",
+        "@io_opentelemetry_cpp//api",
+        "@io_opentelemetry_cpp//exporters/ostream:ostream_metric_exporter",
+        "@io_opentelemetry_cpp//exporters/ostream:ostream_span_exporter",
+        "@io_opentelemetry_cpp//sdk:headers",
     ],
 )
 
 genrule(
     name = "gen_Config",
     outs = ["crt/aws-crt-cpp/include/aws/crt/Config.h"],
-    cmd = "echo '#define AWS_CRT_CPP_VERSION \"1.10.34\"' > $@",
+    cmd = "; ".join([
+        "echo '#define AWS_CRT_CPP_VERSION \"1.11.321\"' > $@",
+        "echo '#define AWS_CRT_CPP_VERSION_MAJOR 1' >> $@",
+        "echo '#define AWS_CRT_CPP_VERSION_MINOR 11' >> $@",
+        "echo '#define AWS_CRT_CPP_VERSION_PATCH 321' >> $@",
+    ]),
     target_compatible_with = ["@platforms//os:linux"],
 )
 
@@ -85,9 +100,8 @@
     hdrs = glob(["crt/aws-crt-cpp/include/**/*.h"]) + [
         ":gen_Config",
     ],
-    copts = [
+    copts = common_copts + [
         "-Wno-sign-compare",
-        "-Wno-cast-qual",
         "-Wno-tautological-type-limit-compare",
         "-Wno-missing-field-initializers",
     ],
@@ -123,6 +137,7 @@
     name = "aws-c-common",
     srcs = glob([
         "crt/aws-crt-cpp/crt/aws-c-common/source/*.c",
+        "crt/aws-crt-cpp/crt/aws-c-common/source/linux/*.c",
         "crt/aws-crt-cpp/crt/aws-c-common/source/external/*.c",
         "crt/aws-crt-cpp/crt/aws-c-common/source/posix/*.c",
     ]) + [
@@ -147,10 +162,8 @@
         ]),
         "//conditions:default": [],
     }),
-    hdrs = glob(["crt/aws-crt-cpp/crt/aws-c-common/include/**/*.h"]),
-    copts = [
-        "-Wno-cast-align",
-        "-Wno-cast-qual",
+    hdrs = glob(["crt/aws-crt-cpp/crt/aws-c-common/include/**/*.h"]) + ["crt/aws-crt-cpp/crt/aws-c-common/source/external/cJSON.h"],
+    copts = common_copts + [
         "-Wno-sign-compare",
         "-Wno-format-nonliteral",
     ] + compiler_select({
@@ -159,7 +172,10 @@
             "-Wno-old-style-declaration",
         ],
     }),
-    includes = ["crt/aws-crt-cpp/crt/aws-c-common/include"],
+    includes = [
+        "crt/aws-crt-cpp/crt/aws-c-common/include",
+        "crt/aws-crt-cpp/crt/aws-c-common/source",
+    ],
     target_compatible_with = ["@platforms//os:linux"],
     textual_hdrs = glob(["crt/aws-crt-cpp/crt/aws-c-common/include/**/*.inl"]),
     visibility = ["//visibility:public"],
@@ -175,10 +191,7 @@
         "//conditions:default": [],
     }),
     hdrs = glob(["crt/aws-crt-cpp/crt/aws-c-event-stream/include/**/*.h"]),
-    copts = [
-        "-Wno-cast-align",
-        "-Wno-cast-qual",
-    ],
+    copts = common_copts,
     includes = ["crt/aws-crt-cpp/crt/aws-c-event-stream/include"],
     deps = [
         ":aws-c-common",
@@ -196,9 +209,7 @@
         "//conditions:default": [],
     }),
     hdrs = glob(["crt/aws-crt-cpp/crt/aws-checksums/include/**/*.h"]),
-    copts = [
-        "-Wno-cast-qual",
-        "-Wno-cast-align",
+    copts = common_copts + [
         "-Wno-implicit-function-declaration",
     ],
     includes = ["crt/aws-crt-cpp/crt/aws-checksums/include"],
@@ -215,13 +226,11 @@
         "crt/aws-crt-cpp/crt/aws-c-cal/source/unix/*.c",
     ]),
     hdrs = glob(["crt/aws-crt-cpp/crt/aws-c-cal/include/**/*.h"]),
-    copts = [
-        "-DOPENSSL_IS_AWSLC",
+    copts = common_copts + [
+        #"-DOPENSSL_IS_AWSLC",
         "-Wno-incompatible-pointer-types",
         "-Wno-unused-function",
         "-Wno-unused-parameter",
-        "-Wno-cast-align",
-        "-Wno-cast-qual",
     ],
     includes = ["crt/aws-crt-cpp/crt/aws-c-cal/include"],
     target_compatible_with = ["@platforms//os:linux"],
@@ -235,10 +244,7 @@
     name = "aws-c-s3",
     srcs = glob(["crt/aws-crt-cpp/crt/aws-c-s3/source/**/*.c"]),
     hdrs = glob(["crt/aws-crt-cpp/crt/aws-c-s3/include/**/*.h"]),
-    copts = [
-        "-Wno-cast-align",
-        "-Wno-cast-qual",
-    ],
+    copts = common_copts,
     includes = ["crt/aws-crt-cpp/crt/aws-c-s3/include"],
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
@@ -252,7 +258,7 @@
     name = "aws-c-compression",
     srcs = glob(["crt/aws-crt-cpp/crt/aws-c-compression/source/*.c"]),
     hdrs = glob(["crt/aws-crt-cpp/crt/aws-c-compression/include/**/*.h"]),
-    copts = ["-Wno-cast-qual"],
+    copts = common_copts,
     includes = ["crt/aws-crt-cpp/crt/aws-c-compression/include"],
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
@@ -264,10 +270,8 @@
     name = "aws-c-http",
     srcs = glob(["crt/aws-crt-cpp/crt/aws-c-http/source/**/*.c"]),
     hdrs = glob(["crt/aws-crt-cpp/crt/aws-c-http/include/**/*.h"]),
-    copts = [
+    copts = common_copts + [
         "-Wno-unused-but-set-variable",
-        "-Wno-cast-align",
-        "-Wno-cast-qual",
     ],
     includes = ["crt/aws-crt-cpp/crt/aws-c-http/include"],
     target_compatible_with = ["@platforms//os:linux"],
@@ -283,10 +287,7 @@
     name = "aws-c-sdkutils",
     srcs = glob(["crt/aws-crt-cpp/crt/aws-c-sdkutils/source/**/*.c"]),
     hdrs = glob(["crt/aws-crt-cpp/crt/aws-c-sdkutils/include/**/*.h"]),
-    copts = [
-        "-Wno-cast-align",
-        "-Wno-cast-qual",
-    ],
+    copts = common_copts,
     includes = ["crt/aws-crt-cpp/crt/aws-c-sdkutils/include"],
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
@@ -298,10 +299,7 @@
     name = "aws-c-auth",
     srcs = glob(["crt/aws-crt-cpp/crt/aws-c-auth/source/**/*.c"]),
     hdrs = glob(["crt/aws-crt-cpp/crt/aws-c-auth/include/**/*.h"]),
-    copts = [
-        "-Wno-cast-align",
-        "-Wno-cast-qual",
-    ],
+    copts = common_copts,
     includes = ["crt/aws-crt-cpp/crt/aws-c-auth/include"],
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
@@ -316,9 +314,7 @@
     name = "aws-c-mqtt",
     srcs = glob(["crt/aws-crt-cpp/crt/aws-c-mqtt/source/**/*.c"]),
     hdrs = glob(["crt/aws-crt-cpp/crt/aws-c-mqtt/include/**/*.h"]),
-    copts = [
-        "-Wno-cast-qual",
-        "-Wno-cast-align",
+    copts = common_copts + [
         "-DAWS_MQTT_WITH_WEBSOCKETS",
     ],
     includes = ["crt/aws-crt-cpp/crt/aws-c-mqtt/include"],
@@ -343,11 +339,9 @@
     ] + glob([
         "crt/aws-crt-cpp/crt/aws-c-io/source/pkcs11/v2.40/*.h",
     ]),
-    copts = [
+    copts = common_copts + [
         "-DUSE_S2N",
         "-DAWS_USE_EPOLL",
-        "-Wno-cast-align",
-        "-Wno-cast-qual",
         "-Wno-sign-compare",
         "-Wno-unused-parameter",
     ],
@@ -372,12 +366,10 @@
         "crt/aws-crt-cpp/crt/s2n/pq-crypto/*.c",
     ]),
     hdrs = ["crt/aws-crt-cpp/crt/s2n/api/s2n.h"],
-    copts = [
+    copts = common_copts + [
         "-Iexternal/aws_sdk/crt/aws-crt-cpp/crt/s2n",
         "-DS2N_NO_PQ",
         "-Wno-unknown-pragmas",
-        "-Wno-cast-align",
-        "-Wno-cast-qual",
         "-Wno-unused-parameter",
         "-Wno-sign-compare",
     ],
diff --git a/debian/aws_sdk.patch b/debian/aws_sdk.patch
index 8780e9b..785cc24 100644
--- a/debian/aws_sdk.patch
+++ b/debian/aws_sdk.patch
@@ -1,25 +1,13 @@
-Submodule crt/aws-crt-cpp contains modified content
-Submodule crt/aws-c-cal contains modified content
 diff --git a/crt/aws-crt-cpp/crt/aws-c-cal/source/unix/openssl_platform_init.c b/crt/aws-crt-cpp/crt/aws-c-cal/source/unix/openssl_platform_init.c
 index 761455b..fc434ba 100644
 --- a/crt/aws-crt-cpp/crt/aws-c-cal/source/unix/openssl_platform_init.c
 +++ b/crt/aws-crt-cpp/crt/aws-c-cal/source/unix/openssl_platform_init.c
-@@ -37,7 +37,7 @@ struct openssl_evp_md_ctx_table *g_aws_openssl_evp_md_ctx_table = NULL;
- /* 1.1 */
- extern HMAC_CTX *HMAC_CTX_new(void) __attribute__((weak, used));
- extern void HMAC_CTX_free(HMAC_CTX *) __attribute__((weak, used));
--extern int HMAC_CTX_reset(HMAC_CTX *) __attribute__((weak, used));
-+//extern int HMAC_CTX_reset(HMAC_CTX *) __attribute__((weak, used));
-
- /* 1.0.2 */
- extern void HMAC_CTX_init(HMAC_CTX *) __attribute__((weak, used));
-@@ -46,7 +46,7 @@ extern void HMAC_CTX_cleanup(HMAC_CTX *) __attribute__((weak)) __attribute__((us
- /* common */
+@@ -44,7 +44,7 @@ extern void HMAC_CTX_init(HMAC_CTX *) __attribute__((weak, used));
+ extern void HMAC_CTX_cleanup(HMAC_CTX *) __attribute__((weak, used));
  extern int HMAC_Update(HMAC_CTX *, const unsigned char *, size_t) __attribute__((weak, used));
  extern int HMAC_Final(HMAC_CTX *, unsigned char *, unsigned int *) __attribute__((weak, used));
--extern int HMAC_Init_ex(HMAC_CTX *, const void *, int, const EVP_MD *, ENGINE *) __attribute__((weak, used));
-+//extern int HMAC_Init_ex(HMAC_CTX *, const void *, int, const EVP_MD *, ENGINE *) __attribute__((weak, used));
-
- /* libcrypto 1.1 stub for init */
- static void s_hmac_ctx_init_noop(HMAC_CTX *ctx) {
-Submodule crt/s2n contains modified content
+-extern int HMAC_Init_ex(HMAC_CTX *, const void *, size_t, const EVP_MD *, ENGINE *) __attribute__((weak, used));
++//extern int HMAC_Init_ex(HMAC_CTX *, const void *, size_t, const EVP_MD *, ENGINE *) __attribute__((weak, used));
+ 
+ static int s_hmac_init_ex_bssl(HMAC_CTX *ctx, const void *key, size_t key_len, const EVP_MD *md, ENGINE *impl) {
+     AWS_PRECONDITION(ctx);
diff --git a/debian/packages.bzl b/debian/packages.bzl
index 97d6355..dad67d4 100644
--- a/debian/packages.bzl
+++ b/debian/packages.bzl
@@ -1,5 +1,5 @@
-load("@rules_pkg//:pkg.bzl", "pkg_tar")
 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
+load("@rules_pkg//:pkg.bzl", "pkg_tar")
 
 # In order to use deb packages in the build you have to follow these steps.
 #
diff --git a/frc971/autonomous/BUILD b/frc971/autonomous/BUILD
index 0dd86ca..f20538c 100644
--- a/frc971/autonomous/BUILD
+++ b/frc971/autonomous/BUILD
@@ -1,5 +1,5 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//aos:config.bzl", "aos_config")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 
 package(default_visibility = ["//visibility:public"])
 
diff --git a/frc971/codelab/BUILD b/frc971/codelab/BUILD
index 5e0c1ea..2d1cfc6 100644
--- a/frc971/codelab/BUILD
+++ b/frc971/codelab/BUILD
@@ -1,5 +1,5 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//aos:config.bzl", "aos_config")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 
 package(default_visibility = ["//visibility:public"])
 
diff --git a/frc971/constants/testdata/BUILD b/frc971/constants/testdata/BUILD
index fee7b86..00dd33d 100644
--- a/frc971/constants/testdata/BUILD
+++ b/frc971/constants/testdata/BUILD
@@ -1,5 +1,5 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//aos:config.bzl", "aos_config")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 
 exports_files([
     "test_constants.json",
diff --git a/frc971/control_loops/BUILD b/frc971/control_loops/BUILD
index 9986fef..9ce0e99 100644
--- a/frc971/control_loops/BUILD
+++ b/frc971/control_loops/BUILD
@@ -1,6 +1,6 @@
+load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 load("//aos:config.bzl", "aos_config")
 load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
-load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 
 package(default_visibility = ["//visibility:public"])
 
diff --git a/frc971/control_loops/drivetrain/BUILD b/frc971/control_loops/drivetrain/BUILD
index 9d439b6..48d7a20 100644
--- a/frc971/control_loops/drivetrain/BUILD
+++ b/frc971/control_loops/drivetrain/BUILD
@@ -1,10 +1,10 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
-load("//tools/build_rules:template.bzl", "jinja2_template")
-load("//tools/build_rules:js.bzl", "ts_project")
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 load("//aos:config.bzl", "aos_config")
-load("//tools/build_rules:select.bzl", "cpu_select")
 load("//aos:flatbuffers.bzl", "cc_static_flatbuffer")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
+load("//tools/build_rules:js.bzl", "ts_project")
+load("//tools/build_rules:select.bzl", "cpu_select")
+load("//tools/build_rules:template.bzl", "jinja2_template")
 
 package(default_visibility = ["//visibility:public"])
 
@@ -197,10 +197,10 @@
         "drivetrain_config.h",
     ],
     deps = [
+        ":drivetrain_config_fbs",
         "//frc971:shifter_hall_effect",
         "//frc971/control_loops:state_feedback_loop",
         "//frc971/control_loops:state_feedback_loop_converters",
-        ":drivetrain_config_fbs",
     ] + select({
         "@platforms//os:linux": [
             "//frc971/control_loops:hybrid_state_feedback_loop",
diff --git a/frc971/control_loops/drivetrain/localization/BUILD b/frc971/control_loops/drivetrain/localization/BUILD
index 1cf83d4..3316446 100644
--- a/frc971/control_loops/drivetrain/localization/BUILD
+++ b/frc971/control_loops/drivetrain/localization/BUILD
@@ -1,5 +1,5 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 
 cc_library(
     name = "utils",
diff --git a/frc971/control_loops/flywheel/BUILD b/frc971/control_loops/flywheel/BUILD
index f077682..bae14aa 100644
--- a/frc971/control_loops/flywheel/BUILD
+++ b/frc971/control_loops/flywheel/BUILD
@@ -1,6 +1,6 @@
+load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 load("//aos:config.bzl", "aos_config")
 load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
-load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 
 static_flatbuffer(
     name = "flywheel_controller_status_fbs",
diff --git a/frc971/image_streamer/image_streamer.cc b/frc971/image_streamer/image_streamer.cc
index 2289df3..6c9a732 100644
--- a/frc971/image_streamer/image_streamer.cc
+++ b/frc971/image_streamer/image_streamer.cc
@@ -208,9 +208,11 @@
  private:
   void OnSample(GstSample *sample);
 
+  aos::ShmEventLoop *event_loop_;
   std::map<::seasocks::WebSocket *, std::unique_ptr<Connection>> connections_;
   ::seasocks::Server *server_;
   std::unique_ptr<GstSampleSource> source_;
+  aos::TimerHandler *manual_restart_handle_;
 
   aos::Sender<frc971::vision::CameraImage> sender_;
 };
@@ -275,7 +277,10 @@
 
 WebsocketHandler::WebsocketHandler(aos::ShmEventLoop *event_loop,
                                    ::seasocks::Server *server)
-    : server_(server) {
+    : event_loop_(event_loop),
+      server_(server),
+      manual_restart_handle_(
+          event_loop_->AddTimer([this]() { event_loop_->Exit(); })) {
   if (FLAGS_listen_on.empty()) {
     if (FLAGS_publish_images) {
       sender_ = event_loop->MakeSender<frc971::vision::CameraImage>("/camera");
@@ -286,6 +291,10 @@
     source_ = std::make_unique<ChannelSource>(
         event_loop, [this](auto sample) { OnSample(sample); });
   }
+  event_loop_->OnRun([this]() {
+    manual_restart_handle_->Schedule(event_loop_->monotonic_now() +
+                                     std::chrono::seconds(10));
+  });
 }
 
 void WebsocketHandler::onConnect(::seasocks::WebSocket *sock) {
@@ -333,6 +342,8 @@
 
     builder.CheckOk(builder.Send(image_builder.Finish()));
   }
+  manual_restart_handle_->Schedule(event_loop_->monotonic_now() +
+                                   std::chrono::seconds(10));
 }
 
 void WebsocketHandler::onDisconnect(::seasocks::WebSocket *sock) {
diff --git a/frc971/image_streamer/www/BUILD b/frc971/image_streamer/www/BUILD
index f808a73..74422bd 100644
--- a/frc971/image_streamer/www/BUILD
+++ b/frc971/image_streamer/www/BUILD
@@ -1,5 +1,5 @@
-load("//tools/build_rules:js.bzl", "rollup_bundle", "ts_project")
 load("//frc971/downloader:downloader.bzl", "aos_downloader_dir")
+load("//tools/build_rules:js.bzl", "rollup_bundle", "ts_project")
 
 package(default_visibility = ["//visibility:public"])
 
diff --git a/frc971/imu_fdcan/Dual_IMU/Core/BUILD b/frc971/imu_fdcan/Dual_IMU/Core/BUILD
index 9ebb287..9405a46 100644
--- a/frc971/imu_fdcan/Dual_IMU/Core/BUILD
+++ b/frc971/imu_fdcan/Dual_IMU/Core/BUILD
@@ -1,5 +1,5 @@
-load("//motors:macros.bzl", "hex_from_elf")
 load("@aspect_bazel_lib//lib:copy_file.bzl", "copy_file")
+load("//motors:macros.bzl", "hex_from_elf")
 
 copy_file(
     name = "copy_startup",
diff --git a/frc971/imu_reader/BUILD b/frc971/imu_reader/BUILD
index cf2df44..809a3fc 100644
--- a/frc971/imu_reader/BUILD
+++ b/frc971/imu_reader/BUILD
@@ -1,5 +1,5 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 
 cc_library(
     name = "imu",
diff --git a/frc971/input/BUILD b/frc971/input/BUILD
index 329dfce..9e5fd9c 100644
--- a/frc971/input/BUILD
+++ b/frc971/input/BUILD
@@ -1,5 +1,5 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//aos:config.bzl", "aos_config")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 
 package(default_visibility = ["//visibility:public"])
 
diff --git a/frc971/math/BUILD b/frc971/math/BUILD
index dd160d0..b8cd2fc 100644
--- a/frc971/math/BUILD
+++ b/frc971/math/BUILD
@@ -1,5 +1,5 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 
 static_flatbuffer(
     name = "matrix_fbs",
diff --git a/frc971/orin/BUILD b/frc971/orin/BUILD
index 75ded47..f69fe85 100644
--- a/frc971/orin/BUILD
+++ b/frc971/orin/BUILD
@@ -1,5 +1,5 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//aos:flatbuffers.bzl", "cc_static_flatbuffer")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//frc971:halide.bzl", "halide_library")
 
 exports_files(["orin_irq_config.json"])
diff --git a/frc971/orin/argus_monitor.cc b/frc971/orin/argus_monitor.cc
index 8f129b2..13130cc 100644
--- a/frc971/orin/argus_monitor.cc
+++ b/frc971/orin/argus_monitor.cc
@@ -11,7 +11,7 @@
 #include "aos/realtime.h"
 
 DEFINE_int32(priority, -1, "If set, the RT priority to run at.");
-DEFINE_double(max_jitter, 5.00,
+DEFINE_double(max_jitter, 10.00,
               "The max time in seconds between messages before considering the "
               "camera processes dead.");
 DEFINE_double(grace_period, 10.00,
@@ -44,6 +44,9 @@
   }
 
   void HandleMessage(const aos::Context &context) {
+    if (last_time_ == aos::monotonic_clock::min_time) {
+      LOG(INFO) << "First message on " << channel_name_;
+    }
     last_time_ = context.monotonic_event_time;
   }
 
@@ -53,6 +56,8 @@
         event_loop->monotonic_now()) {
       // Restart camera services
       LOG(INFO) << "Restarting camera services";
+      LOG(INFO) << "Channel " << channel_name_ << " has not received a message "
+                << FLAGS_max_jitter << " seconds";
       CHECK_EQ(std::system("aos_starter stop argus_camera0"), 0);
       CHECK_EQ(std::system("aos_starter stop argus_camera1"), 0);
       CHECK_EQ(std::system("sudo systemctl restart nvargus-daemon.service"), 0);
diff --git a/frc971/orin/contents/etc/systemd/system/jetson-clocks.service b/frc971/orin/contents/etc/systemd/system/jetson-clocks.service
index bfc68fa..661c040 100644
--- a/frc971/orin/contents/etc/systemd/system/jetson-clocks.service
+++ b/frc971/orin/contents/etc/systemd/system/jetson-clocks.service
@@ -14,5 +14,15 @@
 # Set all the clocks to max frequency
 ExecStart=/usr/bin/jetson_clocks
 
+# Pin the camera clocks to max too to make things simpler.
+ExecStart=bash -c 'echo 1 > /sys/kernel/debug/bpmp/debug/clk/vi/mrq_rate_locked'
+ExecStart=bash -c 'echo 1 > /sys/kernel/debug/bpmp/debug/clk/isp/mrq_rate_locked'
+ExecStart=bash -c 'echo 1 > /sys/kernel/debug/bpmp/debug/clk/nvcsi/mrq_rate_locked'
+ExecStart=bash -c 'echo 1 > /sys/kernel/debug/bpmp/debug/clk/emc/mrq_rate_locked'
+ExecStart=bash -c 'cat /sys/kernel/debug/bpmp/debug/clk/vi/max_rate | tee /sys/kernel/debug/bpmp/debug/clk/vi/rate'
+ExecStart=bash -c 'cat /sys/kernel/debug/bpmp/debug/clk/isp/max_rate | tee /sys/kernel/debug/bpmp/debug/clk/isp/rate'
+ExecStart=bash -c 'cat /sys/kernel/debug/bpmp/debug/clk/nvcsi/max_rate | tee /sys/kernel/debug/bpmp/debug/clk/nvcsi/rate'
+ExecStart=bash -c 'cat /sys/kernel/debug/bpmp/debug/clk/emc/max_rate | tee /sys/kernel/debug/bpmp/debug/clk/emc/rate'
+
 TimeoutSec=0
 RemainAfterExit=yes
diff --git a/frc971/vision/BUILD b/frc971/vision/BUILD
index 46b7cea..01a6d1a 100644
--- a/frc971/vision/BUILD
+++ b/frc971/vision/BUILD
@@ -1,7 +1,7 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("@com_github_google_flatbuffers//:build_defs.bzl", "flatbuffer_py_library")
-load("//aos:config.bzl", "aos_config")
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
+load("//aos:config.bzl", "aos_config")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 
 static_flatbuffer(
     name = "vision_fbs",
diff --git a/frc971/wpilib/BUILD b/frc971/wpilib/BUILD
index 2cf2109..be544ca 100644
--- a/frc971/wpilib/BUILD
+++ b/frc971/wpilib/BUILD
@@ -1,7 +1,7 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
-load("//tools/build_rules:js.bzl", "ts_project")
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 load("//aos:config.bzl", "aos_config")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
+load("//tools/build_rules:js.bzl", "ts_project")
 
 package(default_visibility = ["//visibility:public"])
 
diff --git a/scouting/deploy/BUILD b/scouting/deploy/BUILD
index c8f68c4..65b33fb 100644
--- a/scouting/deploy/BUILD
+++ b/scouting/deploy/BUILD
@@ -1,5 +1,5 @@
-load("@rules_pkg//pkg:pkg.bzl", "pkg_deb", "pkg_tar")
 load("@rules_pkg//pkg:mappings.bzl", "pkg_files")
+load("@rules_pkg//pkg:pkg.bzl", "pkg_deb", "pkg_tar")
 
 pkg_files(
     name = "systemd_files",
diff --git a/third_party/abseil/abseil.patch b/third_party/abseil/abseil.patch
index 6c7f380..36b37dc 100644
--- a/third_party/abseil/abseil.patch
+++ b/third_party/abseil/abseil.patch
@@ -244,15 +244,6 @@
      textual_hdrs = ["include/cctz/civil_time_detail.h"],
      visibility = ["//visibility:public"],
      deps = ["//absl/base:config"],
-@@ -53,6 +62,8 @@ cc_library(
-         "include/cctz/time_zone.h",
-         "include/cctz/zone_info_source.h",
-     ],
-+    copts = ABSL_DEFAULT_COPTS,
-+    linkopts = ABSL_DEFAULT_LINKOPTS,
-     # OS X and iOS no longer use `linkopts = ["-framework CoreFoundation"]`
-     # as (1) bazel adds it automatically, and (2) it caused problems when
-     # cross-compiling for Android.
 diff --git a/absl/copts/configure_copts.bzl b/absl/copts/configure_copts.bzl
 index ca5f26da..0b10dc0b 100644
 --- a/absl/copts/configure_copts.bzl
diff --git a/third_party/rules_js/0001-Fix-package-permissions.patch b/third_party/rules_js/0001-Fix-package-permissions.patch
new file mode 100644
index 0000000..282df88
--- /dev/null
+++ b/third_party/rules_js/0001-Fix-package-permissions.patch
@@ -0,0 +1,33 @@
+diff --git a/npm/private/npm_package_store.bzl b/npm/private/npm_package_store.bzl
+index 9ab33e56..46446bd9 100644
+--- a/npm/private/npm_package_store.bzl
++++ b/npm/private/npm_package_store.bzl
+@@ -198,23 +198,14 @@ def _npm_package_store_impl(ctx):
+             if utils.is_tarball_extension(src_directory.extension):
+                 # npm packages are always published with one top-level directory inside the tarball, tho the name is not predictable
+                 # we can use the --strip-components 1 argument with tar to strip one directory level
+-                args = ctx.actions.args()
+-                args.add("--extract")
+-                args.add("--no-same-owner")
+-                args.add("--no-same-permissions")
+-                args.add("--strip-components")
+-                args.add(str(1))
+-                args.add("--file")
+-                args.add(src_directory.path)
+-                args.add("--directory")
+-                args.add(virtual_store_directory.path)
+-
+                 bsdtar = ctx.toolchains["@aspect_bazel_lib//lib:tar_toolchain_type"]
+-                ctx.actions.run(
+-                    executable = bsdtar.tarinfo.binary,
++                ctx.actions.run_shell(
++                    tools = [bsdtar.tarinfo.binary],
+                     inputs = depset(direct = [src_directory], transitive = [bsdtar.default.files]),
+                     outputs = [virtual_store_directory],
+-                    arguments = [args],
++                    command = bsdtar.tarinfo.binary.path + " --extract --no-same-owner --no-same-permissions --strip-components 1 --file " +
++                              src_directory.path + " --directory " +
++                              virtual_store_directory.path + " && find " + virtual_store_directory.path + " -type d -exec chmod 755 {} \\;",
+                     mnemonic = "NpmPackageExtract",
+                     progress_message = "Extracting npm package {}@{}".format(package, version),
+                 )
diff --git a/tools/bazel b/tools/bazel
index 97f31d9..d4312b2 100755
--- a/tools/bazel
+++ b/tools/bazel
@@ -24,7 +24,7 @@
   exec "${BAZEL_OVERRIDE}" "$@"
 fi
 
-readonly VERSION="6.0.0"
+readonly VERSION="7.1.1"
 
 readonly DOWNLOAD_DIR="${HOME}/.cache/bazel"
 # Directory to unpack bazel into.  This must change whenever bazel changes.
diff --git a/tools/build_rules/autocxx.bzl b/tools/build_rules/autocxx.bzl
index 5cadf2b..92ea16e 100644
--- a/tools/build_rules/autocxx.bzl
+++ b/tools/build_rules/autocxx.bzl
@@ -1,6 +1,6 @@
+load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
 load("@org_frc971//tools/rust:defs.bzl", "rust_library")
 load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cc_toolchain")
-load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
 
 def _cc_toolchain_flags(ctx, cc_toolchain):
     feature_configuration = cc_common.configure_features(
diff --git a/tools/build_rules/js.bzl b/tools/build_rules/js.bzl
index a41f30c..d7096a9 100644
--- a/tools/build_rules/js.bzl
+++ b/tools/build_rules/js.bzl
@@ -1,17 +1,17 @@
+load("@aspect_bazel_lib//lib:copy_file.bzl", "copy_file")
+load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory")
+load("@aspect_rules_cypress//cypress:defs.bzl", "cypress_module_test")
+load("@aspect_rules_esbuild//esbuild:defs.bzl", "esbuild")
 load("@aspect_rules_js//js:providers.bzl", "JsInfo")
 load("@aspect_rules_js//npm:defs.bzl", "npm_package")
+load("@aspect_rules_rollup//rollup:defs.bzl", upstream_rollup_bundle = "rollup")
+load("@aspect_rules_terser//terser:defs.bzl", terser_minified = "terser")
 load("@bazel_skylib//rules:write_file.bzl", "write_file")
-load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory")
-load("@aspect_bazel_lib//lib:copy_file.bzl", "copy_file")
-load("@aspect_rules_esbuild//esbuild:defs.bzl", "esbuild")
 
 #load("@npm//:history-server/package_json.bzl", history_server_bin = "bin")
 load("@npm//:html-insert-assets/package_json.bzl", html_insert_assets_bin = "bin")
 load("//tools/build_rules/js:ng.bzl", "ng_esbuild", "ng_project")
 load("//tools/build_rules/js:ts.bzl", _ts_project = "ts_project")
-load("@aspect_rules_rollup//rollup:defs.bzl", upstream_rollup_bundle = "rollup")
-load("@aspect_rules_terser//terser:defs.bzl", terser_minified = "terser")
-load("@aspect_rules_cypress//cypress:defs.bzl", "cypress_module_test")
 
 ts_project = _ts_project
 
diff --git a/tools/cpp/toolchain_config.bzl b/tools/cpp/toolchain_config.bzl
index 6c37962..ad0c86d 100644
--- a/tools/cpp/toolchain_config.bzl
+++ b/tools/cpp/toolchain_config.bzl
@@ -1,3 +1,4 @@
+load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
 load(
     "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl",
     "action_config",
@@ -8,7 +9,6 @@
     "tool_path",
     "with_feature_set",
 )
-load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
 
 def _impl(ctx):
     if ctx.attr.cpu == "rp2040":
diff --git a/tools/dependency_rewrite b/tools/dependency_rewrite
index 14980dd..f6eb9a0 100644
--- a/tools/dependency_rewrite
+++ b/tools/dependency_rewrite
@@ -19,6 +19,7 @@
 rewrite www.googleapis.com/(.*) software.frc971.org/Build-Dependencies/www.googleapis.com/$1
 rewrite www.johnvansickle.com/(.*) software.frc971.org/Build-Dependencies/www.johnvansickle.com/$1
 rewrite docs.opencv.org/(.*) software.frc971.org/Build-Dependencies/docs.opencv.org/$1
+rewrite security.ubuntu.com/(.*) software.frc971.org/Build-Dependencies/security.ubuntu.com/$1
 allow crates.io
 allow golang.org
 allow go.dev
diff --git a/tools/go/mirrored_go_deps.bzl b/tools/go/mirrored_go_deps.bzl
index dbf4f29..dcd7405 100644
--- a/tools/go/mirrored_go_deps.bzl
+++ b/tools/go/mirrored_go_deps.bzl
@@ -1,6 +1,6 @@
-load("//tools/go:go_mirrors.bzl", "GO_MIRROR_INFO")
 load("@bazel_gazelle//:deps.bzl", "go_repository")
 load("@ci_configure//:ci.bzl", "RUNNING_IN_CI")
+load("//tools/go:go_mirrors.bzl", "GO_MIRROR_INFO")
 
 def maybe_override_go_dep(name, importpath, sum, version, **kwargs):
     """This macro selects between our dependency mirrors and upstream sources.
diff --git a/tools/lint/BUILD b/tools/lint/BUILD
index 907f17c..7b6803d 100644
--- a/tools/lint/BUILD
+++ b/tools/lint/BUILD
@@ -1,6 +1,6 @@
 load("@ci_configure//:ci.bzl", "RUNNING_IN_CI")
-load("@pip_deps//:requirements.bzl", "entry_point")
 load("@npm//:prettier/package_json.bzl", prettier_bin = "bin")
+load("@pip_deps//:requirements.bzl", "entry_point")
 
 prettier_bin.prettier_binary(
     name = "prettier_binary",
diff --git a/tools/rust/BUILD b/tools/rust/BUILD
index 2095511..66242a0 100644
--- a/tools/rust/BUILD
+++ b/tools/rust/BUILD
@@ -1,5 +1,5 @@
-load("@rules_rust//rust:toolchain.bzl", "rust_stdlib_filegroup", "rust_toolchain")
 load("@bazel_skylib//rules:write_file.bzl", "write_file")
+load("@rules_rust//rust:toolchain.bzl", "rust_stdlib_filegroup", "rust_toolchain")
 
 # We have to declare our toolchains individually to get the corect constraints
 # configured so we can robustly select the correct one for each of our
diff --git a/tools/rust/defs.bzl b/tools/rust/defs.bzl
index 88caca5..06f1ad1 100644
--- a/tools/rust/defs.bzl
+++ b/tools/rust/defs.bzl
@@ -1,3 +1,4 @@
+load("@com_github_google_flatbuffers//:build_defs.bzl", _flatbuffer_rust_library = "flatbuffer_rust_library")
 load(
     "@rules_rust//rust:defs.bzl",
     _rust_binary = "rust_binary",
@@ -6,7 +7,6 @@
     _rust_library = "rust_library",
     _rust_test = "rust_test",
 )
-load("@com_github_google_flatbuffers//:build_defs.bzl", _flatbuffer_rust_library = "flatbuffer_rust_library")
 
 def rust_doc_test(target_compatible_with = ["//tools/platforms/rust:has_support"], tags = [], **kwargs):
     # TODO(james): Attempting to execute this remotely results
diff --git a/y2014/BUILD b/y2014/BUILD
index 5be5cfa..c4e419f 100644
--- a/y2014/BUILD
+++ b/y2014/BUILD
@@ -1,5 +1,5 @@
-load("//frc971:downloader.bzl", "robot_downloader")
 load("//aos:config.bzl", "aos_config")
+load("//frc971:downloader.bzl", "robot_downloader")
 
 cc_library(
     name = "constants",
diff --git a/y2016/BUILD b/y2016/BUILD
index ed3256f..849f0f6 100644
--- a/y2016/BUILD
+++ b/y2016/BUILD
@@ -1,5 +1,5 @@
-load("//frc971:downloader.bzl", "robot_downloader")
 load("//aos:config.bzl", "aos_config")
+load("//frc971:downloader.bzl", "robot_downloader")
 
 cc_library(
     name = "constants",
diff --git a/y2016/vision/BUILD b/y2016/vision/BUILD
index f1925a6..8936878 100644
--- a/y2016/vision/BUILD
+++ b/y2016/vision/BUILD
@@ -1,8 +1,8 @@
 load("@rules_cc//cc:defs.bzl", "cc_proto_library")
 load("@rules_proto//proto:defs.bzl", "proto_library")
-load("//tools/build_rules:gtk_dependent.bzl", "gtk_dependent_cc_binary")
 load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//tools:platforms.bzl", "platforms")
+load("//tools/build_rules:gtk_dependent.bzl", "gtk_dependent_cc_binary")
 
 static_flatbuffer(
     name = "vision_fbs",
diff --git a/y2016/vision/tools/BUILD b/y2016/vision/tools/BUILD
index 48ed352..15508e7 100644
--- a/y2016/vision/tools/BUILD
+++ b/y2016/vision/tools/BUILD
@@ -1,5 +1,5 @@
-load("//tools/build_rules:gtk_dependent.bzl", "gtk_dependent_cc_binary")
 load("//tools:platforms.bzl", "platforms")
+load("//tools/build_rules:gtk_dependent.bzl", "gtk_dependent_cc_binary")
 
 gtk_dependent_cc_binary(
     name = "blob_stream_replay",
diff --git a/y2017/BUILD b/y2017/BUILD
index a557815..aeb4d67 100644
--- a/y2017/BUILD
+++ b/y2017/BUILD
@@ -1,5 +1,5 @@
-load("//frc971:downloader.bzl", "robot_downloader")
 load("//aos:config.bzl", "aos_config")
+load("//frc971:downloader.bzl", "robot_downloader")
 
 cc_library(
     name = "constants",
diff --git a/y2017/vision/BUILD b/y2017/vision/BUILD
index c4045b8..dcace86 100644
--- a/y2017/vision/BUILD
+++ b/y2017/vision/BUILD
@@ -1,7 +1,7 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
-load("//tools/build_rules:gtk_dependent.bzl", "gtk_dependent_cc_binary")
 load("@rules_cc//cc:defs.bzl", "cc_proto_library")
 load("@rules_proto//proto:defs.bzl", "proto_library")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
+load("//tools/build_rules:gtk_dependent.bzl", "gtk_dependent_cc_binary")
 
 package(default_visibility = ["//visibility:public"])
 
diff --git a/y2018/BUILD b/y2018/BUILD
index e3531b2..129cd84 100644
--- a/y2018/BUILD
+++ b/y2018/BUILD
@@ -1,8 +1,8 @@
-load("//frc971:downloader.bzl", "robot_downloader")
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
-load("//aos:config.bzl", "aos_config")
 load("@rules_cc//cc:defs.bzl", "cc_proto_library")
 load("@rules_proto//proto:defs.bzl", "proto_library")
+load("//aos:config.bzl", "aos_config")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
+load("//frc971:downloader.bzl", "robot_downloader")
 
 robot_downloader(
     start_binaries = [
diff --git a/y2019/BUILD b/y2019/BUILD
index fee2db9..7bc0c33 100644
--- a/y2019/BUILD
+++ b/y2019/BUILD
@@ -1,8 +1,8 @@
-load("//frc971:downloader.bzl", "robot_downloader")
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
-load("//aos:config.bzl", "aos_config")
 load("@rules_cc//cc:defs.bzl", "cc_proto_library")
 load("@rules_proto//proto:defs.bzl", "proto_library")
+load("//aos:config.bzl", "aos_config")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
+load("//frc971:downloader.bzl", "robot_downloader")
 
 robot_downloader(
     data = [
diff --git a/y2019/control_loops/drivetrain/BUILD b/y2019/control_loops/drivetrain/BUILD
index 53cb777..71bd0ee 100644
--- a/y2019/control_loops/drivetrain/BUILD
+++ b/y2019/control_loops/drivetrain/BUILD
@@ -1,5 +1,5 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//aos:config.bzl", "aos_config")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//tools/build_rules:select.bzl", "cpu_select")
 
 genrule(
diff --git a/y2019/jevois/BUILD b/y2019/jevois/BUILD
index adb1dd2..0b2f618 100644
--- a/y2019/jevois/BUILD
+++ b/y2019/jevois/BUILD
@@ -1,5 +1,5 @@
-load("//motors:macros.bzl", "hex_from_elf")
 load("@org_frc971//tools/build_rules:select.bzl", "compiler_select")
+load("//motors:macros.bzl", "hex_from_elf")
 
 jevois_crc_args = [
     "$(location //third_party/pycrc:pycrc_main)",
diff --git a/y2019/vision/server/BUILD b/y2019/vision/server/BUILD
index 105a8e8..d942ff9 100644
--- a/y2019/vision/server/BUILD
+++ b/y2019/vision/server/BUILD
@@ -1,8 +1,8 @@
-load("//tools/build_rules:js.bzl", "ts_project")
-load("//aos/seasocks:gen_embedded.bzl", "gen_embedded")
 load("@rules_cc//cc:defs.bzl", "cc_proto_library")
 load("@rules_proto//proto:defs.bzl", "proto_library")
+load("//aos/seasocks:gen_embedded.bzl", "gen_embedded")
 load("//frc971/downloader:downloader.bzl", "aos_downloader_dir")
+load("//tools/build_rules:js.bzl", "ts_project")
 
 ts_project(
     name = "demo",
diff --git a/y2020/BUILD b/y2020/BUILD
index 001ef89..3def80a 100644
--- a/y2020/BUILD
+++ b/y2020/BUILD
@@ -1,8 +1,8 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
-load("//frc971:downloader.bzl", "robot_downloader")
 load("//aos:config.bzl", "aos_config")
-load("//tools/build_rules:template.bzl", "jinja2_template")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//aos/util:config_validator_macro.bzl", "config_validator_test")
+load("//frc971:downloader.bzl", "robot_downloader")
+load("//tools/build_rules:template.bzl", "jinja2_template")
 
 config_validator_test(
     name = "config_validator_test",
diff --git a/y2020/control_loops/drivetrain/BUILD b/y2020/control_loops/drivetrain/BUILD
index 0070156..feabb62 100644
--- a/y2020/control_loops/drivetrain/BUILD
+++ b/y2020/control_loops/drivetrain/BUILD
@@ -1,7 +1,7 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
-load("//tools/build_rules:js.bzl", "ts_project")
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 load("//aos:config.bzl", "aos_config")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
+load("//tools/build_rules:js.bzl", "ts_project")
 
 genrule(
     name = "genrule_drivetrain",
diff --git a/y2020/control_loops/superstructure/BUILD b/y2020/control_loops/superstructure/BUILD
index c77f35d..0b91150 100644
--- a/y2020/control_loops/superstructure/BUILD
+++ b/y2020/control_loops/superstructure/BUILD
@@ -1,6 +1,6 @@
+load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//tools/build_rules:js.bzl", "ts_project")
-load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 
 package(default_visibility = ["//visibility:public"])
 
diff --git a/y2020/vision/sift/BUILD b/y2020/vision/sift/BUILD
index 8b420ea..a220664 100644
--- a/y2020/vision/sift/BUILD
+++ b/y2020/vision/sift/BUILD
@@ -1,7 +1,7 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
-load(":fast_gaussian.bzl", "fast_gaussian")
 load("@com_github_google_flatbuffers//:build_defs.bzl", "flatbuffer_py_library")
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
+load(":fast_gaussian.bzl", "fast_gaussian")
 
 # Note that this file is also used directly by :fast_gaussian_halide_generator,
 # without any dependencies added here.
diff --git a/y2020/www/BUILD b/y2020/www/BUILD
index 0c05900..85457b0 100644
--- a/y2020/www/BUILD
+++ b/y2020/www/BUILD
@@ -1,5 +1,5 @@
-load("//tools/build_rules:js.bzl", "rollup_bundle", "ts_project")
 load("//frc971/downloader:downloader.bzl", "aos_downloader_dir")
+load("//tools/build_rules:js.bzl", "rollup_bundle", "ts_project")
 
 ts_project(
     name = "camera_main",
diff --git a/y2021_bot3/BUILD b/y2021_bot3/BUILD
index 0fc468b..7d898f5 100644
--- a/y2021_bot3/BUILD
+++ b/y2021_bot3/BUILD
@@ -1,5 +1,5 @@
-load("//frc971:downloader.bzl", "robot_downloader")
 load("//aos:config.bzl", "aos_config")
+load("//frc971:downloader.bzl", "robot_downloader")
 
 robot_downloader(
     data = [
diff --git a/y2022/BUILD b/y2022/BUILD
index a839f37..bce1f66 100644
--- a/y2022/BUILD
+++ b/y2022/BUILD
@@ -1,8 +1,8 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
-load("//frc971:downloader.bzl", "robot_downloader")
 load("//aos:config.bzl", "aos_config")
-load("//tools/build_rules:template.bzl", "jinja2_template")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//aos/util:config_validator_macro.bzl", "config_validator_test")
+load("//frc971:downloader.bzl", "robot_downloader")
+load("//tools/build_rules:template.bzl", "jinja2_template")
 
 config_validator_test(
     name = "config_validator_test",
diff --git a/y2022/control_loops/superstructure/BUILD b/y2022/control_loops/superstructure/BUILD
index 52b4db0..0a72b71 100644
--- a/y2022/control_loops/superstructure/BUILD
+++ b/y2022/control_loops/superstructure/BUILD
@@ -1,6 +1,6 @@
+load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//tools/build_rules:js.bzl", "ts_project")
-load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 
 package(default_visibility = ["//visibility:public"])
 
diff --git a/y2022/localizer/BUILD b/y2022/localizer/BUILD
index 63f720f..6053efb 100644
--- a/y2022/localizer/BUILD
+++ b/y2022/localizer/BUILD
@@ -1,7 +1,7 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
-load("//tools/build_rules:js.bzl", "ts_project")
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 load("//aos:flatbuffers.bzl", "cc_static_flatbuffer")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
+load("//tools/build_rules:js.bzl", "ts_project")
 
 ts_project(
     name = "localizer_plotter",
diff --git a/y2022/vision/BUILD b/y2022/vision/BUILD
index 523ee04..795d75f 100644
--- a/y2022/vision/BUILD
+++ b/y2022/vision/BUILD
@@ -1,6 +1,6 @@
+load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//tools/build_rules:js.bzl", "ts_project")
-load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 
 ts_project(
     name = "vision_plotter",
diff --git a/y2022/www/BUILD b/y2022/www/BUILD
index e806404..e4969fd 100644
--- a/y2022/www/BUILD
+++ b/y2022/www/BUILD
@@ -1,5 +1,5 @@
-load("//tools/build_rules:js.bzl", "rollup_bundle", "ts_project")
 load("//frc971/downloader:downloader.bzl", "aos_downloader_dir")
+load("//tools/build_rules:js.bzl", "rollup_bundle", "ts_project")
 
 filegroup(
     name = "files",
diff --git a/y2022_bot3/BUILD b/y2022_bot3/BUILD
index 125ff44..08f4e2c 100644
--- a/y2022_bot3/BUILD
+++ b/y2022_bot3/BUILD
@@ -1,5 +1,5 @@
-load("//frc971:downloader.bzl", "robot_downloader")
 load("//aos:config.bzl", "aos_config")
+load("//frc971:downloader.bzl", "robot_downloader")
 
 robot_downloader(
     binaries = [
diff --git a/y2022_bot3/control_loops/superstructure/BUILD b/y2022_bot3/control_loops/superstructure/BUILD
index a3f74f9..cff7b18 100644
--- a/y2022_bot3/control_loops/superstructure/BUILD
+++ b/y2022_bot3/control_loops/superstructure/BUILD
@@ -1,5 +1,5 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 
 package(default_visibility = ["//visibility:public"])
 
diff --git a/y2023/BUILD b/y2023/BUILD
index 9bbed4f..e3d9a2e 100644
--- a/y2023/BUILD
+++ b/y2023/BUILD
@@ -1,7 +1,7 @@
-load("//frc971:downloader.bzl", "robot_downloader")
 load("//aos:config.bzl", "aos_config")
-load("//tools/build_rules:template.bzl", "jinja2_template")
 load("//aos/util:config_validator_macro.bzl", "config_validator_test")
+load("//frc971:downloader.bzl", "robot_downloader")
+load("//tools/build_rules:template.bzl", "jinja2_template")
 
 config_validator_test(
     name = "config_validator_test",
diff --git a/y2023/constants/BUILD b/y2023/constants/BUILD
index bbcec56..5bece66 100644
--- a/y2023/constants/BUILD
+++ b/y2023/constants/BUILD
@@ -1,5 +1,5 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("@aspect_bazel_lib//lib:run_binary.bzl", "run_binary")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//tools/build_rules:template.bzl", "jinja2_template")
 
 cc_library(
diff --git a/y2023/control_loops/drivetrain/BUILD b/y2023/control_loops/drivetrain/BUILD
index ea2110e..a1e1cd8 100644
--- a/y2023/control_loops/drivetrain/BUILD
+++ b/y2023/control_loops/drivetrain/BUILD
@@ -1,5 +1,5 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//aos:config.bzl", "aos_config")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 
 genrule(
     name = "genrule_drivetrain",
diff --git a/y2023/control_loops/superstructure/BUILD b/y2023/control_loops/superstructure/BUILD
index f62d790..91fca1d 100644
--- a/y2023/control_loops/superstructure/BUILD
+++ b/y2023/control_loops/superstructure/BUILD
@@ -1,6 +1,6 @@
+load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//tools/build_rules:js.bzl", "ts_project")
-load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 
 package(default_visibility = ["//visibility:public"])
 
diff --git a/y2023/localizer/BUILD b/y2023/localizer/BUILD
index 9b35fcf..824813a 100644
--- a/y2023/localizer/BUILD
+++ b/y2023/localizer/BUILD
@@ -1,6 +1,6 @@
+load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//tools/build_rules:js.bzl", "ts_project")
-load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 
 ts_project(
     name = "localizer_plotter",
diff --git a/y2023/vision/BUILD b/y2023/vision/BUILD
index 97ce003..79849d9 100644
--- a/y2023/vision/BUILD
+++ b/y2023/vision/BUILD
@@ -1,7 +1,7 @@
-load("//frc971:halide.bzl", "halide_library")
-load("//tools/build_rules:select.bzl", "cpu_select")
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
+load("//frc971:halide.bzl", "halide_library")
+load("//tools/build_rules:select.bzl", "cpu_select")
 
 cc_binary(
     name = "camera_reader",
diff --git a/y2023/www/BUILD b/y2023/www/BUILD
index 94a1a13..051a26f 100644
--- a/y2023/www/BUILD
+++ b/y2023/www/BUILD
@@ -1,5 +1,5 @@
-load("//tools/build_rules:js.bzl", "rollup_bundle", "ts_project")
 load("//frc971/downloader:downloader.bzl", "aos_downloader_dir")
+load("//tools/build_rules:js.bzl", "rollup_bundle", "ts_project")
 
 filegroup(
     name = "files",
diff --git a/y2023_bot3/BUILD b/y2023_bot3/BUILD
index 86625da..e1c8d06 100644
--- a/y2023_bot3/BUILD
+++ b/y2023_bot3/BUILD
@@ -1,6 +1,6 @@
-load("//frc971:downloader.bzl", "robot_downloader")
 load("//aos:config.bzl", "aos_config")
 load("//aos/util:config_validator_macro.bzl", "config_validator_test")
+load("//frc971:downloader.bzl", "robot_downloader")
 
 config_validator_test(
     name = "config_validator_test",
diff --git a/y2023_bot3/control_loops/superstructure/BUILD b/y2023_bot3/control_loops/superstructure/BUILD
index d74d033..97ea2f9 100644
--- a/y2023_bot3/control_loops/superstructure/BUILD
+++ b/y2023_bot3/control_loops/superstructure/BUILD
@@ -1,5 +1,5 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 
 package(default_visibility = ["//visibility:public"])
 
diff --git a/y2024/BUILD b/y2024/BUILD
index 2727ac7..26727a5 100644
--- a/y2024/BUILD
+++ b/y2024/BUILD
@@ -1,6 +1,6 @@
-load("//frc971:downloader.bzl", "robot_downloader")
 load("//aos:config.bzl", "aos_config")
 load("//aos/util:config_validator_macro.bzl", "config_validator_test")
+load("//frc971:downloader.bzl", "robot_downloader")
 
 config_validator_test(
     name = "config_validator_test",
diff --git a/y2024/autonomous/auto_splines.cc b/y2024/autonomous/auto_splines.cc
index 9e52648..c5fb24c 100644
--- a/y2024/autonomous/auto_splines.cc
+++ b/y2024/autonomous/auto_splines.cc
@@ -223,4 +223,47 @@
                    alliance);
 }
 
+flatbuffers::Offset<frc971::MultiSpline>
+AutonomousSplines::TwoPieceViaStageSpline1(
+    aos::Sender<frc971::control_loops::drivetrain::SplineGoal>::Builder
+        *builder,
+    aos::Alliance alliance) {
+  return FixSpline(builder,
+                   aos::CopyFlatBuffer<frc971::MultiSpline>(
+                       two_piece_via_stage_spline_1_, builder->fbb()),
+                   alliance);
+}
+
+flatbuffers::Offset<frc971::MultiSpline>
+AutonomousSplines::TwoPieceViaStageSpline2(
+    aos::Sender<frc971::control_loops::drivetrain::SplineGoal>::Builder
+        *builder,
+    aos::Alliance alliance) {
+  return FixSpline(builder,
+                   aos::CopyFlatBuffer<frc971::MultiSpline>(
+                       two_piece_via_stage_spline_2_, builder->fbb()),
+                   alliance);
+}
+flatbuffers::Offset<frc971::MultiSpline>
+AutonomousSplines::TwoPieceViaStageSpline3(
+    aos::Sender<frc971::control_loops::drivetrain::SplineGoal>::Builder
+        *builder,
+    aos::Alliance alliance) {
+  return FixSpline(builder,
+                   aos::CopyFlatBuffer<frc971::MultiSpline>(
+                       two_piece_via_stage_spline_3_, builder->fbb()),
+                   alliance);
+}
+
+flatbuffers::Offset<frc971::MultiSpline>
+AutonomousSplines::TwoPieceViaStageSpline4(
+    aos::Sender<frc971::control_loops::drivetrain::SplineGoal>::Builder
+        *builder,
+    aos::Alliance alliance) {
+  return FixSpline(builder,
+                   aos::CopyFlatBuffer<frc971::MultiSpline>(
+                       two_piece_via_stage_spline_4_, builder->fbb()),
+                   alliance);
+}
+
 }  // namespace y2024::autonomous
diff --git a/y2024/autonomous/auto_splines.h b/y2024/autonomous/auto_splines.h
index f477cee..8ba7f70 100644
--- a/y2024/autonomous/auto_splines.h
+++ b/y2024/autonomous/auto_splines.h
@@ -44,7 +44,19 @@
                 "splines/2_piece_steal.2.json")),
         two_piece_steal_spline_4_(
             aos::JsonFileToFlatbuffer<frc971::MultiSpline>(
-                "splines/2_piece_steal.3.json")) {}
+                "splines/2_piece_steal.3.json")),
+        two_piece_via_stage_spline_1_(
+            aos::JsonFileToFlatbuffer<frc971::MultiSpline>(
+                "splines/2_piece_via_stage.0.json")),
+        two_piece_via_stage_spline_2_(
+            aos::JsonFileToFlatbuffer<frc971::MultiSpline>(
+                "splines/2_piece_via_stage.1.json")),
+        two_piece_via_stage_spline_3_(
+            aos::JsonFileToFlatbuffer<frc971::MultiSpline>(
+                "splines/2_piece_via_stage.2.json")),
+        two_piece_via_stage_spline_4_(
+            aos::JsonFileToFlatbuffer<frc971::MultiSpline>(
+                "splines/2_piece_via_stage.3.json")) {}
   static flatbuffers::Offset<frc971::MultiSpline> BasicSSpline(
       aos::Sender<frc971::control_loops::drivetrain::SplineGoal>::Builder
           *builder,
@@ -100,6 +112,23 @@
           *builder,
       aos::Alliance alliance);
 
+  flatbuffers::Offset<frc971::MultiSpline> TwoPieceViaStageSpline1(
+      aos::Sender<frc971::control_loops::drivetrain::SplineGoal>::Builder
+          *builder,
+      aos::Alliance alliance);
+  flatbuffers::Offset<frc971::MultiSpline> TwoPieceViaStageSpline2(
+      aos::Sender<frc971::control_loops::drivetrain::SplineGoal>::Builder
+          *builder,
+      aos::Alliance alliance);
+  flatbuffers::Offset<frc971::MultiSpline> TwoPieceViaStageSpline3(
+      aos::Sender<frc971::control_loops::drivetrain::SplineGoal>::Builder
+          *builder,
+      aos::Alliance alliance);
+  flatbuffers::Offset<frc971::MultiSpline> TwoPieceViaStageSpline4(
+      aos::Sender<frc971::control_loops::drivetrain::SplineGoal>::Builder
+          *builder,
+      aos::Alliance alliance);
+
  private:
   aos::FlatbufferDetachedBuffer<frc971::MultiSpline> test_spline_;
   aos::FlatbufferDetachedBuffer<frc971::MultiSpline> mobility_and_shoot_spline_;
@@ -113,6 +142,15 @@
   aos::FlatbufferDetachedBuffer<frc971::MultiSpline> two_piece_steal_spline_2_;
   aos::FlatbufferDetachedBuffer<frc971::MultiSpline> two_piece_steal_spline_3_;
   aos::FlatbufferDetachedBuffer<frc971::MultiSpline> two_piece_steal_spline_4_;
+
+  aos::FlatbufferDetachedBuffer<frc971::MultiSpline>
+      two_piece_via_stage_spline_1_;
+  aos::FlatbufferDetachedBuffer<frc971::MultiSpline>
+      two_piece_via_stage_spline_2_;
+  aos::FlatbufferDetachedBuffer<frc971::MultiSpline>
+      two_piece_via_stage_spline_3_;
+  aos::FlatbufferDetachedBuffer<frc971::MultiSpline>
+      two_piece_via_stage_spline_4_;
 };
 
 }  // namespace y2024::autonomous
diff --git a/y2024/autonomous/autonomous_actor.cc b/y2024/autonomous/autonomous_actor.cc
index 19ff2b8..0f70292 100644
--- a/y2024/autonomous/autonomous_actor.cc
+++ b/y2024/autonomous/autonomous_actor.cc
@@ -129,6 +129,30 @@
           two_piece_steal_splines_.value()[0].starting_position();
       CHECK(starting_position_);
       break;
+    case AutonomousMode::TWO_PIECE_VIA_STAGE:
+      AOS_LOG(INFO, "TWO_PIECE_VIA_STAGE replanning!");
+      two_piece_via_stage_splines_ = {
+          PlanSpline(
+              std::bind(&AutonomousSplines::TwoPieceViaStageSpline1,
+                        &auto_splines_, std::placeholders::_1, alliance_),
+              SplineDirection::kForward),
+          PlanSpline(
+              std::bind(&AutonomousSplines::TwoPieceViaStageSpline2,
+                        &auto_splines_, std::placeholders::_1, alliance_),
+              SplineDirection::kBackward),
+          PlanSpline(
+              std::bind(&AutonomousSplines::TwoPieceViaStageSpline3,
+                        &auto_splines_, std::placeholders::_1, alliance_),
+              SplineDirection::kForward),
+          PlanSpline(
+              std::bind(&AutonomousSplines::TwoPieceViaStageSpline4,
+                        &auto_splines_, std::placeholders::_1, alliance_),
+              SplineDirection::kBackward)};
+
+      starting_position_ =
+          two_piece_via_stage_splines_.value()[0].starting_position();
+      CHECK(starting_position_);
+      break;
   }
 
   is_planned_ = true;
@@ -161,6 +185,9 @@
     case AutonomousMode::TWO_PIECE_STEAL:
       TwoPieceStealAuto();
       break;
+    case AutonomousMode::TWO_PIECE_VIA_STAGE:
+      TwoPieceViaStageAuto();
+      break;
   }
   return true;
 }
@@ -457,6 +484,113 @@
       aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
 }
 
+void AutonomousActor::TwoPieceViaStageAuto() {
+  aos::monotonic_clock::time_point start_time = aos::monotonic_clock::now();
+
+  CHECK(two_piece_via_stage_splines_);
+  auto &splines = *two_piece_via_stage_splines_;
+
+  uint32_t initial_shot_count = shot_count();
+
+  // Always be aiming & firing.
+  Aim();
+  if (!WaitForPreloaded()) return;
+
+  Shoot();
+
+  AOS_LOG(
+      INFO, "Shooting Preloaded Note %lfs\n",
+      aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+
+  if (!WaitForNoteFired(initial_shot_count, std::chrono::seconds(2))) return;
+  StopAiming();
+
+  AOS_LOG(
+      INFO, "Shot first note %lfs\n",
+      aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+
+  StopFiring();
+
+  AOS_LOG(
+      INFO, "Starting Spline 1 %lfs\n",
+      aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+
+  if (!splines[0].WaitForPlan()) return;
+
+  splines[0].Start();
+
+  if (!splines[0].WaitForSplineDistanceRemaining(2.0)) return;
+  Intake();
+
+  if (!splines[0].WaitForSplineDistanceRemaining(0.01)) return;
+
+  if (!splines[1].WaitForPlan()) return;
+
+  AOS_LOG(
+      INFO, "Starting second spline %lfs\n",
+      aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+
+  splines[1].Start();
+
+  if (!splines[1].WaitForSplineDistanceRemaining(0.01)) return;
+
+  Aim();
+
+  AOS_LOG(
+      INFO, "Finished second spline %lfs\n",
+      aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+
+  std::this_thread::sleep_for(chrono::milliseconds(1000));
+
+  Shoot();
+  StopIntake();
+
+  if (!WaitForNoteFired(initial_shot_count + 1, std::chrono::seconds(2)))
+    return;
+
+  StopFiring();
+  StopAiming();
+
+  AOS_LOG(
+      INFO, "Shot second note, starting drive %lfs\n",
+      aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+
+  if (!splines[2].WaitForPlan()) return;
+
+  AOS_LOG(
+      INFO, "Starting third spline %lfs\n",
+      aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+  splines[2].Start();
+
+  if (!splines[2].WaitForSplineDistanceRemaining(2.0)) return;
+
+  Intake();
+
+  if (!splines[2].WaitForSplineDistanceRemaining(0.01)) return;
+
+  if (!splines[3].WaitForPlan()) return;
+
+  AOS_LOG(
+      INFO, "Starting fourth spline %lfs\n",
+      aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+  splines[3].Start();
+
+  if (!splines[3].WaitForSplineDistanceRemaining(0.01)) return;
+
+  Aim();
+
+  Shoot();
+
+  std::this_thread::sleep_for(chrono::milliseconds(400));
+
+  if (!WaitForNoteFired(initial_shot_count + 2, std::chrono::seconds(2)))
+    return;
+
+  AOS_LOG(
+      INFO, "Done %lfs\n",
+      aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
+}
+
 void AutonomousActor::SendSuperstructureGoal() {
   aos::Sender<control_loops::superstructure::GoalStatic>::StaticBuilder
       goal_builder = superstructure_goal_sender_.MakeStaticBuilder();
@@ -493,6 +627,11 @@
   SendSuperstructureGoal();
 }
 
+void AutonomousActor::StopAiming() {
+  set_auto_aim(control_loops::superstructure::AutoAimMode::NONE);
+  SendSuperstructureGoal();
+}
+
 void AutonomousActor::Aim() {
   set_auto_aim(control_loops::superstructure::AutoAimMode::SPEAKER);
   SendSuperstructureGoal();
diff --git a/y2024/autonomous/autonomous_actor.h b/y2024/autonomous/autonomous_actor.h
index e0b4f33..a126feb 100644
--- a/y2024/autonomous/autonomous_actor.h
+++ b/y2024/autonomous/autonomous_actor.h
@@ -43,11 +43,13 @@
   void MobilityAndShoot();
   void FourPieceAuto();
   void TwoPieceStealAuto();
+  void TwoPieceViaStageAuto();
   void SendSuperstructureGoal();
 
   void StopIntake();
   void Intake();
   void Aim();
+  void StopAiming();
   void Shoot();
   void StopFiring();
 
@@ -75,6 +77,7 @@
   std::optional<std::array<SplineHandle, 1>> mobility_and_shoot_splines_;
   std::optional<std::array<SplineHandle, 5>> four_piece_splines_;
   std::optional<std::array<SplineHandle, 4>> two_piece_steal_splines_;
+  std::optional<std::array<SplineHandle, 4>> two_piece_via_stage_splines_;
 
   control_loops::superstructure::IntakeGoal intake_goal_ =
       control_loops::superstructure::IntakeGoal::NONE;
diff --git a/y2024/autonomous/splines/2_piece_via_stage.0.json b/y2024/autonomous/splines/2_piece_via_stage.0.json
new file mode 100644
index 0000000..77fa6d1
--- /dev/null
+++ b/y2024/autonomous/splines/2_piece_via_stage.0.json
@@ -0,0 +1,33 @@
+{
+    "spline_count": 1,
+    "spline_x": [
+        -7.464294557723783,
+        -6.667696122353746,
+        -5.241623212631461,
+        -2.680791277578054,
+        -1.3692863158339523,
+        -0.49099735723340787
+    ],
+    "spline_y": [
+        0.25504399412981815,
+        -1.1178495529758359,
+        -1.7224603852027636,
+        -2.836160505190026,
+        -2.9055524852010888,
+        -3.119986483935894
+    ],
+    "constraints": [
+        {
+            "constraint_type": "LONGITUDINAL_ACCELERATION",
+            "value": 3
+        },
+        {
+            "constraint_type": "LATERAL_ACCELERATION",
+            "value": 2.0
+        },
+        {
+            "constraint_type": "VOLTAGE",
+            "value": 11.0
+        }
+    ]
+}
\ No newline at end of file
diff --git a/y2024/autonomous/splines/2_piece_via_stage.1.json b/y2024/autonomous/splines/2_piece_via_stage.1.json
new file mode 100644
index 0000000..a8e5b02
--- /dev/null
+++ b/y2024/autonomous/splines/2_piece_via_stage.1.json
@@ -0,0 +1,33 @@
+{
+    "spline_count": 1,
+    "spline_x": [
+        -0.49099735723340787,
+        -1.811418619189384,
+        -4.027875271387874,
+        -3.9295391727423667,
+        -3.479861068325508,
+        -4.298882384245665
+    ],
+    "spline_y": [
+        -3.119986483935894,
+        -2.797606009442813,
+        -2.6541176112878206,
+        -0.757854688577488,
+        0.5799550757531173,
+        0.8135924221044322
+    ],
+    "constraints": [
+        {
+            "constraint_type": "LONGITUDINAL_ACCELERATION",
+            "value": 3
+        },
+        {
+            "constraint_type": "LATERAL_ACCELERATION",
+            "value": 2.5
+        },
+        {
+            "constraint_type": "VOLTAGE",
+            "value": 9
+        }
+    ]
+}
\ No newline at end of file
diff --git a/y2024/autonomous/splines/2_piece_via_stage.2.json b/y2024/autonomous/splines/2_piece_via_stage.2.json
new file mode 100644
index 0000000..100bd6a
--- /dev/null
+++ b/y2024/autonomous/splines/2_piece_via_stage.2.json
@@ -0,0 +1,33 @@
+{
+    "spline_count": 1,
+    "spline_x": [
+        -4.298882384245665,
+        -3.1646278127814758,
+        -2.4989652488761096,
+        -2.1136673502503305,
+        -1.479573275804385,
+        -0.5811901698817614
+    ],
+    "spline_y": [
+        0.8135924221044322,
+        0.4900303572196947,
+        -0.13193291080313996,
+        -0.255438653484485,
+        -0.08108049299548094,
+        0.03128456186613349
+    ],
+    "constraints": [
+        {
+            "constraint_type": "LONGITUDINAL_ACCELERATION",
+            "value": 3
+        },
+        {
+            "constraint_type": "LATERAL_ACCELERATION",
+            "value": 2.5
+        },
+        {
+            "constraint_type": "VOLTAGE",
+            "value": 9
+        }
+    ]
+}
\ No newline at end of file
diff --git a/y2024/autonomous/splines/2_piece_via_stage.3.json b/y2024/autonomous/splines/2_piece_via_stage.3.json
new file mode 100644
index 0000000..b5f6f36
--- /dev/null
+++ b/y2024/autonomous/splines/2_piece_via_stage.3.json
@@ -0,0 +1,33 @@
+{
+    "spline_count": 1,
+    "spline_x": [
+        -0.5811901698817614,
+        -1.2747103831333484,
+        -2.2436699872068244,
+        -3.446197110414496,
+        -4.341355458388501,
+        -5.195728191425397
+    ],
+    "spline_y": [
+        0.03128456186613349,
+        -0.05545731506355678,
+        -0.2142730564625337,
+        0.5722193927307038,
+        0.8918482448895331,
+        0.8868886417599413
+    ],
+    "constraints": [
+        {
+            "constraint_type": "LONGITUDINAL_ACCELERATION",
+            "value": 3
+        },
+        {
+            "constraint_type": "LATERAL_ACCELERATION",
+            "value": 2.5
+        },
+        {
+            "constraint_type": "VOLTAGE",
+            "value": 9
+        }
+    ]
+}
\ No newline at end of file
diff --git a/y2024/autonomous/splines/five_note.3.json b/y2024/autonomous/splines/five_note.3.json
index 89dd72f..1727fee 100644
--- a/y2024/autonomous/splines/five_note.3.json
+++ b/y2024/autonomous/splines/five_note.3.json
@@ -4,17 +4,17 @@
         -5.450348048315508,
         -5.412173915783321,
         -3.905867155254269,
-        -2.390277169363972,
-        -1.4242176922097336,
-        -0.44894876385221405
+        -2.3471594367906876,
+        -1.3810999596364493,
+        -0.4058310312789297
     ],
     "spline_y": [
         2.3787148543274097,
         2.9222723661220313,
         4.035977082209158,
-        2.9014194169393095,
-        2.4045843838581282,
-        2.0389901653192535
+        2.6411922097100717,
+        2.1443571766288905,
+        1.7787629580900157
     ],
     "constraints": [
         {
diff --git a/y2024/autonomous/splines/five_note.4.json b/y2024/autonomous/splines/five_note.4.json
index 76ad4c3..e882898 100644
--- a/y2024/autonomous/splines/five_note.4.json
+++ b/y2024/autonomous/splines/five_note.4.json
@@ -1,17 +1,17 @@
 {
     "spline_count": 1,
     "spline_x": [
-        -0.44894876385221405,
-        -1.42422446903808,
-        -2.3902839461923184,
+        -0.4058310312789297,
+        -1.3811067364647958,
+        -2.347166213619034,
         -4.170024929006823,
         -5.19716914509787,
         -5.872082438576494
     ],
     "spline_y": [
-        2.0389901653192535,
-        2.4045869242541067,
-        2.901421957335288,
+        1.7787629580900157,
+        2.144359717024869,
+        2.64119475010605,
         2.268920393640828,
         1.8811990984641065,
         1.7637363058278848
diff --git a/y2024/constants.h b/y2024/constants.h
index 4cb5378..98fe468 100644
--- a/y2024/constants.h
+++ b/y2024/constants.h
@@ -161,6 +161,23 @@
   // 20 -> 28 reduction to a 0.5" radius roller
   static constexpr double kExtendRollerOutputRatio = (20.0 / 28.0) * 0.0127;
 
+  struct NoteParams {
+    // Measured in radians
+    double turret_offset = 0.0;
+
+    static NoteParams BlendY(double coefficient, NoteParams a1, NoteParams a2) {
+      using ::frc971::shooter_interpolation::Blend;
+      return NoteParams{.turret_offset = Blend(coefficient, a1.turret_offset,
+                                               a2.turret_offset)};
+    }
+
+    static NoteParams FromFlatbuffer(const y2024::NoteParams *note_params) {
+      return NoteParams{
+          .turret_offset = note_params->turret_offset(),
+      };
+    }
+  };
+
   struct ShotParams {
     // Measured in radians
     double shot_altitude_angle = 0.0;
@@ -197,6 +214,21 @@
     }
   };
 
+  static frc971::shooter_interpolation::InterpolationTable<NoteParams>
+  NoteInterpolationTableFromFlatbuffer(
+      const flatbuffers::Vector<
+          flatbuffers::Offset<y2024::NoteInterpolationTablePoint>> *table) {
+    std::vector<std::pair<double, NoteParams>> interpolation_table;
+
+    for (const NoteInterpolationTablePoint *point : *table) {
+      interpolation_table.emplace_back(
+          point->amperage(), NoteParams::FromFlatbuffer(point->note_params()));
+    }
+
+    return frc971::shooter_interpolation::InterpolationTable<NoteParams>(
+        interpolation_table);
+  }
+
   static frc971::shooter_interpolation::InterpolationTable<ShotParams>
   InterpolationTableFromFlatbuffer(
       const flatbuffers::Vector<
diff --git a/y2024/constants/7971.json b/y2024/constants/7971.json
index bb482f5..c924174 100644
--- a/y2024/constants/7971.json
+++ b/y2024/constants/7971.json
@@ -11,13 +11,13 @@
       "calibration": {% include 'y2024/constants/calib_files/calibration_imu-7971-0_cam-24-01_2024-03-02_19-44-12.098903651.json' %}
     },
     {
-      "calibration": {% include 'y2024/constants/calib_files/calibration_orin1-7971-0_cam-24-04_2024-03-24_15-52-29.json' %}
+      "calibration": {% include 'y2024/constants/calib_files/calibration_orin1-7971-0_cam-24-04_2024-04-07_19-59-36.json' %}
     },
     {
-      "calibration": {% include 'y2024/constants/calib_files/calibration_orin1-7971-1_cam-24-02_2024-03-24_15-52-29.json' %}
+      "calibration": {% include 'y2024/constants/calib_files/calibration_orin1-7971-1_cam-24-02_2024-04-07_19-59-36.json' %}
     },
     {
-      "calibration": {% include 'y2024/constants/calib_files/calibration_imu-7971-1_cam-24-03_2024-03-24_15-52-29.json' %}
+      "calibration": {% include 'y2024/constants/calib_files/calibration_imu-7971-1_cam-24-03_2024-04-07_19-59-36.json' %}
     }
   ],
   "robot": {
diff --git a/y2024/constants/971.json b/y2024/constants/971.json
index d6850b8..5145613 100644
--- a/y2024/constants/971.json
+++ b/y2024/constants/971.json
@@ -40,29 +40,29 @@
     "altitude_constants": {
       {% set _ = altitude_zero.update(
           {
-              "measured_absolute_position" : 0.156725048053565
+              "measured_absolute_position" : 0.183060873152545
           }
       ) %}
       "zeroing_constants": {{ altitude_zero | tojson(indent=2)}},
-      "potentiometer_offset": {{ -0.16416323147786 + 0.0111742298989474 + 0.0288009597941421 + 0.030747789533187 - 0.014014144034337 }}
+      "potentiometer_offset": {{ -0.18953940426369  }}
     },
     "turret_constants": {
       {% set _ = turret_zero.update(
           {
-              "measured_absolute_position" : 0.869811929996983
+              "measured_absolute_position" : 1.01975376211353
           }
       ) %}
       "zeroing_constants": {{ turret_zero | tojson(indent=2)}},
-      "potentiometer_offset": {{ -6.47164779835404 - 0.0711209027239817 + 1.0576004531907 - 0.343 - 0.05 + 0.72907099601435 }}
+      "potentiometer_offset": {{ -6.47164779835404 - 0.0711209027239817 + 1.0576004531907 - 0.343 - 0.05 + 0.72907099601435 - 0.0499928122527711 + 0.037944928379006 }}
     },
     "extend_constants": {
       {% set _ = extend_zero.update(
           {
-              "measured_absolute_position" : 0.1547
+              "measured_absolute_position" : 0.0992895926495078
           }
       ) %}
       "zeroing_constants": {{ extend_zero | tojson(indent=2)}},
-      "potentiometer_offset": {{ -0.2574404033256 + 0.0170793439542 - 0.177097393974999 + 0.3473623911879  - 0.1577}}
+      "potentiometer_offset": {{ -0.2574404033256 + 0.0170793439542 - 0.177097393974999 + 0.3473623911879  - 0.1577 - 0.0214825988393}}
     },
     "disable_extend": false,
     "disable_climber": false
diff --git a/y2024/constants/BUILD b/y2024/constants/BUILD
index b07851e..7e5a41a 100644
--- a/y2024/constants/BUILD
+++ b/y2024/constants/BUILD
@@ -23,16 +23,16 @@
     includes = glob([
         "test_data/*.json",
     ]) + [
-        "//y2024/control_loops/superstructure/intake_pivot:intake_pivot_json",
-        "//y2024/control_loops/superstructure/climber:climber_json",
-        "//y2024/control_loops/superstructure/catapult:catapult_json",
-        "//y2024/control_loops/superstructure/altitude:altitude_json",
-        "//y2024/control_loops/superstructure/extend:extend_json",
-        "//y2024/control_loops/superstructure/turret:turret_json",
-        "//y2024/control_loops/drivetrain:drivetrain_config.json",
-        "//y2024/constants/calib_files",
-        "common.json",
         "common.jinja2",
+        "common.json",
+        "//y2024/constants/calib_files",
+        "//y2024/control_loops/drivetrain:drivetrain_config.json",
+        "//y2024/control_loops/superstructure/altitude:altitude_json",
+        "//y2024/control_loops/superstructure/catapult:catapult_json",
+        "//y2024/control_loops/superstructure/climber:climber_json",
+        "//y2024/control_loops/superstructure/extend:extend_json",
+        "//y2024/control_loops/superstructure/intake_pivot:intake_pivot_json",
+        "//y2024/control_loops/superstructure/turret:turret_json",
         "//y2024/vision/maps",
     ],
     parameters = {},
diff --git a/y2024/constants/calib_files/calibration_imu-7971-1_cam-24-03_2024-03-24_15-52-29.json b/y2024/constants/calib_files/calibration_imu-7971-1_cam-24-03_2024-04-07_19-59-36.json
similarity index 62%
rename from y2024/constants/calib_files/calibration_imu-7971-1_cam-24-03_2024-03-24_15-52-29.json
rename to y2024/constants/calib_files/calibration_imu-7971-1_cam-24-03_2024-04-07_19-59-36.json
index 531c93a..348f972 100755
--- a/y2024/constants/calib_files/calibration_imu-7971-1_cam-24-03_2024-03-24_15-52-29.json
+++ b/y2024/constants/calib_files/calibration_imu-7971-1_cam-24-03_2024-04-07_19-59-36.json
@@ -14,18 +14,18 @@
  ],
  "fixed_extrinsics": {
   "data": [
-   0.575723,
-   -0.040861,
-   0.816623,
-   0.013075,
-   -0.817594,
-   -0.039986,
-   0.574406,
-   -0.160772,
-   0.009183,
-   -0.998364,
-   -0.056428,
-   -0.001121,
+   0.452192,
+   0.00902,
+   0.891875,
+   -0.110093,
+   -0.891901,
+   -0.002083,
+   0.452226,
+   -0.071899,
+   0.005936,
+   -0.999957,
+   0.007103,
+   -0.059938,
    0.0,
    0.0,
    0.0,
@@ -39,7 +39,7 @@
   -0.000061,
   -0.00879
  ],
- "calibration_timestamp": 1711320749871838931,
+ "calibration_timestamp": 1712545176741878704,
  "camera_id": "24-03",
  "camera_number": 1
 }
\ No newline at end of file
diff --git a/y2024/constants/calib_files/calibration_orin1-7971-0_cam-24-04_2024-03-24_15-52-29.json b/y2024/constants/calib_files/calibration_orin1-7971-0_cam-24-04_2024-04-07_19-59-36.json
similarity index 62%
rename from y2024/constants/calib_files/calibration_orin1-7971-0_cam-24-04_2024-03-24_15-52-29.json
rename to y2024/constants/calib_files/calibration_orin1-7971-0_cam-24-04_2024-04-07_19-59-36.json
index 048b1c2..e1da2b1 100755
--- a/y2024/constants/calib_files/calibration_orin1-7971-0_cam-24-04_2024-03-24_15-52-29.json
+++ b/y2024/constants/calib_files/calibration_orin1-7971-0_cam-24-04_2024-04-07_19-59-36.json
@@ -14,18 +14,18 @@
  ],
  "fixed_extrinsics": {
   "data": [
-   -0.970596,
-   0.003379,
-   0.24069,
-   -0.005665,
-   -0.240584,
-   -0.046418,
-   -0.969518,
-   -0.614682,
-   0.007896,
-   -0.998916,
-   0.045866,
-   -0.040333,
+   -0.999934,
+   0.005678,
+   -0.010023,
+   -0.137953,
+   0.010219,
+   0.035665,
+   -0.999312,
+   -0.441623,
+   -0.005316,
+   -0.999348,
+   -0.035721,
+   -0.062839,
    0.0,
    0.0,
    0.0,
@@ -39,7 +39,7 @@
   0.000099,
   -0.005468
  ],
- "calibration_timestamp": 1711320749872657675,
+ "calibration_timestamp": 1712545176746742231,
  "camera_id": "24-04",
  "camera_number": 0
 }
\ No newline at end of file
diff --git a/y2024/constants/calib_files/calibration_orin1-7971-1_cam-24-02_2024-03-24_15-52-29.json b/y2024/constants/calib_files/calibration_orin1-7971-1_cam-24-02_2024-04-07_19-59-36.json
similarity index 62%
rename from y2024/constants/calib_files/calibration_orin1-7971-1_cam-24-02_2024-03-24_15-52-29.json
rename to y2024/constants/calib_files/calibration_orin1-7971-1_cam-24-02_2024-04-07_19-59-36.json
index 19daf8d..513260e 100755
--- a/y2024/constants/calib_files/calibration_orin1-7971-1_cam-24-02_2024-03-24_15-52-29.json
+++ b/y2024/constants/calib_files/calibration_orin1-7971-1_cam-24-02_2024-04-07_19-59-36.json
@@ -14,18 +14,18 @@
  ],
  "fixed_extrinsics": {
   "data": [
-   -0.36422,
-   -0.025676,
-   0.930959,
-   0.048013,
-   -0.930708,
-   -0.025986,
-   -0.364839,
-   -0.413226,
-   0.03356,
-   -0.999332,
-   -0.014433,
-   -0.000913,
+   -0.509434,
+   0.040476,
+   0.859557,
+   -0.100912,
+   -0.860154,
+   0.004756,
+   -0.510011,
+   -0.308016,
+   -0.024732,
+   -0.999169,
+   0.032393,
+   -0.075196,
    0.0,
    0.0,
    0.0,
@@ -39,7 +39,7 @@
   0.000015,
   -0.005636
  ],
- "calibration_timestamp": 1711320749872324734,
+ "calibration_timestamp": 1712545176745420643,
  "camera_id": "24-02",
  "camera_number": 1
 }
\ No newline at end of file
diff --git a/y2024/constants/common.json b/y2024/constants/common.json
index 9331f54..c1cd1f7 100644
--- a/y2024/constants/common.json
+++ b/y2024/constants/common.json
@@ -9,42 +9,42 @@
     {
       "distance_from_goal": 4.0,
       "shot_params": {
-          "shot_altitude_angle": 1.15,
-          "shot_speed_over_ground": 1.0
+          "shot_altitude_angle": 0.93,
+          "shot_speed_over_ground": 100000.0
       }
     },
     {
       "distance_from_goal": 6.5,
       "shot_params": {
-          "shot_altitude_angle": 1.15,
-          "shot_speed_over_ground": 1.0
+          "shot_altitude_angle": 0.93,
+          "shot_speed_over_ground": 100000.0
       }
     },
     {
       "distance_from_goal": 8.5,
       "shot_params": {
           "shot_altitude_angle": 0.85,
-          "shot_speed_over_ground": 1.0
+          "shot_speed_over_ground": 100000.0
       }
     },
     {
       "distance_from_goal": 10.0,
       "shot_params": {
           "shot_altitude_angle": 0.8,
-          "shot_speed_over_ground": 1.0
+          "shot_speed_over_ground": 100000.0
       }
     },
     {
       "distance_from_goal": 15.0,
       "shot_params": {
           "shot_altitude_angle": 0.75,
-          "shot_speed_over_ground": 1.0
+          "shot_speed_over_ground": 100000.0
       }
     }
   ],
   "shooter_interpolation_table": [
     {
-        "distance_from_goal": 0.7,
+        "distance_from_goal": 0.5,
         "shot_params": {
             "shot_altitude_angle": 0.85,
             "shot_speed_over_ground": 16.0
@@ -53,21 +53,21 @@
     {
       "distance_from_goal": 1.24,
       "shot_params": {
-          "shot_altitude_angle": 0.85,
+          "shot_altitude_angle": 0.825,
           "shot_speed_over_ground": 16.0
       }
     },
     {
       "distance_from_goal": 1.904,
       "shot_params": {
-          "shot_altitude_angle": 0.73,
+          "shot_altitude_angle": 0.66,
           "shot_speed_over_ground": 16.0
       }
     },
     {
       "distance_from_goal": 2.404,
       "shot_params": {
-          "shot_altitude_angle": 0.645,
+          "shot_altitude_angle": 0.59,
           "shot_speed_over_ground": 16.0
       }
     },
@@ -75,32 +75,53 @@
     {
       "distance_from_goal": 2.744,
       "shot_params": {
-          "shot_altitude_angle": 0.61,
+          "shot_altitude_angle": 0.56,
           "shot_speed_over_ground": 16.0
       }
     },
     {
       "distance_from_goal": 3.274,
       "shot_params": {
-          "shot_altitude_angle": 0.55,
+          "shot_altitude_angle": 0.515,
+          "shot_speed_over_ground": 16.0
+      }
+    },
+    {
+      "distance_from_goal": 3.76,
+      "shot_params": {
+          "shot_altitude_angle": 0.50,
           "shot_speed_over_ground": 16.0
       }
     },
     {
       "distance_from_goal": 4.00,
       "shot_params": {
-          "shot_altitude_angle": 0.515,
+          "shot_altitude_angle": 0.465,
           "shot_speed_over_ground": 16.0
       }
     },
     {
       "distance_from_goal": 4.68,
       "shot_params": {
-          "shot_altitude_angle": 0.51,
+          "shot_altitude_angle": 0.47,
           "shot_speed_over_ground": 16.0
       }
     }
   ],
+  "note_interpolation_table": [
+    {
+        "amperage": 6.0,
+        "note_params": {
+            "turret_offset": 0.09
+        }
+    },
+    {
+        "amperage": 10.0,
+        "note_params": {
+            "turret_offset": 0.09
+        }
+    }
+  ],
   "intake_roller_voltages": {
     "spitting": -6.0,
     "intaking": 9.0
@@ -139,7 +160,7 @@
     "transfer_roller_supply_current_limit": 40,
     "transfer_roller_stator_current_limit": 50,
     "drivetrain_supply_current_limit": 50,
-    "drivetrain_stator_current_limit": 200,
+    "drivetrain_stator_current_limit": 70,
     "climber_supply_current_limit": 40,
     "climber_stator_current_limit": 150,
     "extend_supply_current_limit": 30,
@@ -153,7 +174,7 @@
     "catapult_supply_current_limit": 60,
     "catapult_stator_current_limit": 250,
     "retention_roller_stator_current_limit": 20,
-    "slower_retention_roller_stator_current_limit": 2,
+    "slower_retention_roller_stator_current_limit": 12,
     "shooting_retention_roller_stator_current_limit": -20,
     "retention_roller_supply_current_limit": 10
   },
@@ -297,9 +318,10 @@
   "turret_loading_position": 0.58,
   "catapult_return_position": 0.0,
   "min_altitude_shooting_angle": 0.4,
-  "max_altitude_shooting_angle": 1.15,
+  "max_altitude_shooting_angle": 0.94,
   "retention_roller_voltages": {
-    "retaining": 1.5,
+    "intaking": 1.5,
+    "retaining": 0.6,
     "spitting": 6.0
   },
   // TODO(Filip): Update the speaker and amp shooter setpoints
@@ -316,8 +338,8 @@
   "extend_set_points": {
     "trap": 0.46,
     "amp": 0.35,
-    "catapult": 0.017,
-    "retracted": 0.017
+    "catapult": 0.022,
+    "retracted": 0.022
   },
   "turret_avoid_extend_collision_position": 0.0,
   "altitude_avoid_extend_collision_position": 0.3,
diff --git a/y2024/constants/constants.fbs b/y2024/constants/constants.fbs
index 4cc3502..6c1480c 100644
--- a/y2024/constants/constants.fbs
+++ b/y2024/constants/constants.fbs
@@ -29,6 +29,15 @@
     shot_params: ShotParams (id: 1);
 }
 
+table NoteParams {
+    turret_offset: double (id: 0);
+}
+
+table NoteInterpolationTablePoint {
+    amperage: double (id: 0);
+    note_params: NoteParams (id: 1);
+}
+
 // Amount of voltage to give to the intake rollers when:
 // spitting, which represents voltage when IntakeRollerGoal is SPITTING
 // and intaking, which represents voltage when IntakeRollerGoal is INTAKING
@@ -125,6 +134,9 @@
   FIVE_PIECE = 3,
   // Auto which picks up two game pieces from the center
   TWO_PIECE_STEAL = 4,
+  // Auto which picks up two game pieces from the center, routing
+  // through center.
+  TWO_PIECE_VIA_STAGE = 5,
 }
 
 table RobotConstants {
@@ -161,6 +173,8 @@
 table RetentionRollerVoltages {
   retaining:double (id: 0);
   spitting:double (id: 1);
+  // Used for pulling the game-piece in while it is not yet loaded.
+  intaking:double (id: 2);
 }
 
 // Set of april tag targets, by april tag ID, to ignore when on a
@@ -175,6 +189,7 @@
   target_map:frc971.vision.TargetMap (id: 0);
   shooter_interpolation_table: [InterpolationTablePoint] (id: 1);
   shooter_shuttle_interpolation_table: [InterpolationTablePoint] (id: 30);
+  note_interpolation_table: [NoteInterpolationTablePoint] (id: 31);
   intake_roller_voltages:IntakeRollerVoltages (id : 2);
   intake_pivot_set_points:IntakePivotSetPoints (id: 3);
   intake_pivot:frc971.control_loops.StaticZeroingSingleDOFProfiledSubsystemCommonParams (id: 4);
diff --git a/y2024/control_loops/drivetrain/BUILD b/y2024/control_loops/drivetrain/BUILD
index 2a97a7b..958b723 100644
--- a/y2024/control_loops/drivetrain/BUILD
+++ b/y2024/control_loops/drivetrain/BUILD
@@ -1,6 +1,6 @@
 load("//aos:config.bzl", "aos_config")
-load("//tools/build_rules:template.bzl", "jinja2_template")
 load("//frc971/control_loops/drivetrain:drivetrain_config.bzl", "drivetrain_config")
+load("//tools/build_rules:template.bzl", "jinja2_template")
 
 genrule(
     name = "genrule_drivetrain",
diff --git a/y2024/control_loops/superstructure/BUILD b/y2024/control_loops/superstructure/BUILD
index 4e33f20..6c1075a 100644
--- a/y2024/control_loops/superstructure/BUILD
+++ b/y2024/control_loops/superstructure/BUILD
@@ -1,6 +1,6 @@
-load("//tools/build_rules:js.bzl", "ts_project")
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
+load("//tools/build_rules:js.bzl", "ts_project")
 
 package(default_visibility = ["//visibility:public"])
 
@@ -220,11 +220,13 @@
         "aiming.h",
     ],
     deps = [
+        ":superstructure_can_position_fbs",
         ":superstructure_goal_fbs",
         ":superstructure_status_fbs",
         "//frc971/control_loops:static_zeroing_single_dof_profiled_subsystem",
         "//frc971/control_loops/aiming",
         "//frc971/control_loops/drivetrain:drivetrain_status_fbs",
+        "//frc971/zeroing:averager",
         "//y2024:constants",
         "//y2024/constants:constants_fbs",
         "//y2024/control_loops/drivetrain:drivetrain_base",
diff --git a/y2024/control_loops/superstructure/aiming.cc b/y2024/control_loops/superstructure/aiming.cc
index 200029e..d8d336f 100644
--- a/y2024/control_loops/superstructure/aiming.cc
+++ b/y2024/control_loops/superstructure/aiming.cc
@@ -22,8 +22,22 @@
           y2024::constants::Values::InterpolationTableFromFlatbuffer(
               robot_constants_->common()
                   ->shooter_shuttle_interpolation_table())),
+      note_interpolation_table_(
+          y2024::constants::Values::NoteInterpolationTableFromFlatbuffer(
+              robot_constants_->common()->note_interpolation_table())),
       joystick_state_fetcher_(
-          event_loop_->MakeFetcher<aos::JoystickState>("/aos")) {}
+          event_loop_->MakeFetcher<aos::JoystickState>("/aos")) {
+  event_loop_->MakeWatcher(
+      "/superstructure/rio",
+      [this](const y2024::control_loops::superstructure::CANPosition &msg) {
+        if (latch_current_) return;
+
+        if (msg.has_retention_roller()) {
+          note_current_average_.AddData(
+              msg.retention_roller()->torque_current());
+        }
+      });
+}
 
 void Aimer::Update(
     const frc971::control_loops::drivetrain::Status *status,
@@ -38,8 +52,6 @@
   if (status == nullptr) {
     return;
   }
-  const frc971::control_loops::Pose robot_pose({status->x(), status->y(), 0},
-                                               status->theta());
   aos::Alliance alliance = aos::Alliance::kRed;
   if (!joystick_state_fetcher_.Fetch() && !received_joystick_state_) {
     received_joystick_state_ = false;
@@ -50,6 +62,15 @@
     alliance = joystick_state_fetcher_->alliance();
   }
 
+  const bool ignore_localizer_pos =
+      auto_aim_mode == AutoAimMode::TURRET_SHUTTLE;
+  const Eigen::Vector3d ignore_localizer_position{
+      0.0 * (alliance == aos::Alliance::kRed ? 1.0 : -1.0), -1.0, 0.0};
+  const frc971::control_loops::Pose robot_pose(
+      ignore_localizer_pos ? ignore_localizer_position
+                           : Eigen::Vector3d{status->x(), status->y(), 0},
+      status->theta());
+
   frc971::shooter_interpolation::InterpolationTable<
       y2024::constants::Values::ShotParams> *current_interpolation_table =
       interpolation_tables_.at(auto_aim_mode);
@@ -73,7 +94,14 @@
                      robot_constants_->common()->turret()->range()),
                  current_interpolation_table->Get(current_goal_.target_distance)
                      .shot_speed_over_ground,
-                 /*wrap_mode=*/0.15, M_PI - kTurretZeroOffset},
+                 /*wrap_mode=*/0.15,
+                 // If we don't have any retention roller data, the averager
+                 // will return 0. If we get a current that is out-of-range of
+                 // the interpolation table, we will use the terminal values of
+                 // the interpolation table.
+                 M_PI - note_interpolation_table_
+                            .Get(note_current_average_.GetAverage()(0))
+                            .turret_offset},
       RobotState{
           robot_pose, {xdot, ydot}, linear_angular(1), current_goal_.position});
 
@@ -86,6 +114,9 @@
   builder.add_turret_position(current_goal_.position);
   builder.add_turret_velocity(current_goal_.velocity);
   builder.add_target_distance(current_goal_.target_distance);
-  builder.add_shot_distance(DistanceToGoal());
+  builder.add_note_current(note_current_average_.GetAverage()(0));
+  builder.add_current_turret_offset(
+      note_interpolation_table_.Get(note_current_average_.GetAverage()(0))
+          .turret_offset);
   return builder.Finish();
 }
diff --git a/y2024/control_loops/superstructure/aiming.h b/y2024/control_loops/superstructure/aiming.h
index 4560071..95e5840 100644
--- a/y2024/control_loops/superstructure/aiming.h
+++ b/y2024/control_loops/superstructure/aiming.h
@@ -8,9 +8,11 @@
 #include "frc971/control_loops/pose.h"
 #include "frc971/control_loops/static_zeroing_single_dof_profiled_subsystem.h"
 #include "frc971/shooter_interpolation/interpolation.h"
+#include "frc971/zeroing/averager.h"
 #include "y2024/constants.h"
 #include "y2024/constants/constants_generated.h"
 #include "y2024/control_loops/drivetrain/drivetrain_base.h"
+#include "y2024/control_loops/superstructure/superstructure_can_position_static.h"
 #include "y2024/control_loops/superstructure/superstructure_goal_generated.h"
 #include "y2024/control_loops/superstructure/superstructure_status_generated.h"
 using y2024::control_loops::superstructure::AimerStatus;
@@ -19,9 +21,6 @@
 
 class Aimer {
  public:
-  // When the turret is at 0 the note will be leaving the robot at PI.
-  static constexpr double kTurretZeroOffset = 0.11;
-
   Aimer(aos::EventLoop *event_loop, const Constants *robot_constants);
 
   void Update(
@@ -33,6 +32,12 @@
 
   double DistanceToGoal() const { return current_goal_.virtual_shot_distance; }
 
+  // Indicate that we are ready so that we can reset the note current filter to
+  // avoid taking values from when we were still seating the note.
+  void IndicateReady() { note_current_average_.Reset(); }
+
+  void latch_note_current(bool latch) { latch_current_ = latch; }
+
   flatbuffers::Offset<AimerStatus> PopulateStatus(
       flatbuffers::FlatBufferBuilder *fbb) const;
 
@@ -41,6 +46,8 @@
 
   const Constants *robot_constants_;
 
+  bool latch_current_ = false;
+
   frc971::control_loops::drivetrain::DrivetrainConfig<double>
       drivetrain_config_;
 
@@ -52,11 +59,16 @@
       y2024::constants::Values::ShotParams>
       interpolation_table_shuttle_;
 
+  frc971::shooter_interpolation::InterpolationTable<
+      y2024::constants::Values::NoteParams>
+      note_interpolation_table_;
+
   std::map<AutoAimMode, frc971::shooter_interpolation::InterpolationTable<
                             y2024::constants::Values::ShotParams> *>
       interpolation_tables_ = {
           {AutoAimMode::SPEAKER, &interpolation_table_},
-          {AutoAimMode::SHUTTLE, &interpolation_table_shuttle_}};
+          {AutoAimMode::SHUTTLE, &interpolation_table_shuttle_},
+          {AutoAimMode::TURRET_SHUTTLE, &interpolation_table_shuttle_}};
 
   std::map<AutoAimMode, frc971::control_loops::Pose> red_alliance_goals_ = {
       {AutoAimMode::SPEAKER,
@@ -80,6 +92,18 @@
                   ->shooter_shuttle_targets()
                   ->red_alliance()
                   ->theta()),
+      },
+      {
+          AutoAimMode::TURRET_SHUTTLE,
+          frc971::control_loops::Pose(
+              frc971::ToEigenOrDie<3, 1>(*robot_constants_->common()
+                                              ->shooter_shuttle_targets()
+                                              ->red_alliance()
+                                              ->pos()),
+              robot_constants_->common()
+                  ->shooter_shuttle_targets()
+                  ->red_alliance()
+                  ->theta()),
       }};
 
   std::map<AutoAimMode, frc971::control_loops::Pose> blue_alliance_goals_ = {
@@ -104,10 +128,24 @@
                   ->shooter_shuttle_targets()
                   ->blue_alliance()
                   ->theta()),
+      },
+      {
+          AutoAimMode::TURRET_SHUTTLE,
+          frc971::control_loops::Pose(
+              frc971::ToEigenOrDie<3, 1>(*robot_constants_->common()
+                                              ->shooter_shuttle_targets()
+                                              ->blue_alliance()
+                                              ->pos()),
+              robot_constants_->common()
+                  ->shooter_shuttle_targets()
+                  ->blue_alliance()
+                  ->theta()),
       }};
 
   aos::Fetcher<aos::JoystickState> joystick_state_fetcher_;
 
+  frc971::zeroing::Averager<double, 50> note_current_average_;
+
   frc971::control_loops::aiming::TurretGoal current_goal_;
 
   bool received_joystick_state_ = false;
diff --git a/y2024/control_loops/superstructure/collision_avoidance.h b/y2024/control_loops/superstructure/collision_avoidance.h
index be58b35..dcc26d4 100644
--- a/y2024/control_loops/superstructure/collision_avoidance.h
+++ b/y2024/control_loops/superstructure/collision_avoidance.h
@@ -47,7 +47,7 @@
   // Tolerances for the subsystems
   static constexpr double kEpsTurret = 0.05;
   static constexpr double kEpsIntake = 0.05;
-  static constexpr double kEpsExtend = 0.01;
+  static constexpr double kEpsExtend = 0.005;
 
   CollisionAvoidance();
 
diff --git a/y2024/control_loops/superstructure/shooter.cc b/y2024/control_loops/superstructure/shooter.cc
index 0c52360..6e1fc71 100644
--- a/y2024/control_loops/superstructure/shooter.cc
+++ b/y2024/control_loops/superstructure/shooter.cc
@@ -93,9 +93,11 @@
   // Always retain the game piece if we are enabled.
   if (retention_roller_output != nullptr) {
     *retention_roller_output =
-        robot_constants_->common()->retention_roller_voltages()->retaining();
+        robot_constants_->common()->retention_roller_voltages()->intaking();
 
     if (piece_loaded) {
+      *retention_roller_output =
+          robot_constants_->common()->retention_roller_voltages()->retaining();
       *retention_roller_stator_current_limit =
           robot_constants_->common()
               ->current_limits()
@@ -150,7 +152,7 @@
   frc971::shooter_interpolation::InterpolationTable<
       y2024::constants::Values::ShotParams> *interpolation_table =
       (shooter_goal != nullptr &&
-       shooter_goal->auto_aim() == AutoAimMode::SHUTTLE)
+       shooter_goal->auto_aim() != AutoAimMode::SPEAKER)
           ? &interpolation_table_shuttle_
           : &interpolation_table_;
   if ((piece_loaded || state_ == CatapultState::FIRING) &&
@@ -283,9 +285,11 @@
       case CatapultState::READY:
         [[fallthrough]];
       case CatapultState::LOADED: {
+        aimer_.latch_note_current(false);
         if (piece_loaded) {
           state_ = CatapultState::LOADED;
         } else {
+          aimer_.IndicateReady();
           state_ = CatapultState::READY;
         }
 
@@ -311,6 +315,7 @@
         [[fallthrough]];
       }
       case CatapultState::FIRING:
+        aimer_.latch_note_current(true);
         *retention_roller_output =
             robot_constants_->common()->retention_roller_voltages()->spitting();
         *retention_roller_stator_current_limit =
@@ -336,6 +341,7 @@
         }
         [[fallthrough]];
       case CatapultState::RETRACTING:
+        aimer_.latch_note_current(false);
         catapult_.set_controller_index(0);
         catapult_.mutable_profile()->set_maximum_acceleration(
             kLoadingAcceleration);
diff --git a/y2024/control_loops/superstructure/superstructure.cc b/y2024/control_loops/superstructure/superstructure.cc
index e22dc80..a485943 100644
--- a/y2024/control_loops/superstructure/superstructure.cc
+++ b/y2024/control_loops/superstructure/superstructure.cc
@@ -17,7 +17,8 @@
 constexpr double kExtendThreshold = 0.01;
 
 constexpr double kTurretLoadingThreshold = 0.05;
-constexpr double kAltitudeLoadingThreshold = 0.02;
+// Extra large so that we can survive loss of zeroes.
+constexpr double kAltitudeLoadingThreshold = 0.04;
 
 constexpr std::chrono::milliseconds kExtraIntakingTime =
     std::chrono::milliseconds(500);
diff --git a/y2024/control_loops/superstructure/superstructure_goal.fbs b/y2024/control_loops/superstructure/superstructure_goal.fbs
index 2a5fb00..c93f6f3 100644
--- a/y2024/control_loops/superstructure/superstructure_goal.fbs
+++ b/y2024/control_loops/superstructure/superstructure_goal.fbs
@@ -30,6 +30,7 @@
     NONE = 0, // No auto aim.
     SPEAKER = 1, // Auto aim for the speaker shot.
     SHUTTLE = 2, // Auto aim for the shuttle shot.
+    TURRET_SHUTTLE = 3, // Auto aim for the turret-only shuttle shot.
 }
 
 table ShooterGoal {
@@ -79,7 +80,7 @@
     fire: bool (id: 4);
 
     // Tells the climber to go absurdly slow on FULL_EXTEND
-    // Deprecated now because we take care of this through 
+    // Deprecated now because we take care of this through
     // climber_goal_voltage
     slow_climber: bool = false (id: 6, deprecated);
 
diff --git a/y2024/control_loops/superstructure/superstructure_lib_test.cc b/y2024/control_loops/superstructure/superstructure_lib_test.cc
index 512ccab..59398ab 100644
--- a/y2024/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2024/control_loops/superstructure/superstructure_lib_test.cc
@@ -48,6 +48,10 @@
     AbsoluteEncoderSubsystem::State,
     constants::Values::AbsoluteEncoderConstants>;
 
+// Value to make the auto-aim tests pass because they use a current-based
+// interpolation table. This should be the zero-value.
+static constexpr double kTurretZeroOffset = 0.09;
+
 class SuperstructureSimulation {
  public:
   SuperstructureSimulation(::aos::EventLoop *event_loop,
@@ -1389,11 +1393,11 @@
   EXPECT_NEAR(
       -M_PI_2,
       superstructure_status_fetcher_->shooter()->aimer()->turret_position() -
-          M_PI - Aimer::kTurretZeroOffset,
+          M_PI - kTurretZeroOffset,
       5e-4);
   EXPECT_NEAR(-M_PI_2,
               superstructure_status_fetcher_->shooter()->turret()->position() -
-                  M_PI - Aimer::kTurretZeroOffset,
+                  M_PI - kTurretZeroOffset,
               5e-4);
 
   EXPECT_EQ(
@@ -1435,11 +1439,11 @@
   EXPECT_NEAR(
       M_PI_2,
       superstructure_status_fetcher_->shooter()->aimer()->turret_position() +
-          M_PI - Aimer::kTurretZeroOffset,
+          M_PI - kTurretZeroOffset,
       5e-4);
   EXPECT_NEAR(M_PI_2,
               superstructure_status_fetcher_->shooter()->turret()->position() +
-                  M_PI - Aimer::kTurretZeroOffset,
+                  M_PI - kTurretZeroOffset,
               5e-4);
   EXPECT_EQ(
       kDistanceFromSpeaker,
diff --git a/y2024/control_loops/superstructure/superstructure_status.fbs b/y2024/control_loops/superstructure/superstructure_status.fbs
index 7a508dd..c73115f 100644
--- a/y2024/control_loops/superstructure/superstructure_status.fbs
+++ b/y2024/control_loops/superstructure/superstructure_status.fbs
@@ -52,6 +52,10 @@
   // The current "shot distance." When shooting on the fly, this may be
   // different from the static distance to the target.
   shot_distance:double (id: 3);
+  // Estimate of the retention roller current.
+  note_current:double (id: 4);
+  // Turret offset applied due to retention roller current.
+  current_turret_offset:double (id: 5);
 }
 
 // Enum representing where the superstructure
@@ -140,7 +144,7 @@
   transfer_roller:TransferRollerStatus (id: 5);
 
   // Estimated angle and angular velocitiy of the climber.
-  // Deprecated now because climber no longer has an encoder 
+  // Deprecated now because climber no longer has an encoder
   // and climber status is not used
   climber:frc971.control_loops.PotAndAbsoluteEncoderProfiledJointStatus (id: 6, deprecated);
 
diff --git a/y2024/joystick_reader.cc b/y2024/joystick_reader.cc
index a915507..711f9d2 100644
--- a/y2024/joystick_reader.cc
+++ b/y2024/joystick_reader.cc
@@ -34,6 +34,8 @@
 
 DEFINE_double(speaker_altitude_position_override, -1,
               "If set, use this as the altitude angle for the fixed shot.");
+DEFINE_bool(allow_force_preload, false,
+            "If set, enable the kForcePreload button.");
 
 namespace y2024::input::joysticks {
 
@@ -51,6 +53,7 @@
 const ButtonLocation kCatapultLoad(2, 1);
 const ButtonLocation kAmp(2, 4);
 const ButtonLocation kFire(2, 8);
+const ButtonLocation kForceLoad(2, 9);
 const ButtonLocation kDriverFire(1, 1);
 const ButtonLocation kTrap(2, 6);
 const ButtonLocation kAutoAim(1, 8);
@@ -60,6 +63,7 @@
 const ButtonLocation kRaiseClimber(3, 2);
 const ButtonLocation kRaiseFastClimber(3, 1);
 const ButtonLocation kAimShuttle(2, 10);
+const ButtonLocation kTurretShuttle(1, 10);
 const ButtonLocation kExtraButtonTwo(0, 0);
 const ButtonLocation kExtraButtonThree(0, 0);
 const ButtonLocation kExtraButtonFour(0, 0);
@@ -134,12 +138,17 @@
           superstructure::NoteGoal::NONE);
     }
     auto shooter_goal = superstructure_goal_builder->add_shooter_goal();
+    shooter_goal->set_preloaded(FLAGS_allow_force_preload &&
+                                data.IsPressed(kForceLoad));
     if (data.IsPressed(kAutoAim)) {
       shooter_goal->set_auto_aim(
           control_loops::superstructure::AutoAimMode::SPEAKER);
     } else if (data.IsPressed(kAimShuttle)) {
       shooter_goal->set_auto_aim(
           control_loops::superstructure::AutoAimMode::SHUTTLE);
+    } else if (data.IsPressed(kTurretShuttle)) {
+      shooter_goal->set_auto_aim(
+          control_loops::superstructure::AutoAimMode::TURRET_SHUTTLE);
     }
 
     // Updating aiming for shooter goal, only one type of aim should be possible
diff --git a/y2024/localizer/BUILD b/y2024/localizer/BUILD
index 5e2581a..d5a4348 100644
--- a/y2024/localizer/BUILD
+++ b/y2024/localizer/BUILD
@@ -1,6 +1,6 @@
+load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//tools/build_rules:js.bzl", "ts_project")
-load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 
 ts_project(
     name = "localizer_plotter",
diff --git a/y2024/localizer/localizer.cc b/y2024/localizer/localizer.cc
index 86ae457..d73d171 100644
--- a/y2024/localizer/localizer.cc
+++ b/y2024/localizer/localizer.cc
@@ -420,9 +420,13 @@
       return;
     } else {
       if (utils_.MaybeInAutonomous()) {
-        april_tag_noise_scalar = 2.0;
+        april_tag_noise_scalar = 1.5;
       } else {
-        april_tag_noise_scalar = 10.0;
+        if (target_id == 13 || target_id == 14) {
+          april_tag_noise_scalar = 5.0;
+        } else {
+          april_tag_noise_scalar = 5.0;
+        }
       }
     }
   }
diff --git a/y2024/wpilib_interface.cc b/y2024/wpilib_interface.cc
index 7a94595..30d1549 100644
--- a/y2024/wpilib_interface.cc
+++ b/y2024/wpilib_interface.cc
@@ -554,20 +554,20 @@
 
     std::shared_ptr<TalonFX> right_front = std::make_shared<TalonFX>(
         2, true, "Drivetrain Bus", &canivore_signal_registry,
-        current_limits->drivetrain_supply_current_limit(),
-        current_limits->drivetrain_stator_current_limit());
+        current_limits->drivetrain_stator_current_limit(),
+        current_limits->drivetrain_supply_current_limit());
     std::shared_ptr<TalonFX> right_back = std::make_shared<TalonFX>(
         1, true, "Drivetrain Bus", &canivore_signal_registry,
-        current_limits->drivetrain_supply_current_limit(),
-        current_limits->drivetrain_stator_current_limit());
+        current_limits->drivetrain_stator_current_limit(),
+        current_limits->drivetrain_supply_current_limit());
     std::shared_ptr<TalonFX> left_front = std::make_shared<TalonFX>(
         4, false, "Drivetrain Bus", &canivore_signal_registry,
-        current_limits->drivetrain_supply_current_limit(),
-        current_limits->drivetrain_stator_current_limit());
+        current_limits->drivetrain_stator_current_limit(),
+        current_limits->drivetrain_supply_current_limit());
     std::shared_ptr<TalonFX> left_back = std::make_shared<TalonFX>(
         5, false, "Drivetrain Bus", &canivore_signal_registry,
-        current_limits->drivetrain_supply_current_limit(),
-        current_limits->drivetrain_stator_current_limit());
+        current_limits->drivetrain_stator_current_limit(),
+        current_limits->drivetrain_supply_current_limit());
     std::shared_ptr<TalonFX> intake_pivot = std::make_shared<TalonFX>(
         6, false, "Drivetrain Bus", &canivore_signal_registry,
         current_limits->intake_pivot_stator_current_limit(),
diff --git a/y2024/www/BUILD b/y2024/www/BUILD
index 8bc3755..6b751ed 100644
--- a/y2024/www/BUILD
+++ b/y2024/www/BUILD
@@ -1,5 +1,5 @@
-load("//tools/build_rules:js.bzl", "rollup_bundle", "ts_project")
 load("//frc971/downloader:downloader.bzl", "aos_downloader_dir")
+load("//tools/build_rules:js.bzl", "rollup_bundle", "ts_project")
 
 filegroup(
     name = "files",
diff --git a/y2024/y2024_orin1.json b/y2024/y2024_orin1.json
index c37a394..280d8fe 100644
--- a/y2024/y2024_orin1.json
+++ b/y2024/y2024_orin1.json
@@ -441,7 +441,7 @@
         "--exposure=0",
         "--framerate=30",
         "--streaming_port=1181",
-        "--bitrate=2000000",
+        "--bitrate=1000000",
         "--data_dir=/home/pi/bin/image_streamer_www"
       ],
       "user": "pi",
diff --git a/y2024_defense/BUILD b/y2024_defense/BUILD
index 63b9502..8f888a5 100644
--- a/y2024_defense/BUILD
+++ b/y2024_defense/BUILD
@@ -1,6 +1,6 @@
-load("//frc971:downloader.bzl", "robot_downloader")
 load("//aos:config.bzl", "aos_config")
 load("//aos/util:config_validator_macro.bzl", "config_validator_test")
+load("//frc971:downloader.bzl", "robot_downloader")
 
 config_validator_test(
     name = "config_validator_test",
diff --git a/y2024_defense/www/BUILD b/y2024_defense/www/BUILD
index 7af68fe..aeaccf8 100644
--- a/y2024_defense/www/BUILD
+++ b/y2024_defense/www/BUILD
@@ -1,5 +1,5 @@
-load("//tools/build_rules:js.bzl", "rollup_bundle", "ts_project")
 load("//frc971/downloader:downloader.bzl", "aos_downloader_dir")
+load("//tools/build_rules:js.bzl", "rollup_bundle", "ts_project")
 
 filegroup(
     name = "files",
diff --git a/y2023_bot4/BUILD b/y2024_swerve/BUILD
similarity index 96%
rename from y2023_bot4/BUILD
rename to y2024_swerve/BUILD
index 095731a..c696c5a 100644
--- a/y2023_bot4/BUILD
+++ b/y2024_swerve/BUILD
@@ -1,11 +1,11 @@
-load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
-load("//frc971:downloader.bzl", "robot_downloader")
 load("//aos:config.bzl", "aos_config")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 load("//aos/util:config_validator_macro.bzl", "config_validator_test")
+load("//frc971:downloader.bzl", "robot_downloader")
 
 config_validator_test(
     name = "config_validator_test",
-    config = "//y2023_bot4:aos_config",
+    config = "//y2024_swerve:aos_config",
 )
 
 robot_downloader(
@@ -64,7 +64,7 @@
     srcs = [
         "swerve_drivetrain_output.json",
     ],
-    visibility = ["//y2023_bot4:__subpackages__"],
+    visibility = ["//y2024_swerve:__subpackages__"],
 )
 
 cc_library(
@@ -151,7 +151,7 @@
 
 aos_config(
     name = "aos_config",
-    src = "y2023_bot4.json",
+    src = "y2024_swerve.json",
     flatbuffers = [
         "//aos/network:message_bridge_client_fbs",
         "//aos/network:message_bridge_server_fbs",
@@ -169,7 +169,7 @@
 
 aos_config(
     name = "config_roborio",
-    src = "y2023_bot4_roborio.json",
+    src = "y2024_swerve_roborio.json",
     flatbuffers = [
         ":drivetrain_position_fbs",
         ":drivetrain_can_position_fbs",
@@ -195,7 +195,7 @@
 
 aos_config(
     name = "config_imu",
-    src = "y2023_bot4_imu.json",
+    src = "y2024_swerve_imu.json",
     flatbuffers = [
         "//aos/network:message_bridge_client_fbs",
         "//aos/network:message_bridge_server_fbs",
@@ -213,7 +213,7 @@
 
 aos_config(
     name = "config_logger",
-    src = "y2023_bot4_logger.json",
+    src = "y2024_swerve_logger.json",
     flatbuffers = [
         "//aos/network:message_bridge_client_fbs",
         "//aos/network:message_bridge_server_fbs",
diff --git a/y2023_bot4/constants.cc b/y2024_swerve/constants.cc
similarity index 94%
rename from y2023_bot4/constants.cc
rename to y2024_swerve/constants.cc
index 701308d..4f938a3 100644
--- a/y2023_bot4/constants.cc
+++ b/y2024_swerve/constants.cc
@@ -1,4 +1,4 @@
-#include "y2023_bot4/constants.h"
+#include "y2024_swerve/constants.h"
 
 #include <cstdint>
 
@@ -6,7 +6,7 @@
 
 #include "aos/network/team_number.h"
 
-namespace y2023_bot4::constants {
+namespace y2024_swerve::constants {
 Values MakeValues(uint16_t team) {
   LOG(INFO) << "creating a Constants for team: " << team;
   Values r;
@@ -47,4 +47,4 @@
 }
 
 Values MakeValues() { return MakeValues(aos::network::GetTeamNumber()); }
-}  // namespace y2023_bot4::constants
+}  // namespace y2024_swerve::constants
diff --git a/y2023_bot4/constants.h b/y2024_swerve/constants.h
similarity index 89%
rename from y2023_bot4/constants.h
rename to y2024_swerve/constants.h
index fbbc5f2..cf6c183 100644
--- a/y2023_bot4/constants.h
+++ b/y2024_swerve/constants.h
@@ -1,5 +1,5 @@
-#ifndef Y2023_BOT4_CONSTANTS_H
-#define Y2023_BOT4_CONSTANTS_H
+#ifndef Y2024_SWERVE_CONSTANTS_H
+#define Y2024_SWERVE_CONSTANTS_H
 
 #ifndef M_PI
 #define M_PI 3.14159265358979323846
@@ -9,7 +9,7 @@
 
 #include "frc971/constants.h"
 
-namespace y2023_bot4::constants {
+namespace y2024_swerve::constants {
 struct Values {
   static const int kZeroingSampleSize = 200;
 
@@ -48,6 +48,6 @@
 
 // Calls MakeValues with aos::network::GetTeamNumber()
 Values MakeValues();
-}  // namespace y2023_bot4::constants
+}  // namespace y2024_swerve::constants
 
-#endif  // Y2023_BOT4_CONSTANTS_H
+#endif  // Y2024_SWERVE_CONSTANTS_H
diff --git a/y2023_bot4/drivetrain_can_position.fbs b/y2024_swerve/drivetrain_can_position.fbs
similarity index 95%
rename from y2023_bot4/drivetrain_can_position.fbs
rename to y2024_swerve/drivetrain_can_position.fbs
index ef8edf7..f0d41a8 100644
--- a/y2023_bot4/drivetrain_can_position.fbs
+++ b/y2024_swerve/drivetrain_can_position.fbs
@@ -1,5 +1,5 @@
 include "frc971/control_loops/can_talonfx.fbs";
-namespace y2023_bot4;
+namespace y2024_swerve;
 
 table SwerveModuleCANPosition {
   rotation: frc971.control_loops.CANTalonFX (id: 0);
diff --git a/y2023_bot4/drivetrain_position.fbs b/y2024_swerve/drivetrain_position.fbs
similarity index 95%
rename from y2023_bot4/drivetrain_position.fbs
rename to y2024_swerve/drivetrain_position.fbs
index e5d0fc3..902cfee 100644
--- a/y2023_bot4/drivetrain_position.fbs
+++ b/y2024_swerve/drivetrain_position.fbs
@@ -1,5 +1,5 @@
 include "frc971/control_loops/control_loops.fbs";
-namespace y2023_bot4;
+namespace y2024_swerve;
 
 table AbsoluteDrivetrainPosition {
   // Position of the follower wheels from the encoders
diff --git a/y2023_bot4/swerve_drivetrain_output.json b/y2024_swerve/swerve_drivetrain_output.json
similarity index 100%
rename from y2023_bot4/swerve_drivetrain_output.json
rename to y2024_swerve/swerve_drivetrain_output.json
diff --git a/y2023_bot4/swerve_publisher_lib.cc b/y2024_swerve/swerve_publisher_lib.cc
similarity index 84%
rename from y2023_bot4/swerve_publisher_lib.cc
rename to y2024_swerve/swerve_publisher_lib.cc
index 78a778e..771d770 100644
--- a/y2023_bot4/swerve_publisher_lib.cc
+++ b/y2024_swerve/swerve_publisher_lib.cc
@@ -1,9 +1,9 @@
-#include "y2023_bot4/swerve_publisher_lib.h"
+#include "y2024_swerve/swerve_publisher_lib.h"
 
-y2023_bot4::SwervePublisher::SwervePublisher(aos::EventLoop *event_loop,
-                                             aos::ExitHandle *exit_handle,
-                                             const std::string &filename,
-                                             double duration)
+y2024_swerve::SwervePublisher::SwervePublisher(aos::EventLoop *event_loop,
+                                               aos::ExitHandle *exit_handle,
+                                               const std::string &filename,
+                                               double duration)
     : drivetrain_output_sender_(
           event_loop->MakeSender<drivetrain::swerve::Output>("/drivetrain")) {
   event_loop
diff --git a/y2023_bot4/swerve_publisher_lib.h b/y2024_swerve/swerve_publisher_lib.h
similarity index 77%
rename from y2023_bot4/swerve_publisher_lib.h
rename to y2024_swerve/swerve_publisher_lib.h
index 5969b7b..9206eab 100644
--- a/y2023_bot4/swerve_publisher_lib.h
+++ b/y2024_swerve/swerve_publisher_lib.h
@@ -1,5 +1,5 @@
-#ifndef Y2023_BOT4_SWERVE_PUBLISHER_H_
-#define Y2023_BOT4_SWERVE_PUBLISHER_H_
+#ifndef Y2024_SWERVE_SWERVE_PUBLISHER_H_
+#define Y2024_SWERVE_SWERVE_PUBLISHER_H_
 
 #include "gflags/gflags.h"
 #include "glog/logging.h"
@@ -10,7 +10,7 @@
 #include "aos/json_to_flatbuffer.h"
 #include "frc971/control_loops/drivetrain/swerve/swerve_drivetrain_output_generated.h"
 
-namespace y2023_bot4 {
+namespace y2024_swerve {
 
 namespace drivetrain = frc971::control_loops::drivetrain;
 
@@ -24,6 +24,6 @@
       drivetrain_output_sender_;
 };
 
-}  // namespace y2023_bot4
+}  // namespace y2024_swerve
 
-#endif  // Y2023_BOT4_SWERVE_PUBLISHER_H_
+#endif  // Y2024_SWERVE_SWERVE_PUBLISHER_H_
diff --git a/y2023_bot4/swerve_publisher_lib_test.cc b/y2024_swerve/swerve_publisher_lib_test.cc
similarity index 80%
rename from y2023_bot4/swerve_publisher_lib_test.cc
rename to y2024_swerve/swerve_publisher_lib_test.cc
index e834659..95892cc 100644
--- a/y2023_bot4/swerve_publisher_lib_test.cc
+++ b/y2024_swerve/swerve_publisher_lib_test.cc
@@ -1,14 +1,14 @@
-#include "y2023_bot4/swerve_publisher_lib.h"
+#include "y2024_swerve/swerve_publisher_lib.h"
 
 #include "gtest/gtest.h"
 
 #include "aos/events/simulated_event_loop.h"
 
-namespace y2023_bot4::testing {
+namespace y2024_swerve::testing {
 class SwervePublisherTest : public ::testing::Test {
  public:
   SwervePublisherTest()
-      : config_(aos::configuration::ReadConfig("y2023_bot4/aos_config.json")),
+      : config_(aos::configuration::ReadConfig("y2024_swerve/aos_config.json")),
         event_loop_factory_(&config_.message()),
         roborio_(aos::configuration::GetNode(
             event_loop_factory_.configuration(), "roborio")),
@@ -20,7 +20,7 @@
                 frc971::control_loops::drivetrain::swerve::Output>(
                 "/drivetrain")),
         swerve_publisher_(event_loop_.get(), exit_handle_.get(),
-                          "y2023_bot4/swerve_drivetrain_output.json", 100) {}
+                          "y2024_swerve/swerve_drivetrain_output.json", 100) {}
 
   void SendOutput() { event_loop_factory_.Run(); }
 
@@ -42,11 +42,11 @@
   aos::Fetcher<frc971::control_loops::drivetrain::swerve::Output>
       drivetrain_swerve_output_fetcher_;
 
-  y2023_bot4::SwervePublisher swerve_publisher_;
+  y2024_swerve::SwervePublisher swerve_publisher_;
 };
 
 TEST_F(SwervePublisherTest, CheckSentFb) {
   SendOutput();
   CheckOutput();
 }
-}  // namespace y2023_bot4::testing
+}  // namespace y2024_swerve::testing
diff --git a/y2023_bot4/swerve_publisher_main.cc b/y2024_swerve/swerve_publisher_main.cc
similarity index 72%
rename from y2023_bot4/swerve_publisher_main.cc
rename to y2024_swerve/swerve_publisher_main.cc
index 87470d7..5409da3 100644
--- a/y2023_bot4/swerve_publisher_main.cc
+++ b/y2024_swerve/swerve_publisher_main.cc
@@ -1,5 +1,5 @@
 #include "aos/events/shm_event_loop.h"
-#include "y2023_bot4/swerve_publisher_lib.h"
+#include "y2024_swerve/swerve_publisher_lib.h"
 
 DEFINE_double(duration, 100.0, "Length of time in Ms to apply current for");
 DEFINE_string(drivetrain_position, "swerve_drivetrain_output.json",
@@ -16,9 +16,9 @@
 
   std::unique_ptr<aos::ExitHandle> exit_handle = event_loop.MakeExitHandle();
 
-  y2023_bot4::SwervePublisher publisher(&event_loop, exit_handle.get(),
-                                        FLAGS_drivetrain_position,
-                                        FLAGS_duration);
+  y2024_swerve::SwervePublisher publisher(&event_loop, exit_handle.get(),
+                                          FLAGS_drivetrain_position,
+                                          FLAGS_duration);
 
   event_loop.Run();
 }
diff --git a/y2023_bot4/wpilib_interface.cc b/y2024_swerve/wpilib_interface.cc
similarity index 97%
rename from y2023_bot4/wpilib_interface.cc
rename to y2024_swerve/wpilib_interface.cc
index e5b5a6f..65741a4 100644
--- a/y2023_bot4/wpilib_interface.cc
+++ b/y2024_swerve/wpilib_interface.cc
@@ -9,9 +9,9 @@
 #include "frc971/wpilib/swerve/swerve_drivetrain_writer.h"
 #include "frc971/wpilib/talonfx.h"
 #include "frc971/wpilib/wpilib_robot_base.h"
-#include "y2023_bot4/constants.h"
-#include "y2023_bot4/drivetrain_can_position_static.h"
-#include "y2023_bot4/drivetrain_position_generated.h"
+#include "y2024_swerve/constants.h"
+#include "y2024_swerve/drivetrain_can_position_static.h"
+#include "y2024_swerve/drivetrain_position_generated.h"
 
 DEFINE_bool(ctre_diag_server, false,
             "If true, enable the diagnostics server for interacting with "
@@ -24,7 +24,7 @@
 
 namespace drivetrain = frc971::control_loops::drivetrain;
 
-namespace y2023_bot4::wpilib {
+namespace y2024_swerve::wpilib {
 namespace {
 
 template <class T>
@@ -303,6 +303,6 @@
   }
 };
 
-}  // namespace y2023_bot4::wpilib
+}  // namespace y2024_swerve::wpilib
 
-AOS_ROBOT_CLASS(::y2023_bot4::wpilib::WPILibRobot)
+AOS_ROBOT_CLASS(::y2024_swerve::wpilib::WPILibRobot)
diff --git a/y2023_bot4/y2023_bot4.json b/y2024_swerve/y2024_swerve.json
similarity index 71%
rename from y2023_bot4/y2023_bot4.json
rename to y2024_swerve/y2024_swerve.json
index 49db6fc..85d1ed9 100644
--- a/y2023_bot4/y2023_bot4.json
+++ b/y2024_swerve/y2024_swerve.json
@@ -12,8 +12,8 @@
     }
   ],
   "imports": [
-    "y2023_bot4_roborio.json",
-    "y2023_bot4_imu.json",
-    "y2023_bot4_logger.json"
+    "y2024_swerve_roborio.json",
+    "y2024_swerve_imu.json",
+    "y2024_swerve_logger.json"
   ]
 }
diff --git a/y2023_bot4/y2023_bot4_imu.json b/y2024_swerve/y2024_swerve_imu.json
similarity index 100%
rename from y2023_bot4/y2023_bot4_imu.json
rename to y2024_swerve/y2024_swerve_imu.json
diff --git a/y2023_bot4/y2023_bot4_logger.json b/y2024_swerve/y2024_swerve_logger.json
similarity index 100%
rename from y2023_bot4/y2023_bot4_logger.json
rename to y2024_swerve/y2024_swerve_logger.json
diff --git a/y2023_bot4/y2023_bot4_roborio.json b/y2024_swerve/y2024_swerve_roborio.json
similarity index 98%
rename from y2023_bot4/y2023_bot4_roborio.json
rename to y2024_swerve/y2024_swerve_roborio.json
index 7ff175c..2746ade 100644
--- a/y2023_bot4/y2023_bot4_roborio.json
+++ b/y2024_swerve/y2024_swerve_roborio.json
@@ -98,7 +98,7 @@
         },
         {
             "name": "/drivetrain",
-            "type": "y2023_bot4.AbsoluteDrivetrainPosition",
+            "type": "y2024_swerve.AbsoluteDrivetrainPosition",
             "source_node": "roborio",
             "frequency": 250,
             "num_senders": 1,
@@ -106,7 +106,7 @@
         },
         {
             "name": "/drivetrain",
-            "type": "y2023_bot4.AbsoluteCANPosition",
+            "type": "y2024_swerve.AbsoluteCANPosition",
             "source_node": "roborio",
             "frequency": 250,
             "num_senders": 1,