blob: 6f43b519692426dec1c64b38c75660d96239ee62 [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
158 elif test.name in ONE_FINGERTIP_TAP_TESTS:
159 fingertip = robot.fingertips[TAP_TEST_FINGERTIPS[test.name]]
Charlie Mooney587197f2015-06-05 15:35:02 -0700160 num_taps = 20 if test.name == tests.REPEATED_TAPS else 1
Charlie Mooney1777b372015-05-21 10:40:43 -0700161 vertical_offset = 0
162 if test.name != tests.ONE_FINGER_TAP:
163 vertical_offset = robot.LARGE_FINGERTIP_VERTICAL_OFFSET
Charlie Mooney587197f2015-06-05 15:35:02 -0700164 fn = lambda: _PerformOneFingertipTapTest(
165 variation, robot, device_spec, fingertip,
166 vertical_offset, num_taps)
167
Charlie Mooney4198adb2015-05-04 13:55:20 -0700168 elif test.name == tests.TWO_FINGER_TAP:
169 fn = lambda: _PerformTwoFingerTapTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700170
Charlie Mooneya5a5d3e2015-06-11 13:48:01 -0700171 elif test.name in PHYSICAL_CLICK_TESTS:
172 fingertips = [robot.fingertips[STANDARD_FINGERTIP]]
173 if test.name == tests.TWO_FINGER_PHYSICAL_CLICK:
174 fingertips.append(robot.fingertips[STANDARD_SECONDARY_FINGERTIP])
175 fn = lambda: _PerformPhysicalClickTest(variation, robot, device_spec,
176 fingertips)
177
Charlie Mooney9426d0c2015-07-01 15:03:45 -0700178 elif test.name == tests.DRUMROLL:
179 fn = lambda: _PerformDrumroll(variation, robot, device_spec)
180
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700181 elif test.name in SINGLE_FINGER_LINE_TESTS:
182 pause = 1 if test.name == tests.ONE_FINGER_TRACKING_FROM_CENTER else 0
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700183 is_swipe = (test.name == tests.ONE_FINGER_SWIPE)
184 fn = lambda: _PerformOneFingerLineTest(variation, robot, device_spec,
185 pause, is_swipe)
Charlie Mooney1777b372015-05-21 10:40:43 -0700186
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700187 elif test.name in TWO_FINGER_LINE_TESTS:
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700188 spacing = 5
189 fingertips = [robot.fingertips[STANDARD_FINGERTIP],
190 robot.fingertips[STANDARD_SECONDARY_FINGERTIP]]
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700191 is_swipe = (test.name == tests.TWO_FINGER_SWIPE)
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700192 if test.name == tests.TWO_CLOSE_FINGERS_TRACKING:
193 spacing = 0
194 elif test.name == tests.TWO_FAT_FINGERS_TRACKING:
195 spacing = 10
196 fingertips = [robot.fingertips[FAT_FINGERTIP],
197 robot.fingertips[FAT_SECONDARY_FINGERTIP]]
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700198 fn = lambda: _PerformTwoFingerLineTest(variation, robot, device_spec,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700199 fingertips, spacing, is_swipe)
Charlie Mooney1777b372015-05-21 10:40:43 -0700200
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700201 elif test.name == tests.RESTING_FINGER_PLUS_2ND_FINGER_MOVE:
Charlie Mooney9a177682015-06-16 15:24:36 -0700202 moving_fingertip = robot.fingertips[STANDARD_SECONDARY_FINGERTIP]
203 stationary_location = LOCATION_COORDINATES[tests.GV.BL]
204 fn = lambda: _PerformRestingFingerTest(variation, robot, device_spec,
205 moving_fingertip,
206 stationary_location)
207
208 elif test.name == tests.FAT_FINGER_MOVE_WITH_RESTING_FINGER:
209 moving_fingertip = robot.fingertips[FAT_SECONDARY_FINGERTIP]
210 direction, speed = variation
211 stationary_location = STATIONARY_FINGER_LOCATION[direction]
212 fn = lambda: _PerformRestingFingerTest(variation, robot, device_spec,
213 moving_fingertip,
214 stationary_location)
Charlie Mooney1777b372015-05-21 10:40:43 -0700215
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700216 elif test.name == tests.PINCH_TO_ZOOM:
217 fn = lambda: _PerformPinchTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700218
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700219 elif test.name == tests.DRAG_THUMB_EDGE:
220 fn = lambda: _PerformThumbEdgeTest(variation, robot, device_spec)
Charlie Mooney08661912015-04-16 09:20:34 -0700221
222 if fn is None:
Charlie Mooneyca3fc202015-05-21 11:16:53 -0700223 print color.Fore.RED + 'Robot unable to perform gesture! Skipping...'
Charlie Mooney08661912015-04-16 09:20:34 -0700224 return None
225
226 return Thread(target=fn)
227
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700228
Charlie Mooney08661912015-04-16 09:20:34 -0700229def _PerformStationaryNoiseTest(variation, robot, device_spec):
230 frequency, amplitude, waveform, location = variation
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700231 tap_position = LOCATION_COORDINATES[location]
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700232 fingertip = robot.fingertips[NOISE_TESTING_FINGERTIP]
Charlie Mooney4198adb2015-05-04 13:55:20 -0700233 robot.Tap(device_spec, [fingertip], tap_position, touch_time_s=4)
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700234
235
Charlie Mooney1777b372015-05-21 10:40:43 -0700236def _PerformOneFingertipTapTest(variation, robot, device_spec, fingertip,
Charlie Mooney587197f2015-06-05 15:35:02 -0700237 vertical_offset, num_taps):
Charlie Mooney1b708112015-04-28 14:46:21 -0700238 location, = variation
239 tap_position = LOCATION_COORDINATES[location]
Charlie Mooney1777b372015-05-21 10:40:43 -0700240 robot.Tap(device_spec, [fingertip], tap_position,
Charlie Mooney587197f2015-06-05 15:35:02 -0700241 vertical_offset=vertical_offset, num_taps=num_taps)
Charlie Mooney4198adb2015-05-04 13:55:20 -0700242
243
244def _PerformTwoFingerTapTest(variation, robot, device_spec):
245 angle, = variation
246
247 fingertip1 = robot.fingertips[STANDARD_FINGERTIP]
248 fingertip2 = robot.fingertips[STANDARD_SECONDARY_FINGERTIP]
249 fingertips = [fingertip1, fingertip2]
250
251 robot.Tap(device_spec, fingertips, (CENTER, CENTER), angle=ANGLES[angle])
Charlie Mooney1b708112015-04-28 14:46:21 -0700252
253
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700254def _PerformOneFingerLineTest(variation, robot, device_spec, pause_time_s,
255 is_swipe):
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700256 direction, speed = variation
257 start, end = LINE_DIRECTION_COORDINATES[direction]
258 fingertip = robot.fingertips[STANDARD_FINGERTIP]
259
260 robot.PushSpeed(SPEEDS[speed])
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700261 robot.Line(device_spec, [fingertip], start, end, pause_s=pause_time_s,
262 swipe=is_swipe)
Charlie Mooneya337d582015-04-29 10:37:45 -0700263 robot.PopSpeed()
264
265
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700266def _PerformTwoFingerLineTest(variation, robot, device_spec, fingertips,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700267 spacing_mm, is_swipe):
Charlie Mooneya337d582015-04-29 10:37:45 -0700268 direction, speed = variation
269 start, end = LINE_DIRECTION_COORDINATES[direction]
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700270 angle = _ComputePerpendicularAngle(start, end)
Charlie Mooneya337d582015-04-29 10:37:45 -0700271
Charlie Mooneya337d582015-04-29 10:37:45 -0700272 robot.PushSpeed(SPEEDS[speed])
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700273 robot.Line(device_spec, fingertips, start, end, fingertip_spacing=spacing_mm,
274 fingertip_angle=angle, swipe=is_swipe)
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700275 robot.PopSpeed()
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700276
277
Charlie Mooney9a177682015-06-16 15:24:36 -0700278def _PerformRestingFingerTest(variation, robot, device_spec, moving_fingertip,
279 stationary_location):
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700280 direction, speed = variation
281 start, end = LINE_DIRECTION_COORDINATES[direction]
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700282
283 stationary_fingertip = robot.fingertips[STANDARD_FINGERTIP]
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700284
285 robot.PushSpeed(SPEEDS[speed])
286 robot.LineWithStationaryFinger(device_spec, stationary_fingertip,
287 moving_fingertip, start, end,
288 stationary_location)
289 robot.PopSpeed()
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700290
291def _PerformPinchTest(variation, robot, device_spec):
292 direction, angle = variation
293
294 min_spread = 15
295 max_spread = min(device_spec.Height(), device_spec.Width(),
296 robot.MAX_FINGER_DISTANCE)
297 if direction == tests.GV.ZOOM_OUT:
298 start_distance, end_distance = max_spread, min_spread
299 else:
300 start_distance, end_distance = min_spread, max_spread
301
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700302 fingertips = [robot.fingertips[STANDARD_FINGERTIP],
303 robot.fingertips[STANDARD_SECONDARY_FINGERTIP]]
304
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700305 robot.PushSpeed(SPEEDS[tests.GV.NORMAL])
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700306 robot.Pinch(device_spec, fingertips, (CENTER, CENTER), ANGLES[angle],
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700307 start_distance, end_distance)
308 robot.PopSpeed()
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700309
310def _PerformThumbEdgeTest(variation, robot, device_spec):
311 fingertip_type, direction = variation
312 start, end = LINE_DIRECTION_COORDINATES[direction]
313 angle = _ComputePerpendicularAngle(start, end)
314
315 fingertip = robot.fingertips[fingertip_type]
316
317 robot.PushSpeed(SPEEDS[tests.GV.NORMAL])
318 robot.Line(device_spec, [fingertip], start, end, fingertip_angle=angle)
319 robot.PopSpeed()
Charlie Mooneya5a5d3e2015-06-11 13:48:01 -0700320
321def _PerformPhysicalClickTest(variation, robot, device_spec, fingertips):
322 location, = variation
323 click_position = LOCATION_COORDINATES[location]
324 robot.Click(device_spec, fingertips, click_position)
Charlie Mooney9426d0c2015-07-01 15:03:45 -0700325
326def _PerformDrumroll(variation, robot, device_spec):
327 fingertips = [robot.fingertips[STANDARD_FINGERTIP],
328 robot.fingertips[STANDARD_SECONDARY_FINGERTIP]]
329 location = LOCATION_COORDINATES[tests.GV.CENTER]
330 robot.Drumroll(device_spec, fingertips, location)