Enable Touchbot single-finger line-drawing tests

This CL enables the single-finger line drawing tests.  This
is done by adding a line-drawing function to the touchbot class
as well as adding gesture interpreters for these gestures.
They all work very similarly, so the work is replicated.

Also note, the nest_locations are pickled files needed by touchbot.
They were meant to be merged a while ago, but they got missed by
git, so I'm adding them to this CL since it won't work without them.

BUG=chromium:474709
TEST=I ran a robot test over the line gestures and it worked like a
charm, doing all three classes of tests without problem.  The noise
tap-test still works too.

Change-Id: Id814025be1235c6d03a84d8f49bb147d28cc557a
Signed-off-by: Charlie Mooney <charliemooney@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/266896
Reviewed-by: Shyh-In Hwang <josephsih@chromium.org>
diff --git a/gesture_interpreter.py b/gesture_interpreter.py
index be2bf41..71ac01d 100644
--- a/gesture_interpreter.py
+++ b/gesture_interpreter.py
@@ -16,11 +16,18 @@
 from touchbot import Touchbot
 
 
+STANDARD_FINGERTIP = '1round_9mm'
+
 BUFFER_SIZE = 0.1
+OVERSHOOT_DISTANCE = 0.05
 LEFT = BUFFER_SIZE
+OVER_LEFT = -OVERSHOOT_DISTANCE
 RIGHT = 1.0 - BUFFER_SIZE
+OVER_RIGHT = 1.0 + OVERSHOOT_DISTANCE
 TOP = BUFFER_SIZE
+OVER_TOP = -OVERSHOOT_DISTANCE
 BOTTOM = 1.0 - BUFFER_SIZE
+OVER_BOTTOM = 1.0 + OVERSHOOT_DISTANCE
 CENTER = 0.5
 
 LOCATION_COORDINATES = {
@@ -35,12 +42,44 @@
     tests.GV.CENTER: (CENTER, CENTER),
 }
 
+LINE_DIRECTION_COORDINATES = {
+    tests.GV.LR: ((LEFT, CENTER), (RIGHT, CENTER)),
+    tests.GV.RL: ((RIGHT, CENTER), (LEFT, CENTER)),
+    tests.GV.TB: ((CENTER, TOP), (CENTER, BOTTOM)),
+    tests.GV.BT: ((CENTER, BOTTOM), (CENTER, TOP)),
+    tests.GV.BLTR: ((LEFT, BOTTOM), (RIGHT, TOP)),
+    tests.GV.BRTL: ((RIGHT, BOTTOM), (LEFT, TOP)),
+    tests.GV.TRBL: ((RIGHT, TOP), (LEFT, BOTTOM)),
+    tests.GV.TLBR: ((LEFT, TOP), (RIGHT, BOTTOM)),
+    tests.GV.CL: ((CENTER, CENTER), (OVER_LEFT, CENTER)),
+    tests.GV.CR: ((CENTER, CENTER), (OVER_RIGHT, CENTER)),
+    tests.GV.CT: ((CENTER, CENTER), (CENTER, OVER_TOP)),
+    tests.GV.CB: ((CENTER, CENTER), (CENTER, OVER_BOTTOM)),
+    tests.GV.CUL: ((CENTER, CENTER), (OVER_LEFT, OVER_TOP)),
+    tests.GV.CLL: ((CENTER, CENTER), (OVER_LEFT, OVER_BOTTOM)),
+    tests.GV.CLR: ((CENTER, CENTER), (OVER_RIGHT, OVER_BOTTOM)),
+}
+
+SPEEDS = {
+    tests.GV.NORMAL: Touchbot.SPEED_MEDIUM,
+    tests.GV.SLOW: Touchbot.SPEED_SLOW,
+}
+
+SINGLE_FINGER_LINE_TESTS = [
+    tests.ONE_FINGER_TO_EDGE,
+    tests.ONE_FINGER_TRACKING,
+    tests.ONE_FINGER_TRACKING_FROM_CENTER,
+]
+
 
 def PerformCorrespondingGesture(test, variation_number, robot, device_spec):
   variation = test.variations[variation_number]
   fn = None
   if test.name == tests.NOISE_STATIONARY:
     fn = lambda: _PerformStationaryNoiseTest(variation, robot, device_spec)
+  elif test.name in SINGLE_FINGER_LINE_TESTS:
+    pause = 1 if test.name == tests.ONE_FINGER_TRACKING_FROM_CENTER else 0
+    fn = lambda: _PerformOneFingerLineTest(variation, robot, device_spec, pause)
 
   if fn is None:
     print color.Fore.RED + 'Error: Robot unable to perform gesture!'
@@ -48,6 +87,19 @@
 
   return Thread(target=fn)
 
+
 def _PerformStationaryNoiseTest(variation, robot, device_spec):
   frequency, amplitude, waveform, location = variation
-  robot.Tap(device_spec, LOCATION_COORDINATES[location], touch_time_s=4)
+  tap_position = LOCATION_COORDINATES[location]
+  fingertip = robot.fingertips[STANDARD_FINGERTIP]
+  robot.SingleTipTap(device_spec, fingertip, tap_position, touch_time_s=4)
+
+
+def _PerformOneFingerLineTest(variation, robot, device_spec, pause_time_s):
+  direction, speed = variation
+  start, end = LINE_DIRECTION_COORDINATES[direction]
+  fingertip = robot.fingertips[STANDARD_FINGERTIP]
+
+  robot.PushSpeed(SPEEDS[speed])
+  robot.SingleTipLine(device_spec, fingertip, start, end, pause_time_s)
+  robot.PopSpeed()