Create/support "continuous" control loops

This supplies a wrap_point argument to the control loops code that
makes it so that you can have a system that spins infinitely (as the
swerve modules do) and still control them.

TODO: I observed some idiosyncracies in wrapping behavior during
testing; this likely requires additional tests to be written to validate
that we handle wrapping correctly.

Change-Id: Id4b9065de2b3334c0e8097b28a32916c47a54258
Signed-off-by: James Kuszmaul <jabukuszmaul+collab@gmail.com>
diff --git a/frc971/control_loops/BUILD b/frc971/control_loops/BUILD
index 785d2c7..409c75a 100644
--- a/frc971/control_loops/BUILD
+++ b/frc971/control_loops/BUILD
@@ -346,6 +346,7 @@
     ],
     deps = [
         "//aos:macros",
+        "//frc971/zeroing:wrap",
         "@org_tuxfamily_eigen//:eigen",
     ] + select({
         "@platforms//os:linux": ["//aos/logging"],
@@ -611,6 +612,39 @@
     ],
 )
 
+genrule(
+    name = "genrule_wrapped_subsystem_test",
+    outs = [
+        "wrapped_subsystem_test_plant.h",
+        "wrapped_subsystem_test_plant.cc",
+        "wrapped_subsystem_test_plant.json",
+        "wrapped_subsystem_test_integral_plant.h",
+        "wrapped_subsystem_test_integral_plant.cc",
+        "wrapped_subsystem_test_integral_plant.json",
+    ],
+    cmd = "$(location //frc971/control_loops/python:wrapped_subsystem_test) $(OUTS)",
+    target_compatible_with = ["@platforms//os:linux"],
+    tools = [
+        "//frc971/control_loops/python:wrapped_subsystem_test",
+    ],
+)
+
+cc_library(
+    name = "wrapped_subsystem_test_plants",
+    srcs = [
+        "wrapped_subsystem_test_integral_plant.cc",
+        "wrapped_subsystem_test_plant.cc",
+    ],
+    hdrs = [
+        "wrapped_subsystem_test_integral_plant.h",
+        "wrapped_subsystem_test_plant.h",
+    ],
+    target_compatible_with = ["@platforms//os:linux"],
+    deps = [
+        ":state_feedback_loop",
+    ],
+)
+
 cc_library(
     name = "static_zeroing_single_dof_profiled_subsystem_test_plants",
     srcs = [
@@ -713,10 +747,12 @@
         ":static_zeroing_single_dof_profiled_subsystem_test_pot_and_absolute_position_fbs",
         ":static_zeroing_single_dof_profiled_subsystem_test_subsystem_goal_fbs",
         ":static_zeroing_single_dof_profiled_subsystem_test_subsystem_output_fbs",
+        ":wrapped_subsystem_test_plants",
         "//aos/testing:googletest",
         "//frc971/control_loops:control_loop_test",
         "//frc971/zeroing:absolute_and_absolute_encoder",
         "//frc971/zeroing:absolute_encoder",
+        "//frc971/zeroing:continuous_absolute_encoder",
         "//frc971/zeroing:pot_and_absolute_encoder",
     ],
 )