Merge "Add python code to plot a x,y drivetrain spline"
diff --git a/frc971/control_loops/drivetrain/wheel_nonlinearity_plot.py b/frc971/control_loops/drivetrain/wheel_nonlinearity_plot.py
new file mode 100755
index 0000000..57831c5
--- /dev/null
+++ b/frc971/control_loops/drivetrain/wheel_nonlinearity_plot.py
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+#
+# This is a quick script to show the effect of the wheel nonlinearity term on
+# turning rate
+
+from matplotlib import pylab
+import numpy
+
+if __name__ == '__main__':
+  x = numpy.arange(-1, 1, 0.01)
+
+  for nonlin in numpy.arange(0.2, 1.0, 0.1):
+    angular_range = numpy.pi * nonlin / 2.0
+    newx1 = numpy.sin(x * angular_range) / numpy.sin(angular_range)
+    newx2 = numpy.sin(newx1 * angular_range) / numpy.sin(angular_range)
+
+    pylab.plot(x, newx2, label="nonlin %f" % nonlin)
+
+  pylab.legend()
+  pylab.show()
diff --git a/frc971/downloader.bzl b/frc971/downloader.bzl
new file mode 100644
index 0000000..2967127
--- /dev/null
+++ b/frc971/downloader.bzl
@@ -0,0 +1,37 @@
+load('//aos/downloader:downloader.bzl', 'aos_downloader')
+load('//tools/build_rules:label.bzl', 'expand_label')
+
+def robot_downloader(start_binaries, binaries=[], dirs=None, default_target=None):
+  '''Sets up the standard robot download targets.
+
+  Attrs:
+    start_binaries: A list of cc_binary targets to start on the robot.
+    dirs: Passed through to aos_downloader.
+    default_target: Passed through to aos_downloader.
+  '''
+
+  aos_downloader(
+    name = 'download',
+    start_srcs = [
+      '//aos:prime_start_binaries',
+    ] + start_binaries,
+    srcs = [
+      '//aos:prime_binaries',
+    ] + binaries,
+    dirs = dirs,
+    default_target = default_target,
+    restricted_to = ['//tools:roborio'],
+  )
+
+  aos_downloader(
+    name = 'download_stripped',
+    start_srcs = [
+      '//aos:prime_start_binaries_stripped',
+    ] + [expand_label(binary) + ".stripped" for binary in start_binaries],
+    srcs = [
+      '//aos:prime_binaries_stripped',
+    ] + [expand_label(binary) + ".stripped" for binary in binaries],
+    dirs = dirs,
+    default_target = default_target,
+    restricted_to = ['//tools:roborio'],
+  )
diff --git a/tools/build_rules/label.bzl b/tools/build_rules/label.bzl
new file mode 100644
index 0000000..ff02327
--- /dev/null
+++ b/tools/build_rules/label.bzl
@@ -0,0 +1,5 @@
+# This file provides any necessary label abstractions since it doesn't seem like
+# Starlark provides them itself
+
+def expand_label(label):
+  return '%s' % label if ':' in label else '%s:%s' % (label, label.split('/')[-1])
diff --git a/y2012/BUILD b/y2012/BUILD
index 68dcc49..fd9119b 100644
--- a/y2012/BUILD
+++ b/y2012/BUILD
@@ -1,4 +1,4 @@
-load("//aos/downloader:downloader.bzl", "aos_downloader")
+load("//frc971:downloader.bzl", "robot_downloader")
 
 cc_binary(
     name = "joystick_reader",
@@ -19,18 +19,12 @@
     ],
 )
 
-aos_downloader(
-    name = "download",
-    srcs = [
-        "//aos:prime_binaries",
-    ],
-    restricted_to = ["//tools:roborio"],
-    start_srcs = [
+robot_downloader(
+    start_binaries = [
         ":joystick_reader",
         ":wpilib_interface",
         "//y2012/control_loops/drivetrain",
         "//y2012/control_loops/accessories",
-        "//aos:prime_start_binaries",
     ],
 )
 
diff --git a/y2014/BUILD b/y2014/BUILD
index 28569d0..dfd2325 100644
--- a/y2014/BUILD
+++ b/y2014/BUILD
@@ -1,4 +1,4 @@
-load("//aos/downloader:downloader.bzl", "aos_downloader")
+load("//frc971:downloader.bzl", "robot_downloader")
 
 cc_library(
     name = "constants",
@@ -42,13 +42,8 @@
     ],
 )
 
-aos_downloader(
-    name = "download",
-    srcs = [
-        "//aos:prime_binaries",
-    ],
-    restricted_to = ["//tools:roborio"],
-    start_srcs = [
+robot_downloader(
+    start_binaries = [
         ":hot_goal_reader",
         ":joystick_reader",
         ":wpilib_interface",
@@ -57,7 +52,6 @@
         "//y2014/control_loops/shooter:shooter",
         "//y2014/autonomous:auto",
         "//y2014/actors:binaries",
-        "//aos:prime_start_binaries",
     ],
 )
 
diff --git a/y2014/actors/BUILD b/y2014/actors/BUILD
index 1b9cf8e..09eb3b0 100644
--- a/y2014/actors/BUILD
+++ b/y2014/actors/BUILD
@@ -10,6 +10,14 @@
   ],
 )
 
+filegroup(
+  name = 'binaries.stripped',
+  srcs = [
+    ':drivetrain_action.stripped',
+    ':shoot_action.stripped',
+  ],
+)
+
 queue_library(
   name = 'shoot_action_queue',
   srcs = [
diff --git a/y2014_bot3/BUILD b/y2014_bot3/BUILD
index 3654191..ea79dac 100644
--- a/y2014_bot3/BUILD
+++ b/y2014_bot3/BUILD
@@ -1,4 +1,4 @@
-load("//aos/downloader:downloader.bzl", "aos_downloader")
+load("//frc971:downloader.bzl", "robot_downloader")
 
 cc_binary(
     name = "joystick_reader",
@@ -19,19 +19,13 @@
     ],
 )
 
-aos_downloader(
-    name = "download_stripped",
-    srcs = [
-        "//aos:prime_binaries_stripped",
-    ],
-    restricted_to = ["//tools:roborio"],
-    start_srcs = [
-        ":joystick_reader.stripped",
-        ":wpilib_interface.stripped",
-        "//aos:prime_start_binaries_stripped",
-        "//y2014_bot3/autonomous:auto.stripped",
-        "//y2014_bot3/control_loops/drivetrain:drivetrain.stripped",
-        "//y2014_bot3/control_loops/rollers:rollers.stripped",
+robot_downloader(
+    start_binaries = [
+        ":joystick_reader",
+        ":wpilib_interface",
+        "//y2014_bot3/autonomous:auto",
+        "//y2014_bot3/control_loops/drivetrain:drivetrain",
+        "//y2014_bot3/control_loops/rollers:rollers",
     ],
 )
 
diff --git a/y2014_bot3/control_loops/drivetrain/drivetrain_base.cc b/y2014_bot3/control_loops/drivetrain/drivetrain_base.cc
index e39a99a..2daaf6a 100644
--- a/y2014_bot3/control_loops/drivetrain/drivetrain_base.cc
+++ b/y2014_bot3/control_loops/drivetrain/drivetrain_base.cc
@@ -20,7 +20,7 @@
 const DrivetrainConfig<double> &GetDrivetrainConfig() {
   static DrivetrainConfig<double> kDrivetrainConfig{
       ::frc971::control_loops::drivetrain::ShifterType::SIMPLE_SHIFTER,
-      ::frc971::control_loops::drivetrain::LoopType::OPEN_LOOP,
+      ::frc971::control_loops::drivetrain::LoopType::CLOSED_LOOP,
       ::frc971::control_loops::drivetrain::GyroType::SPARTAN_GYRO,
       ::frc971::control_loops::drivetrain::IMUType::IMU_X,
 
@@ -36,7 +36,7 @@
       // No shifter sensors, so we could put anything for the things below.
       kThreeStateDriveShifter, kThreeStateDriveShifter,
       false /* default_high_gear */, 0.0, 0.60 /* wheel_non_linearity */,
-      0.60 /* quickturn_wheel_multiplier */, 1.0 /* wheel_multiplier */,
+      0.60 /* quickturn_wheel_multiplier */, 0.7 /* wheel_multiplier */,
   };
 
   return kDrivetrainConfig;
diff --git a/y2014_bot3/control_loops/drivetrain/drivetrain_base.h b/y2014_bot3/control_loops/drivetrain/drivetrain_base.h
index 36f8ddf..d41ff99 100644
--- a/y2014_bot3/control_loops/drivetrain/drivetrain_base.h
+++ b/y2014_bot3/control_loops/drivetrain/drivetrain_base.h
@@ -8,7 +8,7 @@
 namespace drivetrain {
 
 const double kDrivetrainEncoderRatio =
-    (17.0 / 50.0) /*output reduction*/ * (24.0 / 64.0) /*encoder gears*/;
+    (17.0 / 50.0) /*output reduction*/ * (64.0 / 24.0) /*encoder gears*/;
 
 const ::frc971::control_loops::drivetrain::DrivetrainConfig<double>
     &GetDrivetrainConfig();
diff --git a/y2014_bot3/control_loops/python/drivetrain.py b/y2014_bot3/control_loops/python/drivetrain.py
index 93993c3..48510be 100755
--- a/y2014_bot3/control_loops/python/drivetrain.py
+++ b/y2014_bot3/control_loops/python/drivetrain.py
@@ -22,7 +22,7 @@
                                           q_vel_high = 0.95,
                                           has_imu = False,
                                           dt = 0.005,
-                                          controller_poles = [0.67, 0.67])
+                                          controller_poles = [0.83, 0.83])
 
 def main(argv):
   argv = FLAGS(argv)
diff --git a/y2014_bot3/wpilib_interface.cc b/y2014_bot3/wpilib_interface.cc
index 9f991c9..2b0edb5 100644
--- a/y2014_bot3/wpilib_interface.cc
+++ b/y2014_bot3/wpilib_interface.cc
@@ -114,9 +114,9 @@
     {
       auto drivetrain_message = drivetrain_queue.position.MakeMessage();
       drivetrain_message->right_encoder =
-          drivetrain_translate(drivetrain_right_encoder_->GetRaw());
+          -drivetrain_translate(drivetrain_right_encoder_->GetRaw());
       drivetrain_message->left_encoder =
-          -drivetrain_translate(drivetrain_left_encoder_->GetRaw());
+          drivetrain_translate(drivetrain_left_encoder_->GetRaw());
       drivetrain_message->left_speed =
           drivetrain_velocity_translate(drivetrain_left_encoder_->GetPeriod());
       drivetrain_message->right_speed =
diff --git a/y2016/BUILD b/y2016/BUILD
index 3414331..c7622f8 100644
--- a/y2016/BUILD
+++ b/y2016/BUILD
@@ -1,4 +1,4 @@
-load("//aos/downloader:downloader.bzl", "aos_downloader")
+load('//frc971:downloader.bzl', 'robot_downloader')
 
 cc_library(
     name = "constants",
@@ -50,52 +50,22 @@
     ],
 )
 
-aos_downloader(
-    name = "download",
-    srcs = [
-        "//aos:prime_binaries",
-    ],
-    dirs = [
-        "//y2016/dashboard:www_files",
-    ],
-    restricted_to = ["//tools:roborio"],
-    start_srcs = [
-        ":joystick_reader",
-        ":wpilib_interface",
-        "//aos:prime_start_binaries",
-        "//y2016/control_loops/drivetrain:drivetrain",
-        "//y2016/control_loops/superstructure:superstructure",
-        "//y2016/control_loops/shooter:shooter",
-        "//y2016/dashboard:dashboard",
-        "//y2016/actors:autonomous_action",
-        "//y2016/actors:superstructure_action",
-        "//y2016/actors:vision_align_action",
-        "//y2016/vision:target_receiver",
-    ],
-)
-
-aos_downloader(
-    name = "download_stripped",
-    srcs = [
-        "//aos:prime_binaries_stripped",
-    ],
-    dirs = [
-        "//y2016/dashboard:www_files",
-    ],
-    restricted_to = ["//tools:roborio"],
-    start_srcs = [
-        ":joystick_reader.stripped",
-        ":wpilib_interface.stripped",
-        "//aos:prime_start_binaries_stripped",
-        "//y2016/control_loops/drivetrain:drivetrain.stripped",
-        "//y2016/control_loops/superstructure:superstructure.stripped",
-        "//y2016/control_loops/shooter:shooter.stripped",
-        "//y2016/dashboard:dashboard.stripped",
-        "//y2016/actors:autonomous_action.stripped",
-        "//y2016/actors:superstructure_action.stripped",
-        "//y2016/actors:vision_align_action.stripped",
-        "//y2016/vision:target_receiver.stripped",
-    ],
+robot_downloader(
+  start_binaries = [
+    ':joystick_reader',
+    ':wpilib_interface',
+    '//y2016/control_loops/drivetrain:drivetrain',
+    '//y2016/control_loops/superstructure:superstructure',
+    '//y2016/control_loops/shooter:shooter',
+    '//y2016/dashboard:dashboard',
+    '//y2016/actors:autonomous_action',
+    '//y2016/actors:superstructure_action',
+    '//y2016/actors:vision_align_action',
+    '//y2016/vision:target_receiver',
+  ],
+  dirs = [
+    '//y2016/dashboard:www_files',
+  ],
 )
 
 cc_binary(
diff --git a/y2017/BUILD b/y2017/BUILD
index aa67a78..e002758 100644
--- a/y2017/BUILD
+++ b/y2017/BUILD
@@ -1,4 +1,4 @@
-load("//aos/downloader:downloader.bzl", "aos_downloader")
+load('//frc971:downloader.bzl', 'robot_downloader')
 
 cc_library(
     name = "constants",
@@ -85,38 +85,14 @@
     ],
 )
 
-aos_downloader(
-    name = "download",
-    srcs = [
-        "//aos:prime_binaries",
-    ],
-    restricted_to = ["//tools:roborio"],
-    start_srcs = [
-        ":joystick_reader",
-        ":wpilib_interface",
-        "//aos:prime_start_binaries",
-        "//y2017/actors:autonomous_action",
-        "//y2017/control_loops/drivetrain:drivetrain",
-        "//y2017/control_loops/superstructure:superstructure",
-        "//y2017/vision:target_receiver",
-    ],
-)
-
-aos_downloader(
-    name = "download_stripped",
-    srcs = [
-        "//aos:prime_binaries_stripped",
-    ],
-    restricted_to = ["//tools:roborio"],
-    start_srcs = [
-        ":joystick_reader.stripped",
-        ":wpilib_interface.stripped",
-        "//aos:prime_start_binaries_stripped",
-        "//y2017/actors:autonomous_action.stripped",
-        "//y2017/control_loops/drivetrain:drivetrain.stripped",
-        "//y2017/control_loops/superstructure:superstructure.stripped",
-        "//y2017/vision:target_receiver.stripped",
-    ],
+robot_downloader(
+  start_binaries = [
+    ':joystick_reader',
+    ':wpilib_interface',
+    '//y2017/control_loops/drivetrain:drivetrain',
+    '//y2017/control_loops/superstructure:superstructure',
+    '//y2017/actors:autonomous_action',
+  ],
 )
 
 py_library(
diff --git a/y2018/BUILD b/y2018/BUILD
index 09d2bc9..6173702 100644
--- a/y2018/BUILD
+++ b/y2018/BUILD
@@ -1,41 +1,18 @@
-load("//aos/downloader:downloader.bzl", "aos_downloader")
+load("//frc971:downloader.bzl", "robot_downloader")
 load("//aos/build:queues.bzl", "queue_library")
 load("@com_google_protobuf//:protobuf.bzl", "cc_proto_library")
 
-aos_downloader(
-    name = "download",
-    srcs = [
-        "//aos:prime_binaries",
-    ],
-    restricted_to = ["//tools:roborio"],
-    start_srcs = [
+robot_downloader(
+    start_binaries = [
         ":joystick_reader",
         ":wpilib_interface",
         "//y2018/vision:vision_status",
-        "//aos:prime_start_binaries",
-        "//y2018/control_loops/drivetrain:drivetrain",
         "//y2018/actors:autonomous_action",
+        "//y2018/control_loops/drivetrain:drivetrain",
         "//y2018/control_loops/superstructure:superstructure",
     ],
 )
 
-aos_downloader(
-    name = "download_stripped",
-    srcs = [
-        "//aos:prime_binaries_stripped",
-    ],
-    restricted_to = ["//tools:roborio"],
-    start_srcs = [
-        ":joystick_reader.stripped",
-        ":wpilib_interface.stripped",
-        "//y2018/vision:vision_status.stripped",
-        "//aos:prime_start_binaries_stripped",
-        "//y2018/actors:autonomous_action.stripped",
-        "//y2018/control_loops/drivetrain:drivetrain.stripped",
-        "//y2018/control_loops/superstructure:superstructure.stripped",
-    ],
-)
-
 cc_binary(
     name = "joystick_reader",
     srcs = [