Repository: robotpy/mostrobotpy (language: python)

Issue:
cvnp false-positive noncontiguous input on windows only
### Problem description

so i'm using CameraServer on the desktop, for testing.

here's a minimal case:

```
x = CameraServer.putVideo(..)
x.putFrame(np.zeros((10,10),dtype=np.uint8))
```

trips the [contiguous-input check](https://github.com/robotpy/mostrobotpy/blob/ba97ccbca444ef6f0c7fb24503faf8029d6a4019/subprojects/robotpy-cscore/cscore/cvnp/cvnp.cpp#L203), but only on windows.  on linux, it works fine.

i'm using python 3.11.9 and robotpy 2024.3.2.1

I don't need anything else that CameraServer does, so I switched to mjpeg_streamer, which works fine.

### Operating System

Windows

### Installed Python Packages

_No response_

### Reproducible example code

_No response_


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/dist.yml b/.github/workflows/dist.yml
index 20459647..e6b365bc 100644
--- a/.github/workflows/dist.yml
+++ b/.github/workflows/dist.yml
@@ -44,7 +44,7 @@ jobs:
 
     - uses: actions/setup-python@v5
       with:
-        python-version: "3.12"
+        python-version: "3.13"
 
     - name: Install deps
       shell: bash
@@ -68,13 +68,13 @@ jobs:
       max-parallel: ${{ fromJSON(needs.setup_concurrency.outputs.max-parallel).v }}
       fail-fast: true
       matrix: 
-        os: ["ubuntu-22.04", "macos-12", "windows-2022"]
+        os: ["ubuntu-22.04", "macos-13", "windows-2022"]
         python_version:
-        - '3.8'
         - '3.9'
         - '3.10'
         - '3.11'
         - '3.12'
+        - '3.13'
 
     steps:
     - uses: actions/checkout@v4
@@ -114,7 +114,7 @@ jobs:
     - name: Install numpy (needed for stubgen but broken in raspbian CI)
       shell: bash
       run: |
-        python -m pip --disable-pip-version-check install 'numpy<2'
+        python -m pip --disable-pip-version-check install numpy
 
     - name: Build + test wheels
       shell: bash
@@ -169,30 +169,30 @@ jobs:
       max-parallel: ${{ fromJSON(needs.setup_concurrency.outputs.max-parallel).v }}
       matrix:
         os:
-        - container: wpilib/roborio-cross-ubuntu:2024-22.04-py312
+        - container: wpilib/roborio-cross-ubuntu:2025-22.04-py313
           name: roborio
 
-        - container: wpilib/raspbian-cross-ubuntu:bullseye-22.04-py38
-          name: raspbian-py38
-        - container: wpilib/raspbian-cross-ubuntu:bullseye-22.04-py39
+        - container: wpilib/raspbian-cross-ubuntu:2025-bullseye-22.04-py39
           name: raspbian-py39
-        - container: wpilib/raspbian-cross-ubuntu:bullseye-22.04-py310
+        - container: wpilib/raspbian-cross-ubuntu:2025-bullseye-22.04-py310
           name: raspbian-py310
-        - container: wpilib/raspbian-cross-ubuntu:bullseye-22.04-py311
+        - container: wpilib/raspbian-cross-ubuntu:2025-bullseye-22.04-py311
           name: raspbian-py311
-        - container: wpilib/raspbian-cross-ubuntu:bullseye-22.04-py312
+        - container: wpilib/raspbian-cross-ubuntu:2025-bullseye-22.04-py312
           name: raspbian-py312
-        
-        - container: wpilib/aarch64-cross-ubuntu:bullseye-22.04-py38
-          name: raspbian-aarch64-py38
-        - container: wpilib/aarch64-cross-ubuntu:bullseye-22.04-py39
+        - container: wpilib/raspbian-cross-ubuntu:2025-bullseye-22.04-py313
+          name: raspbian-py313
+
+        - container: wpilib/aarch64-cross-ubuntu:2025-bullseye-22.04-py39
           name: raspbian-aarch64-py39
-        - container: wpilib/aarch64-cross-ubuntu:bullseye-22.04-py310
+        - container: wpilib/aarch64-cross-ubuntu:2025-bullseye-22.04-py310
           name: raspbian-aarch64-py310
-        - container: wpilib/aarch64-cross-ubuntu:bullseye-22.04-py311
+        - container: wpilib/aarch64-cross-ubuntu:2025-bullseye-22.04-py311
           name: raspbian-aarch64-py311
-        - container: wpilib/aarch64-cross-ubuntu:bullseye-22.04-py312
+        - container: wpilib/aarch64-cross-ubuntu:2025-bullseye-22.04-py312
           name: raspbian-aarch64-py312
+        - container: wpilib/aarch64-cross-ubuntu:bullseye-22.04-py313
+          name: raspbian-aarch64-py313
 
     container:
       image: "${{ matrix.os.container }}"
@@ -222,7 +222,13 @@ jobs:
       run: |
         pwd
         /usr/bin/git config --global --add safe.directory $(pwd)
-    
+
+    # See https://github.com/pallets/markupsafe/issues/475
+    - name: Install MarkupSafe
+      shell: bash
+      run: |
+        /build/venv/bin/cross-pip install --no-build-isolation "markupsafe; python_version < '3.12'"
+
     - name: Install deps
       shell: bash
       run: |
diff --git a/devtools/__main__.py b/devtools/__main__.py
index da868cac..02c49486 100644
--- a/devtools/__main__.py
+++ b/devtools/__main__.py
@@ -16,7 +16,7 @@
 
 # MACOSX_DEPLOYMENT_TARGET is required for linking to WPILib
 if sys.platform == "darwin":
-    os.environ["MACOSX_DEPLOYMENT_TARGET"] = "12"
+    os.environ["MACOSX_DEPLOYMENT_TARGET"] = "13"
 
 
 @click.group()
diff --git a/rdev.toml b/rdev.toml
index 695b881e..86d7e6bc 100644
--- a/rdev.toml
+++ b/rdev.toml
@@ -4,16 +4,16 @@
 
 [params]
 
-wpilib_bin_url = "https://frcmaven.wpi.edu/artifactory/release"
-wpilib_bin_version = "2024.3.2"
-# wpilib_bin_url = "https://frcmaven.wpi.edu/artifactory/development"
+# wpilib_bin_url = "https://frcmaven.wpi.edu/artifactory/release"
+wpilib_bin_version = "2025.1.1-beta-1"
+wpilib_bin_url = "https://frcmaven.wpi.edu/artifactory/development"
 
 # Don't update these artifacts
 exclude_artifacts = [
     "opencv-cpp"
 ]
 
-robotpy_build_req = "<2025.0.0,~=2024.0.0"
+robotpy_build_req = "<2025.0.0b1,~=2025.0.0a1"
 
 #
 # Subproject configuration
diff --git a/rdev_requirements.txt b/rdev_requirements.txt
index 6c4ac757..40ae7acd 100644
--- a/rdev_requirements.txt
+++ b/rdev_requirements.txt
@@ -2,6 +2,7 @@ black
 click
 packaging
 pydantic<2
+pytest
 requests
 setuptools
 setuptools_scm >= 6.2, < 8
diff --git a/subprojects/pyntcore/gen/NetworkTableInstance.yml b/subprojects/pyntcore/gen/NetworkTableInstance.yml
index b6c7bda0..cc875e72 100644
--- a/subprojects/pyntcore/gen/NetworkTableInstance.yml
+++ b/subprojects/pyntcore/gen/NetworkTableInstance.yml
@@ -144,7 +144,7 @@ classes:
       StopClient:
       SetServer:
         overloads:
-          const char*, unsigned int:
+          std::string_view, unsigned int:
           std::span<const std::pair<std::string_view, unsigned int>>:
           std::span<const std::string_view>, unsigned int:
       SetServerTeam:
diff --git a/subprojects/pyntcore/ntcore/__init__.py b/subprojects/pyntcore/ntcore/__init__.py
index 0cb7cab1..d193f81d 100644
--- a/subprojects/pyntcore/ntcore/__init__.py
+++ b/subprojects/pyntcore/ntcore/__init__.py
@@ -1,6 +1,6 @@
 from . import _init_ntcore
 
-# autogenerated by 'robotpy-build create-imports ntcore'
+# autogenerated by 'robotpy-build create-imports ntcore ntcore._ntcore'
 from ._ntcore import (
     BooleanArrayEntry,
     BooleanArrayPublisher,
diff --git a/subprojects/pyntcore/pyproject.toml b/subprojects/pyntcore/pyproject.toml
index c8ce73a9..19cf05b2 100644
--- a/subprojects/pyntcore/pyproject.toml
+++ b/subprojects/pyntcore/pyproject.toml
@@ -12,19 +12,32 @@ install_requires = [
 
 [build-system]
 requires = [
-    "robotpy-build<2025.0.0,~=2024.0.0",
+    "robotpy-build<2025.0.0b1,~=2025.0.0a1",
     "robotpy-wpiutil~=2024.3.1",
     "robotpy-wpinet~=2024.3.1",
 ]
 
 [tool.robotpy-build]
 base_package = "ntcore"
+update_init = [
+    "ntcore",
+    "ntcore.meta ntcore._ntcore.meta"
+]
+scan_headers_ignore = [
+    "networktables/ProtobufTopic.h",
+    "networktables/UnitTopic.h",
+
+    "ntcore.h",
+    "ntcore_c.h",
+    "ntcore_c_types.h",
+    "ntcore_test.h",
+]
 
 [tool.robotpy-build.wrappers."ntcore".maven_lib_download]
 artifact_id = "ntcore-cpp"
 group_id = "edu.wpi.first.ntcore"
-repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-version = "2024.3.2"
+repo_url = "https://frcmaven.wpi.edu/artifactory/development"
+version = "2025.1.1-beta-1"
 
 libs = ["ntcore"]
 
@@ -66,11 +79,6 @@ StructArrayTopic = "networktables/StructArrayTopic.h"
 StringArrayTopic = "networktables/StringArrayTopic.h"
 StringTopic = "networktables/StringTopic.h"
 Topic = "networktables/Topic.h"
-# UnitTopic = "networktables/UnitTopic.h"
 
-# ntcore = "ntcore.h"
-# ntcore_c = "ntcore_c.h"
-# ntcore_c_types = "ntcore_c_types.h"
 ntcore_cpp = "ntcore_cpp.h"
 ntcore_cpp_types = "ntcore_cpp_types.h"
-# ntcore_test = "ntcore_test.h"
diff --git a/subprojects/robotpy-apriltag/gen/AprilTagFieldLayout.yml b/subprojects/robotpy-apriltag/gen/AprilTagFieldLayout.yml
index e5b07943..0ab67cd6 100644
--- a/subprojects/robotpy-apriltag/gen/AprilTagFieldLayout.yml
+++ b/subprojects/robotpy-apriltag/gen/AprilTagFieldLayout.yml
@@ -5,6 +5,8 @@ functions:
     ignore: true
   from_json:
     ignore: true
+  LoadAprilTagLayoutField:
+    ignore: true
 classes:
   AprilTagFieldLayout:
     enums:
@@ -15,6 +17,7 @@ classes:
           "":
           std::string_view:
           std::vector<AprilTag>, units::meter_t, units::meter_t:
+      LoadField:
       GetFieldLength:
       GetFieldWidth:
       GetTags:
diff --git a/subprojects/robotpy-apriltag/pyproject.toml b/subprojects/robotpy-apriltag/pyproject.toml
index 59e9208d..1068b52c 100644
--- a/subprojects/robotpy-apriltag/pyproject.toml
+++ b/subprojects/robotpy-apriltag/pyproject.toml
@@ -12,19 +12,35 @@ install_requires = [
 
 [build-system]
 requires = [
-    "robotpy-build<2025.0.0,~=2024.0.0",
+    "robotpy-build<2025.0.0b1,~=2025.0.0a1",
     "robotpy-wpiutil~=2024.3.1",
     "robotpy-wpimath~=2024.3.1",
 ]
 
 [tool.robotpy-build]
 base_package = "robotpy_apriltag"
+update_init = [
+  "robotpy_apriltag robotpy_apriltag._apriltag"
+]
+scan_headers_ignore = [
+  "common/*",
+  "test/*",
+
+  "apriltag.h",
+  "apriltag_math.h",
+  "apriltag_pose.h",
+
+  "frc/apriltag/AprilTagDetector_cv.h",
+
+  "tag16h5.h",
+  "tag36h11.h",
+]
 
 [tool.robotpy-build.wrappers."robotpy_apriltag".maven_lib_download]
 artifact_id = "apriltag-cpp"
 group_id = "edu.wpi.first.apriltag"
-repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-version = "2024.3.2"
+repo_url = "https://frcmaven.wpi.edu/artifactory/development"
+version = "2025.1.1-beta-1"
 
 libs = ["apriltag"]
 
diff --git a/subprojects/robotpy-apriltag/robotpy_apriltag/__init__.py b/subprojects/robotpy-apriltag/robotpy_apriltag/__init__.py
index a37b1590..f40314d4 100644
--- a/subprojects/robotpy-apriltag/robotpy_apriltag/__init__.py
+++ b/subprojects/robotpy-apriltag/robotpy_apriltag/__init__.py
@@ -9,7 +9,6 @@
     AprilTagFieldLayout,
     AprilTagPoseEstimate,
     AprilTagPoseEstimator,
-    loadAprilTagLayoutField,
 )
 
 __all__ = [
@@ -20,5 +19,4 @@
     "AprilTagFieldLayout",
     "AprilTagPoseEstimate",
     "AprilTagPoseEstimator",
-    "loadAprilTagLayoutField",
 ]
diff --git a/subprojects/robotpy-cscore/cscore/__init__.py b/subprojects/robotpy-cscore/cscore/__init__.py
index 93b37fb2..0f065ed7 100644
--- a/subprojects/robotpy-cscore/cscore/__init__.py
+++ b/subprojects/robotpy-cscore/cscore/__init__.py
@@ -1,8 +1,6 @@
 from . import _init_cscore
 
-from ._logging import enableLogging
-
-# autogenerated by 'robotpy-build create-imports cscore'
+# autogenerated by 'robotpy-build create-imports cscore cscore._cscore'
 from ._cscore import (
     AxisCamera,
     CameraServer,
@@ -49,9 +47,12 @@
     "runMainRunLoop",
     "runMainRunLoopTimeout",
     "stopMainRunLoop",
-    "enableLogging",
 ]
 
+from ._logging import enableLogging
+
+__all__.append("enableLogging")
+
 try:
     from .version import __version__
 except ImportError:
diff --git a/subprojects/robotpy-cscore/cscore/cvnp/cvnp.cpp b/subprojects/robotpy-cscore/cscore/cvnp/cvnp.cpp
index 5950218b..284f406e 100644
--- a/subprojects/robotpy-cscore/cscore/cvnp/cvnp.cpp
+++ b/subprojects/robotpy-cscore/cscore/cvnp/cvnp.cpp
@@ -181,15 +181,7 @@ namespace cvnp
 
     bool is_array_contiguous(const pybind11::array& a)
     {
-        pybind11::ssize_t expected_stride = a.itemsize();
-        for (int i = a.ndim() - 1; i >=0; --i)
-        {
-            pybind11::ssize_t current_stride = a.strides()[i];
-            if (current_stride != expected_stride)
-                return false;
-            expected_stride = expected_stride * a.shape()[i];
-        }
-        return true;
+        return a.flags() & pybind11::array::c_style;
     }
 
 
diff --git a/subprojects/robotpy-cscore/cscore/cvnp/cvnp.h b/subprojects/robotpy-cscore/cscore/cvnp/cvnp.h
index c069c625..c78a9d11 100644
--- a/subprojects/robotpy-cscore/cscore/cvnp/cvnp.h
+++ b/subprojects/robotpy-cscore/cscore/cvnp/cvnp.h
@@ -49,6 +49,7 @@ namespace cvnp
         return pybind11::array(
             pybind11::dtype::of<_Tp>()
             , std::vector<std::size_t> {_rows, _cols}
+            , std::vector<std::size_t>{_cols * sizeof(_Tp), sizeof(_Tp)} // Strides
             , m.val
         );
     }
diff --git a/subprojects/robotpy-cscore/pyproject.toml b/subprojects/robotpy-cscore/pyproject.toml
index 74c14c3c..61a51e40 100644
--- a/subprojects/robotpy-cscore/pyproject.toml
+++ b/subprojects/robotpy-cscore/pyproject.toml
@@ -13,7 +13,7 @@ install_requires = [
 
 [build-system]
 requires = [
-    "robotpy-build<2025.0.0,~=2024.0.0",
+    "robotpy-build<2025.0.0b1,~=2025.0.0a1",
     "robotpy-wpiutil~=2024.3.1",
     "robotpy-wpinet~=2024.3.1",
     "pyntcore~=2024.3.1",
@@ -22,20 +22,23 @@ requires = [
 
 [tool.robotpy-build]
 base_package = "cscore"
+update_init = [
+  "cscore"
+]
 
 [tool.robotpy-build.static_libs."cscore_cpp".maven_lib_download]
 artifact_id = "cscore-cpp"
 group_id = "edu.wpi.first.cscore"
-repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-version = "2024.3.2"
+repo_url = "https://frcmaven.wpi.edu/artifactory/development"
+version = "2025.1.1-beta-1"
 
 libs = ["cscore"]
 
 [tool.robotpy-build.static_libs."cameraserver_cpp".maven_lib_download]
 artifact_id = "cameraserver-cpp"
 group_id = "edu.wpi.first.cameraserver"
-repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-version = "2024.3.2"
+repo_url = "https://frcmaven.wpi.edu/artifactory/development"
+version = "2025.1.1-beta-1"
 
 libs = ["cameraserver"]
 
diff --git a/subprojects/robotpy-hal/gen/DriverStation.yml b/subprojects/robotpy-hal/gen/DriverStation.yml
index 9e9db3ba..2d0980bb 100644
--- a/subprojects/robotpy-hal/gen/DriverStation.yml
+++ b/subprojects/robotpy-hal/gen/DriverStation.yml
@@ -18,15 +18,17 @@ functions:
   HAL_GetJoystickIsXbox:
   HAL_GetJoystickType:
   HAL_GetJoystickName:
+    param_override:
+      name:
+        ignore: true
     cpp_code: |
       [](int32_t joystickNum) {
-        auto name = HAL_GetJoystickName(joystickNum);
-        std::string sname(name);
-        HAL_FreeJoystickName(name);
+        WPI_String name;
+        HAL_GetJoystickName(&name, joystickNum);
+        std::string sname(wpi::to_string_view(&name));
+        WPI_FreeString(&name);
         return sname;
       }
-  HAL_FreeJoystickName:
-    ignore: true
   HAL_GetJoystickAxisType:
   HAL_SetJoystickOutputs:
   HAL_GetMatchTime:
diff --git a/subprojects/robotpy-hal/gen/HALBase.yml b/subprojects/robotpy-hal/gen/HALBase.yml
index 357c59da..eaef4fb0 100644
--- a/subprojects/robotpy-hal/gen/HALBase.yml
+++ b/subprojects/robotpy-hal/gen/HALBase.yml
@@ -10,7 +10,29 @@ functions:
   HAL_GetFPGAVersion:
   HAL_GetFPGARevision:
   HAL_GetSerialNumber:
+    param_override:
+      serialNumber:
+        ignore: true
+    cpp_code: |
+      []() {
+        WPI_String s;
+        HAL_GetSerialNumber(&s);
+        std::string ss(wpi::to_string_view(&s));
+        WPI_FreeString(&s);
+        return ss;
+      }
   HAL_GetComments:
+    param_override:
+      comments:
+        ignore: true
+    cpp_code: |
+      []() {
+        WPI_String s;
+        HAL_GetComments(&s);
+        std::string ss(wpi::to_string_view(&s));
+        WPI_FreeString(&s);
+        return ss;
+      }
   HAL_GetTeamNumber:
   HAL_GetRuntimeType:
   HAL_GetFPGAButton:
diff --git a/subprojects/robotpy-hal/gen/REVPH.yml b/subprojects/robotpy-hal/gen/REVPH.yml
index 2491f41e..866c7480 100644
--- a/subprojects/robotpy-hal/gen/REVPH.yml
+++ b/subprojects/robotpy-hal/gen/REVPH.yml
@@ -30,6 +30,7 @@ functions:
   HAL_GetREVPHFaults:
   HAL_GetREVPHStickyFaults:
   HAL_ClearREVPHStickyFaults:
+  HAL_GetREVPHSolenoidDisabledList:
 classes:
   HAL_REVPHVersion:
     shared_ptr: true
@@ -82,3 +83,5 @@ classes:
       canWarning:
       canBusOff:
       hasReset:
+      hardwareFault:
+      firmwareFault:
diff --git a/subprojects/robotpy-hal/gen/simulation/DriverStationData.yml b/subprojects/robotpy-hal/gen/simulation/DriverStationData.yml
index 452d1533..8e4964d5 100644
--- a/subprojects/robotpy-hal/gen/simulation/DriverStationData.yml
+++ b/subprojects/robotpy-hal/gen/simulation/DriverStationData.yml
@@ -87,9 +87,24 @@ functions:
   HALSIM_SetJoystickIsXbox:
   HALSIM_SetJoystickType:
   HALSIM_SetJoystickName:
+    cpp_code: |
+      [](int32_t stick, std::string_view sv) {
+        auto s = wpi::make_string(sv);
+        HALSIM_SetJoystickName(stick, &s);
+      }
   HALSIM_SetJoystickAxisType:
   HALSIM_SetGameSpecificMessage:
+    cpp_code: |
+      [](std::string_view sv) {
+        auto s = wpi::make_string(sv);
+        HALSIM_SetGameSpecificMessage(&s);
+      }
   HALSIM_SetEventName:
+    cpp_code: |
+      [](std::string_view sv) {
+        auto s = wpi::make_string(sv);
+        HALSIM_SetEventName(&s);
+      }
   HALSIM_SetMatchType:
   HALSIM_SetMatchNumber:
   HALSIM_SetReplayNumber:
diff --git a/subprojects/robotpy-hal/gen/simulation/RoboRioData.yml b/subprojects/robotpy-hal/gen/simulation/RoboRioData.yml
index 6a9b795d..f89de89f 100644
--- a/subprojects/robotpy-hal/gen/simulation/RoboRioData.yml
+++ b/subprojects/robotpy-hal/gen/simulation/RoboRioData.yml
@@ -94,12 +94,44 @@ functions:
     ignore: true
   HALSIM_CancelRoboRioSerialNumberCallback:
   HALSIM_GetRoboRioSerialNumber:
+    param_override:
+      serialNumber:
+        ignore: true
+    cpp_code: |
+      []() {
+        WPI_String s;
+        HALSIM_GetRoboRioSerialNumber(&s);
+        std::string ss(wpi::to_string_view(&s));
+        WPI_FreeString(&s);
+        return ss;
+      }
   HALSIM_SetRoboRioSerialNumber:
+    cpp_code: |
+      [](std::string_view sv) {
+        auto s = wpi::make_string(sv);
+        HALSIM_SetRoboRioSerialNumber(&s);
+      }
   HALSIM_RegisterRoboRioCommentsCallback:
     ignore: true
   HALSIM_CancelRoboRioCommentsCallback:
   HALSIM_GetRoboRioComments:
+    param_override:
+      comments:
+        ignore: true
+    cpp_code: |
+      []() {
+        WPI_String s;
+        HALSIM_GetRoboRioComments(&s);
+        std::string ss(wpi::to_string_view(&s));
+        WPI_FreeString(&s);
+        return ss;
+      }
   HALSIM_SetRoboRioComments:
+    cpp_code: |
+      [](std::string_view sv) {
+        auto s = wpi::make_string(sv);
+        HALSIM_SetRoboRioComments(&s);
+      }
   HALSIM_RegisterRoboRioAllCallbacks:
     ignore: true
   HALSIM_RegisterRoboRioCPUTempCallback:
diff --git a/subprojects/robotpy-hal/gen/simulation/SPIAccelerometerData.yml b/subprojects/robotpy-hal/gen/simulation/SPIAccelerometerData.yml
index 28c1a210..00381b52 100644
--- a/subprojects/robotpy-hal/gen/simulation/SPIAccelerometerData.yml
+++ b/subprojects/robotpy-hal/gen/simulation/SPIAccelerometerData.yml
@@ -30,5 +30,5 @@ functions:
   HALSIM_CancelSPIAccelerometerZCallback:
   HALSIM_GetSPIAccelerometerZ:
   HALSIM_SetSPIAccelerometerZ:
-  HALSIM_RegisterSPIAccelerometerAllCallbcaks:
-    ignore: true
+  HALSIM_RegisterSPIAccelerometerAllCallbacks:
+    ignore: true
\ No newline at end of file
diff --git a/subprojects/robotpy-hal/hal/simulation/resethandles.cpp b/subprojects/robotpy-hal/hal/simulation/resethandles.cpp
index 5f2ac2e5..90a4d32d 100644
--- a/subprojects/robotpy-hal/hal/simulation/resethandles.cpp
+++ b/subprojects/robotpy-hal/hal/simulation/resethandles.cpp
@@ -15,7 +15,7 @@ void HALSIM_ResetGlobalHandles() {
     HALSIM_GetNotifierInfo(info, sz);
 
     for (int i = 0; i < sz; i++) {
-      HAL_CleanNotifier(info->handle, nullptr);
+      HAL_CleanNotifier(info->handle);
     }
   }
 
diff --git a/subprojects/robotpy-hal/pyproject.toml b/subprojects/robotpy-hal/pyproject.toml
index 87a5d60b..b9f78b47 100644
--- a/subprojects/robotpy-hal/pyproject.toml
+++ b/subprojects/robotpy-hal/pyproject.toml
@@ -11,20 +11,49 @@ install_requires = [
 
 [build-system]
 requires = [
-    "robotpy-build<2025.0.0,~=2024.0.0",
+    "robotpy-build<2025.0.0b1,~=2025.0.0a1",
     "robotpy-wpiutil~=2024.3.1",
 ]
 
 [tool.robotpy-build]
 base_package = "hal"
+scan_headers_ignore = [
+    "hal/ChipObject.h",
+    "hal/DMA.h",
+    "hal/Errors.h",
+    "hal/HAL.h",
+    "hal/Types.h",
+    "hal/Value.h",
+
+    "hal/cpp/SerialHelper.h",
+    "hal/cpp/UnsafeDIO.h",
+    "hal/cpp/fpga_clock.h",
+
+    "hal/handles/DigitalHandleResource.h",
+    "hal/handles/IndexedClassedHandleResource.h",
+    "hal/handles/IndexedHandleResource.h",
+    "hal/handles/LimitedClassedHandleResource.h",
+    "hal/handles/LimitedHandleResource.h",
+    "hal/handles/UnlimitedHandleResource.h",
+
+    "hal/roborio/HMB.h",
+    "hal/roborio/InterruptManager.h",
+
+    "hal/simulation/CanData.h",
+    "hal/simulation/I2CData.h",
+    "hal/simulation/NotifyListener.h",
+    "hal/simulation/SPIData.h",
+    "hal/simulation/SimCallbackRegistry.h",
+    "hal/simulation/SimDataValue.h",
+]
 
 
 [tool.robotpy-build.wrappers."hal".maven_lib_download]
 artifact_id = "hal-cpp"
 group_id = "edu.wpi.first.hal"
 # repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-version = "2024.3.2"
+repo_url = "https://frcmaven.wpi.edu/artifactory/development"
+version = "2025.1.1-beta-1"
 
 libs = ["wpiHal"]
 
diff --git a/subprojects/robotpy-halsim-ds-socket/pyproject.toml b/subprojects/robotpy-halsim-ds-socket/pyproject.toml
index b4b6c6a0..0050c316 100644
--- a/subprojects/robotpy-halsim-ds-socket/pyproject.toml
+++ b/subprojects/robotpy-halsim-ds-socket/pyproject.toml
@@ -15,7 +15,7 @@ robotpysimext = ["ds-socket = halsim_ds_socket"]
 
 [build-system]
 requires = [
-    "robotpy-build<2025.0.0,~=2024.0.0",
+    "robotpy-build<2025.0.0b1,~=2025.0.0a1",
     "robotpy-hal~=2024.3.1",
     "robotpy-wpinet~=2024.3.1",
 ]
@@ -27,8 +27,8 @@ base_package = "halsim_ds_socket"
 artifact_id = "halsim_ds_socket"
 group_id = "edu.wpi.first.halsim"
 # repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-version = "2024.3.2"
+repo_url = "https://frcmaven.wpi.edu/artifactory/development"
+version = "2025.1.1-beta-1"
 
 dlopenlibs = ["halsim_ds_socket"]
 
diff --git a/subprojects/robotpy-halsim-gui/pyproject.toml b/subprojects/robotpy-halsim-gui/pyproject.toml
index 5cc87435..8dcc49b2 100644
--- a/subprojects/robotpy-halsim-gui/pyproject.toml
+++ b/subprojects/robotpy-halsim-gui/pyproject.toml
@@ -14,7 +14,7 @@ install_requires = [
 
 [build-system]
 requires = [
-    "robotpy-build<2025.0.0,~=2024.0.0",
+    "robotpy-build<2025.0.0b1,~=2025.0.0a1",
     "robotpy-wpiutil~=2024.3.1",
     "robotpy-wpimath~=2024.3.1",
     "robotpy-hal~=2024.3.1",
@@ -29,8 +29,8 @@ base_package = "halsim_gui"
 artifact_id = "halsim_gui"
 group_id = "edu.wpi.first.halsim"
 # repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-version = "2024.3.2"
+repo_url = "https://frcmaven.wpi.edu/artifactory/development"
+version = "2025.1.1-beta-1"
 
 dlopenlibs = ["halsim_gui"]
 
diff --git a/subprojects/robotpy-halsim-ws/pyproject.toml b/subprojects/robotpy-halsim-ws/pyproject.toml
index ccb4c239..a2eb24b3 100644
--- a/subprojects/robotpy-halsim-ws/pyproject.toml
+++ b/subprojects/robotpy-halsim-ws/pyproject.toml
@@ -19,7 +19,7 @@ robotpysimext = [
 
 [build-system]
 requires = [
-    "robotpy-build<2025.0.0,~=2024.0.0",
+    "robotpy-build<2025.0.0b1,~=2025.0.0a1",
     "robotpy-hal~=2024.3.1",
     "robotpy-wpinet~=2024.3.1",
 ]
@@ -31,8 +31,8 @@ base_package = "halsim_ws"
 artifact_id = "halsim_ws_server"
 group_id = "edu.wpi.first.halsim"
 # repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-version = "2024.3.2"
+repo_url = "https://frcmaven.wpi.edu/artifactory/development"
+version = "2025.1.1-beta-1"
 
 dlopenlibs = ["halsim_ws_server"]
 
@@ -44,8 +44,8 @@ depends = ["wpiHal", "wpinet"]
 artifact_id = "halsim_ws_client"
 group_id = "edu.wpi.first.halsim"
 # repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-version = "2024.3.2"
+repo_url = "https://frcmaven.wpi.edu/artifactory/development"
+version = "2025.1.1-beta-1"
 
 dlopenlibs = ["halsim_ws_client"]
 
diff --git a/subprojects/robotpy-romi/pyproject.toml b/subprojects/robotpy-romi/pyproject.toml
index 538d32b2..a5f784e1 100644
--- a/subprojects/robotpy-romi/pyproject.toml
+++ b/subprojects/robotpy-romi/pyproject.toml
@@ -11,7 +11,7 @@ install_requires = [
 
 [build-system]
 requires = [
-    "robotpy-build<2025.0.0,~=2024.0.0",
+    "robotpy-build<2025.0.0b1,~=2025.0.0a1",
     "wpilib~=2024.3.1"
 ]
 
@@ -38,6 +38,6 @@ RomiMotor = "frc/romi/RomiMotor.h"
 artifact_id = "romiVendordep-cpp"
 group_id = "edu.wpi.first.romiVendordep"
 # repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-version = "2024.3.2"
+repo_url = "https://frcmaven.wpi.edu/artifactory/development"
+version = "2025.1.1-beta-1"
 libs = ["romiVendordep"]
diff --git a/subprojects/robotpy-wpilib/gen/ADIS16470_IMU.yml b/subprojects/robotpy-wpilib/gen/ADIS16470_IMU.yml
index 9169510f..53777da7 100644
--- a/subprojects/robotpy-wpilib/gen/ADIS16470_IMU.yml
+++ b/subprojects/robotpy-wpilib/gen/ADIS16470_IMU.yml
@@ -7,6 +7,8 @@ classes:
   ADIS16470_IMU:
     attributes:
       m_yaw_axis:
+      m_pitch_axis:
+      m_roll_axis:
     enums:
       CalibrationTime:
       IMUAxis:
diff --git a/subprojects/robotpy-wpilib/gen/Accelerometer.yml b/subprojects/robotpy-wpilib/gen/Accelerometer.yml
deleted file mode 100644
index f5d8cb83..00000000
--- a/subprojects/robotpy-wpilib/gen/Accelerometer.yml
+++ /dev/null
@@ -1,13 +0,0 @@
----
-
-classes:
-  Accelerometer:
-    shared_ptr: true
-    enums:
-      Range:
-    methods:
-      Accelerometer:
-      SetRange:
-      GetX:
-      GetY:
-      GetZ:
diff --git a/subprojects/robotpy-wpilib/gen/Alert.yml b/subprojects/robotpy-wpilib/gen/Alert.yml
new file mode 100644
index 00000000..4909bfeb
--- /dev/null
+++ b/subprojects/robotpy-wpilib/gen/Alert.yml
@@ -0,0 +1,13 @@
+---
+
+classes:
+  Alert:
+    enums:
+      AlertType:
+    methods:
+      Alert:
+        overloads:
+          std::string_view, AlertType:
+          std::string_view, std::string_view, AlertType:
+      Set:
+      SetText:
diff --git a/subprojects/robotpy-wpilib/gen/AnalogEncoder.yml b/subprojects/robotpy-wpilib/gen/AnalogEncoder.yml
index 883377e5..873cc08c 100644
--- a/subprojects/robotpy-wpilib/gen/AnalogEncoder.yml
+++ b/subprojects/robotpy-wpilib/gen/AnalogEncoder.yml
@@ -18,6 +18,12 @@ classes:
           AnalogInput*:
             ignore: true
           std::shared_ptr<AnalogInput>:
+          int, double, double:
+          AnalogInput&, double, double:
+            ignore: true
+          AnalogInput*, double, double:
+            ignore: true
+          std::shared_ptr<AnalogInput>, double, double:
       Reset:
       Get:
       GetAbsolutePosition:
@@ -27,4 +33,6 @@ classes:
       GetDistancePerRotation:
       GetDistance:
       GetChannel:
+      SetVoltagePercentageRange:
+      SetInverted:
       InitSendable:
diff --git a/subprojects/robotpy-wpilib/gen/AnalogTrigger.yml b/subprojects/robotpy-wpilib/gen/AnalogTrigger.yml
index a733ba59..bc8d4c54 100644
--- a/subprojects/robotpy-wpilib/gen/AnalogTrigger.yml
+++ b/subprojects/robotpy-wpilib/gen/AnalogTrigger.yml
@@ -8,15 +8,22 @@ extra_includes:
 
 classes:
   AnalogTrigger:
-    shared_ptr: true
     ignored_bases:
     - wpi::SendableHelper<AnalogTrigger>
     methods:
       AnalogTrigger:
         overloads:
           int:
+          AnalogInput&:
+            ignore: true
           AnalogInput*:
+            ignore: true
+          std::shared_ptr<AnalogInput>:
+          DutyCycle&:
+            ignore: true
           DutyCycle*:
+            ignore: true
+          std::shared_ptr<DutyCycle>:
       SetLimitsVoltage:
       SetLimitsDutyCycle:
       SetLimitsRaw:
diff --git a/subprojects/robotpy-wpilib/gen/DataLogManager.yml b/subprojects/robotpy-wpilib/gen/DataLogManager.yml
index 9f06e884..bcbdd505 100644
--- a/subprojects/robotpy-wpilib/gen/DataLogManager.yml
+++ b/subprojects/robotpy-wpilib/gen/DataLogManager.yml
@@ -13,3 +13,4 @@ classes:
         return_value_policy: reference
       GetLogDir:
       LogNetworkTables:
+      LogConsoleOutput:
diff --git a/subprojects/robotpy-wpilib/gen/DutyCycleEncoder.yml b/subprojects/robotpy-wpilib/gen/DutyCycleEncoder.yml
index a209c0db..8a30c20c 100644
--- a/subprojects/robotpy-wpilib/gen/DutyCycleEncoder.yml
+++ b/subprojects/robotpy-wpilib/gen/DutyCycleEncoder.yml
@@ -24,6 +24,17 @@ classes:
           DigitalSource*:
             ignore: true
           std::shared_ptr<DigitalSource>:
+          int, double, double:
+          DutyCycle&, double, double:
+            ignore: true
+          DutyCycle*, double, double:
+            ignore: true
+          std::shared_ptr<DutyCycle>, double, double:
+          DigitalSource&, double, double:
+            ignore: true
+          DigitalSource*, double, double:
+            ignore: true
+          std::shared_ptr<DigitalSource>, double, double:
       GetFrequency:
       IsConnected:
       SetConnectedFrequencyThreshold:
@@ -38,6 +49,8 @@ classes:
       SetDutyCycleRange:
       GetFPGAIndex:
       GetSourceChannel:
+      SetAssumedFrequency:
+      SetInverted:
       InitSendable:
 
 inline_code: |
diff --git a/subprojects/robotpy-wpilib/gen/Gyro.yml b/subprojects/robotpy-wpilib/gen/Gyro.yml
deleted file mode 100644
index f18f7edf..00000000
--- a/subprojects/robotpy-wpilib/gen/Gyro.yml
+++ /dev/null
@@ -1,12 +0,0 @@
----
-
-classes:
-  Gyro:
-    shared_ptr: true
-    methods:
-      Gyro:
-      Calibrate:
-      Reset:
-      GetAngle:
-      GetRate:
-      GetRotation2d:
diff --git a/subprojects/robotpy-wpilib/gen/IterativeRobotBase.yml b/subprojects/robotpy-wpilib/gen/IterativeRobotBase.yml
index e887d482..74257e79 100644
--- a/subprojects/robotpy-wpilib/gen/IterativeRobotBase.yml
+++ b/subprojects/robotpy-wpilib/gen/IterativeRobotBase.yml
@@ -35,6 +35,7 @@ classes:
       EnableLiveWindowInTest:
       IsLiveWindowEnabledInTest:
       GetPeriod:
+      PrintWatchdogEpochs:
     doc: |
       IterativeRobotBase implements a specific type of robot program framework,
       extending the RobotBase class.
diff --git a/subprojects/robotpy-wpilib/gen/LEDPattern.yml b/subprojects/robotpy-wpilib/gen/LEDPattern.yml
new file mode 100644
index 00000000..0d0369ec
--- /dev/null
+++ b/subprojects/robotpy-wpilib/gen/LEDPattern.yml
@@ -0,0 +1,42 @@
+---
+
+classes:
+  LEDPattern:
+    attributes:
+      kOff:
+    enums:
+      GradientType:
+    methods:
+      'Off':
+      LEDPattern:
+      ApplyTo:
+        overloads:
+          std::span<frc::AddressableLED::LEDData>, LEDWriterFn [const]:
+          std::span<frc::AddressableLED::LEDData> [const]:
+      Reversed:
+      OffsetBy:
+      ScrollAtRelativeSpeed:
+      ScrollAtAbsoluteSpeed:
+      Blink:
+        overloads:
+          units::second_t, units::second_t:
+          units::second_t:
+      SynchronizedBlink:
+      Breathe:
+      OverlayOn:
+      Blend:
+      Mask:
+      AtBrightness:
+      Solid:
+      ProgressMaskLayer:
+      Steps:
+        overloads:
+          std::span<const std::pair<double, Color>>:
+          std::initializer_list<std::pair<double, Color>>:
+            ignore: true
+      Gradient:
+        overloads:
+          GradientType, std::span<const Color>:
+          GradientType, std::initializer_list<Color>:
+            ignore: true
+      Rainbow:
diff --git a/subprojects/robotpy-wpilib/gen/Notifier.yml b/subprojects/robotpy-wpilib/gen/Notifier.yml
index 93d30c91..7024a6f0 100644
--- a/subprojects/robotpy-wpilib/gen/Notifier.yml
+++ b/subprojects/robotpy-wpilib/gen/Notifier.yml
@@ -9,7 +9,7 @@ classes:
         overloads:
           std::function<void ( )>:
       SetName:
-      SetHandler:
+      SetCallback:
       StartSingle:
         overloads:
           double:
diff --git a/subprojects/robotpy-wpilib/gen/PS4Controller.yml b/subprojects/robotpy-wpilib/gen/PS4Controller.yml
index 3515ca9c..97a04ddc 100644
--- a/subprojects/robotpy-wpilib/gen/PS4Controller.yml
+++ b/subprojects/robotpy-wpilib/gen/PS4Controller.yml
@@ -1,10 +1,13 @@
 ---
 
 extra_includes:
+- wpi/sendable/SendableBuilder.h
 - frc/event/BooleanEvent.h
 
 classes:
   PS4Controller:
+    ignored_bases:
+    - wpi::SendableHelper<PS4Controller>
     methods:
       PS4Controller:
       GetLeftX:
@@ -69,6 +72,10 @@ classes:
       GetTouchpadPressed:
       GetTouchpadReleased:
       Touchpad:
+      GetTouchpadButton:
+      GetTouchpadButtonPressed:
+      GetTouchpadButtonReleased:
+      InitSendable:
   PS4Controller::Button:
     attributes:
       kSquare:
diff --git a/subprojects/robotpy-wpilib/gen/PS5Controller.yml b/subprojects/robotpy-wpilib/gen/PS5Controller.yml
index 9640f4e3..96f635ae 100644
--- a/subprojects/robotpy-wpilib/gen/PS5Controller.yml
+++ b/subprojects/robotpy-wpilib/gen/PS5Controller.yml
@@ -1,7 +1,12 @@
 ---
 
+extra_includes:
+- wpi/sendable/SendableBuilder.h
+
 classes:
   PS5Controller:
+    ignored_bases:
+    - wpi::SendableHelper<PS5Controller>
     methods:
       PS5Controller:
       GetLeftX:
@@ -66,6 +71,10 @@ classes:
       GetTouchpadPressed:
       GetTouchpadReleased:
       Touchpad:
+      GetTouchpadButton:
+      GetTouchpadButtonPressed:
+      GetTouchpadButtonReleased:
+      InitSendable:
   PS5Controller::Button:
     attributes:
       kSquare:
diff --git a/subprojects/robotpy-wpilib/gen/PWMMotorController.yml b/subprojects/robotpy-wpilib/gen/PWMMotorController.yml
index f0b07ca1..c06871e5 100644
--- a/subprojects/robotpy-wpilib/gen/PWMMotorController.yml
+++ b/subprojects/robotpy-wpilib/gen/PWMMotorController.yml
@@ -14,6 +14,7 @@ classes:
       Set:
       SetVoltage:
       Get:
+      GetVoltage:
       SetInverted:
       GetInverted:
       Disable:
diff --git a/subprojects/robotpy-wpilib/gen/PneumaticHub.yml b/subprojects/robotpy-wpilib/gen/PneumaticHub.yml
index 700e6f75..5a287541 100644
--- a/subprojects/robotpy-wpilib/gen/PneumaticHub.yml
+++ b/subprojects/robotpy-wpilib/gen/PneumaticHub.yml
@@ -88,3 +88,5 @@ classes:
       CanWarning:
       CanBusOff:
       HasReset:
+      HardwareFault:
+      FirmwareFault:
diff --git a/subprojects/robotpy-wpilib/gen/PowerDistribution.yml b/subprojects/robotpy-wpilib/gen/PowerDistribution.yml
index 6378b803..2a2dfb1e 100644
--- a/subprojects/robotpy-wpilib/gen/PowerDistribution.yml
+++ b/subprojects/robotpy-wpilib/gen/PowerDistribution.yml
@@ -31,6 +31,8 @@ classes:
       GetVersion:
       GetFaults:
       GetStickyFaults:
+      GetNumChannels:
+      GetAllCurrents:
       InitSendable:
   PowerDistribution::Version:
     attributes:
@@ -101,5 +103,7 @@ classes:
       CanWarning:
       CanBusOff:
       HasReset:
+      HardwareFault:
+      FirmwareFault:
     methods:
       GetBreakerFault:
diff --git a/subprojects/robotpy-wpilib/gen/RobotController.yml b/subprojects/robotpy-wpilib/gen/RobotController.yml
index 6bedfab9..6dfc62a5 100644
--- a/subprojects/robotpy-wpilib/gen/RobotController.yml
+++ b/subprojects/robotpy-wpilib/gen/RobotController.yml
@@ -53,3 +53,5 @@ classes:
       SetRadioLEDState:
       GetRadioLEDState:
       GetCANStatus:
+      GetCommsDisableCount:
+      ResetRailFaultCounts:
diff --git a/subprojects/robotpy-wpilib/gen/SensorUtil.yml b/subprojects/robotpy-wpilib/gen/SensorUtil.yml
index 83b1d478..7b9de874 100644
--- a/subprojects/robotpy-wpilib/gen/SensorUtil.yml
+++ b/subprojects/robotpy-wpilib/gen/SensorUtil.yml
@@ -27,3 +27,8 @@ classes:
       CheckPDPModule:
       GetDefaultCTREPCMModule:
       GetDefaultREVPHModule:
+      GetNumDigitalChannels:
+      GetNumAnalogInputs:
+      GetNumAnalogOuputs:
+      GetNumPwmChannels:
+      GetNumRelayChannels:
diff --git a/subprojects/robotpy-wpilib/gen/SharpIR.yml b/subprojects/robotpy-wpilib/gen/SharpIR.yml
new file mode 100644
index 00000000..99babe2f
--- /dev/null
+++ b/subprojects/robotpy-wpilib/gen/SharpIR.yml
@@ -0,0 +1,18 @@
+---
+
+extra_includes:
+- wpi/sendable/SendableBuilder.h
+
+classes:
+  SharpIR:
+    ignored_bases:
+    - wpi::SendableHelper<SharpIR>
+    methods:
+      GP2Y0A02YK0F:
+      GP2Y0A21YK0F:
+      GP2Y0A41SK0F:
+      GP2Y0A51SK0F:
+      SharpIR:
+      GetChannel:
+      GetRange:
+      InitSendable:
diff --git a/subprojects/robotpy-wpilib/gen/StadiaController.yml b/subprojects/robotpy-wpilib/gen/StadiaController.yml
index 8ecd72cf..8aada62d 100644
--- a/subprojects/robotpy-wpilib/gen/StadiaController.yml
+++ b/subprojects/robotpy-wpilib/gen/StadiaController.yml
@@ -1,7 +1,12 @@
 ---
 
+extra_includes:
+- wpi/sendable/SendableBuilder.h
+
 classes:
   StadiaController:
+    ignored_bases:
+    - wpi::SendableHelper<StadiaController>
     methods:
       StadiaController:
       GetLeftX:
@@ -68,6 +73,13 @@ classes:
       GetRightTriggerButtonPressed:
       GetRightTriggerButtonReleased:
       RightTrigger:
+      GetLeftBumperButton:
+      GetLeftBumperButtonPressed:
+      GetLeftBumperButtonReleased:
+      GetRightBumperButton:
+      GetRightBumperButtonPressed:
+      GetRightBumperButtonReleased:
+      InitSendable:
   StadiaController::Button:
     attributes:
       kA:
diff --git a/subprojects/robotpy-wpilib/gen/XboxController.yml b/subprojects/robotpy-wpilib/gen/XboxController.yml
index 384788a4..b746a7ff 100644
--- a/subprojects/robotpy-wpilib/gen/XboxController.yml
+++ b/subprojects/robotpy-wpilib/gen/XboxController.yml
@@ -1,11 +1,14 @@
 ---
 
 extra_includes:
+- wpi/sendable/SendableBuilder.h
 - frc/DriverStation.h
 - frc/event/BooleanEvent.h
 
 classes:
   XboxController:
+    ignored_bases:
+    - wpi::SendableHelper<XboxController>
     methods:
       XboxController:
       GetLeftX:
@@ -62,6 +65,13 @@ classes:
         overloads:
           double, EventLoop* [const]:
           EventLoop* [const]:
+      GetLeftBumperButton:
+      GetLeftBumperButtonPressed:
+      GetLeftBumperButtonReleased:
+      GetRightBumperButton:
+      GetRightBumperButtonPressed:
+      GetRightBumperButtonReleased:
+      InitSendable:
   XboxController::Button:
     attributes:
       kLeftBumper:
diff --git a/subprojects/robotpy-wpilib/gen/drive/DifferentialDrive.yml b/subprojects/robotpy-wpilib/gen/drive/DifferentialDrive.yml
index e11250ce..b0359975 100644
--- a/subprojects/robotpy-wpilib/gen/drive/DifferentialDrive.yml
+++ b/subprojects/robotpy-wpilib/gen/drive/DifferentialDrive.yml
@@ -14,9 +14,12 @@ classes:
       kDefaultQuickStopAlpha:
     methods:
       DifferentialDrive:
-        keepalive:
-        - [1, 2]
-        - [1, 3]
+        overloads:
+          MotorController&, MotorController&:
+            keepalive:
+            - [1, 2]
+            - [1, 3]
+          std::function<void (double)>, std::function<void (double)>:
       ArcadeDrive:
       CurvatureDrive:
       TankDrive:
diff --git a/subprojects/robotpy-wpilib/gen/drive/MecanumDrive.yml b/subprojects/robotpy-wpilib/gen/drive/MecanumDrive.yml
index 8288855f..ee50b561 100644
--- a/subprojects/robotpy-wpilib/gen/drive/MecanumDrive.yml
+++ b/subprojects/robotpy-wpilib/gen/drive/MecanumDrive.yml
@@ -12,11 +12,14 @@ classes:
     - wpi::SendableHelper<MecanumDrive>
     methods:
       MecanumDrive:
-        keepalive:
-        - [1, 2]
-        - [1, 3]
-        - [1, 4]
-        - [1, 5]
+        overloads:
+          MotorController&, MotorController&, MotorController&, MotorController&:
+            keepalive:
+            - [1, 2]
+            - [1, 3]
+            - [1, 4]
+            - [1, 5]
+          std::function<void (double)>, std::function<void (double)>, std::function<void (double)>, std::function<void (double)>:
       DriveCartesian:
         param_override:
           gyroAngle:
diff --git a/subprojects/robotpy-wpilib/gen/simulation/AnalogEncoderSim.yml b/subprojects/robotpy-wpilib/gen/simulation/AnalogEncoderSim.yml
index 6debf63f..2934deb2 100644
--- a/subprojects/robotpy-wpilib/gen/simulation/AnalogEncoderSim.yml
+++ b/subprojects/robotpy-wpilib/gen/simulation/AnalogEncoderSim.yml
@@ -14,3 +14,5 @@ classes:
       SetTurns:
       GetTurns:
       GetPosition:
+      Set:
+      Get:
diff --git a/subprojects/robotpy-wpilib/gen/simulation/DCMotorSim.yml b/subprojects/robotpy-wpilib/gen/simulation/DCMotorSim.yml
index 8cef12a3..90bfcb93 100644
--- a/subprojects/robotpy-wpilib/gen/simulation/DCMotorSim.yml
+++ b/subprojects/robotpy-wpilib/gen/simulation/DCMotorSim.yml
@@ -7,11 +7,10 @@ classes:
     methods:
       DCMotorSim:
         overloads:
-          const LinearSystem<2, 1, 2>&, const DCMotor&, double, const std::array<double, 2>&:
+          const LinearSystem<2, 1, 2>&, const DCMotor&, const std::array<double, 2>&:
             param_override:
               plant:
                 x_type: frc::LinearSystem<2,1,2>
-          const DCMotor&, double, units::kilogram_square_meter_t, const std::array<double, 2>&:
       SetState:
       GetAngularPosition:
       GetAngularVelocity:
diff --git a/subprojects/robotpy-wpilib/gen/simulation/DutyCycleEncoderSim.yml b/subprojects/robotpy-wpilib/gen/simulation/DutyCycleEncoderSim.yml
index 9d592d26..1766b569 100644
--- a/subprojects/robotpy-wpilib/gen/simulation/DutyCycleEncoderSim.yml
+++ b/subprojects/robotpy-wpilib/gen/simulation/DutyCycleEncoderSim.yml
@@ -8,6 +8,9 @@ classes:
     shared_ptr: true
     methods:
       DutyCycleEncoderSim:
+        overloads:
+          const DutyCycleEncoder&:
+          int:
       Get:
       Set:
       GetDistance:
diff --git a/subprojects/robotpy-wpilib/gen/simulation/ElevatorSim.yml b/subprojects/robotpy-wpilib/gen/simulation/ElevatorSim.yml
index 0c42eee6..2614084a 100644
--- a/subprojects/robotpy-wpilib/gen/simulation/ElevatorSim.yml
+++ b/subprojects/robotpy-wpilib/gen/simulation/ElevatorSim.yml
@@ -10,21 +10,21 @@ classes:
     methods:
       ElevatorSim:
         overloads:
-          ? const LinearSystem<2, 1, 1>&, const DCMotor&, units::meter_t, units::meter_t,
-            bool, units::meter_t, const std::array<double, 1>&
+          ? const LinearSystem<2, 1, 2>&, const DCMotor&, units::meter_t, units::meter_t,
+            bool, units::meter_t, const std::array<double, 2>&
           :
             param_override:
               measurementStdDevs:
-                default: std::array<double, 1>{0.0}
+                default: std::array<double, 2>{0.0, 0.0}
           ? const DCMotor&, double, units::kilogram_t, units::meter_t, units::meter_t,
-            units::meter_t, bool, units::meter_t, const std::array<double, 1>&
+            units::meter_t, bool, units::meter_t, const std::array<double, 2>&
           :
             param_override:
               measurementStdDevs:
-                default: std::array<double, 1>{0.0}
+                default: std::array<double, 2>{0.0}
           ? decltype(1_V/Velocity_t<Distance> (1)), decltype(1_V/Acceleration_t<Distance>
             (1)), const DCMotor&, units::meter_t, units::meter_t, bool, units::meter_t,
-            const std::array<double, 1>&
+            const std::array<double, 2>&
           :
             ignore: true
       SetState:
diff --git a/subprojects/robotpy-wpilib/gen/simulation/FlywheelSim.yml b/subprojects/robotpy-wpilib/gen/simulation/FlywheelSim.yml
index 9f31bc9e..9c03f427 100644
--- a/subprojects/robotpy-wpilib/gen/simulation/FlywheelSim.yml
+++ b/subprojects/robotpy-wpilib/gen/simulation/FlywheelSim.yml
@@ -21,3 +21,10 @@ classes:
       GetAngularVelocity:
       GetCurrentDraw:
       SetInputVoltage:
+      SetVelocity:
+      GetAngularAcceleration:
+      GetTorque:
+      GetInputVoltage:
+      Gearbox:
+      Gearing:
+      J:
diff --git a/subprojects/robotpy-wpilib/gen/simulation/LinearSystemSim.yml b/subprojects/robotpy-wpilib/gen/simulation/LinearSystemSim.yml
index ff809303..a72bcf15 100644
--- a/subprojects/robotpy-wpilib/gen/simulation/LinearSystemSim.yml
+++ b/subprojects/robotpy-wpilib/gen/simulation/LinearSystemSim.yml
@@ -30,6 +30,10 @@ classes:
         overloads:
           const Vectord<Inputs>&:
           int, double:
+      GetInput:
+        overloads:
+          '[const]':
+          int [const]:
       SetState:
       GetCurrentDraw:
       UpdateX:
diff --git a/subprojects/robotpy-wpilib/gen/simulation/PS4ControllerSim.yml b/subprojects/robotpy-wpilib/gen/simulation/PS4ControllerSim.yml
index 889333b5..c1bcd635 100644
--- a/subprojects/robotpy-wpilib/gen/simulation/PS4ControllerSim.yml
+++ b/subprojects/robotpy-wpilib/gen/simulation/PS4ControllerSim.yml
@@ -31,3 +31,5 @@ classes:
       SetR3Button:
       SetPSButton:
       SetTouchpad:
+        ignore: true
+      SetTouchpadButton:
diff --git a/subprojects/robotpy-wpilib/gen/simulation/PS5ControllerSim.yml b/subprojects/robotpy-wpilib/gen/simulation/PS5ControllerSim.yml
index b63e0471..fe537454 100644
--- a/subprojects/robotpy-wpilib/gen/simulation/PS5ControllerSim.yml
+++ b/subprojects/robotpy-wpilib/gen/simulation/PS5ControllerSim.yml
@@ -31,3 +31,5 @@ classes:
       SetR3Button:
       SetPSButton:
       SetTouchpad:
+        ignore: true
+      SetTouchpadButton:
\ No newline at end of file
diff --git a/subprojects/robotpy-wpilib/gen/simulation/SendableChooserSim.yml b/subprojects/robotpy-wpilib/gen/simulation/SendableChooserSim.yml
new file mode 100644
index 00000000..8303133a
--- /dev/null
+++ b/subprojects/robotpy-wpilib/gen/simulation/SendableChooserSim.yml
@@ -0,0 +1,10 @@
+---
+
+classes:
+  SendableChooserSim:
+    methods:
+      SendableChooserSim:
+        overloads:
+          std::string_view:
+          nt::NetworkTableInstance, std::string_view:
+      SetSelected:
diff --git a/subprojects/robotpy-wpilib/gen/simulation/SharpIRSim.yml b/subprojects/robotpy-wpilib/gen/simulation/SharpIRSim.yml
new file mode 100644
index 00000000..7d7c6c6d
--- /dev/null
+++ b/subprojects/robotpy-wpilib/gen/simulation/SharpIRSim.yml
@@ -0,0 +1,10 @@
+---
+
+classes:
+  SharpIRSim:
+    methods:
+      SharpIRSim:
+        overloads:
+          const SharpIR&:
+          int:
+      SetRange:
diff --git a/subprojects/robotpy-wpilib/gen/simulation/SingleJointedArmSim.yml b/subprojects/robotpy-wpilib/gen/simulation/SingleJointedArmSim.yml
index 9440d6f4..38ba432f 100644
--- a/subprojects/robotpy-wpilib/gen/simulation/SingleJointedArmSim.yml
+++ b/subprojects/robotpy-wpilib/gen/simulation/SingleJointedArmSim.yml
@@ -10,20 +10,20 @@ classes:
     methods:
       SingleJointedArmSim:
         overloads:
-          ? const LinearSystem<2, 1, 1>&, const DCMotor&, double, units::meter_t,
+          ? const LinearSystem<2, 1, 2>&, const DCMotor&, double, units::meter_t,
             units::radian_t, units::radian_t, bool, units::radian_t, const std::array<double,
-            1>&
+            2>&
           :
             param_override:
               measurementStdDevs:
-                default: std::array<double, 1>{0.0}
+                default: std::array<double, 2>{0.0, 0.0}
           ? const DCMotor&, double, units::kilogram_square_meter_t, units::meter_t,
             units::radian_t, units::radian_t, bool, units::radian_t, const std::array<double,
-            1>&
+            2>&
           :
             param_override:
               measurementStdDevs:
-                default: std::array<double, 1>{0.0}
+                default: std::array<double, 2>{0.0, 0.0}
       SetState:
       WouldHitLowerLimit:
       WouldHitUpperLimit:
diff --git a/subprojects/robotpy-wpilib/gen/simulation/StadiaControllerSim.yml b/subprojects/robotpy-wpilib/gen/simulation/StadiaControllerSim.yml
new file mode 100644
index 00000000..a85bd277
--- /dev/null
+++ b/subprojects/robotpy-wpilib/gen/simulation/StadiaControllerSim.yml
@@ -0,0 +1,32 @@
+---
+
+extra_includes:
+- frc/StadiaController.h
+
+classes:
+  StadiaControllerSim:
+    force_no_trampoline: true
+    methods:
+      StadiaControllerSim:
+        overloads:
+          const StadiaController&:
+          int:
+      SetLeftX:
+      SetRightX:
+      SetLeftY:
+      SetRightY:
+      SetAButton:
+      SetBButton:
+      SetXButton:
+      SetYButton:
+      SetLeftBumperButton:
+      SetRightBumperButton:
+      SetLeftStickButton:
+      SetRightStickButton:
+      SetEllipsesButton:
+      SetHamburgerButton:
+      SetStadiaButton:
+      SetRightTriggerButton:
+      SetLeftTriggerButton:
+      SetGoogleButton:
+      SetFrameButton:
diff --git a/subprojects/robotpy-wpilib/gen/simulation/UltrasonicSim.yml b/subprojects/robotpy-wpilib/gen/simulation/UltrasonicSim.yml
index f2ce35b7..073ad758 100644
--- a/subprojects/robotpy-wpilib/gen/simulation/UltrasonicSim.yml
+++ b/subprojects/robotpy-wpilib/gen/simulation/UltrasonicSim.yml
@@ -9,5 +9,8 @@ classes:
     - frc::Ultrasonic
     methods:
       UltrasonicSim:
+        overloads:
+          const Ultrasonic&:
+          int, int:
       SetRangeValid:
       SetRange:
diff --git a/subprojects/robotpy-wpilib/gen/simulation/XboxControllerSim.yml b/subprojects/robotpy-wpilib/gen/simulation/XboxControllerSim.yml
index d50ac7b7..def08f49 100644
--- a/subprojects/robotpy-wpilib/gen/simulation/XboxControllerSim.yml
+++ b/subprojects/robotpy-wpilib/gen/simulation/XboxControllerSim.yml
@@ -20,7 +20,9 @@ classes:
       SetLeftTriggerAxis:
       SetRightTriggerAxis:
       SetLeftBumper:
+        ignore: true
       SetRightBumper:
+        ignore: true
       SetLeftStickButton:
       SetRightStickButton:
       SetAButton:
@@ -29,3 +31,5 @@ classes:
       SetYButton:
       SetBackButton:
       SetStartButton:
+      SetLeftBumperButton:
+      SetRightBumperButton:
diff --git a/subprojects/robotpy-wpilib/pyproject.toml b/subprojects/robotpy-wpilib/pyproject.toml
index 98e4756f..911cf19b 100644
--- a/subprojects/robotpy-wpilib/pyproject.toml
+++ b/subprojects/robotpy-wpilib/pyproject.toml
@@ -18,7 +18,7 @@ robotpy = ["run = wpilib._impl.start:Main"]
 
 [build-system]
 requires = [
-    "robotpy-build<2025.0.0,~=2024.0.0",
+    "robotpy-build<2025.0.0b1,~=2025.0.0a1",
     "robotpy-wpiutil~=2024.3.1",
     "robotpy-wpimath~=2024.3.1",
     "robotpy-hal~=2024.3.1",
@@ -27,12 +27,49 @@ requires = [
 
 [tool.robotpy-build]
 base_package = "wpilib"
+update_init = [
+    "wpilib",
+    "wpilib.counter",
+    "wpilib.drive",
+    "wpilib.event",
+    "wpilib.interfaces",
+    "wpilib.shuffleboard",
+    "wpilib.simulation",
+    "wpilib.sysid wpilib._wpilib.sysid",
+]
+scan_headers_ignore = [
+    "WPILibVersion.h",
+
+    # needs a python wrapper
+    "frc/AsynchronousInterrupt.h",
+
+    # Needs HAL object support, not sure if this is a good idea for python
+    "frc/DMA.h",
+    "frc/DMASample.h",
+
+    "frc/Filesystem.h",
+    "frc/Notifier.h", # wrapped separately
+    "frc/Resource.h",
+    "frc/ScopedTracer.h", # not useful for python
+
+    "frc/motorcontrol/MotorControllerGroup.h", # wrapped separately
+
+    # Not possible
+    "frc/shuffleboard/RecordingController.h",
+    "frc/shuffleboard/SendableCameraWrapper.h",
+
+    "frc/smartdashboard/ListenerExecutor.h",    # internal detail
+
+    # Internals
+    "rpy/ControlWord.h",
+    "rpy/SmartDashboardData.h",
+]
 
 [tool.robotpy-build.wrappers."wpilib._impl".maven_lib_download]
 artifact_id = "wpilibc-cpp"
 group_id = "edu.wpi.first.wpilibc"
-repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-version = "2024.3.2"
+repo_url = "https://frcmaven.wpi.edu/artifactory/development"
+version = "2025.1.1-beta-1"
 
 libs = ["wpilibc"]
 
@@ -66,8 +103,6 @@ pp_defines = [
 ]
 
 [tool.robotpy-build.wrappers."wpilib".autogen_headers]
-# WPILibVersion = "WPILibVersion.h"
-
 # frc
 ADIS16448_IMU = "frc/ADIS16448_IMU.h"
 ADIS16470_IMU = "frc/ADIS16470_IMU.h"
@@ -76,6 +111,7 @@ ADXL345_SPI = "frc/ADXL345_SPI.h"
 ADXL362 = "frc/ADXL362.h"
 ADXRS450_Gyro = "frc/ADXRS450_Gyro.h"
 AddressableLED = "frc/AddressableLED.h"
+Alert = "frc/Alert.h"
 AnalogAccelerometer = "frc/AnalogAccelerometer.h"
 AnalogEncoder = "frc/AnalogEncoder.h"
 AnalogGyro = "frc/AnalogGyro.h"
@@ -84,19 +120,13 @@ AnalogOutput = "frc/AnalogOutput.h"
 AnalogPotentiometer = "frc/AnalogPotentiometer.h"
 AnalogTrigger = "frc/AnalogTrigger.h"
 AnalogTriggerOutput = "frc/AnalogTriggerOutput.h"
-AnalogTriggerType = "frc/AnalogTriggerType.h"
-# AsynchronousInterrupt = "frc/AsynchronousInterrupt.h"     # needs a python wrapper
+AnalogTriggerType = "frc/AnalogTriggerType.h"  
 BuiltInAccelerometer = "frc/BuiltInAccelerometer.h"
 CAN = "frc/CAN.h"
 Compressor = "frc/Compressor.h"
 CompressorConfigType = "frc/CompressorConfigType.h"
-# Controller = "frc/Controller.h"   # deprecated
 Counter = "frc/Counter.h"
-# CounterBase = "frc/CounterBase.h" # interfaces
 DataLogManager = "frc/DataLogManager.h"
-# Needs HAL object support, not sure if this is a good idea for python
-#   DMA = "frc/DMA.h"
-#   DMASample = "frc/DMASample.h"
 DSControlWord = "frc/DSControlWord.h"
 DigitalGlitchFilter = "frc/DigitalGlitchFilter.h"
 DigitalInput = "frc/DigitalInput.h"
@@ -108,14 +138,12 @@ DutyCycle = "frc/DutyCycle.h"
 DutyCycleEncoder = "frc/DutyCycleEncoder.h"
 Encoder = "frc/Encoder.h"
 Errors = "frc/Errors.h"
-# Filesystem = "frc/Filesystem.h"
 Filesystem = "rpy/Filesystem.h"
-# GenericHID = "frc/GenericHID.h"   # interfaces
 I2C = "frc/I2C.h"
 IterativeRobotBase = "frc/IterativeRobotBase.h"
 Joystick = "frc/Joystick.h"
+LEDPattern = "frc/LEDPattern.h"
 MotorSafety = "frc/MotorSafety.h"
-# Notifier = "frc/Notifier.h"
 Notifier = "rpy/Notifier.h"
 PS4Controller = "frc/PS4Controller.h"
 PS5Controller = "frc/PS5Controller.h"
@@ -127,19 +155,16 @@ PneumaticsModuleType = "frc/PneumaticsModuleType.h"
 PowerDistribution = "frc/PowerDistribution.h"
 Preferences = "frc/Preferences.h"
 Relay = "frc/Relay.h"
-# Resource = "frc/Resource.h"
 RobotBase = "frc/RobotBase.h"
 RobotController = "frc/RobotController.h"
 RobotState = "frc/RobotState.h"
 RuntimeType = "frc/RuntimeType.h"
 SPI = "frc/SPI.h"
-# ScopedTracer = "frc/ScopedTracer.h" # Not useful for python
 SensorUtil = "frc/SensorUtil.h"
 SerialPort = "frc/SerialPort.h"
 Servo = "frc/Servo.h"
+SharpIR = "frc/SharpIR.h"
 Solenoid = "frc/Solenoid.h"
-# SpeedController = "frc/SpeedController.h" # interfaces
-# SpeedControllerGroup = "frc/SpeedControllerGroup.h"
 StadiaController = "frc/StadiaController.h"
 SynchronousInterrupt = "frc/SynchronousInterrupt.h"
 Threads = "frc/Threads.h"
@@ -160,7 +185,6 @@ LiveWindow = "frc/livewindow/LiveWindow.h"
 # frc/motorcontrol
 DMC60 = "frc/motorcontrol/DMC60.h"
 Jaguar = "frc/motorcontrol/Jaguar.h"
-# MotorController = "frc/motorcontrol/MotorController.h" # interfaces
 MotorControllerGroup = "rpy/MotorControllerGroup.h"
 NidecBrushless = "frc/motorcontrol/NidecBrushless.h"
 PWMMotorController = "frc/motorcontrol/PWMMotorController.h"
@@ -179,7 +203,6 @@ VictorSP = "frc/motorcontrol/VictorSP.h"
 # frc/smartdashboard
 Field2d = "frc/smartdashboard/Field2d.h"
 FieldObject2d = "frc/smartdashboard/FieldObject2d.h"
-# ListenerExecutor = "frc/smartdashboard/ListenerExecutor.h"    # internal detail
 Mechanism2d = "frc/smartdashboard/Mechanism2d.h"
 MechanismLigament2d = "frc/smartdashboard/MechanismLigament2d.h"
 MechanismObject2d = "frc/smartdashboard/MechanismObject2d.h"
@@ -264,10 +287,6 @@ CounterBase = "frc/CounterBase.h"
 GenericHID = "frc/GenericHID.h"
 MotorController = "frc/motorcontrol/MotorController.h"
 
-# frc/interfaces
-Accelerometer = "frc/interfaces/Accelerometer.h"
-Gyro = "frc/interfaces/Gyro.h"
-
 [tool.robotpy-build.wrappers."wpilib.shuffleboard"]
 name = "wpilibc_shuffleboard"
 extension = "_shuffleboard"
@@ -361,9 +380,12 @@ REVPHSim = "frc/simulation/REVPHSim.h"
 RelaySim = "frc/simulation/RelaySim.h"
 RoboRioSim = "frc/simulation/RoboRioSim.h"
 SPIAccelerometerSim = "frc/simulation/SPIAccelerometerSim.h"
+SendableChooserSim = "frc/simulation/SendableChooserSim.h"
+SharpIRSim = "frc/simulation/SharpIRSim.h"
 SimDeviceSim = "frc/simulation/SimDeviceSim.h"
 SimHooks = "frc/simulation/SimHooks.h"
 SingleJointedArmSim = "frc/simulation/SingleJointedArmSim.h"
 SolenoidSim = "frc/simulation/SolenoidSim.h"
+StadiaControllerSim = "frc/simulation/StadiaControllerSim.h"
 UltrasonicSim = "frc/simulation/UltrasonicSim.h"
 XboxControllerSim = "frc/simulation/XboxControllerSim.h"
diff --git a/subprojects/robotpy-wpilib/wpilib/__init__.py b/subprojects/robotpy-wpilib/wpilib/__init__.py
index 1e914f3f..42e8f3e7 100644
--- a/subprojects/robotpy-wpilib/wpilib/__init__.py
+++ b/subprojects/robotpy-wpilib/wpilib/__init__.py
@@ -3,7 +3,7 @@
 # TODO: robotpy-build subpackage bug
 from wpimath._controls._controls import trajectory as _
 
-# autogenerated by 'robotpy-build create-imports wpilib'
+# autogenerated by 'robotpy-build create-imports wpilib wpilib._wpilib'
 from ._wpilib import (
     ADIS16448_IMU,
     ADIS16470_IMU,
@@ -48,6 +48,7 @@
     IterativeRobotBase,
     Jaguar,
     Joystick,
+    LEDPattern,
     LiveWindow,
     Mechanism2d,
     MechanismLigament2d,
@@ -87,6 +88,7 @@
     SensorUtil,
     SerialPort,
     Servo,
+    SharpIR,
     SmartDashboard,
     Solenoid,
     Spark,
@@ -155,6 +157,7 @@
     "IterativeRobotBase",
     "Jaguar",
     "Joystick",
+    "LEDPattern",
     "LiveWindow",
     "Mechanism2d",
     "MechanismLigament2d",
@@ -194,6 +197,7 @@
     "SensorUtil",
     "SerialPort",
     "Servo",
+    "SharpIR",
     "SmartDashboard",
     "Solenoid",
     "Spark",
diff --git a/subprojects/robotpy-wpilib/wpilib/counter/__init__.py b/subprojects/robotpy-wpilib/wpilib/counter/__init__.py
index db3bbb09..b0563ab4 100644
--- a/subprojects/robotpy-wpilib/wpilib/counter/__init__.py
+++ b/subprojects/robotpy-wpilib/wpilib/counter/__init__.py
@@ -1,6 +1,6 @@
 from . import _init_counter
 
-# autogenerated by 'robotpy-build create-imports wpilib.counter'
+# autogenerated by 'robotpy-build create-imports wpilib.counter wpilib.counter._counter'
 from ._counter import (
     EdgeConfiguration,
     ExternalDirectionCounter,
diff --git a/subprojects/robotpy-wpilib/wpilib/drive/__init__.py b/subprojects/robotpy-wpilib/wpilib/drive/__init__.py
index ff962a3f..372de1f2 100644
--- a/subprojects/robotpy-wpilib/wpilib/drive/__init__.py
+++ b/subprojects/robotpy-wpilib/wpilib/drive/__init__.py
@@ -1,16 +1,8 @@
 from . import _init_drive
 
-# autogenerated by 'robotpy-build create-imports wpilib.drive'
-from ._drive import (
-    DifferentialDrive,
-    MecanumDrive,
-    RobotDriveBase,
-)
+# autogenerated by 'robotpy-build create-imports wpilib.drive wpilib.drive._drive'
+from ._drive import DifferentialDrive, MecanumDrive, RobotDriveBase
 
-__all__ = [
-    "DifferentialDrive",
-    "MecanumDrive",
-    "RobotDriveBase",
-]
+__all__ = ["DifferentialDrive", "MecanumDrive", "RobotDriveBase"]
 
 del _init_drive
diff --git a/subprojects/robotpy-wpilib/wpilib/event/__init__.py b/subprojects/robotpy-wpilib/wpilib/event/__init__.py
index 355d4206..31d3f82a 100644
--- a/subprojects/robotpy-wpilib/wpilib/event/__init__.py
+++ b/subprojects/robotpy-wpilib/wpilib/event/__init__.py
@@ -1,6 +1,6 @@
 from . import _init_event
 
-# autogenerated by 'robotpy-build create-imports wpilib.event'
-from ._event import BooleanEvent, EventLoop
+# autogenerated by 'robotpy-build create-imports wpilib.event wpilib.event._event'
+from ._event import BooleanEvent, EventLoop, NetworkBooleanEvent
 
-__all__ = ["BooleanEvent", "EventLoop"]
+__all__ = ["BooleanEvent", "EventLoop", "NetworkBooleanEvent"]
diff --git a/subprojects/robotpy-wpilib/wpilib/interfaces/__init__.py b/subprojects/robotpy-wpilib/wpilib/interfaces/__init__.py
index a0bef2ce..965f072a 100644
--- a/subprojects/robotpy-wpilib/wpilib/interfaces/__init__.py
+++ b/subprojects/robotpy-wpilib/wpilib/interfaces/__init__.py
@@ -1,20 +1,8 @@
 from . import _init_interfaces
 
 # autogenerated by 'robotpy-build create-imports wpilib.interfaces wpilib.interfaces._interfaces'
-from ._interfaces import (
-    Accelerometer,
-    CounterBase,
-    GenericHID,
-    Gyro,
-    MotorController,
-)
+from ._interfaces import CounterBase, GenericHID, MotorController
 
-__all__ = [
-    "Accelerometer",
-    "CounterBase",
-    "GenericHID",
-    "Gyro",
-    "MotorController",
-]
+__all__ = ["CounterBase", "GenericHID", "MotorController"]
 
 del _init_interfaces
diff --git a/subprojects/robotpy-wpilib/wpilib/shuffleboard/__init__.py b/subprojects/robotpy-wpilib/wpilib/shuffleboard/__init__.py
index 0d155084..3d7aeb06 100644
--- a/subprojects/robotpy-wpilib/wpilib/shuffleboard/__init__.py
+++ b/subprojects/robotpy-wpilib/wpilib/shuffleboard/__init__.py
@@ -1,6 +1,6 @@
 from . import _init_shuffleboard
 
-# autogenerated by 'robotpy-build create-imports wpilib.shuffleboard'
+# autogenerated by 'robotpy-build create-imports wpilib.shuffleboard wpilib.shuffleboard._shuffleboard'
 from ._shuffleboard import (
     BuiltInLayouts,
     BuiltInWidgets,
diff --git a/subprojects/robotpy-wpilib/wpilib/simulation/__init__.py b/subprojects/robotpy-wpilib/wpilib/simulation/__init__.py
index 541dda8d..e6049006 100644
--- a/subprojects/robotpy-wpilib/wpilib/simulation/__init__.py
+++ b/subprojects/robotpy-wpilib/wpilib/simulation/__init__.py
@@ -3,7 +3,7 @@
 # needed for dcmotor return value, TODO fix in robotpy-build
 from wpimath._controls._controls import plant as _
 
-# autogenerated by 'robotpy-build create-imports wpilib.simulation'
+# autogenerated by 'robotpy-build create-imports wpilib.simulation wpilib.simulation._simulation'
 from ._simulation import (
     ADIS16448_IMUSim,
     ADIS16470_IMUSim,
@@ -40,6 +40,7 @@
     LinearSystemSim_2_2_1,
     LinearSystemSim_2_2_2,
     PS4ControllerSim,
+    PS5ControllerSim,
     PWMSim,
     PneumaticsBaseSim,
     PowerDistributionSim,
@@ -47,9 +48,12 @@
     RelaySim,
     RoboRioSim,
     SPIAccelerometerSim,
+    SendableChooserSim,
+    SharpIRSim,
     SimDeviceSim,
     SingleJointedArmSim,
     SolenoidSim,
+    StadiaControllerSim,
     UltrasonicSim,
     XboxControllerSim,
     getProgramStarted,
@@ -100,6 +104,7 @@
     "LinearSystemSim_2_2_1",
     "LinearSystemSim_2_2_2",
     "PS4ControllerSim",
+    "PS5ControllerSim",
     "PWMSim",
     "PneumaticsBaseSim",
     "PowerDistributionSim",
@@ -107,9 +112,12 @@
     "RelaySim",
     "RoboRioSim",
     "SPIAccelerometerSim",
+    "SendableChooserSim",
+    "SharpIRSim",
     "SimDeviceSim",
     "SingleJointedArmSim",
     "SolenoidSim",
+    "StadiaControllerSim",
     "UltrasonicSim",
     "XboxControllerSim",
     "getProgramStarted",
diff --git a/subprojects/robotpy-wpilib/wpilib/src/rpy/Notifier.cpp b/subprojects/robotpy-wpilib/wpilib/src/rpy/Notifier.cpp
index e31aec23..f04b7714 100644
--- a/subprojects/robotpy-wpilib/wpilib/src/rpy/Notifier.cpp
+++ b/subprojects/robotpy-wpilib/wpilib/src/rpy/Notifier.cpp
@@ -15,6 +15,7 @@
 #include "frc/Timer.h"
 
 #include <pybind11/functional.h>
+#include <gilsafe_object.h>
 
 using namespace frc;
 using namespace pybind11::literals;
@@ -58,7 +59,7 @@ PyNotifier::PyNotifier(std::function<void()> handler) {
       if (handler)
         handler();
     }
-    if (_Py_IsFinalizing()) {
+    if (Py_IsFinalizing()) {
       release.disarm();
     }
   });
@@ -84,7 +85,7 @@ PyNotifier::~PyNotifier() {
     m_thread.attr("join")();
   }
 
-  HAL_CleanNotifier(handle, &status);
+  HAL_CleanNotifier(handle);
 }
 
 PyNotifier::PyNotifier(PyNotifier &&rhs)
@@ -117,7 +118,7 @@ void PyNotifier::SetName(std::string_view name) {
   HAL_SetNotifierName(m_notifier, buf.data(), &status);
 }
 
-void PyNotifier::SetHandler(std::function<void()> handler) {
+void PyNotifier::SetCallback(std::function<void()> handler) {
   std::scoped_lock lock(m_processMutex);
   m_handler = handler;
 }
diff --git a/subprojects/robotpy-wpilib/wpilib/src/rpy/Notifier.h b/subprojects/robotpy-wpilib/wpilib/src/rpy/Notifier.h
index 0e3b8a61..c05a4088 100644
--- a/subprojects/robotpy-wpilib/wpilib/src/rpy/Notifier.h
+++ b/subprojects/robotpy-wpilib/wpilib/src/rpy/Notifier.h
@@ -57,7 +57,7 @@ class PyNotifier {
    *
    * @param handler Handler
    */
-  void SetHandler(std::function<void()> handler);
+  void SetCallback(std::function<void()> handler);
 
   /**
    * Register for single event notification.
diff --git a/subprojects/robotpy-wpimath/gen/MathUtil.yml b/subprojects/robotpy-wpimath/gen/MathUtil.yml
index b4846673..d22b180a 100644
--- a/subprojects/robotpy-wpimath/gen/MathUtil.yml
+++ b/subprojects/robotpy-wpimath/gen/MathUtil.yml
@@ -5,6 +5,22 @@ functions:
     template_impls:
     - [double]
   AngleModulus:
+  FloorDiv:
+    template_impls:
+    - [int64_t, int64_t]
+    # work around GCC 10 issue on raspbian
+    cpp_code: |
+      [](int64_t x, int64_t y) -> int64_t {
+        return frc::FloorDiv(x, y);
+      }
+  FloorMod:
+    template_impls:
+    - [int64_t, int64_t]
+    # work around GCC 10 issue on raspbian
+    cpp_code: |
+      [](int64_t x, int64_t y) -> int64_t {
+        return frc::FloorMod(x, y);
+      }
   ApplyDeadband:
     param_override:
       maxMagnitude:
diff --git a/subprojects/robotpy-wpimath/gen/controls/ArmFeedforward.yml b/subprojects/robotpy-wpimath/gen/controls/ArmFeedforward.yml
index d55f091a..9b8f9b27 100644
--- a/subprojects/robotpy-wpimath/gen/controls/ArmFeedforward.yml
+++ b/subprojects/robotpy-wpimath/gen/controls/ArmFeedforward.yml
@@ -10,21 +10,23 @@ classes:
     - frc::ArmFeedforward::Acceleration
     - frc::ArmFeedforward::kv_unit
     - frc::ArmFeedforward::ka_unit
-    attributes:
-      kS:
-      kG:
-      kV:
-      kA:
     methods:
       ArmFeedforward:
         overloads:
           '[constexpr]':
           units::volt_t, units::volt_t, units::unit_t<kv_unit>, units::unit_t<ka_unit> [constexpr]:
       Calculate:
+        overloads:
+          units::unit_t<Angle>, units::unit_t<Velocity>, units::unit_t<Acceleration> [const]:
+          units::unit_t<Angle>, units::unit_t<Velocity>, units::unit_t<Velocity>, units::second_t [const]:
       MaxAchievableVelocity:
       MinAchievableVelocity:
       MaxAchievableAcceleration:
       MinAchievableAcceleration:
+      GetKs:
+      GetKg:
+      GetKv:
+      GetKa:
 
 extra_includes:
 - wpystruct.h
diff --git a/subprojects/robotpy-wpimath/gen/controls/DCMotor.yml b/subprojects/robotpy-wpimath/gen/controls/DCMotor.yml
index 2a8c6d8c..3b2bb296 100644
--- a/subprojects/robotpy-wpimath/gen/controls/DCMotor.yml
+++ b/subprojects/robotpy-wpimath/gen/controls/DCMotor.yml
@@ -19,6 +19,9 @@ classes:
     methods:
       DCMotor:
       Current:
+        overloads:
+          units::radians_per_second_t, units::volt_t [const]:
+          units::newton_meter_t [const]:
       Torque:
       Voltage:
       Speed:
diff --git a/subprojects/robotpy-wpimath/gen/controls/DifferentialDriveFeedforward.yml b/subprojects/robotpy-wpimath/gen/controls/DifferentialDriveFeedforward.yml
index 208d6b38..40a57c00 100644
--- a/subprojects/robotpy-wpimath/gen/controls/DifferentialDriveFeedforward.yml
+++ b/subprojects/robotpy-wpimath/gen/controls/DifferentialDriveFeedforward.yml
@@ -8,6 +8,11 @@ classes:
     - units::radians_per_second
     - units::radians_per_second_squared
     - units::compound_unit
+    attributes:
+      m_kVLinear:
+      m_kALinear:
+      m_kVAngular:
+      m_kAAngular:
     methods:
       DifferentialDriveFeedforward:
         overloads:
diff --git a/subprojects/robotpy-wpimath/gen/controls/DifferentialDrivePoseEstimator.yml b/subprojects/robotpy-wpimath/gen/controls/DifferentialDrivePoseEstimator.yml
index 9926dec3..73a4f44f 100644
--- a/subprojects/robotpy-wpimath/gen/controls/DifferentialDrivePoseEstimator.yml
+++ b/subprojects/robotpy-wpimath/gen/controls/DifferentialDrivePoseEstimator.yml
@@ -39,9 +39,12 @@ classes:
       containing left encoder position, right encoder position, and gyro heading.
     methods:
       DifferentialDrivePoseEstimator:
-        param_override:
-          nominalDt:
-            default: 0.02_s
+        overloads:
+          DifferentialDriveKinematics&, const Rotation2d&, units::meter_t, units::meter_t, const Pose2d&:
+          ? DifferentialDriveKinematics&, const Rotation2d&, units::meter_t, units::meter_t,
+            const Pose2d&, const wpi::array<double, 3>&, const wpi::array<double,
+            3>&
+          :
       SetVisionMeasurementStdDevs:
       ResetPosition:
       GetEstimatedPosition:
diff --git a/subprojects/robotpy-wpimath/gen/controls/ElevatorFeedforward.yml b/subprojects/robotpy-wpimath/gen/controls/ElevatorFeedforward.yml
index 3f4084e9..c9d6e682 100644
--- a/subprojects/robotpy-wpimath/gen/controls/ElevatorFeedforward.yml
+++ b/subprojects/robotpy-wpimath/gen/controls/ElevatorFeedforward.yml
@@ -6,21 +6,23 @@ classes:
     - units::meters_per_second
     - meters_per_second_squared
     subpackage: controller
-    attributes:
-      kS:
-      kG:
-      kV:
-      kA:
     methods:
       ElevatorFeedforward:
         overloads:
           "":
           units::volt_t, units::volt_t, units::unit_t<kv_unit>, units::unit_t<ka_unit> [constexpr]:
       Calculate:
+        overloads:
+          units::unit_t<Velocity>, units::unit_t<Acceleration> [constexpr]:
+          units::unit_t<Velocity>, units::unit_t<Velocity>, units::second_t [const]:
       MaxAchievableVelocity:
       MinAchievableVelocity:
       MaxAchievableAcceleration:
       MinAchievableAcceleration:
+      GetKs:
+      GetKg:
+      GetKv:
+      GetKa:
 
 extra_includes:
 - wpystruct.h
diff --git a/subprojects/robotpy-wpimath/gen/controls/EllipticalRegionConstraint.yml b/subprojects/robotpy-wpimath/gen/controls/EllipticalRegionConstraint.yml
index 694513f6..b7833d5b 100644
--- a/subprojects/robotpy-wpimath/gen/controls/EllipticalRegionConstraint.yml
+++ b/subprojects/robotpy-wpimath/gen/controls/EllipticalRegionConstraint.yml
@@ -12,6 +12,9 @@ classes:
       - frc::TrajectoryConstraint::MinMax
     methods:
       EllipticalRegionConstraint:
+        overloads:
+          const Translation2d&, units::meter_t, units::meter_t, const Rotation2d&, const Constraint&:
+          const Ellipse2d&, const Constraint&:
       MaxVelocity:
       MinMaxAcceleration:
       IsPoseInRegion:
diff --git a/subprojects/robotpy-wpimath/gen/controls/KalmanFilter.yml b/subprojects/robotpy-wpimath/gen/controls/KalmanFilter.yml
index 5b9c59f6..b5f835ff 100644
--- a/subprojects/robotpy-wpimath/gen/controls/KalmanFilter.yml
+++ b/subprojects/robotpy-wpimath/gen/controls/KalmanFilter.yml
@@ -29,6 +29,9 @@ classes:
       Reset:
       Predict:
       Correct:
+        overloads:
+          const InputVector&, const OutputVector&:
+          const InputVector&, const OutputVector&, const Matrixd<Outputs, Outputs>&:
 
 templates:
   KalmanFilter_1_1_1:
diff --git a/subprojects/robotpy-wpimath/gen/controls/LinearSystem.yml b/subprojects/robotpy-wpimath/gen/controls/LinearSystem.yml
index 001c584a..50133b63 100644
--- a/subprojects/robotpy-wpimath/gen/controls/LinearSystem.yml
+++ b/subprojects/robotpy-wpimath/gen/controls/LinearSystem.yml
@@ -27,6 +27,9 @@ classes:
           int, int [const]:
       CalculateX:
       CalculateY:
+      Slice:
+        # TODO?
+        ignore: true
 
 templates:
   LinearSystem_1_1_1:
diff --git a/subprojects/robotpy-wpimath/gen/controls/MecanumDrivePoseEstimator.yml b/subprojects/robotpy-wpimath/gen/controls/MecanumDrivePoseEstimator.yml
index ff126e38..ea2f06ff 100644
--- a/subprojects/robotpy-wpimath/gen/controls/MecanumDrivePoseEstimator.yml
+++ b/subprojects/robotpy-wpimath/gen/controls/MecanumDrivePoseEstimator.yml
@@ -32,9 +32,12 @@ classes:
       heading.
     methods:
       MecanumDrivePoseEstimator:
-        param_override:
-          nominalDt:
-            default: 0.02_s
+        overloads:
+          MecanumDriveKinematics&, const Rotation2d&, const MecanumDriveWheelPositions&, const Pose2d&:
+          ? MecanumDriveKinematics&, const Rotation2d&, const MecanumDriveWheelPositions&,
+            const Pose2d&, const wpi::array<double, 3>&, const wpi::array<double,
+            3>&
+          :
       SetVisionMeasurementStdDevs:
       ResetPosition:
       GetEstimatedPosition:
diff --git a/subprojects/robotpy-wpimath/gen/controls/PIDController.yml b/subprojects/robotpy-wpimath/gen/controls/PIDController.yml
index 14c54699..85b7809e 100644
--- a/subprojects/robotpy-wpimath/gen/controls/PIDController.yml
+++ b/subprojects/robotpy-wpimath/gen/controls/PIDController.yml
@@ -20,8 +20,11 @@ classes:
       GetD:
       GetIZone:
       GetPeriod:
+      GetErrorTolerance:
+      GetErrorDerivativeTolerance:
       GetPositionTolerance:
       GetVelocityTolerance:
+      GetAccumulatedError:
       SetSetpoint:
       GetSetpoint:
       AtSetpoint:
@@ -30,6 +33,8 @@ classes:
       IsContinuousInputEnabled:
       SetIntegratorRange:
       SetTolerance:
+      GetError:
+      GetErrorDerivative:
       GetPositionError:
       GetVelocityError:
       Calculate:
diff --git a/subprojects/robotpy-wpimath/gen/controls/PoseEstimator.yml b/subprojects/robotpy-wpimath/gen/controls/PoseEstimator.yml
index 85741cb5..d1adda6e 100644
--- a/subprojects/robotpy-wpimath/gen/controls/PoseEstimator.yml
+++ b/subprojects/robotpy-wpimath/gen/controls/PoseEstimator.yml
@@ -6,7 +6,6 @@ extra_includes:
 - frc/kinematics/MecanumDriveWheelPositions.h
 - frc/kinematics/MecanumDriveWheelSpeeds.h
 - frc/kinematics/SwerveDriveKinematics.h
-- frc/kinematics/SwerveDriveWheelPositions.h
 
 
 classes:
@@ -18,7 +17,11 @@ classes:
       PoseEstimator:
       SetVisionMeasurementStdDevs:
       ResetPosition:
+      ResetPose:
+      ResetTranslation:
+      ResetRotation:
       GetEstimatedPosition:
+      SampleAt:
       AddVisionMeasurement:
         overloads:
           const Pose2d&, units::second_t:
@@ -43,23 +46,23 @@ templates:
     qualname: frc::PoseEstimator
     subpackage: estimator
     params:
-    - frc::SwerveDriveWheelSpeeds<2>
-    - frc::SwerveDriveWheelPositions<2>
+    - wpi::array<frc::SwerveModuleState,2>
+    - wpi::array<frc::SwerveModulePosition,2>
   SwerveDrive3PoseEstimatorBase:
     qualname: frc::PoseEstimator
     subpackage: estimator
     params:
-    - frc::SwerveDriveWheelSpeeds<3>
-    - frc::SwerveDriveWheelPositions<3>
+    - wpi::array<frc::SwerveModuleState,3>
+    - wpi::array<frc::SwerveModulePosition,3>
   SwerveDrive4PoseEstimatorBase:
     qualname: frc::PoseEstimator
     subpackage: estimator
     params:
-    - frc::SwerveDriveWheelSpeeds<4>
-    - frc::SwerveDriveWheelPositions<4>
+    - wpi::array<frc::SwerveModuleState,4>
+    - wpi::array<frc::SwerveModulePosition,4>
   SwerveDrive6PoseEstimatorBase:
     qualname: frc::PoseEstimator
     subpackage: estimator
     params:
-    - frc::SwerveDriveWheelSpeeds<6>
-    - frc::SwerveDriveWheelPositions<6>
+    - wpi::array<frc::SwerveModuleState,6>
+    - wpi::array<frc::SwerveModulePosition,6>
diff --git a/subprojects/robotpy-wpimath/gen/controls/ProfiledPIDController.yml b/subprojects/robotpy-wpimath/gen/controls/ProfiledPIDController.yml
index 79470ab1..2eb14552 100644
--- a/subprojects/robotpy-wpimath/gen/controls/ProfiledPIDController.yml
+++ b/subprojects/robotpy-wpimath/gen/controls/ProfiledPIDController.yml
@@ -35,6 +35,7 @@ classes:
       GetPeriod:
       GetPositionTolerance:
       GetVelocityTolerance:
+      GetAccumulatedError:
       SetGoal:
         overloads:
           State:
diff --git a/subprojects/robotpy-wpimath/gen/controls/RectangularRegionConstraint.yml b/subprojects/robotpy-wpimath/gen/controls/RectangularRegionConstraint.yml
index ba14c96b..772fee9d 100644
--- a/subprojects/robotpy-wpimath/gen/controls/RectangularRegionConstraint.yml
+++ b/subprojects/robotpy-wpimath/gen/controls/RectangularRegionConstraint.yml
@@ -12,6 +12,9 @@ classes:
       - frc::TrajectoryConstraint::MinMax
     methods:
       RectangularRegionConstraint:
+        overloads:
+          const Translation2d&, const Translation2d&, const Constraint&:
+          const Rectangle2d&, const Constraint&:
       MaxVelocity:
       MinMaxAcceleration:
       IsPoseInRegion:
diff --git a/subprojects/robotpy-wpimath/gen/controls/SimpleMotorFeedforward.yml b/subprojects/robotpy-wpimath/gen/controls/SimpleMotorFeedforward.yml
index 6adbb0c9..cc6498d2 100644
--- a/subprojects/robotpy-wpimath/gen/controls/SimpleMotorFeedforward.yml
+++ b/subprojects/robotpy-wpimath/gen/controls/SimpleMotorFeedforward.yml
@@ -18,10 +18,6 @@ classes:
     - typename frc::SimpleMotorFeedforward<Distance>::ka_unit
     template_params:
     - Distance
-    attributes:
-      kS:
-      kV:
-      kA:
     methods:
       SimpleMotorFeedforward:
         overloads:
@@ -30,11 +26,17 @@ classes:
       Calculate:
         overloads:
           units::unit_t<Velocity>, units::unit_t<Acceleration> [const]:
-          units::unit_t<Velocity>, units::unit_t<Velocity>, units::second_t [const]:
+            ignore: true
+          units::unit_t<Velocity> [const]:
+          units::unit_t<Velocity>, units::unit_t<Velocity> [const]:
       MaxAchievableVelocity:
       MinAchievableVelocity:
       MaxAchievableAcceleration:
       MinAchievableAcceleration:
+      GetKs:
+      GetKv:
+      GetKa:
+      GetDt:
 
 templates:
   # Unfortunately this is broken because calculate requires an SI unit
diff --git a/subprojects/robotpy-wpimath/gen/controls/SwerveDrivePoseEstimator.yml b/subprojects/robotpy-wpimath/gen/controls/SwerveDrivePoseEstimator.yml
index 11df7108..ca55e09e 100644
--- a/subprojects/robotpy-wpimath/gen/controls/SwerveDrivePoseEstimator.yml
+++ b/subprojects/robotpy-wpimath/gen/controls/SwerveDrivePoseEstimator.yml
@@ -32,9 +32,12 @@ classes:
       Outputs:
     methods:
       SwerveDrivePoseEstimator:
-        param_override:
-          nominalDt:
-            default: 0.02_s
+        overloads:
+          SwerveDriveKinematics<NumModules>&, const Rotation2d&, const wpi::array<SwerveModulePosition, NumModules>&, const Pose2d&:
+          ? SwerveDriveKinematics<NumModules>&, const Rotation2d&, const wpi::array<SwerveModulePosition,
+            NumModules>&, const Pose2d&, const wpi::array<double, 3>&, const wpi::array<double,
+            3>&
+          :
       ResetPosition:
       GetEstimatedPosition:
       SetVisionMeasurementStdDevs:
diff --git a/subprojects/robotpy-wpimath/gen/filter/LinearFilter.yml b/subprojects/robotpy-wpimath/gen/filter/LinearFilter.yml
index 7e4972e8..ea2c7b57 100644
--- a/subprojects/robotpy-wpimath/gen/filter/LinearFilter.yml
+++ b/subprojects/robotpy-wpimath/gen/filter/LinearFilter.yml
@@ -15,6 +15,9 @@ classes:
       HighPass:
       MovingAverage:
       Reset:
+        overloads:
+          "":
+          std::span<const T>, std::span<const T>:
       Calculate:
       LastValue:
       BackwardFiniteDifference:
diff --git a/subprojects/robotpy-wpimath/gen/geometry/Ellipse2d.yml b/subprojects/robotpy-wpimath/gen/geometry/Ellipse2d.yml
new file mode 100644
index 00000000..c417c1bc
--- /dev/null
+++ b/subprojects/robotpy-wpimath/gen/geometry/Ellipse2d.yml
@@ -0,0 +1,48 @@
+---
+
+extra_includes:
+  - rpy/geometryToString.h
+  - wpystruct.h
+
+classes:
+  Ellipse2d:
+    force_type_casters:
+    - units::foot_t
+    - units::meter_t
+    methods:
+      Ellipse2d:
+        overloads:
+          const Pose2d&, units::meter_t, units::meter_t [constexpr]:
+          const Translation2d&, double [constexpr]:
+      Center:
+      Rotation:
+      XSemiAxis:
+        ignore: true
+      YSemiAxis:
+        ignore: true
+      FocalPoints:
+      TransformBy:
+      RotateBy:
+      Intersects:
+      Contains:
+      Distance:
+      FindNearestPoint:
+      operator==:
+
+inline_code: |
+  cls_Ellipse2d
+    .def_static("fromFeet", [](const Pose2d& center, units::foot_t xSemiAxis, units::foot_t ySemiAxis) {
+      return std::make_unique<Ellipse2d>(center, xSemiAxis, ySemiAxis);
+    }, py::arg("center"), py::arg("xSemiAxis"), py::arg("ySemiAxis"))
+    .def_property_readonly("xsemiaxis", &Ellipse2d::XSemiAxis)
+    .def_property_readonly("ysemiaxis", &Ellipse2d::YSemiAxis)
+    .def_property_readonly("xsemiaxis_feet", [](Ellipse2d &self) -> units::foot_t {
+      return self.XSemiAxis();
+    })
+    .def_property_readonly("ysemiaxis_feet", [](Ellipse2d &self) -> units::foot_t {
+      return self.YSemiAxis();
+    })
+    .def("__repr__", py::overload_cast<const Ellipse2d&>(&rpy::toString));
+
+
+  SetupWPyStruct<frc::Ellipse2d>(cls_Ellipse2d);
\ No newline at end of file
diff --git a/subprojects/robotpy-wpimath/gen/geometry/Quaternion.yml b/subprojects/robotpy-wpimath/gen/geometry/Quaternion.yml
index 42e227af..24628276 100644
--- a/subprojects/robotpy-wpimath/gen/geometry/Quaternion.yml
+++ b/subprojects/robotpy-wpimath/gen/geometry/Quaternion.yml
@@ -19,6 +19,9 @@ classes:
       operator+:
       operator-:
       operator*:
+        overloads:
+          const double [const]:
+          const Quaternion& [const]:
       operator/:
       operator==:
       operator!=:
diff --git a/subprojects/robotpy-wpimath/gen/geometry/Rectangle2d.yml b/subprojects/robotpy-wpimath/gen/geometry/Rectangle2d.yml
new file mode 100644
index 00000000..56bc9f93
--- /dev/null
+++ b/subprojects/robotpy-wpimath/gen/geometry/Rectangle2d.yml
@@ -0,0 +1,47 @@
+---
+
+extra_includes:
+  - rpy/geometryToString.h
+  - wpystruct.h
+
+classes:
+  Rectangle2d:
+    force_type_casters:
+    - units::foot_t
+    - units::meter_t
+    methods:
+      Rectangle2d:
+        overloads:
+          const Pose2d&, units::meter_t, units::meter_t [constexpr]:
+          const Translation2d&, const Translation2d& [constexpr]:
+      Center:
+      Rotation:
+      XWidth:
+        ignore: true
+      YWidth:
+        ignore: true
+      TransformBy:
+      RotateBy:
+      Intersects:
+      Contains:
+      Distance:
+      FindNearestPoint:
+      operator==:
+
+inline_code: |
+  cls_Rectangle2d
+    .def_static("fromFeet", [](const Pose2d& center, units::foot_t xWidth, units::foot_t yWidth) {
+      return std::make_unique<Rectangle2d>(center, xWidth, yWidth);
+    }, py::arg("center"), py::arg("xWidth"), py::arg("yWidth"))
+    .def_property_readonly("xwidth", &Rectangle2d::XWidth)
+    .def_property_readonly("ywidth", &Rectangle2d::YWidth)
+    .def_property_readonly("xwidth_feet", [](Rectangle2d &self) -> units::foot_t {
+      return self.XWidth();
+    })
+    .def_property_readonly("ywidth_feet", [](Rectangle2d &self) -> units::foot_t {
+      return self.YWidth();
+    })
+    .def("__repr__", py::overload_cast<const Rectangle2d&>(&rpy::toString));
+
+
+  SetupWPyStruct<frc::Rectangle2d>(cls_Rectangle2d);
\ No newline at end of file
diff --git a/subprojects/robotpy-wpimath/gen/geometry/Translation2d.yml b/subprojects/robotpy-wpimath/gen/geometry/Translation2d.yml
index a91998db..106ae12a 100644
--- a/subprojects/robotpy-wpimath/gen/geometry/Translation2d.yml
+++ b/subprojects/robotpy-wpimath/gen/geometry/Translation2d.yml
@@ -22,9 +22,11 @@ classes:
       Distance:
       X:
       Y:
+      ToVector:
       Norm:
       Angle:
       RotateBy:
+      RotateAround:
       Nearest:
         overloads:
           std::span<const Translation2d> [const]:
@@ -49,6 +51,9 @@ inline_code: |
     .def_static("fromFeet", [](units::foot_t x, units::foot_t y){
       return std::make_unique<Translation2d>(x, y);
     }, py::arg("x"), py::arg("y"))
+    .def_static("fromFeet", [](units::foot_t distance, const Rotation2d &angle) {
+      return std::make_unique<Translation2d>(distance, angle);
+    }, py::arg("distance"), py::arg("angle"))
     .def_property_readonly("x", &Translation2d::X)
     .def_property_readonly("y", &Translation2d::Y)
     .def_property_readonly("x_feet", [](Translation2d * self) -> units::foot_t {
diff --git a/subprojects/robotpy-wpimath/gen/geometry/Translation3d.yml b/subprojects/robotpy-wpimath/gen/geometry/Translation3d.yml
index 5ef0d393..a60d7179 100644
--- a/subprojects/robotpy-wpimath/gen/geometry/Translation3d.yml
+++ b/subprojects/robotpy-wpimath/gen/geometry/Translation3d.yml
@@ -23,6 +23,7 @@ classes:
       X:
       Y:
       Z:
+      ToVector:
       Norm:
       RotateBy:
       ToTranslation2d:
diff --git a/subprojects/robotpy-wpimath/gen/interpolation/TimeInterpolatableBuffer.yml b/subprojects/robotpy-wpimath/gen/interpolation/TimeInterpolatableBuffer.yml
index 4fee0c9f..f59369fc 100644
--- a/subprojects/robotpy-wpimath/gen/interpolation/TimeInterpolatableBuffer.yml
+++ b/subprojects/robotpy-wpimath/gen/interpolation/TimeInterpolatableBuffer.yml
@@ -18,6 +18,10 @@ classes:
       Clear:
       Sample:
       GetInternalBuffer:
+        overloads:
+          "":
+          '[const]':
+            ignore: true
 
 templates:
   TimeInterpolatablePose2dBuffer:
diff --git a/subprojects/robotpy-wpimath/gen/kinematics/ChassisSpeeds.yml b/subprojects/robotpy-wpimath/gen/kinematics/ChassisSpeeds.yml
index 7978aeca..d2f6c739 100644
--- a/subprojects/robotpy-wpimath/gen/kinematics/ChassisSpeeds.yml
+++ b/subprojects/robotpy-wpimath/gen/kinematics/ChassisSpeeds.yml
@@ -12,6 +12,7 @@ classes:
       vy:
       omega:
     methods:
+      ToTwist2d:
       Discretize:
         overloads:
           units::meters_per_second_t, units::meters_per_second_t, units::radians_per_second_t, units::second_t:
@@ -31,6 +32,7 @@ classes:
           '[const]':
       operator*:
       operator/:
+      operator==:
 
 inline_code: |
   cls_ChassisSpeeds
diff --git a/subprojects/robotpy-wpimath/gen/kinematics/DifferentialDriveKinematics.yml b/subprojects/robotpy-wpimath/gen/kinematics/DifferentialDriveKinematics.yml
index 36d43e91..b69bc70f 100644
--- a/subprojects/robotpy-wpimath/gen/kinematics/DifferentialDriveKinematics.yml
+++ b/subprojects/robotpy-wpimath/gen/kinematics/DifferentialDriveKinematics.yml
@@ -12,6 +12,10 @@ classes:
       ToChassisSpeeds:
       ToWheelSpeeds:
       ToTwist2d:
+        overloads:
+          const units::meter_t, const units::meter_t [const]:
+          const DifferentialDriveWheelPositions&, const DifferentialDriveWheelPositions& [const]:
+      Interpolate:
 
 inline_code: |
   SetupWPyStruct<frc::DifferentialDriveKinematics>(cls_DifferentialDriveKinematics);
diff --git a/subprojects/robotpy-wpimath/gen/kinematics/Kinematics.yml b/subprojects/robotpy-wpimath/gen/kinematics/Kinematics.yml
index 03adb28f..fd0e5326 100644
--- a/subprojects/robotpy-wpimath/gen/kinematics/Kinematics.yml
+++ b/subprojects/robotpy-wpimath/gen/kinematics/Kinematics.yml
@@ -6,7 +6,6 @@ extra_includes:
 - frc/kinematics/MecanumDriveWheelPositions.h
 - frc/kinematics/MecanumDriveWheelSpeeds.h
 - frc/kinematics/SwerveDriveKinematics.h
-- frc/kinematics/SwerveDriveWheelPositions.h
 
 
 classes:
@@ -20,6 +19,7 @@ classes:
       ToChassisSpeeds:
       ToWheelSpeeds:
       ToTwist2d:
+      Interpolate:
 
 
 templates:
@@ -36,20 +36,20 @@ templates:
   SwerveDrive2KinematicsBase:
     qualname: frc::Kinematics
     params:
-    - frc::SwerveDriveWheelSpeeds<2>
-    - frc::SwerveDriveWheelPositions<2>
+    - wpi::array<frc::SwerveModuleState,2>
+    - wpi::array<frc::SwerveModulePosition,2>
   SwerveDrive3KinematicsBase:
     qualname: frc::Kinematics
     params:
-    - frc::SwerveDriveWheelSpeeds<3>
-    - frc::SwerveDriveWheelPositions<3>
+    - wpi::array<frc::SwerveModuleState,3>
+    - wpi::array<frc::SwerveModulePosition,3>
   SwerveDrive4KinematicsBase:
     qualname: frc::Kinematics
     params:
-    - frc::SwerveDriveWheelSpeeds<4>
-    - frc::SwerveDriveWheelPositions<4>
+    - wpi::array<frc::SwerveModuleState,4>
+    - wpi::array<frc::SwerveModulePosition,4>
   SwerveDrive6KinematicsBase:
     qualname: frc::Kinematics
     params:
-    - frc::SwerveDriveWheelSpeeds<6>
-    - frc::SwerveDriveWheelPositions<6>
+    - wpi::array<frc::SwerveModuleState,6>
+    - wpi::array<frc::SwerveModulePosition,6>
diff --git a/subprojects/robotpy-wpimath/gen/kinematics/MecanumDriveKinematics.yml b/subprojects/robotpy-wpimath/gen/kinematics/MecanumDriveKinematics.yml
index 30ea322d..01bdade4 100644
--- a/subprojects/robotpy-wpimath/gen/kinematics/MecanumDriveKinematics.yml
+++ b/subprojects/robotpy-wpimath/gen/kinematics/MecanumDriveKinematics.yml
@@ -36,10 +36,14 @@ classes:
                       fl, fr, bl, br = kinematics.toWheelSpeeds(chassisSpeeds)
       ToChassisSpeeds:
       ToTwist2d:
+        overloads:
+          const MecanumDriveWheelPositions&, const MecanumDriveWheelPositions& [const]:
+          const MecanumDriveWheelPositions& [const]:
       GetFrontLeft:
       GetFrontRight:
       GetRearLeft:
       GetRearRight:
+      Interpolate:
 
 inline_code: |
   SetupWPyStruct<frc::MecanumDriveKinematics>(cls_MecanumDriveKinematics);
diff --git a/subprojects/robotpy-wpimath/gen/kinematics/Odometry.yml b/subprojects/robotpy-wpimath/gen/kinematics/Odometry.yml
index a37e84cf..c2ea93c2 100644
--- a/subprojects/robotpy-wpimath/gen/kinematics/Odometry.yml
+++ b/subprojects/robotpy-wpimath/gen/kinematics/Odometry.yml
@@ -6,7 +6,6 @@ extra_includes:
 - frc/kinematics/MecanumDriveWheelPositions.h
 - frc/kinematics/MecanumDriveWheelSpeeds.h
 - frc/kinematics/SwerveDriveKinematics.h
-- frc/kinematics/SwerveDriveWheelPositions.h
 
 classes:
   Odometry:
@@ -16,6 +15,9 @@ classes:
     methods:
       Odometry:
       ResetPosition:
+      ResetPose:
+      ResetTranslation:
+      ResetRotation:
       GetPose:
       Update:
 
@@ -33,20 +35,20 @@ templates:
   SwerveDrive2OdometryBase:
     qualname: frc::Odometry
     params:
-    - frc::SwerveDriveWheelSpeeds<2>
-    - frc::SwerveDriveWheelPositions<2>
+    - wpi::array<frc::SwerveModuleState,2>
+    - wpi::array<frc::SwerveModulePosition,2>
   SwerveDrive3OdometryBase:
     qualname: frc::Odometry
     params:
-    - frc::SwerveDriveWheelSpeeds<3>
-    - frc::SwerveDriveWheelPositions<3>
+    - wpi::array<frc::SwerveModuleState,3>
+    - wpi::array<frc::SwerveModulePosition,3>
   SwerveDrive4OdometryBase:
     qualname: frc::Odometry
     params:
-    - frc::SwerveDriveWheelSpeeds<4>
-    - frc::SwerveDriveWheelPositions<4>
+    - wpi::array<frc::SwerveModuleState,4>
+    - wpi::array<frc::SwerveModulePosition,4>
   SwerveDrive6OdometryBase:
     qualname: frc::Odometry
     params:
-    - frc::SwerveDriveWheelSpeeds<6>
-    - frc::SwerveDriveWheelPositions<6>
+    - wpi::array<frc::SwerveModuleState,6>
+    - wpi::array<frc::SwerveModulePosition,6>
diff --git a/subprojects/robotpy-wpimath/gen/kinematics/SwerveDriveKinematics.yml b/subprojects/robotpy-wpimath/gen/kinematics/SwerveDriveKinematics.yml
index fec1c3f7..5002b3d9 100644
--- a/subprojects/robotpy-wpimath/gen/kinematics/SwerveDriveKinematics.yml
+++ b/subprojects/robotpy-wpimath/gen/kinematics/SwerveDriveKinematics.yml
@@ -58,8 +58,7 @@ classes:
           ModuleDeltas&&... [const]:
             ignore: true
           wpi::array<SwerveModulePosition, NumModules> [const]:
-          const SwerveDriveWheelPositions<NumModules>&, const SwerveDriveWheelPositions<NumModules>& [const]:
-            ignore: true
+          const wpi::array<SwerveModulePosition, NumModules>&, const wpi::array<SwerveModulePosition, NumModules>& [const]:
       DesaturateWheelSpeeds:
         overloads:
           wpi::array<SwerveModuleState, NumModules>*, units::meters_per_second_t:
@@ -81,6 +80,9 @@ classes:
                 return moduleStates;
               }
 
+      Interpolate:
+      GetModules:
+
     template_inline_code: |
       if constexpr (NumModules == 2) {
         cls_SwerveDriveKinematics.def(py::init<Translation2d, Translation2d>());
diff --git a/subprojects/robotpy-wpimath/gen/kinematics/SwerveDriveWheelPositions.yml b/subprojects/robotpy-wpimath/gen/kinematics/SwerveDriveWheelPositions.yml
deleted file mode 100644
index 2de56c85..00000000
--- a/subprojects/robotpy-wpimath/gen/kinematics/SwerveDriveWheelPositions.yml
+++ /dev/null
@@ -1,47 +0,0 @@
----
-
-classes:
-  SwerveDriveWheelPositions:
-    template_params:
-    - size_t NumModules
-    force_type_casters:
-    - wpi::array
-    force_no_default_constructor: true
-    attributes:
-      positions:
-    methods:
-      operator==:
-        cpp_code: |
-          "__eq__", [](frc::SwerveDriveWheelPositions<NumModules> &self, frc::SwerveDriveWheelPositions<NumModules> &other) {
-              return self == other;
-          }, py::is_operator()
-      operator!=:
-        cpp_code: |
-          "__ne__", [](frc::SwerveDriveWheelPositions<NumModules> &self, frc::SwerveDriveWheelPositions<NumModules> &other) {
-              return self != other;
-          }, py::is_operator()
-      Interpolate:
-
-    template_inline_code: |
-      cls_SwerveDriveWheelPositions
-        .def(py::init<wpi::array<SwerveModulePosition, NumModules>>(),
-          py::arg("positions")
-        );
-
-templates:
-  SwerveDrive2WheelPositions:
-    qualname: frc::SwerveDriveWheelPositions
-    params:
-    - 2
-  SwerveDrive3WheelPositions:
-    qualname: frc::SwerveDriveWheelPositions
-    params:
-    - 3
-  SwerveDrive4WheelPositions:
-    qualname: frc::SwerveDriveWheelPositions
-    params:
-    - 4
-  SwerveDrive6WheelPositions:
-    qualname: frc::SwerveDriveWheelPositions
-    params:
-    - 6
diff --git a/subprojects/robotpy-wpimath/gen/kinematics/SwerveModuleState.yml b/subprojects/robotpy-wpimath/gen/kinematics/SwerveModuleState.yml
index fca240ba..0d5c07f7 100644
--- a/subprojects/robotpy-wpimath/gen/kinematics/SwerveModuleState.yml
+++ b/subprojects/robotpy-wpimath/gen/kinematics/SwerveModuleState.yml
@@ -13,6 +13,10 @@ classes:
     methods:
       operator==:
       Optimize:
+        overloads:
+          const Rotation2d&:
+          const SwerveModuleState&, const Rotation2d&:
+            ignore: true
 
 inline_code: |
   cls_SwerveModuleState
diff --git a/subprojects/robotpy-wpimath/pyproject.toml b/subprojects/robotpy-wpimath/pyproject.toml
index 78b01600..0ef3d93b 100644
--- a/subprojects/robotpy-wpimath/pyproject.toml
+++ b/subprojects/robotpy-wpimath/pyproject.toml
@@ -11,7 +11,7 @@ install_requires = [
 
 [build-system]
 requires = [
-    "robotpy-build<2025.0.0,~=2024.0.0",
+    "robotpy-build<2025.0.0b1,~=2025.0.0a1",
     "robotpy-wpiutil~=2024.3.1",
     # "numpy", # broken in raspbian CI
 ]
@@ -19,11 +19,58 @@ requires = [
 [tool.robotpy-build]
 base_package = "wpimath"
 
+update_init = [
+    "wpimath"
+]
+
+scan_headers_ignore = [
+    
+    "frc/DARE.h",
+    "frc/EigenCore.h",
+    "frc/StateSpaceUtil.h",
+
+    "frc/fmt/Eigen.h",
+
+    "frc/estimator/AngleStatistics.h",
+    "frc/estimator/KalmanFilterLatencyCompensator.h",
+    "frc/estimator/MerweScaledSigmaPoints.h",
+    "frc/estimator/SteadyStateKalmanFilter.h",
+    "frc/estimator/UnscentedKalmanFilter.h",
+    "frc/estimator/UnscentedTransform.h",
+
+    "frc/system/Discretization.h",
+    "frc/system/NumericalIntegration.h",
+    "frc/system/NumericalJacobian.h",
+
+    "frc/proto/*",
+    "frc/*/proto/*",
+    
+    "frc/struct/*",
+    "frc/*/struct/*",
+    
+    "[eE]igen/*",
+
+    "gcem.hpp",
+    "gcem_incl/*",
+
+    "sleipnir/*",
+    "type_casters/*",
+    "unsupported/*",
+    "units/*",
+    "wpimath/protobuf/*",
+
+    "wpimath/MathShared.h",
+
+    "rpy/geometryToString.h",
+    "PyTrajectoryConstraint.h",
+    "_units_base_type_caster.h",
+]
+
 [tool.robotpy-build.wrappers."wpimath._impl".maven_lib_download]
 artifact_id = "wpimath-cpp"
 group_id = "edu.wpi.first.wpimath"
-repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-version = "2024.3.2"
+repo_url = "https://frcmaven.wpi.edu/artifactory/development"
+version = "2025.1.1-beta-1"
 
 
 libs = ["wpimath"]
@@ -621,6 +668,7 @@ header = "units_length_type_caster.h"
 types = [
     "units::angstrom_t",
     "units::astronicalUnit_t",
+    "units::centimeter_t",
     "units::chain_t",
     "units::cubit_t",
     "units::fathom_t",
@@ -1495,9 +1543,11 @@ generation_data = "gen/geometry"
 # frc/geometry
 CoordinateAxis = "frc/geometry/CoordinateAxis.h"
 CoordinateSystem = "frc/geometry/CoordinateSystem.h"
+Ellipse2d = "frc/geometry/Ellipse2d.h"
 Pose2d = "frc/geometry/Pose2d.h"
 Pose3d = "frc/geometry/Pose3d.h"
 Quaternion = "frc/geometry/Quaternion.h"
+Rectangle2d = "frc/geometry/Rectangle2d.h"
 Rotation2d = "frc/geometry/Rotation2d.h"
 Rotation3d = "frc/geometry/Rotation3d.h"
 Transform2d = "frc/geometry/Transform2d.h"
@@ -1542,10 +1592,8 @@ MecanumDriveWheelSpeeds = "frc/kinematics/MecanumDriveWheelSpeeds.h"
 Odometry = "frc/kinematics/Odometry.h"
 SwerveDriveKinematics = "frc/kinematics/SwerveDriveKinematics.h"
 SwerveDriveOdometry = "frc/kinematics/SwerveDriveOdometry.h"
-SwerveDriveWheelPositions = "frc/kinematics/SwerveDriveWheelPositions.h"
 SwerveModulePosition = "frc/kinematics/SwerveModulePosition.h"
 SwerveModuleState = "frc/kinematics/SwerveModuleState.h"
-WheelPositions = "frc/kinematics/WheelPositions.h"
 
 [tool.robotpy-build.wrappers."wpimath.spline"]
 
diff --git a/subprojects/robotpy-wpimath/wpimath/__init__.py b/subprojects/robotpy-wpimath/wpimath/__init__.py
index c1364eed..0bf7d9aa 100644
--- a/subprojects/robotpy-wpimath/wpimath/__init__.py
+++ b/subprojects/robotpy-wpimath/wpimath/__init__.py
@@ -1,6 +1,37 @@
 from . import _init_wpimath  # noqa: F401
 
 # autogenerated by 'robotpy-build create-imports wpimath'
-from ._wpimath import angleModulus, applyDeadband, inputModulus, objectToRobotPose
+from ._wpimath import (
+    angleModulus,
+    applyDeadband,
+    inputModulus,
+    objectToRobotPose,
+)
 
-__all__ = ["angleModulus", "applyDeadband", "inputModulus", "objectToRobotPose"]
+__all__ = [
+    "angleModulus",
+    "applyDeadband",
+    "inputModulus",
+    "objectToRobotPose",
+]
+
+# What
+
+# autogenerated by 'robotpy-build create-imports wpimath wpimath._wpimath'
+from ._wpimath import (
+    angleModulus,
+    applyDeadband,
+    floorDiv,
+    floorMod,
+    inputModulus,
+    objectToRobotPose,
+)
+
+__all__ = [
+    "angleModulus",
+    "applyDeadband",
+    "floorDiv",
+    "floorMod",
+    "inputModulus",
+    "objectToRobotPose",
+]
diff --git a/subprojects/robotpy-wpimath/wpimath/_impl/src/type_casters/units_length_type_caster.h b/subprojects/robotpy-wpimath/wpimath/_impl/src/type_casters/units_length_type_caster.h
index 262a48f5..9f0cee40 100644
--- a/subprojects/robotpy-wpimath/wpimath/_impl/src/type_casters/units_length_type_caster.h
+++ b/subprojects/robotpy-wpimath/wpimath/_impl/src/type_casters/units_length_type_caster.h
@@ -36,6 +36,14 @@ template <> struct handle_type_name<units::millimeters> {
   static constexpr auto name = _("wpimath.units.millimeters");
 };
 
+template <> struct handle_type_name<units::centimeter_t> {
+  static constexpr auto name = _("wpimath.units.centimeters");
+};
+
+template <> struct handle_type_name<units::centimeters> {
+  static constexpr auto name = _("wpimath.units.centimeters");
+};
+
 template <> struct handle_type_name<units::kilometer_t> {
   static constexpr auto name = _("wpimath.units.kilometers");
 };
diff --git a/subprojects/robotpy-wpimath/wpimath/geometry/__init__.py b/subprojects/robotpy-wpimath/wpimath/geometry/__init__.py
index 93e6a473..02cfc474 100644
--- a/subprojects/robotpy-wpimath/wpimath/geometry/__init__.py
+++ b/subprojects/robotpy-wpimath/wpimath/geometry/__init__.py
@@ -4,9 +4,11 @@
 from ._geometry import (
     CoordinateAxis,
     CoordinateSystem,
+    Ellipse2d,
     Pose2d,
     Pose3d,
     Quaternion,
+    Rectangle2d,
     Rotation2d,
     Rotation3d,
     Transform2d,
@@ -20,9 +22,11 @@
 __all__ = [
     "CoordinateAxis",
     "CoordinateSystem",
+    "Ellipse2d",
     "Pose2d",
     "Pose3d",
     "Quaternion",
+    "Rectangle2d",
     "Rotation2d",
     "Rotation3d",
     "Transform2d",
diff --git a/subprojects/robotpy-wpimath/wpimath/geometry/include/rpy/geometryToString.h b/subprojects/robotpy-wpimath/wpimath/geometry/include/rpy/geometryToString.h
index 803e582b..4ba07ad5 100644
--- a/subprojects/robotpy-wpimath/wpimath/geometry/include/rpy/geometryToString.h
+++ b/subprojects/robotpy-wpimath/wpimath/geometry/include/rpy/geometryToString.h
@@ -1,7 +1,9 @@
 #include <string>
 
+#include <frc/geometry/Ellipse2d.h>
 #include <frc/geometry/Pose2d.h>
 #include <frc/geometry/Pose3d.h>
+#include <frc/geometry/Rectangle2d.h>
 #include <frc/geometry/Rotation2d.h>
 #include <frc/geometry/Rotation3d.h>
 #include <frc/geometry/Translation2d.h>
@@ -81,5 +83,17 @@ inline std::string toString(const frc::Pose3d &self) {
          rpy::toString(self.Rotation()) + ")";
 }
 
+inline std::string toString(const frc::Rectangle2d &self) {
+  return "Rectangle2d(center=" + rpy::toString(self.Center()) +
+    ", xWidth=" + std::to_string(self.XWidth()()) +
+    ", yWidth=" + std::to_string(self.YWidth()()) + ")";
+}
+
+inline std::string toString(const frc::Ellipse2d &self) {
+  return "Ellipse2d(center=" + rpy::toString(self.Center()) +
+    ", xSemiAxis=" + std::to_string(self.XSemiAxis()()) +
+    ", ySemiAxis=" + std::to_string(self.YSemiAxis()()) + ")";
+}
+
 
 } // namespace rpy
diff --git a/subprojects/robotpy-wpimath/wpimath/kinematics/__init__.py b/subprojects/robotpy-wpimath/wpimath/kinematics/__init__.py
index 780cab8b..6092835c 100644
--- a/subprojects/robotpy-wpimath/wpimath/kinematics/__init__.py
+++ b/subprojects/robotpy-wpimath/wpimath/kinematics/__init__.py
@@ -19,22 +19,18 @@
     SwerveDrive2KinematicsBase,
     SwerveDrive2Odometry,
     SwerveDrive2OdometryBase,
-    SwerveDrive2WheelPositions,
     SwerveDrive3Kinematics,
     SwerveDrive3KinematicsBase,
     SwerveDrive3Odometry,
     SwerveDrive3OdometryBase,
-    SwerveDrive3WheelPositions,
     SwerveDrive4Kinematics,
     SwerveDrive4KinematicsBase,
     SwerveDrive4Odometry,
     SwerveDrive4OdometryBase,
-    SwerveDrive4WheelPositions,
     SwerveDrive6Kinematics,
     SwerveDrive6KinematicsBase,
     SwerveDrive6Odometry,
     SwerveDrive6OdometryBase,
-    SwerveDrive6WheelPositions,
     SwerveModulePosition,
     SwerveModuleState,
 )
diff --git a/subprojects/robotpy-wpimath/wpimath/units.py b/subprojects/robotpy-wpimath/wpimath/units.py
index 9554046f..cdcb0f5f 100644
--- a/subprojects/robotpy-wpimath/wpimath/units.py
+++ b/subprojects/robotpy-wpimath/wpimath/units.py
@@ -344,6 +344,7 @@ def lbsToKilograms(lbs: pounds) -> kilograms:
 nanometers = float
 micrometers = float
 millimeters = float
+centimeters = float
 kilometers = float
 feet = float
 mils = float
diff --git a/subprojects/robotpy-wpinet/pyproject.toml b/subprojects/robotpy-wpinet/pyproject.toml
index 6972d367..15aa2827 100644
--- a/subprojects/robotpy-wpinet/pyproject.toml
+++ b/subprojects/robotpy-wpinet/pyproject.toml
@@ -1,5 +1,10 @@
 [tool.robotpy-build]
 base_package = "wpinet"
+update_init = [
+    "wpinet"
+]
+# we don't wrap anything here
+scan_headers_ignore = ["*"]
 
 [tool.robotpy-build.wrappers."wpinet"]
 name = "wpinet"
@@ -14,8 +19,8 @@ generation_data = "gen"
 artifact_id = "wpinet-cpp"
 group_id = "edu.wpi.first.wpinet"
 # repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-version = "2024.3.2"
+repo_url = "https://frcmaven.wpi.edu/artifactory/development"
+version = "2025.1.1-beta-1"
 
 libs = ["wpinet"]
 
@@ -36,6 +41,6 @@ install_requires = [
 
 [build-system]
 requires = [
-    "robotpy-build<2025.0.0,~=2024.0.0",
+    "robotpy-build<2025.0.0b1,~=2025.0.0a1",
     "robotpy-wpiutil~=2024.3.1",
 ]
diff --git a/subprojects/robotpy-wpinet/wpinet/__init__.py b/subprojects/robotpy-wpinet/wpinet/__init__.py
index 5ec246d7..163985e0 100644
--- a/subprojects/robotpy-wpinet/wpinet/__init__.py
+++ b/subprojects/robotpy-wpinet/wpinet/__init__.py
@@ -1,5 +1,6 @@
 from . import _init_wpinet
 
+
 # autogenerated by 'robotpy-build create-imports wpinet wpinet._wpinet'
 from ._wpinet import PortForwarder
 
diff --git a/subprojects/robotpy-wpiutil/gen/DataLog.yml b/subprojects/robotpy-wpiutil/gen/DataLog.yml
index 96b772e7..85789bee 100644
--- a/subprojects/robotpy-wpiutil/gen/DataLog.yml
+++ b/subprojects/robotpy-wpiutil/gen/DataLog.yml
@@ -7,16 +7,15 @@ enums:
 classes:
   DataLog:
     subpackage: log
+    attributes:
+      kBlockSize:
+      s_defaultMessageLog:
+        ignore: true
+      m_msglog:
+        ignore: true
     methods:
       DataLog:
-        overloads:
-          std::string_view, std::string_view, double, std::string_view:
-          wpi::Logger&, std::string_view, std::string_view, double, std::string_view:
-            ignore: true
-          std::function<void (std::span<const uint8_t> data)>, double, std::string_view:
-          wpi::Logger&, std::function<void (std::span<const uint8_t> data)>, double, std::string_view:
-            ignore: true
-      SetFilename:
+        ignore: true
       Flush:
       Pause:
       Resume:
@@ -63,8 +62,15 @@ classes:
           int, std::span<const std::string>, int64_t:
             ignore: true
           int, std::span<const std::string_view>, int64_t:
-          int, std::span<const WPI_DataLog_String>, int64_t:
+          int, std::span<const struct WPI_String>, int64_t:
             ignore: true
+      StartFile:
+      FlushBufs:
+        ignore: true
+      ReleaseBufs:
+        ignore: true
+      BufferHalfFull:
+      BufferFull:
   DataLogEntry:
     subpackage: log
     force_no_trampoline: true
@@ -76,6 +82,23 @@ classes:
           "":
             ignore: true
           DataLog&, std::string_view, std::string_view, std::string_view, int64_t:
+  DataLogValueEntryImpl:
+    template_params:
+    - T
+    force_no_trampoline: true
+    attributes:
+      m_mutex:
+        ignore: true
+      m_lastValue:
+        ignore: true
+    methods:
+      HasLastValue:
+      GetLastValue:
+      DataLogValueEntryImpl:
+        overloads:
+          "":
+            ignore: true
+          DataLog&, std::string_view, std::string_view, std::string_view, int64_t:
   RawLogEntry:
     subpackage: log
     force_no_trampoline: true
@@ -90,6 +113,7 @@ classes:
           DataLog&, std::string_view, std::string_view, int64_t:
           DataLog&, std::string_view, std::string_view, std::string_view, int64_t:
       Append:
+      Update:
   BooleanLogEntry:
     subpackage: log
     force_no_trampoline: true
@@ -103,6 +127,7 @@ classes:
           DataLog&, std::string_view, int64_t:
           DataLog&, std::string_view, std::string_view, int64_t:
       Append:
+      Update:
   IntegerLogEntry:
     subpackage: log
     force_no_trampoline: true
@@ -116,6 +141,7 @@ classes:
           DataLog&, std::string_view, int64_t:
           DataLog&, std::string_view, std::string_view, int64_t:
       Append:
+      Update:
   FloatLogEntry:
     subpackage: log
     force_no_trampoline: true
@@ -129,6 +155,7 @@ classes:
           DataLog&, std::string_view, int64_t:
           DataLog&, std::string_view, std::string_view, int64_t:
       Append:
+      Update:
   DoubleLogEntry:
     subpackage: log
     force_no_trampoline: true
@@ -142,6 +169,7 @@ classes:
           DataLog&, std::string_view, int64_t:
           DataLog&, std::string_view, std::string_view, int64_t:
       Append:
+      Update:
   StringLogEntry:
     subpackage: log
     force_no_trampoline: true
@@ -156,6 +184,7 @@ classes:
           DataLog&, std::string_view, std::string_view, int64_t:
           DataLog&, std::string_view, std::string_view, std::string_view, int64_t:
       Append:
+      Update:
   BooleanArrayLogEntry:
     subpackage: log
     force_no_trampoline: true
@@ -179,6 +208,16 @@ classes:
             ignore: true
           std::span<const uint8_t>, int64_t:
             ignore: true
+      Update:
+        overloads:
+          std::span<const bool>, int64_t:
+          std::initializer_list<bool>, int64_t:
+            ignore: true
+          std::span<const int>, int64_t:
+          std::initializer_list<int>, int64_t:
+            ignore: true
+          std::span<const uint8_t>, int64_t:
+            ignore: true
   IntegerArrayLogEntry:
     subpackage: log
     force_no_trampoline: true
@@ -196,6 +235,11 @@ classes:
           std::span<const int64_t>, int64_t:
           std::initializer_list<int64_t>, int64_t:
             ignore: true
+      Update:
+        overloads:
+          std::span<const int64_t>, int64_t:
+          std::initializer_list<int64_t>, int64_t:
+            ignore: true
   FloatArrayLogEntry:
     subpackage: log
     force_no_trampoline: true
@@ -213,6 +257,11 @@ classes:
           std::span<const float>, int64_t:
           std::initializer_list<float>, int64_t:
             ignore: true
+      Update:
+        overloads:
+          std::span<const float>, int64_t:
+          std::initializer_list<float>, int64_t:
+            ignore: true
   DoubleArrayLogEntry:
     subpackage: log
     force_no_trampoline: true
@@ -230,6 +279,11 @@ classes:
           std::span<const double>, int64_t:
           std::initializer_list<double>, int64_t:
             ignore: true
+      Update:
+        overloads:
+          std::span<const double>, int64_t:
+          std::initializer_list<double>, int64_t:
+            ignore: true
   StringArrayLogEntry:
     subpackage: log
     force_no_trampoline: true
@@ -249,6 +303,13 @@ classes:
           std::span<const std::string_view>, int64_t:
           std::initializer_list<std::string_view>, int64_t:
             ignore: true
+      Update:
+        overloads:
+          std::span<const std::string>, int64_t:
+            ignore: true
+          std::span<const std::string_view>, int64_t:
+          std::initializer_list<std::string_view>, int64_t:
+            ignore: true
   StructLogEntry:
     force_no_trampoline: true
     template_params:
@@ -335,4 +396,60 @@ templates:
     subpackage: log
     params:
     - WPyStruct
-    - WPyStructInfo
\ No newline at end of file
+    - WPyStructInfo
+
+  _RawLogEntryImpl:
+    qualname: wpi::log::DataLogValueEntryImpl
+    subpackage: log
+    params:
+    - std::vector<uint8_t>
+  _BooleanLogEntryImpl:
+    qualname: wpi::log::DataLogValueEntryImpl
+    subpackage: log
+    params:
+    - bool
+  _IntegerLogEntryImpl:
+    qualname: wpi::log::DataLogValueEntryImpl
+    subpackage: log
+    params:
+    - int64_t
+  _FloatLogEntryImpl:
+    qualname: wpi::log::DataLogValueEntryImpl
+    subpackage: log
+    params:
+    - float
+  _DoubleLogEntryImpl:
+    qualname: wpi::log::DataLogValueEntryImpl
+    subpackage: log
+    params:
+    - double
+  _StringLogEntryImpl:
+    qualname: wpi::log::DataLogValueEntryImpl
+    subpackage: log
+    params:
+    - std::string
+  _BooleanArrayLogEntryImpl:
+    qualname: wpi::log::DataLogValueEntryImpl
+    subpackage: log
+    params:
+    - std::vector<int>
+  _IntegerArrayLogEntryImpl:
+    qualname: wpi::log::DataLogValueEntryImpl
+    subpackage: log
+    params:
+    - std::vector<int64_t>
+  _FloatArrayLogEntryImpl:
+    qualname: wpi::log::DataLogValueEntryImpl
+    subpackage: log
+    params:
+    - std::vector<float>
+  _DoubleArrayLogEntryImpl:
+    qualname: wpi::log::DataLogValueEntryImpl
+    subpackage: log
+    params:
+    - std::vector<double>
+  _StringArrayLogEntryImpl:
+    qualname: wpi::log::DataLogValueEntryImpl
+    subpackage: log
+    params:
+    - std::vector<std::string>
\ No newline at end of file
diff --git a/subprojects/robotpy-wpiutil/gen/DataLogBackgroundWriter.yml b/subprojects/robotpy-wpiutil/gen/DataLogBackgroundWriter.yml
new file mode 100644
index 00000000..fbb78b25
--- /dev/null
+++ b/subprojects/robotpy-wpiutil/gen/DataLogBackgroundWriter.yml
@@ -0,0 +1,18 @@
+---
+
+classes:
+  DataLogBackgroundWriter:
+    methods:
+      DataLogBackgroundWriter:
+        overloads:
+          std::string_view, std::string_view, double, std::string_view:
+          wpi::Logger&, std::string_view, std::string_view, double, std::string_view:
+            ignore: true
+          std::function<void (std::span<const uint8_t> data)>, double, std::string_view:
+          wpi::Logger&, std::function<void (std::span<const uint8_t> data)>, double, std::string_view:
+            ignore: true
+      SetFilename:
+      Flush:
+      Pause:
+      Resume:
+      Stop:
diff --git a/subprojects/robotpy-wpiutil/gen/DataLogReader.yml b/subprojects/robotpy-wpiutil/gen/DataLogReader.yml
index 3feb1b2f..eea2dd1e 100644
--- a/subprojects/robotpy-wpiutil/gen/DataLogReader.yml
+++ b/subprojects/robotpy-wpiutil/gen/DataLogReader.yml
@@ -300,20 +300,19 @@ inline_code: |
 
   cls_DataLogReader
     .def(py::init([](const std::string &filename) {
-      std::error_code ec;
-      auto mbuf = wpi::MemoryBuffer::GetFile(filename, ec);
-      if (ec) {
+      auto mbuf = wpi::MemoryBuffer::GetFile(filename);
+      if (!mbuf) {
         py::gil_scoped_acquire gil;
         #ifdef _WIN32
-          PyErr_SetFromWindowsErr(ec.value());
+          PyErr_SetFromWindowsErr(mbuf.error().value());
         #else
-          errno = ec.value();
+          errno = mbuf.error().value();
           PyErr_SetFromErrno(PyExc_OSError);
         #endif
         throw py::error_already_set();
       }
 
-      return std::make_shared<wpi::log::DataLogReader>(std::move(mbuf));
+      return std::make_shared<wpi::log::DataLogReader>(std::move(*mbuf));
     }),
       release_gil(), py::arg("filename"))
 
diff --git a/subprojects/robotpy-wpiutil/gen/DataLogWriter.yml b/subprojects/robotpy-wpiutil/gen/DataLogWriter.yml
new file mode 100644
index 00000000..72a99a01
--- /dev/null
+++ b/subprojects/robotpy-wpiutil/gen/DataLogWriter.yml
@@ -0,0 +1,30 @@
+---
+
+classes:
+  DataLogWriter:
+    methods:
+      DataLogWriter:
+        overloads:
+          std::string_view, std::error_code&, std::string_view:
+            cpp_code: |
+              [](std::string_view filename, std::string_view extraHeader) {
+                std::error_code ec;
+                auto writer = std::make_unique<DataLogWriter>(filename, ec, extraHeader);
+                if (ec) {
+                  throw std::system_error(ec);
+                }
+                return writer;
+              }
+            param_override:
+              ec:
+                ignore: true
+          wpi::Logger&, std::string_view, std::error_code&, std::string_view:
+            ignore: true
+          std::unique_ptr<wpi::raw_ostream>, std::string_view:
+            ignore: true
+          wpi::Logger&, std::unique_ptr<wpi::raw_ostream>, std::string_view:
+            ignore: true
+      Flush:
+      Stop:
+      GetStream:
+        ignore: true
diff --git a/subprojects/robotpy-wpiutil/gen/WPyStruct.yml b/subprojects/robotpy-wpiutil/gen/WPyStruct.yml
index f41affcf..981f4563 100644
--- a/subprojects/robotpy-wpiutil/gen/WPyStruct.yml
+++ b/subprojects/robotpy-wpiutil/gen/WPyStruct.yml
@@ -2,7 +2,7 @@ functions:
   forEachNested:
     subpackage: wpistruct
     no_release_gil: true
-  getTypeString:
+  getTypeName:
     subpackage: wpistruct
     no_release_gil: true
   getSchema:
diff --git a/subprojects/robotpy-wpiutil/pyproject.toml b/subprojects/robotpy-wpiutil/pyproject.toml
index 4b26c10b..6a8eedf3 100644
--- a/subprojects/robotpy-wpiutil/pyproject.toml
+++ b/subprojects/robotpy-wpiutil/pyproject.toml
@@ -9,11 +9,23 @@ install_requires = []
 
 [build-system]
 requires = [
-    "robotpy-build<2025.0.0,~=2024.0.0",
+    "robotpy-build<2025.0.0b1,~=2025.0.0a1",
 ]
 
 [tool.robotpy-build]
 base_package = "wpiutil"
+update_init = [
+    "wpiutil",
+    "wpiutil.log wpiutil._wpiutil.log",
+    "wpiutil.sync wpiutil._wpiutil.sync",
+    "wpiutil.wpistruct wpiutil._wpiutil.wpistruct",
+]
+scan_headers_ignore = [
+    "fmt/*",
+    "google/*",
+    "wpi/*",
+    "wpystruct_fns.h",
+]
 
 [tool.robotpy-build.wrappers."wpiutil"]
 name = "wpiutil"
@@ -33,9 +45,9 @@ generation_data = "gen"
 [tool.robotpy-build.wrappers."wpiutil".maven_lib_download]
 artifact_id = "wpiutil-cpp"
 group_id = "edu.wpi.first.wpiutil"
-repo_url = "https://frcmaven.wpi.edu/artifactory/release"
+repo_url = "https://frcmaven.wpi.edu/artifactory/development"
 # repo_url = "https://frcmaven.wpi.edu/artifactory/development"
-version = "2024.3.2"
+version = "2025.1.1-beta-1"
 
 libs = ["wpiutil"]
 
@@ -43,6 +55,8 @@ libs = ["wpiutil"]
 # wpi
 DataLog = "wpi/DataLog.h"
 DataLogReader = "wpi/DataLogReader.h"
+DataLogBackgroundWriter = "wpi/DataLogBackgroundWriter.h"
+DataLogWriter = "wpi/DataLogWriter.h"
 StackTrace = "wpi/StackTrace.h"
 Synchronization = "wpi/Synchronization.h"
 
diff --git a/subprojects/robotpy-wpiutil/wpiutil/__init__.py b/subprojects/robotpy-wpiutil/wpiutil/__init__.py
index c7d05032..ea1f9427 100644
--- a/subprojects/robotpy-wpiutil/wpiutil/__init__.py
+++ b/subprojects/robotpy-wpiutil/wpiutil/__init__.py
@@ -3,22 +3,24 @@
 # autogenerated by 'robotpy-build create-imports wpiutil wpiutil._wpiutil'
 from ._wpiutil import (
     ControlRecordType,
+    DataLogBackgroundWriter,
+    DataLogWriter,
     Sendable,
     SendableBuilder,
     SendableRegistry,
     getStackTrace,
     getStackTraceDefault,
-    # log,
 )
 
 __all__ = [
     "ControlRecordType",
+    "DataLogBackgroundWriter",
+    "DataLogWriter",
     "Sendable",
     "SendableBuilder",
     "SendableRegistry",
     "getStackTrace",
     "getStackTraceDefault",
-    # "log",
 ]
 
 # Imported for side effects only
diff --git a/subprojects/robotpy-wpiutil/wpiutil/log/__init__.py b/subprojects/robotpy-wpiutil/wpiutil/log/__init__.py
index d8b90355..da36f1d8 100644
--- a/subprojects/robotpy-wpiutil/wpiutil/log/__init__.py
+++ b/subprojects/robotpy-wpiutil/wpiutil/log/__init__.py
@@ -17,6 +17,8 @@
     StartRecordData,
     StringArrayLogEntry,
     StringLogEntry,
+    StructArrayLogEntry,
+    StructLogEntry,
 )
 
 __all__ = [
@@ -37,4 +39,6 @@
     "StartRecordData",
     "StringArrayLogEntry",
     "StringLogEntry",
+    "StructArrayLogEntry",
+    "StructLogEntry",
 ]
diff --git a/subprojects/robotpy-wpiutil/wpiutil/src/safethread_gil.cpp b/subprojects/robotpy-wpiutil/wpiutil/src/safethread_gil.cpp
index 9251c192..131d6fd4 100644
--- a/subprojects/robotpy-wpiutil/wpiutil/src/safethread_gil.cpp
+++ b/subprojects/robotpy-wpiutil/wpiutil/src/safethread_gil.cpp
@@ -1,5 +1,6 @@
 
 #include <atomic>
+#include <gilsafe_object.h>
 #include <robotpy_build.h>
 
 using OnThreadStartFn = void *(*)();
@@ -17,7 +18,7 @@ struct SafeThreadState {
 std::atomic<bool> g_gilstate_managed = false;
 
 void *on_safe_thread_start() {
-  if (_Py_IsFinalizing()            // python is shutting down
+  if (Py_IsFinalizing()            // python is shutting down
       || !g_gilstate_managed.load() // python has shutdown)
   ) {
     return nullptr;
@@ -37,7 +38,7 @@ void on_safe_thread_end(void *opaque) {
 
   // don't cleanup if it's unsafe to do so. Several possibilities here:
   if (!opaque                       // internal error?
-      || _Py_IsFinalizing()         // python is shutting down
+      || Py_IsFinalizing()         // python is shutting down
       || !g_gilstate_managed.load() // python has shutdown
   ) {
     return;
diff --git a/subprojects/robotpy-wpiutil/wpiutil/src/type_casters/wpi_ct_string_type_caster.h b/subprojects/robotpy-wpiutil/wpiutil/src/type_casters/wpi_ct_string_type_caster.h
index cc658457..702afcf5 100644
--- a/subprojects/robotpy-wpiutil/wpiutil/src/type_casters/wpi_ct_string_type_caster.h
+++ b/subprojects/robotpy-wpiutil/wpiutil/src/type_casters/wpi_ct_string_type_caster.h
@@ -8,9 +8,9 @@
 namespace pybind11 {
 namespace detail {
 
-template <typename Char, typename Traits, size_t N>
-struct type_caster<wpi::ct_string<Char, Traits, N>> {
-    using str_type = wpi::ct_string<Char, Traits, N>;
+template <typename CharT, typename Traits, size_t N>
+struct type_caster<wpi::ct_string<CharT, Traits, N>> {
+    using str_type = wpi::ct_string<CharT, Traits, N>;
     PYBIND11_TYPE_CASTER(str_type, const_name(PYBIND11_STRING_NAME));
 
     // TODO
@@ -21,19 +21,35 @@ struct type_caster<wpi::ct_string<Char, Traits, N>> {
     static handle cast(const str_type& src,
                          py::return_value_policy policy,
                          py::handle parent) {
-    const char *buffer = reinterpret_cast<const char *>(src.data());
-        auto nbytes = ssize_t(src.size() * sizeof(Char));
-        handle s;
-        if (policy == return_value_policy::_return_as_bytes) {
-            s = PyBytes_FromStringAndSize(buffer, nbytes);
-        } else {
-            s = PyUnicode_DecodeUTF8(buffer, nbytes, nullptr);
-        }
+        const char *buffer = reinterpret_cast<const char *>(src.data());
+        auto nbytes = ssize_t(src.size() * sizeof(CharT));
+        handle s = decode_utfN(buffer, nbytes);
         if (!s) {
             throw error_already_set();
         }
         return s;
-  }
+    }
+
+    // copied from py::string_caster
+    static constexpr size_t UTF_N = 8 * sizeof(CharT);
+
+    static handle decode_utfN(const char *buffer, ssize_t nbytes) {
+#if !defined(PYPY_VERSION)
+        return UTF_N == 8    ? PyUnicode_DecodeUTF8(buffer, nbytes, nullptr)
+               : UTF_N == 16 ? PyUnicode_DecodeUTF16(buffer, nbytes, nullptr, nullptr)
+                             : PyUnicode_DecodeUTF32(buffer, nbytes, nullptr, nullptr);
+#else
+        // PyPy segfaults when on PyUnicode_DecodeUTF16 (and possibly on PyUnicode_DecodeUTF32 as
+        // well), so bypass the whole thing by just passing the encoding as a string value, which
+        // works properly:
+        return PyUnicode_Decode(buffer,
+                                nbytes,
+                                UTF_N == 8    ? "utf-8"
+                                : UTF_N == 16 ? "utf-16"
+                                              : "utf-32",
+                                nullptr);
+#endif
+    }
 
 };
 
diff --git a/subprojects/robotpy-wpiutil/wpiutil/src/wpistruct/wpystruct.h b/subprojects/robotpy-wpiutil/wpiutil/src/wpistruct/wpystruct.h
index d547ad8f..9305d003 100644
--- a/subprojects/robotpy-wpiutil/wpiutil/src/wpistruct/wpystruct.h
+++ b/subprojects/robotpy-wpiutil/wpiutil/src/wpistruct/wpystruct.h
@@ -81,7 +81,7 @@ template <> struct type_caster<WPyStruct> {
 // two types of converters: static C++ converter, and dynamic python converter
 struct WPyStructConverter {
   virtual ~WPyStructConverter() = default;
-  virtual std::string_view GetTypeString() const = 0;
+  virtual std::string_view GetTypeName() const = 0;
 
   virtual size_t GetSize() const = 0;
 
@@ -101,8 +101,8 @@ struct WPyStructConverter {
 
 // static C++ converter
 template <typename T> struct WPyStructCppConverter : WPyStructConverter {
-  std::string_view GetTypeString() const override {
-    return wpi::Struct<T>::GetTypeString();
+  std::string_view GetTypeName() const override {
+    return wpi::Struct<T>::GetTypeName();
   }
 
   size_t GetSize() const override { return wpi::Struct<T>::GetSize(); }
@@ -155,7 +155,7 @@ template <typename T> void SetupWPyStruct(auto pycls) {
 struct WPyStructPyConverter : WPyStructConverter {
 
   WPyStructPyConverter(py::object o) {
-    m_typestring = o.attr("typeString").cast<std::string>();
+    m_typename = o.attr("typename").cast<std::string>();
     m_schema = o.attr("schema").cast<std::string>();
     m_size = o.attr("size").cast<size_t>();
 
@@ -168,7 +168,7 @@ struct WPyStructPyConverter : WPyStructConverter {
   }
 
   // copy all the relevant attributes locally
-  std::string m_typestring;
+  std::string m_typename;
   std::string m_schema;
   size_t m_size;
 
@@ -178,7 +178,7 @@ struct WPyStructPyConverter : WPyStructConverter {
   // py::function m_unpackInto;
   py::function m_forEachNested; // might be none
 
-  std::string_view GetTypeString() const override { return m_typestring; }
+  std::string_view GetTypeName() const override { return m_typename; }
 
   size_t GetSize() const override { return m_size; }
 
@@ -275,8 +275,8 @@ struct WPyStructInfo {
 
 // Leverages the converter stored in WPyStructInfo to do the actual work
 template <> struct wpi::Struct<WPyStruct, WPyStructInfo> {
-  static std::string_view GetTypeString(const WPyStructInfo &info) {
-    return info->GetTypeString();
+  static std::string_view GetTypeName(const WPyStructInfo &info) {
+    return info->GetTypeName();
   }
 
   static size_t GetSize(const WPyStructInfo &info) {
diff --git a/subprojects/robotpy-wpiutil/wpiutil/src/wpistruct/wpystruct_fns.cpp b/subprojects/robotpy-wpiutil/wpiutil/src/wpistruct/wpystruct_fns.cpp
index 95c719ee..fcb18a30 100644
--- a/subprojects/robotpy-wpiutil/wpiutil/src/wpistruct/wpystruct_fns.cpp
+++ b/subprojects/robotpy-wpiutil/wpiutil/src/wpistruct/wpystruct_fns.cpp
@@ -8,9 +8,9 @@ void forEachNested(
   wpi::ForEachStructSchema<WPyStruct, WPyStructInfo>(fn, info);
 }
 
-py::str getTypeString(const py::type &t) {
+py::str getTypeName(const py::type &t) {
   WPyStructInfo info(t);
-  return wpi::GetStructTypeString<WPyStruct, WPyStructInfo>(info);
+  return wpi::GetStructTypeName<WPyStruct, WPyStructInfo>(info);
 }
 
 py::str getSchema(const py::type &t) {
diff --git a/subprojects/robotpy-wpiutil/wpiutil/src/wpistruct/wpystruct_fns.h b/subprojects/robotpy-wpiutil/wpiutil/src/wpistruct/wpystruct_fns.h
index bddbeb9a..a2e19949 100644
--- a/subprojects/robotpy-wpiutil/wpiutil/src/wpistruct/wpystruct_fns.h
+++ b/subprojects/robotpy-wpiutil/wpiutil/src/wpistruct/wpystruct_fns.h
@@ -11,9 +11,9 @@ void forEachNested(
     const std::function<void(std::string_view, std::string_view)> &fn);
 
 /**
-    Retrieve the type string for the specified type
+    Retrieve the type name for the specified type
 */
-py::str getTypeString(const py::type &t);
+py::str getTypeName(const py::type &t);
 
 /**
     Retrieve schema for the specified type
diff --git a/subprojects/robotpy-wpiutil/wpiutil/sync/__init__.py b/subprojects/robotpy-wpiutil/wpiutil/sync/__init__.py
index dc2d01be..1ea57e0b 100644
--- a/subprojects/robotpy-wpiutil/wpiutil/sync/__init__.py
+++ b/subprojects/robotpy-wpiutil/wpiutil/sync/__init__.py
@@ -1,3 +1,4 @@
+# autogenerated by 'robotpy-build create-imports wpiutil.sync wpiutil._wpiutil.sync'
 from .._wpiutil.sync import (
     createEvent,
     createSemaphore,
diff --git a/subprojects/robotpy-wpiutil/wpiutil/wpistruct/__init__.py b/subprojects/robotpy-wpiutil/wpiutil/wpistruct/__init__.py
index 9fa1b487..d8a480e1 100644
--- a/subprojects/robotpy-wpiutil/wpiutil/wpistruct/__init__.py
+++ b/subprojects/robotpy-wpiutil/wpiutil/wpistruct/__init__.py
@@ -8,7 +8,7 @@
     forEachNested,
     getSchema,
     getSize,
-    getTypeString,
+    getTypeName,
     pack,
     packInto,
     unpack,
@@ -18,7 +18,7 @@
     "forEachNested",
     "getSchema",
     "getSize",
-    "getTypeString",
+    "getTypeName",
     "pack",
     "packInto",
     "unpack",
diff --git a/subprojects/robotpy-wpiutil/wpiutil/wpistruct/dataclass.py b/subprojects/robotpy-wpiutil/wpiutil/wpistruct/dataclass.py
index 0c8b3baf..160db3e7 100644
--- a/subprojects/robotpy-wpiutil/wpiutil/wpistruct/dataclass.py
+++ b/subprojects/robotpy-wpiutil/wpiutil/wpistruct/dataclass.py
@@ -133,7 +133,7 @@ def _process_class(cls, struct_name: typing.Optional[str]):
             typn = f"type_{name}"
 
             ctx[typn] = ftype
-            ts = wpistruct.getTypeString(ftype).split(":", 1)[1].strip()
+            ts = wpistruct.getTypeName(ftype)
             schema.append(f"{ts} {name}")
             sz = wpistruct.getSize(ftype)
             fmts.append(f"{sz}s")
@@ -216,7 +216,7 @@ def _unpack(b):
     exec(fnsrc, ctx, ctx)
 
     cls.WPIStruct = StructDescriptor(
-        typeString=f"struct:{struct_name}",
+        typename=struct_name,
         schema="; ".join(schema),
         size=s.size,
         pack=ctx["_pack"],
diff --git a/subprojects/robotpy-wpiutil/wpiutil/wpistruct/desc.py b/subprojects/robotpy-wpiutil/wpiutil/wpistruct/desc.py
index fce77d47..e75a3a55 100644
--- a/subprojects/robotpy-wpiutil/wpiutil/wpistruct/desc.py
+++ b/subprojects/robotpy-wpiutil/wpiutil/wpistruct/desc.py
@@ -20,8 +20,8 @@ class StructDescriptor(typing.NamedTuple):
     for defining custom structs using a dataclass.
     """
 
-    #: The type string
-    typeString: str
+    #: The type name
+    typename: str
 
     #: The struct schema
     schema: str
diff --git a/subprojects/robotpy-xrp/.gitignore b/subprojects/robotpy-xrp/.gitignore
index ca5b76cd..5d85e7ee 100644
--- a/subprojects/robotpy-xrp/.gitignore
+++ b/subprojects/robotpy-xrp/.gitignore
@@ -9,4 +9,7 @@
 /xrp/lib
 /xrp/_init_xrp.py
 /xrp/pkgcfg.py
-/xrp/version.py
\ No newline at end of file
+/xrp/version.py
+/xrp/extension/_init_xrp_ext.py
+/xrp/extension/include
+/xrp/extension/pkgcfg.py
\ No newline at end of file
diff --git a/subprojects/robotpy-xrp/pyproject.toml b/subprojects/robotpy-xrp/pyproject.toml
index 6fec9a2c..102bb5bf 100644
--- a/subprojects/robotpy-xrp/pyproject.toml
+++ b/subprojects/robotpy-xrp/pyproject.toml
@@ -16,7 +16,7 @@ robotpysimext = [
 
 [build-system]
 requires = [
-    "robotpy-build<2025.0.0,~=2024.0.0",
+    "robotpy-build<2025.0.0b1,~=2025.0.0a1",
     "wpilib~=2024.3.1"
 ]
 
@@ -47,16 +47,16 @@ XRPServo = "frc/xrp/XRPServo.h"
 artifact_id = "xrpVendordep-cpp"
 group_id = "edu.wpi.first.xrpVendordep"
 # repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-version = "2024.3.2"
+repo_url = "https://frcmaven.wpi.edu/artifactory/development"
+version = "2025.1.1-beta-1"
 libs = ["xrpVendordep"]
 
 [tool.robotpy-build.wrappers."xrp.extension".maven_lib_download]
 artifact_id = "halsim_xrp"
 group_id = "edu.wpi.first.halsim"
 # repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-repo_url = "https://frcmaven.wpi.edu/artifactory/release"
-version = "2024.3.2"
+repo_url = "https://frcmaven.wpi.edu/artifactory/development"
+version = "2025.1.1-beta-1"
 
 dlopenlibs = ["halsim_xrp"]
 


Test patch:
diff --git a/subprojects/robotpy-apriltag/tests/tag1_640_480.jpg b/subprojects/robotpy-apriltag/tests/tag1_640_480.jpg
index a18957d6..ad5cdce4 100644
Binary files a/subprojects/robotpy-apriltag/tests/tag1_640_480.jpg and b/subprojects/robotpy-apriltag/tests/tag1_640_480.jpg differ
diff --git a/subprojects/robotpy-wpimath/tests/test_trajectory.py b/subprojects/robotpy-wpimath/tests/test_trajectory.py
index 817a63fb..da2c04b3 100644
--- a/subprojects/robotpy-wpimath/tests/test_trajectory.py
+++ b/subprojects/robotpy-wpimath/tests/test_trajectory.py
@@ -4,7 +4,7 @@
 import wpimath.trajectory.constraint
 from wpimath.spline import CubicHermiteSpline, SplineHelper
 
-from wpimath.geometry import Pose2d, Rotation2d, Translation2d
+from wpimath.geometry import Ellipse2d, Pose2d, Rectangle2d, Rotation2d, Translation2d
 
 from wpimath.trajectory import Trajectory, TrajectoryConfig
 
@@ -47,15 +47,11 @@ def getTestTrajectory(config: TrajectoryConfig) -> Trajectory:
 
 def test_elliptical_region_constraint():
     maxVelocity = 2
+    ellipse = Ellipse2d.fromFeet(Pose2d.fromFeet(5, 2.5, math.radians(180)), 5, 2.5)
+
     config = TrajectoryConfig.fromFps(13, 13)
     maxVelConstraint = MaxVelocityConstraint.fromFps(maxVelocity)
-    regionConstraint = EllipticalRegionConstraint.fromFeet(
-        Translation2d.fromFeet(5, 2.5),
-        10,
-        5,
-        Rotation2d.fromDegrees(180),
-        maxVelConstraint,
-    )
+    regionConstraint = EllipticalRegionConstraint(ellipse, maxVelConstraint)
 
     config.addConstraint(regionConstraint)
 
@@ -63,22 +59,18 @@ def test_elliptical_region_constraint():
 
     exceededConstraintOutsideRegion = False
     for point in trajectory.states():
-        translation = point.pose.translation()
-        if translation.x_feet < 10 and translation.y_feet < 5:
+        if ellipse.contains(point.pose.translation()):
             assert abs(point.velocity_fps) < maxVelocity + 0.05
         elif abs(point.velocity_fps) >= maxVelocity + 0.05:
             exceededConstraintOutsideRegion = True
 
-    assert exceededConstraintOutsideRegion
-
-
-def test_elliptical_region_is_pose_in_region():
-    maxVelConstraint = MaxVelocityConstraint.fromFps(2)
-    regionConstraintNoRotation = EllipticalRegionConstraint.fromFeet(
-        Translation2d.fromFeet(1, 1), 2, 4, Rotation2d(0), maxVelConstraint
-    )
+        # translation = point.pose.translation()
+        # if translation.x_feet < 10 and translation.y_feet < 5:
+        #     assert abs(point.velocity_fps) < maxVelocity + 0.05
+        # elif abs(point.velocity_fps) >= maxVelocity + 0.05:
+        #     exceededConstraintOutsideRegion = True
 
-    assert not regionConstraintNoRotation.isPoseInRegion(Pose2d.fromFeet(2.1, 1, 0))
+    assert exceededConstraintOutsideRegion
 
 
 #
@@ -88,13 +80,11 @@ def test_elliptical_region_is_pose_in_region():
 
 def test_rectangular_region_constraint():
     maxVelocity = 2
+    rectangle = Rectangle2d(Translation2d.fromFeet(1, 1), Translation2d.fromFeet(5, 27))
+
     config = TrajectoryConfig.fromFps(13, 13)
     maxVelConstraint = MaxVelocityConstraint.fromFps(maxVelocity)
-    regionConstraint = RectangularRegionConstraint(
-        Translation2d.fromFeet(1, 1),
-        Translation2d.fromFeet(5, 27),
-        maxVelConstraint,
-    )
+    regionConstraint = RectangularRegionConstraint(rectangle, maxVelConstraint)
 
     config.addConstraint(regionConstraint)
 
@@ -102,7 +92,7 @@ def test_rectangular_region_constraint():
 
     exceededConstraintOutsideRegion = False
     for point in trajectory.states():
-        if regionConstraint.isPoseInRegion(point.pose):
+        if rectangle.contains(point.pose.translation()):
             assert abs(point.velocity_fps) < maxVelocity + 0.05
         elif abs(point.velocity_fps) >= maxVelocity + 0.05:
             exceededConstraintOutsideRegion = True
@@ -110,15 +100,6 @@ def test_rectangular_region_constraint():
     assert exceededConstraintOutsideRegion
 
 
-def test_rectangular_region_is_pose_in_region():
-    maxVelConstraint = MaxVelocityConstraint.fromFps(2)
-    regionConstraint = RectangularRegionConstraint(
-        Translation2d.fromFeet(1, 1), Translation2d.fromFeet(5, 27), maxVelConstraint
-    )
-    assert not regionConstraint.isPoseInRegion(Pose2d())
-    assert regionConstraint.isPoseInRegion(Pose2d.fromFeet(3, 14.5, Rotation2d()))
-
-
 #
 # TrajectoryParameterizer
 #
diff --git a/subprojects/robotpy-wpimath/tests/test_trajectory_exponential_profile.py b/subprojects/robotpy-wpimath/tests/test_trajectory_exponential_profile.py
index c9e9dc36..0bb90cf1 100644
--- a/subprojects/robotpy-wpimath/tests/test_trajectory_exponential_profile.py
+++ b/subprojects/robotpy-wpimath/tests/test_trajectory_exponential_profile.py
@@ -8,7 +8,7 @@
 from wpimath.trajectory import ExponentialProfileMeterVolts
 
 kDt = 0.01
-feedforward = SimpleMotorFeedforwardMeters(0, 2.5629, 0.43277)
+feedforward = SimpleMotorFeedforwardMeters(0, 2.5629, 0.43277, kDt)
 constraints = ExponentialProfileMeterVolts.Constraints.fromCharacteristics(
     12, 2.5629, 0.43277
 )
@@ -32,7 +32,7 @@ def check_dynamics(
 ):
     next_state = profile.calculate(kDt, current, goal)
 
-    signal = feedforward.calculate(current.velocity, next_state.velocity, kDt)
+    signal = feedforward.calculate(current.velocity, next_state.velocity)
 
     assert abs(signal) < constraints.maxInput + 1e-9
 
diff --git a/subprojects/robotpy-wpiutil/tests/cpp/wpiutil_test/struct_test.cpp b/subprojects/robotpy-wpiutil/tests/cpp/wpiutil_test/struct_test.cpp
index d8ffe68b..200822e9 100644
--- a/subprojects/robotpy-wpiutil/tests/cpp/wpiutil_test/struct_test.cpp
+++ b/subprojects/robotpy-wpiutil/tests/cpp/wpiutil_test/struct_test.cpp
@@ -16,7 +16,7 @@ struct ThingA {
 };
 
 template <> struct wpi::Struct<ThingA> {
-  static constexpr std::string_view GetTypeString() { return "struct:ThingA"; }
+  static constexpr std::string_view GetTypeName() { return "ThingA"; }
   static constexpr size_t GetSize() { return 1; }
   static constexpr std::string_view GetSchema() { return "uint8 value"; }
   static ThingA Unpack(std::span<const uint8_t> data) {
@@ -41,7 +41,7 @@ struct Outer {
 
 template <>
 struct wpi::Struct<Outer> {
-  static constexpr std::string_view GetTypeString() { return "struct:Outer"; }
+  static constexpr std::string_view GetTypeName() { return "Outer"; }
   static constexpr size_t GetSize() { return wpi::GetStructSize<ThingA>() + 4; }
   static constexpr std::string_view GetSchema() {
     return "ThingA inner; int32 c";
diff --git a/subprojects/robotpy-wpiutil/tests/test_struct.py b/subprojects/robotpy-wpiutil/tests/test_struct.py
index 0ae62ae5..bef5c9a0 100644
--- a/subprojects/robotpy-wpiutil/tests/test_struct.py
+++ b/subprojects/robotpy-wpiutil/tests/test_struct.py
@@ -31,7 +31,7 @@ def _fn(*args):
 
 
 def test_get_type_string():
-    assert wpistruct.getTypeString(module.ThingA) == "struct:ThingA"
+    assert wpistruct.getTypeName(module.ThingA) == "ThingA"
 
 
 def test_get_schema():
@@ -89,7 +89,7 @@ def _fn(*args):
 
 
 def test_nested_get_type_string():
-    assert wpistruct.getTypeString(module.ThingA) == "struct:ThingA"
+    assert wpistruct.getTypeName(module.ThingA) == "ThingA"
 
 
 def test_nested_get_schema():
@@ -140,7 +140,7 @@ def _fn(*args):
 
 
 def test_user_get_type_string():
-    assert wpistruct.getTypeString(MyStruct) == "struct:mystruct"
+    assert wpistruct.getTypeName(MyStruct) == "mystruct"
 
 
 def test_user_get_schema():
@@ -202,7 +202,7 @@ def _fn(*args):
 
 
 def test_user_nested_get_type_string():
-    assert wpistruct.getTypeString(Outer) == "struct:Outer"
+    assert wpistruct.getTypeName(Outer) == "Outer"
 
 
 def test_user_nested_get_schema():