blob: 6fbd3f0a0885a134c04888b6a1673247ddcb2b54 [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 Mooney1777b372015-05-21 10:40:43 -070025THREE_FINGER_FINGERTIP = 'three_fingers'
26FOUR_FINGER_FINGERTIP = 'four_fingers'
27FIVE_FINGER_FINGERTIP = 'five_fingers'
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070028
Charlie Mooney08661912015-04-16 09:20:34 -070029BUFFER_SIZE = 0.1
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070030OVERSHOOT_DISTANCE = 0.05
Charlie Mooney08661912015-04-16 09:20:34 -070031LEFT = BUFFER_SIZE
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070032OVER_LEFT = -OVERSHOOT_DISTANCE
Charlie Mooney08661912015-04-16 09:20:34 -070033RIGHT = 1.0 - BUFFER_SIZE
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070034OVER_RIGHT = 1.0 + OVERSHOOT_DISTANCE
Charlie Mooney08661912015-04-16 09:20:34 -070035TOP = BUFFER_SIZE
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070036OVER_TOP = -OVERSHOOT_DISTANCE
Charlie Mooney08661912015-04-16 09:20:34 -070037BOTTOM = 1.0 - BUFFER_SIZE
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070038OVER_BOTTOM = 1.0 + OVERSHOOT_DISTANCE
Charlie Mooney08661912015-04-16 09:20:34 -070039CENTER = 0.5
40
41LOCATION_COORDINATES = {
42 tests.GV.TL: (LEFT, TOP),
43 tests.GV.TR: (RIGHT, TOP),
44 tests.GV.BL: (LEFT, BOTTOM),
45 tests.GV.BR: (RIGHT, BOTTOM),
46 tests.GV.TS: (CENTER, TOP),
47 tests.GV.BS: (CENTER, BOTTOM),
48 tests.GV.LS: (LEFT, CENTER),
49 tests.GV.RS: (RIGHT, CENTER),
50 tests.GV.CENTER: (CENTER, CENTER),
51}
52
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070053LINE_DIRECTION_COORDINATES = {
54 tests.GV.LR: ((LEFT, CENTER), (RIGHT, CENTER)),
55 tests.GV.RL: ((RIGHT, CENTER), (LEFT, CENTER)),
56 tests.GV.TB: ((CENTER, TOP), (CENTER, BOTTOM)),
57 tests.GV.BT: ((CENTER, BOTTOM), (CENTER, TOP)),
58 tests.GV.BLTR: ((LEFT, BOTTOM), (RIGHT, TOP)),
59 tests.GV.BRTL: ((RIGHT, BOTTOM), (LEFT, TOP)),
60 tests.GV.TRBL: ((RIGHT, TOP), (LEFT, BOTTOM)),
61 tests.GV.TLBR: ((LEFT, TOP), (RIGHT, BOTTOM)),
62 tests.GV.CL: ((CENTER, CENTER), (OVER_LEFT, CENTER)),
63 tests.GV.CR: ((CENTER, CENTER), (OVER_RIGHT, CENTER)),
64 tests.GV.CT: ((CENTER, CENTER), (CENTER, OVER_TOP)),
65 tests.GV.CB: ((CENTER, CENTER), (CENTER, OVER_BOTTOM)),
66 tests.GV.CUL: ((CENTER, CENTER), (OVER_LEFT, OVER_TOP)),
67 tests.GV.CLL: ((CENTER, CENTER), (OVER_LEFT, OVER_BOTTOM)),
68 tests.GV.CLR: ((CENTER, CENTER), (OVER_RIGHT, OVER_BOTTOM)),
69}
70
Charlie Mooney9a177682015-06-16 15:24:36 -070071STATIONARY_FINGER_LOCATION = {
72 tests.GV.LR: LOCATION_COORDINATES[tests.GV.TS],
73 tests.GV.RL: LOCATION_COORDINATES[tests.GV.BS],
74 tests.GV.TB: LOCATION_COORDINATES[tests.GV.LS],
75 tests.GV.BT: LOCATION_COORDINATES[tests.GV.RS],
76}
77
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070078SPEEDS = {
79 tests.GV.NORMAL: Touchbot.SPEED_MEDIUM,
80 tests.GV.SLOW: Touchbot.SPEED_SLOW,
Charlie Mooneybe4661e2015-05-20 11:46:43 -070081 tests.GV.FAST: Touchbot.SPEED_FAST,
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070082}
83
Charlie Mooney4198adb2015-05-04 13:55:20 -070084ANGLES = {
Charlie Mooney5065bcb2015-05-04 13:18:09 -070085 tests.GV.HORIZONTAL: 0,
86 tests.GV.VERTICAL: 90,
87 tests.GV.DIAGONAL: 45,
88}
89
Charlie Mooney1777b372015-05-21 10:40:43 -070090ONE_FINGERTIP_TAP_TESTS = [
91 tests.ONE_FINGER_TAP,
Charlie Mooney587197f2015-06-05 15:35:02 -070092 tests.REPEATED_TAPS,
Charlie Mooney1777b372015-05-21 10:40:43 -070093 tests.THREE_FINGER_TAP,
94 tests.FOUR_FINGER_TAP,
95 tests.FIVE_FINGER_TAP,
96]
97
98TAP_TEST_FINGERTIPS = {
99 tests.ONE_FINGER_TAP: STANDARD_FINGERTIP,
Charlie Mooney587197f2015-06-05 15:35:02 -0700100 tests.REPEATED_TAPS: STANDARD_FINGERTIP,
Charlie Mooney1777b372015-05-21 10:40:43 -0700101 tests.THREE_FINGER_TAP: THREE_FINGER_FINGERTIP,
102 tests.FOUR_FINGER_TAP: FOUR_FINGER_FINGERTIP,
103 tests.FIVE_FINGER_TAP: FIVE_FINGER_FINGERTIP,
104}
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700105
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700106SINGLE_FINGER_LINE_TESTS = [
107 tests.ONE_FINGER_TO_EDGE,
108 tests.ONE_FINGER_TRACKING,
109 tests.ONE_FINGER_TRACKING_FROM_CENTER,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700110 tests.ONE_FINGER_SWIPE,
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700111]
112
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700113TWO_FINGER_LINE_TESTS = [
114 tests.TWO_FINGER_TRACKING,
115 tests.TWO_CLOSE_FINGERS_TRACKING,
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700116 tests.TWO_FAT_FINGERS_TRACKING,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700117 tests.TWO_FINGER_SWIPE,
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700118]
119
Charlie Mooneya5a5d3e2015-06-11 13:48:01 -0700120PHYSICAL_CLICK_TESTS = [
121 tests.ONE_FINGER_PHYSICAL_CLICK,
122 tests.TWO_FINGER_PHYSICAL_CLICK,
123]
124
Charlie Mooney08661912015-04-16 09:20:34 -0700125
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700126def _ComputePerpendicularAngle(start, end):
127 """ Compute the fingertip angle to be perpendicular to the
128 movement direction.
129
130 The robot's X/Y axes are not in the same direction as the touch device's,
131 they are flipped.
132
133 DUT x ----> Robot y ---->
134 y x
135 | |
136 | |
137 \/ \/
138
139 As a result the angle is computed in the DUT space, but then must have
140 its sign flipped before being used in any commands to the robot or
141 everything will be wrong since it's a clockwise angle instead of counter-
142 clockwise.
143 """
144 x1, y1 = start
145 x2, y2 = end
146 dy = y2 - y1
147 dx = x2 - x1
148 return -1 * (math.degrees(math.atan2(y2 - y1, x2 - x1)) + 90)
149
150
Charlie Mooney08661912015-04-16 09:20:34 -0700151def PerformCorrespondingGesture(test, variation_number, robot, device_spec):
152 variation = test.variations[variation_number]
153 fn = None
Charlie Mooney1777b372015-05-21 10:40:43 -0700154
Charlie Mooney08661912015-04-16 09:20:34 -0700155 if test.name == tests.NOISE_STATIONARY:
156 fn = lambda: _PerformStationaryNoiseTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700157
Charlie Mooney2107d6b2015-08-07 11:16:59 -0700158 elif test.name == tests.NOISE_LINE:
159 fn = lambda: _PerformLineNoiseTest(variation, robot, device_spec)
160
Charlie Mooney1777b372015-05-21 10:40:43 -0700161 elif test.name in ONE_FINGERTIP_TAP_TESTS:
162 fingertip = robot.fingertips[TAP_TEST_FINGERTIPS[test.name]]
Charlie Mooney587197f2015-06-05 15:35:02 -0700163 num_taps = 20 if test.name == tests.REPEATED_TAPS else 1
Charlie Mooney1777b372015-05-21 10:40:43 -0700164 vertical_offset = 0
165 if test.name != tests.ONE_FINGER_TAP:
166 vertical_offset = robot.LARGE_FINGERTIP_VERTICAL_OFFSET
Charlie Mooney587197f2015-06-05 15:35:02 -0700167 fn = lambda: _PerformOneFingertipTapTest(
168 variation, robot, device_spec, fingertip,
169 vertical_offset, num_taps)
170
Charlie Mooney4198adb2015-05-04 13:55:20 -0700171 elif test.name == tests.TWO_FINGER_TAP:
172 fn = lambda: _PerformTwoFingerTapTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700173
Charlie Mooneya5a5d3e2015-06-11 13:48:01 -0700174 elif test.name in PHYSICAL_CLICK_TESTS:
175 fingertips = [robot.fingertips[STANDARD_FINGERTIP]]
176 if test.name == tests.TWO_FINGER_PHYSICAL_CLICK:
177 fingertips.append(robot.fingertips[STANDARD_SECONDARY_FINGERTIP])
178 fn = lambda: _PerformPhysicalClickTest(variation, robot, device_spec,
179 fingertips)
180
Charlie Mooney9426d0c2015-07-01 15:03:45 -0700181 elif test.name == tests.DRUMROLL:
182 fn = lambda: _PerformDrumroll(variation, robot, device_spec)
183
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700184 elif test.name in SINGLE_FINGER_LINE_TESTS:
185 pause = 1 if test.name == tests.ONE_FINGER_TRACKING_FROM_CENTER else 0
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700186 is_swipe = (test.name == tests.ONE_FINGER_SWIPE)
187 fn = lambda: _PerformOneFingerLineTest(variation, robot, device_spec,
188 pause, is_swipe)
Charlie Mooney1777b372015-05-21 10:40:43 -0700189
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700190 elif test.name in TWO_FINGER_LINE_TESTS:
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700191 spacing = 5
192 fingertips = [robot.fingertips[STANDARD_FINGERTIP],
193 robot.fingertips[STANDARD_SECONDARY_FINGERTIP]]
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700194 is_swipe = (test.name == tests.TWO_FINGER_SWIPE)
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700195 if test.name == tests.TWO_CLOSE_FINGERS_TRACKING:
196 spacing = 0
197 elif test.name == tests.TWO_FAT_FINGERS_TRACKING:
198 spacing = 10
199 fingertips = [robot.fingertips[FAT_FINGERTIP],
200 robot.fingertips[FAT_SECONDARY_FINGERTIP]]
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700201 fn = lambda: _PerformTwoFingerLineTest(variation, robot, device_spec,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700202 fingertips, spacing, is_swipe)
Charlie Mooney1777b372015-05-21 10:40:43 -0700203
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700204 elif test.name == tests.RESTING_FINGER_PLUS_2ND_FINGER_MOVE:
Charlie Mooney9a177682015-06-16 15:24:36 -0700205 moving_fingertip = robot.fingertips[STANDARD_SECONDARY_FINGERTIP]
206 stationary_location = LOCATION_COORDINATES[tests.GV.BL]
207 fn = lambda: _PerformRestingFingerTest(variation, robot, device_spec,
208 moving_fingertip,
209 stationary_location)
210
211 elif test.name == tests.FAT_FINGER_MOVE_WITH_RESTING_FINGER:
212 moving_fingertip = robot.fingertips[FAT_SECONDARY_FINGERTIP]
213 direction, speed = variation
214 stationary_location = STATIONARY_FINGER_LOCATION[direction]
215 fn = lambda: _PerformRestingFingerTest(variation, robot, device_spec,
216 moving_fingertip,
217 stationary_location)
Charlie Mooney1777b372015-05-21 10:40:43 -0700218
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700219 elif test.name == tests.PINCH_TO_ZOOM:
220 fn = lambda: _PerformPinchTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700221
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700222 elif test.name == tests.DRAG_THUMB_EDGE:
223 fn = lambda: _PerformThumbEdgeTest(variation, robot, device_spec)
Charlie Mooney08661912015-04-16 09:20:34 -0700224
Charlie Mooney030267f2016-02-05 15:34:26 -0800225 elif test.name == tests.SQUARE_RESOLUTION:
226 fn = lambda: _PerformSquareResolutionTest(variation, robot, device_spec)
227
Charlie Mooney08661912015-04-16 09:20:34 -0700228 if fn is None:
Charlie Mooneyca3fc202015-05-21 11:16:53 -0700229 print color.Fore.RED + 'Robot unable to perform gesture! Skipping...'
Charlie Mooney08661912015-04-16 09:20:34 -0700230 return None
231
232 return Thread(target=fn)
233
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700234
Charlie Mooney08661912015-04-16 09:20:34 -0700235def _PerformStationaryNoiseTest(variation, robot, device_spec):
236 frequency, amplitude, waveform, location = variation
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700237 tap_position = LOCATION_COORDINATES[location]
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700238 fingertip = robot.fingertips[NOISE_TESTING_FINGERTIP]
Charlie Mooney4198adb2015-05-04 13:55:20 -0700239 robot.Tap(device_spec, [fingertip], tap_position, touch_time_s=4)
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700240
Charlie Mooney2107d6b2015-08-07 11:16:59 -0700241def _PerformLineNoiseTest(variation, robot, device_spec):
242 frequency, amplitude, waveform, direction = variation
243 start, end = LINE_DIRECTION_COORDINATES[direction]
244 fingertip = robot.fingertips[NOISE_TESTING_FINGERTIP]
245 robot.Line(device_spec, [fingertip], start, end, pause_s=1, swipe=False)
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700246
Charlie Mooney1777b372015-05-21 10:40:43 -0700247def _PerformOneFingertipTapTest(variation, robot, device_spec, fingertip,
Charlie Mooney587197f2015-06-05 15:35:02 -0700248 vertical_offset, num_taps):
Charlie Mooney1b708112015-04-28 14:46:21 -0700249 location, = variation
250 tap_position = LOCATION_COORDINATES[location]
Charlie Mooney1777b372015-05-21 10:40:43 -0700251 robot.Tap(device_spec, [fingertip], tap_position,
Charlie Mooney587197f2015-06-05 15:35:02 -0700252 vertical_offset=vertical_offset, num_taps=num_taps)
Charlie Mooney4198adb2015-05-04 13:55:20 -0700253
254
255def _PerformTwoFingerTapTest(variation, robot, device_spec):
256 angle, = variation
257
258 fingertip1 = robot.fingertips[STANDARD_FINGERTIP]
259 fingertip2 = robot.fingertips[STANDARD_SECONDARY_FINGERTIP]
260 fingertips = [fingertip1, fingertip2]
261
262 robot.Tap(device_spec, fingertips, (CENTER, CENTER), angle=ANGLES[angle])
Charlie Mooney1b708112015-04-28 14:46:21 -0700263
264
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700265def _PerformOneFingerLineTest(variation, robot, device_spec, pause_time_s,
266 is_swipe):
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700267 direction, speed = variation
268 start, end = LINE_DIRECTION_COORDINATES[direction]
269 fingertip = robot.fingertips[STANDARD_FINGERTIP]
270
271 robot.PushSpeed(SPEEDS[speed])
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700272 robot.Line(device_spec, [fingertip], start, end, pause_s=pause_time_s,
273 swipe=is_swipe)
Charlie Mooneya337d582015-04-29 10:37:45 -0700274 robot.PopSpeed()
275
276
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700277def _PerformTwoFingerLineTest(variation, robot, device_spec, fingertips,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700278 spacing_mm, is_swipe):
Charlie Mooneya337d582015-04-29 10:37:45 -0700279 direction, speed = variation
280 start, end = LINE_DIRECTION_COORDINATES[direction]
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700281 angle = _ComputePerpendicularAngle(start, end)
Charlie Mooneya337d582015-04-29 10:37:45 -0700282
Charlie Mooneya337d582015-04-29 10:37:45 -0700283 robot.PushSpeed(SPEEDS[speed])
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700284 robot.Line(device_spec, fingertips, start, end, fingertip_spacing=spacing_mm,
285 fingertip_angle=angle, swipe=is_swipe)
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700286 robot.PopSpeed()
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700287
288
Charlie Mooney9a177682015-06-16 15:24:36 -0700289def _PerformRestingFingerTest(variation, robot, device_spec, moving_fingertip,
290 stationary_location):
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700291 direction, speed = variation
292 start, end = LINE_DIRECTION_COORDINATES[direction]
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700293
294 stationary_fingertip = robot.fingertips[STANDARD_FINGERTIP]
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700295
296 robot.PushSpeed(SPEEDS[speed])
297 robot.LineWithStationaryFinger(device_spec, stationary_fingertip,
298 moving_fingertip, start, end,
299 stationary_location)
300 robot.PopSpeed()
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700301
302def _PerformPinchTest(variation, robot, device_spec):
303 direction, angle = variation
304
305 min_spread = 15
306 max_spread = min(device_spec.Height(), device_spec.Width(),
307 robot.MAX_FINGER_DISTANCE)
308 if direction == tests.GV.ZOOM_OUT:
309 start_distance, end_distance = max_spread, min_spread
310 else:
311 start_distance, end_distance = min_spread, max_spread
312
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700313 fingertips = [robot.fingertips[STANDARD_FINGERTIP],
314 robot.fingertips[STANDARD_SECONDARY_FINGERTIP]]
315
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700316 robot.PushSpeed(SPEEDS[tests.GV.NORMAL])
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700317 robot.Pinch(device_spec, fingertips, (CENTER, CENTER), ANGLES[angle],
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700318 start_distance, end_distance)
319 robot.PopSpeed()
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700320
321def _PerformThumbEdgeTest(variation, robot, device_spec):
322 fingertip_type, direction = variation
323 start, end = LINE_DIRECTION_COORDINATES[direction]
324 angle = _ComputePerpendicularAngle(start, end)
325
326 fingertip = robot.fingertips[fingertip_type]
327
328 robot.PushSpeed(SPEEDS[tests.GV.NORMAL])
329 robot.Line(device_spec, [fingertip], start, end, fingertip_angle=angle)
330 robot.PopSpeed()
Charlie Mooneya5a5d3e2015-06-11 13:48:01 -0700331
332def _PerformPhysicalClickTest(variation, robot, device_spec, fingertips):
333 location, = variation
334 click_position = LOCATION_COORDINATES[location]
335 robot.Click(device_spec, fingertips, click_position)
Charlie Mooney9426d0c2015-07-01 15:03:45 -0700336
337def _PerformDrumroll(variation, robot, device_spec):
338 fingertips = [robot.fingertips[STANDARD_FINGERTIP],
339 robot.fingertips[STANDARD_SECONDARY_FINGERTIP]]
340 location = LOCATION_COORDINATES[tests.GV.CENTER]
341 robot.Drumroll(device_spec, fingertips, location)
Charlie Mooney030267f2016-02-05 15:34:26 -0800342
343def _PerformSquareResolutionTest(variation, robot, device_spec):
344 fingertip = robot.fingertips[STANDARD_FINGERTIP]
345 location = LOCATION_COORDINATES[tests.GV.CENTER]
346 robot.Draw45DegreeLineSegment(device_spec, [fingertip], location)