blob: 8b43ec495ae3c062ebd80d4005a58127f5b550ca [file] [log] [blame]
Charlie Mooney08661912015-04-16 09:20:34 -07001# Copyright 2015 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5""" This is a module containing functions that allow the test suite to
6determine the specifics of the gesture and execute them on the touchbot.
7In essence, you use this class to go from a Test object to the robot
8actually performing the correct gesture on the pad.
9"""
10
Charlie Mooneya337d582015-04-29 10:37:45 -070011import math
Charlie Mooney08661912015-04-16 09:20:34 -070012from threading import Thread
13
14import colorama as color
15
16import tests
17from touchbot import Touchbot
18
19
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070020STANDARD_FINGERTIP = '1round_9mm'
Charlie Mooneya337d582015-04-29 10:37:45 -070021STANDARD_SECONDARY_FINGERTIP = '2round_9mm'
Charlie Mooney7b1fdb92015-05-08 09:22:55 -070022FAT_FINGERTIP = '1round_14mm'
23FAT_SECONDARY_FINGERTIP = '2round_14mm'
24NOISE_TESTING_FINGERTIP = '1round_12mm'
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070025
Charlie Mooney08661912015-04-16 09:20:34 -070026BUFFER_SIZE = 0.1
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070027OVERSHOOT_DISTANCE = 0.05
Charlie Mooney08661912015-04-16 09:20:34 -070028LEFT = BUFFER_SIZE
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070029OVER_LEFT = -OVERSHOOT_DISTANCE
Charlie Mooney08661912015-04-16 09:20:34 -070030RIGHT = 1.0 - BUFFER_SIZE
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070031OVER_RIGHT = 1.0 + OVERSHOOT_DISTANCE
Charlie Mooney08661912015-04-16 09:20:34 -070032TOP = BUFFER_SIZE
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070033OVER_TOP = -OVERSHOOT_DISTANCE
Charlie Mooney08661912015-04-16 09:20:34 -070034BOTTOM = 1.0 - BUFFER_SIZE
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070035OVER_BOTTOM = 1.0 + OVERSHOOT_DISTANCE
Charlie Mooney08661912015-04-16 09:20:34 -070036CENTER = 0.5
37
38LOCATION_COORDINATES = {
39 tests.GV.TL: (LEFT, TOP),
40 tests.GV.TR: (RIGHT, TOP),
41 tests.GV.BL: (LEFT, BOTTOM),
42 tests.GV.BR: (RIGHT, BOTTOM),
43 tests.GV.TS: (CENTER, TOP),
44 tests.GV.BS: (CENTER, BOTTOM),
45 tests.GV.LS: (LEFT, CENTER),
46 tests.GV.RS: (RIGHT, CENTER),
47 tests.GV.CENTER: (CENTER, CENTER),
48}
49
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070050LINE_DIRECTION_COORDINATES = {
51 tests.GV.LR: ((LEFT, CENTER), (RIGHT, CENTER)),
52 tests.GV.RL: ((RIGHT, CENTER), (LEFT, CENTER)),
53 tests.GV.TB: ((CENTER, TOP), (CENTER, BOTTOM)),
54 tests.GV.BT: ((CENTER, BOTTOM), (CENTER, TOP)),
55 tests.GV.BLTR: ((LEFT, BOTTOM), (RIGHT, TOP)),
56 tests.GV.BRTL: ((RIGHT, BOTTOM), (LEFT, TOP)),
57 tests.GV.TRBL: ((RIGHT, TOP), (LEFT, BOTTOM)),
58 tests.GV.TLBR: ((LEFT, TOP), (RIGHT, BOTTOM)),
59 tests.GV.CL: ((CENTER, CENTER), (OVER_LEFT, CENTER)),
60 tests.GV.CR: ((CENTER, CENTER), (OVER_RIGHT, CENTER)),
61 tests.GV.CT: ((CENTER, CENTER), (CENTER, OVER_TOP)),
62 tests.GV.CB: ((CENTER, CENTER), (CENTER, OVER_BOTTOM)),
63 tests.GV.CUL: ((CENTER, CENTER), (OVER_LEFT, OVER_TOP)),
64 tests.GV.CLL: ((CENTER, CENTER), (OVER_LEFT, OVER_BOTTOM)),
65 tests.GV.CLR: ((CENTER, CENTER), (OVER_RIGHT, OVER_BOTTOM)),
66}
67
68SPEEDS = {
69 tests.GV.NORMAL: Touchbot.SPEED_MEDIUM,
70 tests.GV.SLOW: Touchbot.SPEED_SLOW,
71}
72
Charlie Mooney4198adb2015-05-04 13:55:20 -070073ANGLES = {
Charlie Mooney5065bcb2015-05-04 13:18:09 -070074 tests.GV.HORIZONTAL: 0,
75 tests.GV.VERTICAL: 90,
76 tests.GV.DIAGONAL: 45,
77}
78
79
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070080SINGLE_FINGER_LINE_TESTS = [
81 tests.ONE_FINGER_TO_EDGE,
82 tests.ONE_FINGER_TRACKING,
83 tests.ONE_FINGER_TRACKING_FROM_CENTER,
84]
85
Charlie Mooneycfb4a642015-05-07 15:33:37 -070086TWO_FINGER_LINE_TESTS = [
87 tests.TWO_FINGER_TRACKING,
88 tests.TWO_CLOSE_FINGERS_TRACKING,
Charlie Mooney7b1fdb92015-05-08 09:22:55 -070089 tests.TWO_FAT_FINGERS_TRACKING,
Charlie Mooneycfb4a642015-05-07 15:33:37 -070090]
91
Charlie Mooney08661912015-04-16 09:20:34 -070092
Charlie Mooneyc56c8602015-05-07 15:15:40 -070093def _ComputePerpendicularAngle(start, end):
94 """ Compute the fingertip angle to be perpendicular to the
95 movement direction.
96
97 The robot's X/Y axes are not in the same direction as the touch device's,
98 they are flipped.
99
100 DUT x ----> Robot y ---->
101 y x
102 | |
103 | |
104 \/ \/
105
106 As a result the angle is computed in the DUT space, but then must have
107 its sign flipped before being used in any commands to the robot or
108 everything will be wrong since it's a clockwise angle instead of counter-
109 clockwise.
110 """
111 x1, y1 = start
112 x2, y2 = end
113 dy = y2 - y1
114 dx = x2 - x1
115 return -1 * (math.degrees(math.atan2(y2 - y1, x2 - x1)) + 90)
116
117
Charlie Mooney08661912015-04-16 09:20:34 -0700118def PerformCorrespondingGesture(test, variation_number, robot, device_spec):
119 variation = test.variations[variation_number]
120 fn = None
121 if test.name == tests.NOISE_STATIONARY:
122 fn = lambda: _PerformStationaryNoiseTest(variation, robot, device_spec)
Charlie Mooney1b708112015-04-28 14:46:21 -0700123 elif test.name == tests.ONE_FINGER_TAP:
124 fn = lambda: _PerformOneFingerTapTest(variation, robot, device_spec)
Charlie Mooney4198adb2015-05-04 13:55:20 -0700125 elif test.name == tests.TWO_FINGER_TAP:
126 fn = lambda: _PerformTwoFingerTapTest(variation, robot, device_spec)
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700127 elif test.name in SINGLE_FINGER_LINE_TESTS:
128 pause = 1 if test.name == tests.ONE_FINGER_TRACKING_FROM_CENTER else 0
129 fn = lambda: _PerformOneFingerLineTest(variation, robot, device_spec, pause)
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700130 elif test.name in TWO_FINGER_LINE_TESTS:
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700131 spacing = 5
132 fingertips = [robot.fingertips[STANDARD_FINGERTIP],
133 robot.fingertips[STANDARD_SECONDARY_FINGERTIP]]
134
135 if test.name == tests.TWO_CLOSE_FINGERS_TRACKING:
136 spacing = 0
137 elif test.name == tests.TWO_FAT_FINGERS_TRACKING:
138 spacing = 10
139 fingertips = [robot.fingertips[FAT_FINGERTIP],
140 robot.fingertips[FAT_SECONDARY_FINGERTIP]]
141
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700142 fn = lambda: _PerformTwoFingerLineTest(variation, robot, device_spec,
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700143 fingertips, spacing)
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700144 elif test.name == tests.RESTING_FINGER_PLUS_2ND_FINGER_MOVE:
145 fn = lambda: _PerformRestingFingerTest(variation, robot, device_spec)
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700146 elif test.name == tests.PINCH_TO_ZOOM:
147 fn = lambda: _PerformPinchTest(variation, robot, device_spec)
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700148 elif test.name == tests.DRAG_THUMB_EDGE:
149 fn = lambda: _PerformThumbEdgeTest(variation, robot, device_spec)
Charlie Mooney08661912015-04-16 09:20:34 -0700150
151 if fn is None:
152 print color.Fore.RED + 'Error: Robot unable to perform gesture!'
153 return None
154
155 return Thread(target=fn)
156
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700157
Charlie Mooney08661912015-04-16 09:20:34 -0700158def _PerformStationaryNoiseTest(variation, robot, device_spec):
159 frequency, amplitude, waveform, location = variation
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700160 tap_position = LOCATION_COORDINATES[location]
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700161 fingertip = robot.fingertips[NOISE_TESTING_FINGERTIP]
Charlie Mooney4198adb2015-05-04 13:55:20 -0700162 robot.Tap(device_spec, [fingertip], tap_position, touch_time_s=4)
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700163
164
Charlie Mooney1b708112015-04-28 14:46:21 -0700165def _PerformOneFingerTapTest(variation, robot, device_spec):
166 location, = variation
167 tap_position = LOCATION_COORDINATES[location]
168 fingertip = robot.fingertips[STANDARD_FINGERTIP]
Charlie Mooney4198adb2015-05-04 13:55:20 -0700169 robot.Tap(device_spec, [fingertip], tap_position)
170
171
172def _PerformTwoFingerTapTest(variation, robot, device_spec):
173 angle, = variation
174
175 fingertip1 = robot.fingertips[STANDARD_FINGERTIP]
176 fingertip2 = robot.fingertips[STANDARD_SECONDARY_FINGERTIP]
177 fingertips = [fingertip1, fingertip2]
178
179 robot.Tap(device_spec, fingertips, (CENTER, CENTER), angle=ANGLES[angle])
Charlie Mooney1b708112015-04-28 14:46:21 -0700180
181
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700182def _PerformOneFingerLineTest(variation, robot, device_spec, pause_time_s):
183 direction, speed = variation
184 start, end = LINE_DIRECTION_COORDINATES[direction]
185 fingertip = robot.fingertips[STANDARD_FINGERTIP]
186
187 robot.PushSpeed(SPEEDS[speed])
Charlie Mooneya337d582015-04-29 10:37:45 -0700188 robot.Line(device_spec, [fingertip], start, end, pause_time_s)
189 robot.PopSpeed()
190
191
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700192def _PerformTwoFingerLineTest(variation, robot, device_spec, fingertips,
193 spacing_mm):
Charlie Mooneya337d582015-04-29 10:37:45 -0700194 direction, speed = variation
195 start, end = LINE_DIRECTION_COORDINATES[direction]
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700196 angle = _ComputePerpendicularAngle(start, end)
Charlie Mooneya337d582015-04-29 10:37:45 -0700197
Charlie Mooneya337d582015-04-29 10:37:45 -0700198 robot.PushSpeed(SPEEDS[speed])
199 robot.Line(device_spec, fingertips, start, end,
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700200 fingertip_spacing=spacing_mm, fingertip_angle=angle)
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700201 robot.PopSpeed()
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700202
203
204def _PerformRestingFingerTest(variation, robot, device_spec):
205 direction, speed = variation
206 start, end = LINE_DIRECTION_COORDINATES[direction]
207 stationary_location = LOCATION_COORDINATES[tests.GV.BL]
208
209 stationary_fingertip = robot.fingertips[STANDARD_FINGERTIP]
210 moving_fingertip = robot.fingertips[STANDARD_SECONDARY_FINGERTIP]
211
212 robot.PushSpeed(SPEEDS[speed])
213 robot.LineWithStationaryFinger(device_spec, stationary_fingertip,
214 moving_fingertip, start, end,
215 stationary_location)
216 robot.PopSpeed()
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700217
218def _PerformPinchTest(variation, robot, device_spec):
219 direction, angle = variation
220
221 min_spread = 15
222 max_spread = min(device_spec.Height(), device_spec.Width(),
223 robot.MAX_FINGER_DISTANCE)
224 if direction == tests.GV.ZOOM_OUT:
225 start_distance, end_distance = max_spread, min_spread
226 else:
227 start_distance, end_distance = min_spread, max_spread
228
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700229 fingertips = [robot.fingertips[STANDARD_FINGERTIP],
230 robot.fingertips[STANDARD_SECONDARY_FINGERTIP]]
231
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700232 robot.PushSpeed(SPEEDS[tests.GV.NORMAL])
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700233 robot.Pinch(device_spec, fingertips, (CENTER, CENTER), ANGLES[angle],
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700234 start_distance, end_distance)
235 robot.PopSpeed()
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700236
237def _PerformThumbEdgeTest(variation, robot, device_spec):
238 fingertip_type, direction = variation
239 start, end = LINE_DIRECTION_COORDINATES[direction]
240 angle = _ComputePerpendicularAngle(start, end)
241
242 fingertip = robot.fingertips[fingertip_type]
243
244 robot.PushSpeed(SPEEDS[tests.GV.NORMAL])
245 robot.Line(device_spec, [fingertip], start, end, fingertip_angle=angle)
246 robot.PopSpeed()