Drive code works on Tantrum.

Need to write the spring code.  Drive now supports doubles...  What a
pain.

Change-Id: Id589acdc443dcd81242a21e3b0c26f81d6974dc8
diff --git a/aos/common/BUILD b/aos/common/BUILD
index 2ee374d..4de57b6 100644
--- a/aos/common/BUILD
+++ b/aos/common/BUILD
@@ -1,401 +1,402 @@
-package(default_visibility = ['//visibility:public'])
+package(default_visibility = ["//visibility:public"])
 
-load('//aos/build:queues.bzl', 'queue_library')
+load("//aos/build:queues.bzl", "queue_library")
 load("//tools:environments.bzl", "mcu_cpus")
 
 queue_library(
-  name = 'test_queue',
-  srcs = [
-    'test_queue.q',
-  ],
+    name = "test_queue",
+    srcs = [
+        "test_queue.q",
+    ],
 )
 
 cc_library(
-  name = 'math',
-  hdrs = [
-    'commonmath.h',
-  ],
+    name = "math",
+    hdrs = [
+        "commonmath.h",
+    ],
+    compatible_with = mcu_cpus,
 )
 
 cc_library(
-  name = 'macros',
-  hdrs = [
-    'macros.h',
-  ],
-  compatible_with = mcu_cpus,
+    name = "macros",
+    hdrs = [
+        "macros.h",
+    ],
+    compatible_with = mcu_cpus,
 )
 
 cc_library(
-  name = 'type_traits',
-  hdrs = [
-    'type_traits.h',
-  ],
+    name = "type_traits",
+    hdrs = [
+        "type_traits.h",
+    ],
 )
 
 cc_library(
-  name = 'time',
-  srcs = [
-    'time.cc',
-  ],
-  hdrs = [
-    'time.h',
-  ],
-  deps = [
-    '//aos/common/logging:logging',
-    ':mutex',
-    ':macros',
-    '//aos/linux_code/ipc_lib:shared_mem',
-  ],
+    name = "time",
+    srcs = [
+        "time.cc",
+    ],
+    hdrs = [
+        "time.h",
+    ],
+    deps = [
+        ":macros",
+        ":mutex",
+        "//aos/common/logging",
+        "//aos/linux_code/ipc_lib:shared_mem",
+    ],
 )
 
 genrule(
-  name = 'gen_queue_primitives',
-  visibility = ['//visibility:private'],
-  tools = ['//aos/build/queues:queue_primitives'],
-  outs = ['queue_primitives.h'],
-  cmd = '$(location //aos/build/queues:queue_primitives) $@',
+    name = "gen_queue_primitives",
+    outs = ["queue_primitives.h"],
+    cmd = "$(location //aos/build/queues:queue_primitives) $@",
+    tools = ["//aos/build/queues:queue_primitives"],
+    visibility = ["//visibility:private"],
 )
 
 genrule(
-  name = 'gen_print_field',
-  visibility = ['//visibility:private'],
-  tools = ['//aos/build/queues:print_field'],
-  outs = ['print_field.cc'],
-  cmd = '$(location //aos/build/queues:print_field) $@',
+    name = "gen_print_field",
+    outs = ["print_field.cc"],
+    cmd = "$(location //aos/build/queues:print_field) $@",
+    tools = ["//aos/build/queues:print_field"],
+    visibility = ["//visibility:private"],
 )
 
 cc_library(
-  name = 'generated_queue_headers',
-  visibility = ['//aos/common/logging:__pkg__'],
-  hdrs = [
-    ':gen_queue_primitives',
-  ],
+    name = "generated_queue_headers",
+    hdrs = [
+        ":gen_queue_primitives",
+    ],
+    visibility = ["//aos/common/logging:__pkg__"],
 )
 
 cc_library(
-  name = 'event',
-  hdrs = [
-    'event.h',
-  ],
-  srcs = [
-    'event.cc',
-  ],
-  deps = [
-    '//aos/linux_code/ipc_lib:aos_sync',
-    ':time',
-    '//aos/common/logging:logging',
-  ],
+    name = "event",
+    srcs = [
+        "event.cc",
+    ],
+    hdrs = [
+        "event.h",
+    ],
+    deps = [
+        ":time",
+        "//aos/common/logging",
+        "//aos/linux_code/ipc_lib:aos_sync",
+    ],
 )
 
 cc_library(
-  name = 'unique_malloc_ptr',
-  hdrs = [
-    'unique_malloc_ptr.h',
-  ],
+    name = "unique_malloc_ptr",
+    hdrs = [
+        "unique_malloc_ptr.h",
+    ],
 )
 
 cc_library(
-  name = 'queue_types',
-  srcs = [
-    'queue_types.cc',
-    ':gen_print_field',
-    'print_field_helpers.h',
-  ],
-  hdrs = [
-    'queue_types.h',
-  ],
-  deps = [
-    ':generated_queue_headers',
-    '//aos/linux_code/ipc_lib:shared_mem',
-    '//aos/linux_code/ipc_lib:core_lib',
-    ':mutex',
-    '//aos/common/logging:printf_formats',
-    ':time',
-    ':byteorder'
-  ],
+    name = "queue_types",
+    srcs = [
+        "print_field_helpers.h",
+        "queue_types.cc",
+        ":gen_print_field",
+    ],
+    hdrs = [
+        "queue_types.h",
+    ],
+    deps = [
+        ":byteorder",
+        ":generated_queue_headers",
+        ":mutex",
+        ":time",
+        "//aos/common/logging:printf_formats",
+        "//aos/linux_code/ipc_lib:core_lib",
+        "//aos/linux_code/ipc_lib:shared_mem",
+    ],
 )
 
 cc_test(
-  name = 'queue_types_test',
-  srcs = [
-    'queue_types_test.cc',
-  ],
-  deps = [
-    ':queue_types',
-    '//aos/testing:googletest',
-    ':test_queue',
-    '//aos/common/logging',
-    '//aos/testing:test_logging',
-  ],
+    name = "queue_types_test",
+    srcs = [
+        "queue_types_test.cc",
+    ],
+    deps = [
+        ":queue_types",
+        ":test_queue",
+        "//aos/common/logging",
+        "//aos/testing:googletest",
+        "//aos/testing:test_logging",
+    ],
 )
 
 cc_library(
-  name = 'network_port',
-  hdrs = [
-    'network_port.h',
-  ],
+    name = "network_port",
+    hdrs = [
+        "network_port.h",
+    ],
 )
 
 cc_library(
-  name = 'byteorder',
-  hdrs = [
-    'byteorder.h',
-  ],
+    name = "byteorder",
+    hdrs = [
+        "byteorder.h",
+    ],
 )
 
 cc_library(
-  name = 'messages',
-  srcs = [
-    'message.cc',
-  ],
-  hdrs = [
-    'message.h',
-  ],
-  deps = [
-    ':time',
-    ':macros',
-    ':byteorder',
-  ],
+    name = "messages",
+    srcs = [
+        "message.cc",
+    ],
+    hdrs = [
+        "message.h",
+    ],
+    deps = [
+        ":byteorder",
+        ":macros",
+        ":time",
+    ],
 )
 
 cc_library(
-  name = 'queues',
-  srcs = [],
-  hdrs = [
-    'queue.h',
-  ],
-  deps = [
-    '//aos/linux_code/ipc_lib:queue',
-    '//aos/linux_code:queue',
-    ':messages',
-  ],
+    name = "queues",
+    srcs = [],
+    hdrs = [
+        "queue.h",
+    ],
+    deps = [
+        ":messages",
+        "//aos/linux_code:queue",
+        "//aos/linux_code/ipc_lib:queue",
+    ],
 )
 
 cc_library(
-  name = 'scoped_fd',
-  hdrs = [
-    'scoped_fd.h',
-  ],
-  deps = [
-    '//aos/common/logging',
-  ],
+    name = "scoped_fd",
+    hdrs = [
+        "scoped_fd.h",
+    ],
+    deps = [
+        "//aos/common/logging",
+    ],
 )
 
 cc_test(
-  name = 'queue_test',
-  srcs = [
-    'queue_test.cc',
-  ],
-  deps = [
-    '//aos/testing:googletest',
-    '//aos/testing:test_shm',
-    ':test_queue',
-    '//aos/common/util:thread',
-    ':die',
-  ],
+    name = "queue_test",
+    srcs = [
+        "queue_test.cc",
+    ],
+    deps = [
+        ":die",
+        ":test_queue",
+        "//aos/common/util:thread",
+        "//aos/testing:googletest",
+        "//aos/testing:test_shm",
+    ],
 )
 
 cc_test(
-  name = 'type_traits_test',
-  srcs = [
-    'type_traits_test.cpp',
-  ],
-  deps = [
-    '//aos/testing:googletest',
-    ':type_traits',
-  ],
+    name = "type_traits_test",
+    srcs = [
+        "type_traits_test.cpp",
+    ],
+    deps = [
+        ":type_traits",
+        "//aos/testing:googletest",
+    ],
 )
 
 cc_library(
-  name = 'gtest_prod',
-  hdrs = [
-    'gtest_prod.h',
-  ],
+    name = "gtest_prod",
+    hdrs = [
+        "gtest_prod.h",
+    ],
 )
 
 cc_test(
-  name = 'time_test',
-  srcs = [
-    'time_test.cc',
-  ],
-  deps = [
-    '//aos/testing:googletest',
-    ':time',
-    '//aos/common/logging',
-    '//aos/common/util:death_test_log_implementation',
-  ],
+    name = "time_test",
+    srcs = [
+        "time_test.cc",
+    ],
+    deps = [
+        ":time",
+        "//aos/common/logging",
+        "//aos/common/util:death_test_log_implementation",
+        "//aos/testing:googletest",
+    ],
 )
 
 cc_library(
-  name = 'die',
-  srcs = [
-    'die.cc',
-  ],
-  hdrs = [
-    'die.h',
-  ],
-  deps = [
-    ':macros',
-    '//aos/common/libc:aos_strerror',
-  ],
+    name = "die",
+    srcs = [
+        "die.cc",
+    ],
+    hdrs = [
+        "die.h",
+    ],
+    deps = [
+        ":macros",
+        "//aos/common/libc:aos_strerror",
+    ],
 )
 
 cc_test(
-  name = 'mutex_test',
-  srcs = [
-    'mutex_test.cc',
-  ],
-  deps = [
-    '//aos/testing:googletest',
-    ':mutex',
-    ':die',
-    '//aos/common/logging',
-    '//aos/common/util:death_test_log_implementation',
-    '//aos/common/util:thread',
-    '//aos/common:time',
-    '//aos/testing:test_logging',
-    '//aos/testing:test_shm',
-  ],
+    name = "mutex_test",
+    srcs = [
+        "mutex_test.cc",
+    ],
+    deps = [
+        ":die",
+        ":mutex",
+        "//aos/common:time",
+        "//aos/common/logging",
+        "//aos/common/util:death_test_log_implementation",
+        "//aos/common/util:thread",
+        "//aos/testing:googletest",
+        "//aos/testing:test_logging",
+        "//aos/testing:test_shm",
+    ],
 )
 
 cc_test(
-  name = 'event_test',
-  srcs = [
-    'event_test.cc',
-  ],
-  deps = [
-    '//aos/testing:googletest',
-    ':event',
-    '//aos/testing:test_logging',
-    ':time',
-  ],
+    name = "event_test",
+    srcs = [
+        "event_test.cc",
+    ],
+    deps = [
+        ":event",
+        ":time",
+        "//aos/testing:googletest",
+        "//aos/testing:test_logging",
+    ],
 )
 
 cc_library(
-  name = 'condition',
-  hdrs = [
-    'condition.h',
-  ],
-  srcs = [
-    'condition.cc',
-  ],
-  deps = [
-    ':mutex',
-    '//aos/linux_code/ipc_lib:aos_sync',
-    '//aos/common/logging:logging',
-  ],
+    name = "condition",
+    srcs = [
+        "condition.cc",
+    ],
+    hdrs = [
+        "condition.h",
+    ],
+    deps = [
+        ":mutex",
+        "//aos/common/logging",
+        "//aos/linux_code/ipc_lib:aos_sync",
+    ],
 )
 
 cc_test(
-  name = 'condition_test',
-  srcs = [
-    'condition_test.cc',
-  ],
-  deps = [
-    '//aos/testing:googletest',
-    '//aos/testing:prevent_exit',
-    ':condition',
-    '//aos/common/util:thread',
-    ':time',
-    ':mutex',
-    '//aos/common/logging',
-    '//aos/testing:test_shm',
-    '//aos/linux_code/ipc_lib:core_lib',
-    '//aos/linux_code/ipc_lib:aos_sync',
-    ':die',
-  ],
+    name = "condition_test",
+    srcs = [
+        "condition_test.cc",
+    ],
+    deps = [
+        ":condition",
+        ":die",
+        ":mutex",
+        ":time",
+        "//aos/common/logging",
+        "//aos/common/util:thread",
+        "//aos/linux_code/ipc_lib:aos_sync",
+        "//aos/linux_code/ipc_lib:core_lib",
+        "//aos/testing:googletest",
+        "//aos/testing:prevent_exit",
+        "//aos/testing:test_shm",
+    ],
 )
 
 cc_test(
-  name = 'die_test',
-  srcs = [
-    'die_test.cc',
-  ],
-  deps = [
-    '//aos/testing:googletest',
-    ':die',
-  ],
+    name = "die_test",
+    srcs = [
+        "die_test.cc",
+    ],
+    deps = [
+        ":die",
+        "//aos/testing:googletest",
+    ],
 )
 
 cc_library(
-  name = 'stl_mutex',
-  hdrs = [
-    'stl_mutex.h',
-  ],
-  deps = [
-    '//aos/linux_code/ipc_lib:aos_sync',
-    '//aos/common/logging',
-  ],
+    name = "stl_mutex",
+    hdrs = [
+        "stl_mutex.h",
+    ],
+    deps = [
+        "//aos/common/logging",
+        "//aos/linux_code/ipc_lib:aos_sync",
+    ],
 )
 
 cc_library(
-  name = 'mutex',
-  hdrs = [
-    'mutex.h',
-  ],
-  srcs = [
-    'mutex.cc',
-  ],
-  deps = [
-    '//aos/linux_code/ipc_lib:aos_sync',
-    ':die',
-    '//aos/common/logging:logging',
-    ':type_traits',
-  ],
+    name = "mutex",
+    srcs = [
+        "mutex.cc",
+    ],
+    hdrs = [
+        "mutex.h",
+    ],
+    deps = [
+        ":die",
+        ":type_traits",
+        "//aos/common/logging",
+        "//aos/linux_code/ipc_lib:aos_sync",
+    ],
 )
 
 cc_test(
-  name = 'stl_mutex_test',
-  srcs = [
-    'stl_mutex_test.cc',
-  ],
-  deps = [
-    ':stl_mutex',
-    '//aos/testing:googletest',
-    '//aos/testing:test_logging',
-    '//aos/common/util:thread',
-    ':die',
-  ],
+    name = "stl_mutex_test",
+    srcs = [
+        "stl_mutex_test.cc",
+    ],
+    deps = [
+        ":die",
+        ":stl_mutex",
+        "//aos/common/util:thread",
+        "//aos/testing:googletest",
+        "//aos/testing:test_logging",
+    ],
 )
 
 cc_library(
-  name = 'transaction',
-  hdrs = [
-    'transaction.h',
-  ],
-  deps = [
-    '//aos/common/logging:logging',
-    '//aos/common/util:compiler_memory_barrier',
-  ],
+    name = "transaction",
+    hdrs = [
+        "transaction.h",
+    ],
+    deps = [
+        "//aos/common/logging",
+        "//aos/common/util:compiler_memory_barrier",
+    ],
 )
 
 cc_test(
-  name = 'transaction_test',
-  srcs = [
-    'transaction_test.cc',
-  ],
-  deps = [
-    ':transaction',
-    '//aos/testing:googletest',
-    '//aos/common/logging',
-    '//aos/common/util:death_test_log_implementation',
-  ],
+    name = "transaction_test",
+    srcs = [
+        "transaction_test.cc",
+    ],
+    deps = [
+        ":transaction",
+        "//aos/common/logging",
+        "//aos/common/util:death_test_log_implementation",
+        "//aos/testing:googletest",
+    ],
 )
 
 cc_library(
-  name = 'ring_buffer',
-  hdrs = [
-    'ring_buffer.h',
-  ],
+    name = "ring_buffer",
+    hdrs = [
+        "ring_buffer.h",
+    ],
 )
 
 cc_test(
-  name = 'ring_buffer_test',
-  srcs = [
-    'ring_buffer_test.cc',
-  ],
-  deps = [
-    ':ring_buffer',
-    '//aos/testing:googletest',
-  ],
+    name = "ring_buffer_test",
+    srcs = [
+        "ring_buffer_test.cc",
+    ],
+    deps = [
+        ":ring_buffer",
+        "//aos/testing:googletest",
+    ],
 )
diff --git a/aos/common/controls/BUILD b/aos/common/controls/BUILD
index 456cf44..46b5f24 100644
--- a/aos/common/controls/BUILD
+++ b/aos/common/controls/BUILD
@@ -1,89 +1,101 @@
-package(default_visibility = ['//visibility:public'])
+package(default_visibility = ["//visibility:public"])
 
-load('//aos/build:queues.bzl', 'queue_library')
+load("//aos/build:queues.bzl", "queue_library")
+load("//tools:environments.bzl", "mcu_cpus")
 
 cc_library(
-  name = 'replay_control_loop',
-  hdrs = [
-    'replay_control_loop.h',
-  ],
-  deps = [
-    '//aos/common:queues',
-    ':control_loop',
-    '//aos/common/logging:replay',
-    '//aos/common/logging:queue_logging',
-    '//aos/common:time',
-  ],
+    name = "replay_control_loop",
+    hdrs = [
+        "replay_control_loop.h",
+    ],
+    deps = [
+        ":control_loop",
+        "//aos/common:queues",
+        "//aos/common:time",
+        "//aos/common/logging:queue_logging",
+        "//aos/common/logging:replay",
+    ],
 )
 
 cc_library(
-  name = 'control_loop_test',
-  srcs = [
-    'control_loop_test.cc',
-  ],
-  hdrs = [
-    'control_loop_test.h',
-  ],
-  deps = [
-    '//aos/common/logging:queue_logging',
-    '//aos/common/messages:robot_state',
-    '//aos/common:time',
-    '//aos/testing:googletest',
-    '//aos/testing:test_shm',
-  ],
-  testonly = True,
+    name = "control_loop_test",
+    testonly = True,
+    srcs = [
+        "control_loop_test.cc",
+    ],
+    hdrs = [
+        "control_loop_test.h",
+    ],
+    deps = [
+        "//aos/common:time",
+        "//aos/common/logging:queue_logging",
+        "//aos/common/messages:robot_state",
+        "//aos/testing:googletest",
+        "//aos/testing:test_shm",
+    ],
 )
 
 cc_library(
-  name = 'polytope',
-  hdrs = [
-    'polytope.h',
-  ],
-  deps = [
-    '//third_party/eigen',
-    '//third_party/cddlib',
-    '//aos/common/logging',
-    '//aos/common/logging:matrix_logging',
-  ],
+    name = "polytope_uc",
+    hdrs = [
+        "polytope.h",
+    ],
+    restricted_to = mcu_cpus,
+    deps = [
+        "//third_party/eigen",
+    ],
+)
+
+cc_library(
+    name = "polytope",
+    hdrs = [
+        "polytope.h",
+    ],
+    deps = [
+        "//aos/common/logging",
+        "//aos/common/logging:matrix_logging",
+        "//third_party/cddlib",
+        "//third_party/eigen",
+    ],
 )
 
 cc_test(
-  name = 'polytope_test',
-  srcs = [
-    'polytope_test.cc',
-  ],
-  deps = [
-    ':polytope',
-    '//aos/testing:googletest',
-    '//third_party/eigen',
-    '//third_party/googletest:googlemock',
-    '//aos/testing:test_logging',
-  ],
+    name = "polytope_test",
+    srcs = [
+        "polytope_test.cc",
+    ],
+    deps = [
+        ":polytope",
+        "//aos/testing:googletest",
+        "//aos/testing:test_logging",
+        "//third_party/eigen",
+        "//third_party/googletest:googlemock",
+    ],
 )
 
 queue_library(
-  name = 'control_loop_queues',
-  srcs = [
-    'control_loops.q',
-  ],
+    name = "control_loop_queues",
+    srcs = [
+        "control_loops.q",
+    ],
 )
 
 cc_library(
-  name = 'control_loop',
-  srcs = [
-    'control_loop.cc',
-    'control_loop-tmpl.h',
-  ],
-  hdrs = [
-    'control_loop.h',
-  ],
-  deps = [
-    ':control_loop_queues',
-    '//aos/common/logging',
-    '//aos/common/logging:queue_logging',
-    '//aos/common/messages:robot_state',
-    '//aos/common/util:log_interval',
-    '//aos/common:queues',
-    '//aos/common:time',
-  ],
+    name = "control_loop",
+    srcs = [
+        "control_loop.cc",
+        "control_loop-tmpl.h",
+    ],
+    hdrs = [
+        "control_loop.h",
+    ],
+    deps = [
+        ":control_loop_queues",
+        "//aos/common:queues",
+        "//aos/common:time",
+        "//aos/common/logging",
+        "//aos/common/logging:queue_logging",
+        "//aos/common/messages:robot_state",
+        "//aos/common/util:log_interval",
+    ],
 )
diff --git a/aos/common/controls/polytope.h b/aos/common/controls/polytope.h
index 4399524..03d8fcd 100644
--- a/aos/common/controls/polytope.h
+++ b/aos/common/controls/polytope.h
@@ -2,11 +2,14 @@
 #define AOS_COMMON_CONTROLS_POLYTOPE_H_
 
 #include "Eigen/Dense"
+
+#ifdef __linux__
 #include "third_party/cddlib/lib-src/setoper.h"
 #include "third_party/cddlib/lib-src/cdd.h"
 
 #include "aos/common/logging/logging.h"
 #include "aos/common/logging/matrix_logging.h"
+#endif  // __linux__
 
 namespace aos {
 namespace controls {
@@ -18,18 +21,18 @@
 // random-seeming polytopes it refuses to calculate the vertices completely. To
 // avoid issues with that, using the "shifting" constructor is recommended
 // whenever possible.
-template <int number_of_dimensions>
+template <int number_of_dimensions, typename Scalar = double>
 class Polytope {
  public:
   virtual ~Polytope() {}
 
   // Returns a reference to H.
   virtual Eigen::Ref<
-      const Eigen::Matrix<double, Eigen::Dynamic, number_of_dimensions>>
+      const Eigen::Matrix<Scalar, Eigen::Dynamic, number_of_dimensions>>
   H() const = 0;
 
   // Returns a reference to k.
-  virtual Eigen::Ref<const Eigen::Matrix<double, Eigen::Dynamic, 1>> k()
+  virtual Eigen::Ref<const Eigen::Matrix<Scalar, Eigen::Dynamic, 1>> k()
       const = 0;
 
   // Returns the number of dimensions in the polytope.
@@ -39,72 +42,74 @@
   int num_constraints() const { return k().rows(); }
 
   // Returns true if the point is inside the polytope.
-  bool IsInside(Eigen::Matrix<double, number_of_dimensions, 1> point) const;
+  bool IsInside(Eigen::Matrix<Scalar, number_of_dimensions, 1> point) const;
 
   // Returns the list of vertices inside the polytope.
-  virtual Eigen::Matrix<double, number_of_dimensions, Eigen::Dynamic> Vertices()
+  virtual Eigen::Matrix<Scalar, number_of_dimensions, Eigen::Dynamic> Vertices()
       const = 0;
 };
 
-template <int number_of_dimensions, int num_vertices>
-Eigen::Matrix<double, number_of_dimensions, num_vertices> ShiftPoints(
-    const Eigen::Matrix<double, number_of_dimensions, num_vertices> &vertices,
-    const Eigen::Matrix<double, number_of_dimensions, 1> &offset) {
-  Eigen::Matrix<double, number_of_dimensions, num_vertices> ans = vertices;
+template <int number_of_dimensions, int num_vertices, typename Scalar = double>
+Eigen::Matrix<Scalar, number_of_dimensions, num_vertices> ShiftPoints(
+    const Eigen::Matrix<Scalar, number_of_dimensions, num_vertices> &vertices,
+    const Eigen::Matrix<Scalar, number_of_dimensions, 1> &offset) {
+  Eigen::Matrix<Scalar, number_of_dimensions, num_vertices> ans = vertices;
   for (int i = 0; i < num_vertices; ++i) {
     ans.col(i) += offset;
   }
   return ans;
 }
 
-template <int number_of_dimensions, int num_constraints, int num_vertices>
-class HVPolytope : public Polytope<number_of_dimensions> {
+template <int number_of_dimensions, int num_constraints, int num_vertices,
+          typename Scalar = double>
+class HVPolytope : public Polytope<number_of_dimensions, Scalar> {
  public:
   // Constructs a polytope given the H and k matrices.
-  HVPolytope(Eigen::Ref<const Eigen::Matrix<double, num_constraints,
+  HVPolytope(Eigen::Ref<const Eigen::Matrix<Scalar, num_constraints,
                                             number_of_dimensions>> H,
-             Eigen::Ref<const Eigen::Matrix<double, num_constraints, 1>> k,
-             Eigen::Ref<const Eigen::Matrix<double, number_of_dimensions,
+             Eigen::Ref<const Eigen::Matrix<Scalar, num_constraints, 1>> k,
+             Eigen::Ref<const Eigen::Matrix<Scalar, number_of_dimensions,
                                             num_vertices>> vertices)
       : H_(H), k_(k), vertices_(vertices) {}
 
-  Eigen::Ref<const Eigen::Matrix<double, num_constraints, number_of_dimensions>>
+  Eigen::Ref<const Eigen::Matrix<Scalar, num_constraints, number_of_dimensions>>
   static_H() const {
     return H_;
   }
 
-  Eigen::Ref<const Eigen::Matrix<double, Eigen::Dynamic, number_of_dimensions>>
+  Eigen::Ref<const Eigen::Matrix<Scalar, Eigen::Dynamic, number_of_dimensions>>
   H() const override {
     return H_;
   }
 
-  Eigen::Ref<const Eigen::Matrix<double, num_constraints, 1>> static_k()
+  Eigen::Ref<const Eigen::Matrix<Scalar, num_constraints, 1>> static_k()
       const {
     return k_;
   }
-  Eigen::Ref<const Eigen::Matrix<double, Eigen::Dynamic, 1>> k()
+  Eigen::Ref<const Eigen::Matrix<Scalar, Eigen::Dynamic, 1>> k()
       const override {
     return k_;
   }
 
-  Eigen::Matrix<double, number_of_dimensions, Eigen::Dynamic> Vertices()
+  Eigen::Matrix<Scalar, number_of_dimensions, Eigen::Dynamic> Vertices()
       const override {
     return vertices_;
   }
 
-  Eigen::Matrix<double, number_of_dimensions, num_vertices>
+  Eigen::Matrix<Scalar, number_of_dimensions, num_vertices>
   StaticVertices() const {
     return vertices_;
   }
 
  private:
-  const Eigen::Matrix<double, num_constraints, number_of_dimensions> H_;
-  const Eigen::Matrix<double, num_constraints, 1> k_;
-  const Eigen::Matrix<double, number_of_dimensions, num_vertices> vertices_;
+  const Eigen::Matrix<Scalar, num_constraints, number_of_dimensions> H_;
+  const Eigen::Matrix<Scalar, num_constraints, 1> k_;
+  const Eigen::Matrix<Scalar, number_of_dimensions, num_vertices> vertices_;
 };
 
 
 
+#ifdef __linux__
 template <int number_of_dimensions>
 class HPolytope : public Polytope<number_of_dimensions> {
  public:
@@ -146,12 +151,14 @@
       Eigen::Ref<const Eigen::Matrix<double, Eigen::Dynamic, 1>> &k);
 };
 
-template <int number_of_dimensions>
-bool Polytope<number_of_dimensions>::IsInside(
-    Eigen::Matrix<double, number_of_dimensions, 1> point) const {
-  Eigen::Ref<const Eigen::Matrix<double, Eigen::Dynamic, 1>> k_ptr = k();
+#endif  // __linux__
+
+template <int number_of_dimensions, typename Scalar>
+bool Polytope<number_of_dimensions, Scalar>::IsInside(
+    Eigen::Matrix<Scalar, number_of_dimensions, 1> point) const {
+  Eigen::Ref<const Eigen::Matrix<Scalar, Eigen::Dynamic, 1>> k_ptr = k();
   for (int i = 0; i < k_ptr.rows(); ++i) {
-    double ev = (H().row(i) * point)(0, 0);
+    Scalar ev = (H().row(i) * point)(0, 0);
     if (ev > k_ptr(i, 0)) {
       return false;
     }
@@ -159,6 +166,7 @@
   return true;
 }
 
+#ifdef __linux__
 template <int number_of_dimensions>
 Eigen::Matrix<double, number_of_dimensions, Eigen::Dynamic>
 HPolytope<number_of_dimensions>::CalculateVertices(
@@ -221,6 +229,7 @@
 
   return vertices;
 }
+#endif  // __linux__
 
 }  // namespace controls
 }  // namespace aos
diff --git a/aos/input/drivetrain_input.cc b/aos/input/drivetrain_input.cc
index 506e4b6..852b94e 100644
--- a/aos/input/drivetrain_input.cc
+++ b/aos/input/drivetrain_input.cc
@@ -246,7 +246,8 @@
 }
 ::std::unique_ptr<DrivetrainInputReader> DrivetrainInputReader::Make(
     InputType type,
-    const ::frc971::control_loops::drivetrain::DrivetrainConfig &dt_config) {
+    const ::frc971::control_loops::drivetrain::DrivetrainConfig<double>
+        &dt_config) {
   std::unique_ptr<DrivetrainInputReader> drivetrain_input_reader;
 
   using InputType = DrivetrainInputReader::InputType;
diff --git a/aos/input/drivetrain_input.h b/aos/input/drivetrain_input.h
index 86b0e10..e38320c 100644
--- a/aos/input/drivetrain_input.h
+++ b/aos/input/drivetrain_input.h
@@ -59,7 +59,8 @@
   // Constructs the appropriate DrivetrainInputReader.
   static std::unique_ptr<DrivetrainInputReader> Make(
       InputType type,
-      const ::frc971::control_loops::drivetrain::DrivetrainConfig &dt_config);
+      const ::frc971::control_loops::drivetrain::DrivetrainConfig<double>
+          &dt_config);
 
   // Processes new joystick data and publishes drivetrain goal messages.
   void HandleDrivetrain(const ::aos::input::driver_station::Data &data);