blob: 10a1f9e9308ac52a720cd4f911f19ca895c4dafb [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 Mooney08661912015-04-16 09:20:34 -0700113
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700114def _ComputePerpendicularAngle(start, end):
115 """ Compute the fingertip angle to be perpendicular to the
116 movement direction.
117
118 The robot's X/Y axes are not in the same direction as the touch device's,
119 they are flipped.
120
121 DUT x ----> Robot y ---->
122 y x
123 | |
124 | |
125 \/ \/
126
127 As a result the angle is computed in the DUT space, but then must have
128 its sign flipped before being used in any commands to the robot or
129 everything will be wrong since it's a clockwise angle instead of counter-
130 clockwise.
131 """
132 x1, y1 = start
133 x2, y2 = end
134 dy = y2 - y1
135 dx = x2 - x1
136 return -1 * (math.degrees(math.atan2(y2 - y1, x2 - x1)) + 90)
137
138
Charlie Mooney08661912015-04-16 09:20:34 -0700139def PerformCorrespondingGesture(test, variation_number, robot, device_spec):
140 variation = test.variations[variation_number]
141 fn = None
Charlie Mooney1777b372015-05-21 10:40:43 -0700142
Charlie Mooney08661912015-04-16 09:20:34 -0700143 if test.name == tests.NOISE_STATIONARY:
144 fn = lambda: _PerformStationaryNoiseTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700145
146 elif test.name in ONE_FINGERTIP_TAP_TESTS:
147 fingertip = robot.fingertips[TAP_TEST_FINGERTIPS[test.name]]
Charlie Mooney587197f2015-06-05 15:35:02 -0700148 num_taps = 20 if test.name == tests.REPEATED_TAPS else 1
Charlie Mooney1777b372015-05-21 10:40:43 -0700149 vertical_offset = 0
150 if test.name != tests.ONE_FINGER_TAP:
151 vertical_offset = robot.LARGE_FINGERTIP_VERTICAL_OFFSET
Charlie Mooney587197f2015-06-05 15:35:02 -0700152 fn = lambda: _PerformOneFingertipTapTest(
153 variation, robot, device_spec, fingertip,
154 vertical_offset, num_taps)
155
Charlie Mooney4198adb2015-05-04 13:55:20 -0700156 elif test.name == tests.TWO_FINGER_TAP:
157 fn = lambda: _PerformTwoFingerTapTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700158
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700159 elif test.name in SINGLE_FINGER_LINE_TESTS:
160 pause = 1 if test.name == tests.ONE_FINGER_TRACKING_FROM_CENTER else 0
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700161 is_swipe = (test.name == tests.ONE_FINGER_SWIPE)
162 fn = lambda: _PerformOneFingerLineTest(variation, robot, device_spec,
163 pause, is_swipe)
Charlie Mooney1777b372015-05-21 10:40:43 -0700164
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700165 elif test.name in TWO_FINGER_LINE_TESTS:
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700166 spacing = 5
167 fingertips = [robot.fingertips[STANDARD_FINGERTIP],
168 robot.fingertips[STANDARD_SECONDARY_FINGERTIP]]
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700169 is_swipe = (test.name == tests.TWO_FINGER_SWIPE)
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700170 if test.name == tests.TWO_CLOSE_FINGERS_TRACKING:
171 spacing = 0
172 elif test.name == tests.TWO_FAT_FINGERS_TRACKING:
173 spacing = 10
174 fingertips = [robot.fingertips[FAT_FINGERTIP],
175 robot.fingertips[FAT_SECONDARY_FINGERTIP]]
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700176 fn = lambda: _PerformTwoFingerLineTest(variation, robot, device_spec,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700177 fingertips, spacing, is_swipe)
Charlie Mooney1777b372015-05-21 10:40:43 -0700178
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700179 elif test.name == tests.RESTING_FINGER_PLUS_2ND_FINGER_MOVE:
180 fn = lambda: _PerformRestingFingerTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700181
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700182 elif test.name == tests.PINCH_TO_ZOOM:
183 fn = lambda: _PerformPinchTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700184
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700185 elif test.name == tests.DRAG_THUMB_EDGE:
186 fn = lambda: _PerformThumbEdgeTest(variation, robot, device_spec)
Charlie Mooney08661912015-04-16 09:20:34 -0700187
188 if fn is None:
Charlie Mooneyca3fc202015-05-21 11:16:53 -0700189 print color.Fore.RED + 'Robot unable to perform gesture! Skipping...'
Charlie Mooney08661912015-04-16 09:20:34 -0700190 return None
191
192 return Thread(target=fn)
193
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700194
Charlie Mooney08661912015-04-16 09:20:34 -0700195def _PerformStationaryNoiseTest(variation, robot, device_spec):
196 frequency, amplitude, waveform, location = variation
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700197 tap_position = LOCATION_COORDINATES[location]
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700198 fingertip = robot.fingertips[NOISE_TESTING_FINGERTIP]
Charlie Mooney4198adb2015-05-04 13:55:20 -0700199 robot.Tap(device_spec, [fingertip], tap_position, touch_time_s=4)
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700200
201
Charlie Mooney1777b372015-05-21 10:40:43 -0700202def _PerformOneFingertipTapTest(variation, robot, device_spec, fingertip,
Charlie Mooney587197f2015-06-05 15:35:02 -0700203 vertical_offset, num_taps):
Charlie Mooney1b708112015-04-28 14:46:21 -0700204 location, = variation
205 tap_position = LOCATION_COORDINATES[location]
Charlie Mooney1777b372015-05-21 10:40:43 -0700206 robot.Tap(device_spec, [fingertip], tap_position,
Charlie Mooney587197f2015-06-05 15:35:02 -0700207 vertical_offset=vertical_offset, num_taps=num_taps)
Charlie Mooney4198adb2015-05-04 13:55:20 -0700208
209
210def _PerformTwoFingerTapTest(variation, robot, device_spec):
211 angle, = variation
212
213 fingertip1 = robot.fingertips[STANDARD_FINGERTIP]
214 fingertip2 = robot.fingertips[STANDARD_SECONDARY_FINGERTIP]
215 fingertips = [fingertip1, fingertip2]
216
217 robot.Tap(device_spec, fingertips, (CENTER, CENTER), angle=ANGLES[angle])
Charlie Mooney1b708112015-04-28 14:46:21 -0700218
219
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700220def _PerformOneFingerLineTest(variation, robot, device_spec, pause_time_s,
221 is_swipe):
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700222 direction, speed = variation
223 start, end = LINE_DIRECTION_COORDINATES[direction]
224 fingertip = robot.fingertips[STANDARD_FINGERTIP]
225
226 robot.PushSpeed(SPEEDS[speed])
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700227 robot.Line(device_spec, [fingertip], start, end, pause_s=pause_time_s,
228 swipe=is_swipe)
Charlie Mooneya337d582015-04-29 10:37:45 -0700229 robot.PopSpeed()
230
231
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700232def _PerformTwoFingerLineTest(variation, robot, device_spec, fingertips,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700233 spacing_mm, is_swipe):
Charlie Mooneya337d582015-04-29 10:37:45 -0700234 direction, speed = variation
235 start, end = LINE_DIRECTION_COORDINATES[direction]
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700236 angle = _ComputePerpendicularAngle(start, end)
Charlie Mooneya337d582015-04-29 10:37:45 -0700237
Charlie Mooneya337d582015-04-29 10:37:45 -0700238 robot.PushSpeed(SPEEDS[speed])
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700239 robot.Line(device_spec, fingertips, start, end, fingertip_spacing=spacing_mm,
240 fingertip_angle=angle, swipe=is_swipe)
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700241 robot.PopSpeed()
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700242
243
244def _PerformRestingFingerTest(variation, robot, device_spec):
245 direction, speed = variation
246 start, end = LINE_DIRECTION_COORDINATES[direction]
247 stationary_location = LOCATION_COORDINATES[tests.GV.BL]
248
249 stationary_fingertip = robot.fingertips[STANDARD_FINGERTIP]
250 moving_fingertip = robot.fingertips[STANDARD_SECONDARY_FINGERTIP]
251
252 robot.PushSpeed(SPEEDS[speed])
253 robot.LineWithStationaryFinger(device_spec, stationary_fingertip,
254 moving_fingertip, start, end,
255 stationary_location)
256 robot.PopSpeed()
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700257
258def _PerformPinchTest(variation, robot, device_spec):
259 direction, angle = variation
260
261 min_spread = 15
262 max_spread = min(device_spec.Height(), device_spec.Width(),
263 robot.MAX_FINGER_DISTANCE)
264 if direction == tests.GV.ZOOM_OUT:
265 start_distance, end_distance = max_spread, min_spread
266 else:
267 start_distance, end_distance = min_spread, max_spread
268
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700269 fingertips = [robot.fingertips[STANDARD_FINGERTIP],
270 robot.fingertips[STANDARD_SECONDARY_FINGERTIP]]
271
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700272 robot.PushSpeed(SPEEDS[tests.GV.NORMAL])
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700273 robot.Pinch(device_spec, fingertips, (CENTER, CENTER), ANGLES[angle],
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700274 start_distance, end_distance)
275 robot.PopSpeed()
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700276
277def _PerformThumbEdgeTest(variation, robot, device_spec):
278 fingertip_type, direction = variation
279 start, end = LINE_DIRECTION_COORDINATES[direction]
280 angle = _ComputePerpendicularAngle(start, end)
281
282 fingertip = robot.fingertips[fingertip_type]
283
284 robot.PushSpeed(SPEEDS[tests.GV.NORMAL])
285 robot.Line(device_spec, [fingertip], start, end, fingertip_angle=angle)
286 robot.PopSpeed()