blob: 03a44e355a8a5758116ca0bf33b7bceda2536c7f [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,
85 tests.THREE_FINGER_TAP,
86 tests.FOUR_FINGER_TAP,
87 tests.FIVE_FINGER_TAP,
88]
89
90TAP_TEST_FINGERTIPS = {
91 tests.ONE_FINGER_TAP: STANDARD_FINGERTIP,
92 tests.THREE_FINGER_TAP: THREE_FINGER_FINGERTIP,
93 tests.FOUR_FINGER_TAP: FOUR_FINGER_FINGERTIP,
94 tests.FIVE_FINGER_TAP: FIVE_FINGER_FINGERTIP,
95}
Charlie Mooney5065bcb2015-05-04 13:18:09 -070096
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070097SINGLE_FINGER_LINE_TESTS = [
98 tests.ONE_FINGER_TO_EDGE,
99 tests.ONE_FINGER_TRACKING,
100 tests.ONE_FINGER_TRACKING_FROM_CENTER,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700101 tests.ONE_FINGER_SWIPE,
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700102]
103
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700104TWO_FINGER_LINE_TESTS = [
105 tests.TWO_FINGER_TRACKING,
106 tests.TWO_CLOSE_FINGERS_TRACKING,
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700107 tests.TWO_FAT_FINGERS_TRACKING,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700108 tests.TWO_FINGER_SWIPE,
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700109]
110
Charlie Mooney08661912015-04-16 09:20:34 -0700111
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700112def _ComputePerpendicularAngle(start, end):
113 """ Compute the fingertip angle to be perpendicular to the
114 movement direction.
115
116 The robot's X/Y axes are not in the same direction as the touch device's,
117 they are flipped.
118
119 DUT x ----> Robot y ---->
120 y x
121 | |
122 | |
123 \/ \/
124
125 As a result the angle is computed in the DUT space, but then must have
126 its sign flipped before being used in any commands to the robot or
127 everything will be wrong since it's a clockwise angle instead of counter-
128 clockwise.
129 """
130 x1, y1 = start
131 x2, y2 = end
132 dy = y2 - y1
133 dx = x2 - x1
134 return -1 * (math.degrees(math.atan2(y2 - y1, x2 - x1)) + 90)
135
136
Charlie Mooney08661912015-04-16 09:20:34 -0700137def PerformCorrespondingGesture(test, variation_number, robot, device_spec):
138 variation = test.variations[variation_number]
139 fn = None
Charlie Mooney1777b372015-05-21 10:40:43 -0700140
Charlie Mooney08661912015-04-16 09:20:34 -0700141 if test.name == tests.NOISE_STATIONARY:
142 fn = lambda: _PerformStationaryNoiseTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700143
144 elif test.name in ONE_FINGERTIP_TAP_TESTS:
145 fingertip = robot.fingertips[TAP_TEST_FINGERTIPS[test.name]]
146 vertical_offset = 0
147 if test.name != tests.ONE_FINGER_TAP:
148 vertical_offset = robot.LARGE_FINGERTIP_VERTICAL_OFFSET
149 fn = lambda: _PerformOneFingertipTapTest(variation, robot, device_spec,
150 fingertip, vertical_offset)
Charlie Mooney4198adb2015-05-04 13:55:20 -0700151 elif test.name == tests.TWO_FINGER_TAP:
152 fn = lambda: _PerformTwoFingerTapTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700153
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700154 elif test.name in SINGLE_FINGER_LINE_TESTS:
155 pause = 1 if test.name == tests.ONE_FINGER_TRACKING_FROM_CENTER else 0
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700156 is_swipe = (test.name == tests.ONE_FINGER_SWIPE)
157 fn = lambda: _PerformOneFingerLineTest(variation, robot, device_spec,
158 pause, is_swipe)
Charlie Mooney1777b372015-05-21 10:40:43 -0700159
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700160 elif test.name in TWO_FINGER_LINE_TESTS:
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700161 spacing = 5
162 fingertips = [robot.fingertips[STANDARD_FINGERTIP],
163 robot.fingertips[STANDARD_SECONDARY_FINGERTIP]]
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700164 is_swipe = (test.name == tests.TWO_FINGER_SWIPE)
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700165 if test.name == tests.TWO_CLOSE_FINGERS_TRACKING:
166 spacing = 0
167 elif test.name == tests.TWO_FAT_FINGERS_TRACKING:
168 spacing = 10
169 fingertips = [robot.fingertips[FAT_FINGERTIP],
170 robot.fingertips[FAT_SECONDARY_FINGERTIP]]
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700171 fn = lambda: _PerformTwoFingerLineTest(variation, robot, device_spec,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700172 fingertips, spacing, is_swipe)
Charlie Mooney1777b372015-05-21 10:40:43 -0700173
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700174 elif test.name == tests.RESTING_FINGER_PLUS_2ND_FINGER_MOVE:
175 fn = lambda: _PerformRestingFingerTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700176
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700177 elif test.name == tests.PINCH_TO_ZOOM:
178 fn = lambda: _PerformPinchTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700179
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700180 elif test.name == tests.DRAG_THUMB_EDGE:
181 fn = lambda: _PerformThumbEdgeTest(variation, robot, device_spec)
Charlie Mooney08661912015-04-16 09:20:34 -0700182
183 if fn is None:
Charlie Mooneyca3fc202015-05-21 11:16:53 -0700184 print color.Fore.RED + 'Robot unable to perform gesture! Skipping...'
Charlie Mooney08661912015-04-16 09:20:34 -0700185 return None
186
187 return Thread(target=fn)
188
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700189
Charlie Mooney08661912015-04-16 09:20:34 -0700190def _PerformStationaryNoiseTest(variation, robot, device_spec):
191 frequency, amplitude, waveform, location = variation
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700192 tap_position = LOCATION_COORDINATES[location]
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700193 fingertip = robot.fingertips[NOISE_TESTING_FINGERTIP]
Charlie Mooney4198adb2015-05-04 13:55:20 -0700194 robot.Tap(device_spec, [fingertip], tap_position, touch_time_s=4)
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700195
196
Charlie Mooney1777b372015-05-21 10:40:43 -0700197def _PerformOneFingertipTapTest(variation, robot, device_spec, fingertip,
198 vertical_offset):
Charlie Mooney1b708112015-04-28 14:46:21 -0700199 location, = variation
200 tap_position = LOCATION_COORDINATES[location]
Charlie Mooney1777b372015-05-21 10:40:43 -0700201 robot.Tap(device_spec, [fingertip], tap_position,
202 vertical_offset=vertical_offset)
Charlie Mooney4198adb2015-05-04 13:55:20 -0700203
204
205def _PerformTwoFingerTapTest(variation, robot, device_spec):
206 angle, = variation
207
208 fingertip1 = robot.fingertips[STANDARD_FINGERTIP]
209 fingertip2 = robot.fingertips[STANDARD_SECONDARY_FINGERTIP]
210 fingertips = [fingertip1, fingertip2]
211
212 robot.Tap(device_spec, fingertips, (CENTER, CENTER), angle=ANGLES[angle])
Charlie Mooney1b708112015-04-28 14:46:21 -0700213
214
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700215def _PerformOneFingerLineTest(variation, robot, device_spec, pause_time_s,
216 is_swipe):
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700217 direction, speed = variation
218 start, end = LINE_DIRECTION_COORDINATES[direction]
219 fingertip = robot.fingertips[STANDARD_FINGERTIP]
220
221 robot.PushSpeed(SPEEDS[speed])
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700222 robot.Line(device_spec, [fingertip], start, end, pause_s=pause_time_s,
223 swipe=is_swipe)
Charlie Mooneya337d582015-04-29 10:37:45 -0700224 robot.PopSpeed()
225
226
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700227def _PerformTwoFingerLineTest(variation, robot, device_spec, fingertips,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700228 spacing_mm, is_swipe):
Charlie Mooneya337d582015-04-29 10:37:45 -0700229 direction, speed = variation
230 start, end = LINE_DIRECTION_COORDINATES[direction]
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700231 angle = _ComputePerpendicularAngle(start, end)
Charlie Mooneya337d582015-04-29 10:37:45 -0700232
Charlie Mooneya337d582015-04-29 10:37:45 -0700233 robot.PushSpeed(SPEEDS[speed])
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700234 robot.Line(device_spec, fingertips, start, end, fingertip_spacing=spacing_mm,
235 fingertip_angle=angle, swipe=is_swipe)
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700236 robot.PopSpeed()
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700237
238
239def _PerformRestingFingerTest(variation, robot, device_spec):
240 direction, speed = variation
241 start, end = LINE_DIRECTION_COORDINATES[direction]
242 stationary_location = LOCATION_COORDINATES[tests.GV.BL]
243
244 stationary_fingertip = robot.fingertips[STANDARD_FINGERTIP]
245 moving_fingertip = robot.fingertips[STANDARD_SECONDARY_FINGERTIP]
246
247 robot.PushSpeed(SPEEDS[speed])
248 robot.LineWithStationaryFinger(device_spec, stationary_fingertip,
249 moving_fingertip, start, end,
250 stationary_location)
251 robot.PopSpeed()
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700252
253def _PerformPinchTest(variation, robot, device_spec):
254 direction, angle = variation
255
256 min_spread = 15
257 max_spread = min(device_spec.Height(), device_spec.Width(),
258 robot.MAX_FINGER_DISTANCE)
259 if direction == tests.GV.ZOOM_OUT:
260 start_distance, end_distance = max_spread, min_spread
261 else:
262 start_distance, end_distance = min_spread, max_spread
263
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700264 fingertips = [robot.fingertips[STANDARD_FINGERTIP],
265 robot.fingertips[STANDARD_SECONDARY_FINGERTIP]]
266
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700267 robot.PushSpeed(SPEEDS[tests.GV.NORMAL])
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700268 robot.Pinch(device_spec, fingertips, (CENTER, CENTER), ANGLES[angle],
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700269 start_distance, end_distance)
270 robot.PopSpeed()
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700271
272def _PerformThumbEdgeTest(variation, robot, device_spec):
273 fingertip_type, direction = variation
274 start, end = LINE_DIRECTION_COORDINATES[direction]
275 angle = _ComputePerpendicularAngle(start, end)
276
277 fingertip = robot.fingertips[fingertip_type]
278
279 robot.PushSpeed(SPEEDS[tests.GV.NORMAL])
280 robot.Line(device_spec, [fingertip], start, end, fingertip_angle=angle)
281 robot.PopSpeed()