blob: 0e6faa88870e7493b2457c959aa3fa0fd54403f7 [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
71SPEEDS = {
72 tests.GV.NORMAL: Touchbot.SPEED_MEDIUM,
73 tests.GV.SLOW: Touchbot.SPEED_SLOW,
Charlie Mooneybe4661e2015-05-20 11:46:43 -070074 tests.GV.FAST: Touchbot.SPEED_FAST,
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070075}
76
Charlie Mooney4198adb2015-05-04 13:55:20 -070077ANGLES = {
Charlie Mooney5065bcb2015-05-04 13:18:09 -070078 tests.GV.HORIZONTAL: 0,
79 tests.GV.VERTICAL: 90,
80 tests.GV.DIAGONAL: 45,
81}
82
Charlie Mooney1777b372015-05-21 10:40:43 -070083ONE_FINGERTIP_TAP_TESTS = [
84 tests.ONE_FINGER_TAP,
Charlie Mooney587197f2015-06-05 15:35:02 -070085 tests.REPEATED_TAPS,
Charlie Mooney1777b372015-05-21 10:40:43 -070086 tests.THREE_FINGER_TAP,
87 tests.FOUR_FINGER_TAP,
88 tests.FIVE_FINGER_TAP,
89]
90
91TAP_TEST_FINGERTIPS = {
92 tests.ONE_FINGER_TAP: STANDARD_FINGERTIP,
Charlie Mooney587197f2015-06-05 15:35:02 -070093 tests.REPEATED_TAPS: STANDARD_FINGERTIP,
Charlie Mooney1777b372015-05-21 10:40:43 -070094 tests.THREE_FINGER_TAP: THREE_FINGER_FINGERTIP,
95 tests.FOUR_FINGER_TAP: FOUR_FINGER_FINGERTIP,
96 tests.FIVE_FINGER_TAP: FIVE_FINGER_FINGERTIP,
97}
Charlie Mooney5065bcb2015-05-04 13:18:09 -070098
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070099SINGLE_FINGER_LINE_TESTS = [
100 tests.ONE_FINGER_TO_EDGE,
101 tests.ONE_FINGER_TRACKING,
102 tests.ONE_FINGER_TRACKING_FROM_CENTER,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700103 tests.ONE_FINGER_SWIPE,
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700104]
105
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700106TWO_FINGER_LINE_TESTS = [
107 tests.TWO_FINGER_TRACKING,
108 tests.TWO_CLOSE_FINGERS_TRACKING,
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700109 tests.TWO_FAT_FINGERS_TRACKING,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700110 tests.TWO_FINGER_SWIPE,
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700111]
112
Charlie Mooneya5a5d3e2015-06-11 13:48:01 -0700113PHYSICAL_CLICK_TESTS = [
114 tests.ONE_FINGER_PHYSICAL_CLICK,
115 tests.TWO_FINGER_PHYSICAL_CLICK,
116]
117
Charlie Mooney08661912015-04-16 09:20:34 -0700118
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700119def _ComputePerpendicularAngle(start, end):
120 """ Compute the fingertip angle to be perpendicular to the
121 movement direction.
122
123 The robot's X/Y axes are not in the same direction as the touch device's,
124 they are flipped.
125
126 DUT x ----> Robot y ---->
127 y x
128 | |
129 | |
130 \/ \/
131
132 As a result the angle is computed in the DUT space, but then must have
133 its sign flipped before being used in any commands to the robot or
134 everything will be wrong since it's a clockwise angle instead of counter-
135 clockwise.
136 """
137 x1, y1 = start
138 x2, y2 = end
139 dy = y2 - y1
140 dx = x2 - x1
141 return -1 * (math.degrees(math.atan2(y2 - y1, x2 - x1)) + 90)
142
143
Charlie Mooney08661912015-04-16 09:20:34 -0700144def PerformCorrespondingGesture(test, variation_number, robot, device_spec):
145 variation = test.variations[variation_number]
146 fn = None
Charlie Mooney1777b372015-05-21 10:40:43 -0700147
Charlie Mooney08661912015-04-16 09:20:34 -0700148 if test.name == tests.NOISE_STATIONARY:
149 fn = lambda: _PerformStationaryNoiseTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700150
151 elif test.name in ONE_FINGERTIP_TAP_TESTS:
152 fingertip = robot.fingertips[TAP_TEST_FINGERTIPS[test.name]]
Charlie Mooney587197f2015-06-05 15:35:02 -0700153 num_taps = 20 if test.name == tests.REPEATED_TAPS else 1
Charlie Mooney1777b372015-05-21 10:40:43 -0700154 vertical_offset = 0
155 if test.name != tests.ONE_FINGER_TAP:
156 vertical_offset = robot.LARGE_FINGERTIP_VERTICAL_OFFSET
Charlie Mooney587197f2015-06-05 15:35:02 -0700157 fn = lambda: _PerformOneFingertipTapTest(
158 variation, robot, device_spec, fingertip,
159 vertical_offset, num_taps)
160
Charlie Mooney4198adb2015-05-04 13:55:20 -0700161 elif test.name == tests.TWO_FINGER_TAP:
162 fn = lambda: _PerformTwoFingerTapTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700163
Charlie Mooneya5a5d3e2015-06-11 13:48:01 -0700164 elif test.name in PHYSICAL_CLICK_TESTS:
165 fingertips = [robot.fingertips[STANDARD_FINGERTIP]]
166 if test.name == tests.TWO_FINGER_PHYSICAL_CLICK:
167 fingertips.append(robot.fingertips[STANDARD_SECONDARY_FINGERTIP])
168 fn = lambda: _PerformPhysicalClickTest(variation, robot, device_spec,
169 fingertips)
170
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700171 elif test.name in SINGLE_FINGER_LINE_TESTS:
172 pause = 1 if test.name == tests.ONE_FINGER_TRACKING_FROM_CENTER else 0
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700173 is_swipe = (test.name == tests.ONE_FINGER_SWIPE)
174 fn = lambda: _PerformOneFingerLineTest(variation, robot, device_spec,
175 pause, is_swipe)
Charlie Mooney1777b372015-05-21 10:40:43 -0700176
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700177 elif test.name in TWO_FINGER_LINE_TESTS:
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700178 spacing = 5
179 fingertips = [robot.fingertips[STANDARD_FINGERTIP],
180 robot.fingertips[STANDARD_SECONDARY_FINGERTIP]]
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700181 is_swipe = (test.name == tests.TWO_FINGER_SWIPE)
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700182 if test.name == tests.TWO_CLOSE_FINGERS_TRACKING:
183 spacing = 0
184 elif test.name == tests.TWO_FAT_FINGERS_TRACKING:
185 spacing = 10
186 fingertips = [robot.fingertips[FAT_FINGERTIP],
187 robot.fingertips[FAT_SECONDARY_FINGERTIP]]
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700188 fn = lambda: _PerformTwoFingerLineTest(variation, robot, device_spec,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700189 fingertips, spacing, is_swipe)
Charlie Mooney1777b372015-05-21 10:40:43 -0700190
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700191 elif test.name == tests.RESTING_FINGER_PLUS_2ND_FINGER_MOVE:
192 fn = lambda: _PerformRestingFingerTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700193
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700194 elif test.name == tests.PINCH_TO_ZOOM:
195 fn = lambda: _PerformPinchTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700196
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700197 elif test.name == tests.DRAG_THUMB_EDGE:
198 fn = lambda: _PerformThumbEdgeTest(variation, robot, device_spec)
Charlie Mooney08661912015-04-16 09:20:34 -0700199
200 if fn is None:
Charlie Mooneyca3fc202015-05-21 11:16:53 -0700201 print color.Fore.RED + 'Robot unable to perform gesture! Skipping...'
Charlie Mooney08661912015-04-16 09:20:34 -0700202 return None
203
204 return Thread(target=fn)
205
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700206
Charlie Mooney08661912015-04-16 09:20:34 -0700207def _PerformStationaryNoiseTest(variation, robot, device_spec):
208 frequency, amplitude, waveform, location = variation
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700209 tap_position = LOCATION_COORDINATES[location]
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700210 fingertip = robot.fingertips[NOISE_TESTING_FINGERTIP]
Charlie Mooney4198adb2015-05-04 13:55:20 -0700211 robot.Tap(device_spec, [fingertip], tap_position, touch_time_s=4)
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700212
213
Charlie Mooney1777b372015-05-21 10:40:43 -0700214def _PerformOneFingertipTapTest(variation, robot, device_spec, fingertip,
Charlie Mooney587197f2015-06-05 15:35:02 -0700215 vertical_offset, num_taps):
Charlie Mooney1b708112015-04-28 14:46:21 -0700216 location, = variation
217 tap_position = LOCATION_COORDINATES[location]
Charlie Mooney1777b372015-05-21 10:40:43 -0700218 robot.Tap(device_spec, [fingertip], tap_position,
Charlie Mooney587197f2015-06-05 15:35:02 -0700219 vertical_offset=vertical_offset, num_taps=num_taps)
Charlie Mooney4198adb2015-05-04 13:55:20 -0700220
221
222def _PerformTwoFingerTapTest(variation, robot, device_spec):
223 angle, = variation
224
225 fingertip1 = robot.fingertips[STANDARD_FINGERTIP]
226 fingertip2 = robot.fingertips[STANDARD_SECONDARY_FINGERTIP]
227 fingertips = [fingertip1, fingertip2]
228
229 robot.Tap(device_spec, fingertips, (CENTER, CENTER), angle=ANGLES[angle])
Charlie Mooney1b708112015-04-28 14:46:21 -0700230
231
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700232def _PerformOneFingerLineTest(variation, robot, device_spec, pause_time_s,
233 is_swipe):
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700234 direction, speed = variation
235 start, end = LINE_DIRECTION_COORDINATES[direction]
236 fingertip = robot.fingertips[STANDARD_FINGERTIP]
237
238 robot.PushSpeed(SPEEDS[speed])
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700239 robot.Line(device_spec, [fingertip], start, end, pause_s=pause_time_s,
240 swipe=is_swipe)
Charlie Mooneya337d582015-04-29 10:37:45 -0700241 robot.PopSpeed()
242
243
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700244def _PerformTwoFingerLineTest(variation, robot, device_spec, fingertips,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700245 spacing_mm, is_swipe):
Charlie Mooneya337d582015-04-29 10:37:45 -0700246 direction, speed = variation
247 start, end = LINE_DIRECTION_COORDINATES[direction]
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700248 angle = _ComputePerpendicularAngle(start, end)
Charlie Mooneya337d582015-04-29 10:37:45 -0700249
Charlie Mooneya337d582015-04-29 10:37:45 -0700250 robot.PushSpeed(SPEEDS[speed])
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700251 robot.Line(device_spec, fingertips, start, end, fingertip_spacing=spacing_mm,
252 fingertip_angle=angle, swipe=is_swipe)
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700253 robot.PopSpeed()
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700254
255
256def _PerformRestingFingerTest(variation, robot, device_spec):
257 direction, speed = variation
258 start, end = LINE_DIRECTION_COORDINATES[direction]
259 stationary_location = LOCATION_COORDINATES[tests.GV.BL]
260
261 stationary_fingertip = robot.fingertips[STANDARD_FINGERTIP]
262 moving_fingertip = robot.fingertips[STANDARD_SECONDARY_FINGERTIP]
263
264 robot.PushSpeed(SPEEDS[speed])
265 robot.LineWithStationaryFinger(device_spec, stationary_fingertip,
266 moving_fingertip, start, end,
267 stationary_location)
268 robot.PopSpeed()
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700269
270def _PerformPinchTest(variation, robot, device_spec):
271 direction, angle = variation
272
273 min_spread = 15
274 max_spread = min(device_spec.Height(), device_spec.Width(),
275 robot.MAX_FINGER_DISTANCE)
276 if direction == tests.GV.ZOOM_OUT:
277 start_distance, end_distance = max_spread, min_spread
278 else:
279 start_distance, end_distance = min_spread, max_spread
280
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700281 fingertips = [robot.fingertips[STANDARD_FINGERTIP],
282 robot.fingertips[STANDARD_SECONDARY_FINGERTIP]]
283
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700284 robot.PushSpeed(SPEEDS[tests.GV.NORMAL])
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700285 robot.Pinch(device_spec, fingertips, (CENTER, CENTER), ANGLES[angle],
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700286 start_distance, end_distance)
287 robot.PopSpeed()
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700288
289def _PerformThumbEdgeTest(variation, robot, device_spec):
290 fingertip_type, direction = variation
291 start, end = LINE_DIRECTION_COORDINATES[direction]
292 angle = _ComputePerpendicularAngle(start, end)
293
294 fingertip = robot.fingertips[fingertip_type]
295
296 robot.PushSpeed(SPEEDS[tests.GV.NORMAL])
297 robot.Line(device_spec, [fingertip], start, end, fingertip_angle=angle)
298 robot.PopSpeed()
Charlie Mooneya5a5d3e2015-06-11 13:48:01 -0700299
300def _PerformPhysicalClickTest(variation, robot, device_spec, fingertips):
301 location, = variation
302 click_position = LOCATION_COORDINATES[location]
303 robot.Click(device_spec, fingertips, click_position)