1 # -*- coding: utf-8 -*- 2 # 3 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 4 # Use of this source code is governed by a BSD-style license that can be 5 # found in the LICENSE file. 6 7 """This configuration file defines the gestures to perform.""" 8 9 from collections import defaultdict 10 from firmware_constants import DEV, GV, VAL 11 from validators import (CountPacketsValidator, 12 CountTrackingIDNormalFingerValidator, 13 CountTrackingIDFatFingerValidator, 14 DragLatencyValidator, 15 DiscardInitialSecondsValidator, 16 DrumrollValidator, 17 HysteresisValidator, 18 LinearityFatFingerValidator, 19 LinearityNormalFingerValidator, 20 MtbSanityValidator, 21 NoGapValidator, 22 NoReversedMotionValidator, 23 PhysicalClickValidator, 24 PinchValidator, 25 RangeValidator, 26 ReportRateValidator, 27 StationaryValidator, 28 StationaryFingerValidator, 29 StationaryTapValidator, 30 ) 31 32 33 # Define which score aggregator is to be used. A score aggregator collects 34 # the scores from every tests and calculates the final score for the touch 35 # firmware test suite. 36 score_aggregator = 'fuzzy.average' 37 38 39 # Define some common criteria 40 count_packets_criteria = '>= 3, ~ -3' 41 drumroll_criteria = '<= 2.0' 42 # linearity_criteria is used for strictly straight line drawn with a ruler. 43 linearity_criteria = '<= 0.8, ~ +2.4' 44 # relaxed_linearity_criteria is used for lines drawn with thumb edge or 45 # fat fingers which are allowed to be curvy to some extent. 46 relaxed_linearity_criteria = '<= 1.5, ~ +3.0' 47 no_gap_criteria = '<= 1.8, ~ +1.0' 48 no_level_jump_criteria = '<= 10, ~ +30' 49 no_reversed_motion_criteria = '<= 5, ~ +30' 50 pinch_criteria = '>= 200, ~ -100' 51 range_criteria = '<= 0.01, ~ +0.07' 52 min_report_rate = 60 53 max_report_interval = 1.0 / min_report_rate * 1000 54 report_rate_criteria = '>= %d' % min_report_rate 55 stationary_finger_criteria = '<= 1.0' 56 stationary_tap_criteria = '<= 1.0' 57 hysteresis_criteria = '<= 2.0' 58 drag_latency_criteria = '<= 28.0' 59 60 MIN_MOVING_DISTANCE = 20 61 62 63 # Define filenames and paths 64 docroot = '/tmp' 65 report_basename = 'touch_firmware_report' 66 html_ext = '.html' 67 ENVIRONMENT_REPORT_HTML_NAME = 'REPORT_HTML_NAME' 68 log_root_dir = '/var/tmp/touch_firmware_test' 69 fw_prefix = 'fw_' 70 device_description_dir = 'tests/device' 71 version_filename = '.version' 72 73 74 # Define parameters for GUI 75 score_colors = ((0.9, 'blue'), (0.8, 'orange'), (0.0, 'red')) 76 num_chars_per_row = 28 77 78 79 # Define the validators that are shown only when there are failures. 80 validators_hidden_when_no_failures = ['PinchValidator', 81 'CountTrackingIDNormalFingerValidator', 82 'CountTrackingIDFatFingerValidator', 83 'CountPacketsValidator'] 84 85 86 # Define the parent validators from which the derived validators should be 87 # merged in the top-level summary table. 88 merged_validators = [StationaryValidator,] 89 90 91 # Define the path to find the robot gestures library path 92 robot_lib_path_local = '/usr/local/lib*' 93 robot_lib_path = '/usr/lib*' 94 python_package = 'python*\.*' 95 gestures_sub_path = 'site-packages/touchbotII' 96 97 98 # Define the gesture names 99 NOISE_LINE = 'noise_line' 100 NOISE_STATIONARY = 'noise_stationary' 101 NOISE_STATIONARY_EXTENDED = 'noise_stationary_extended' 102 ONE_FINGER_TRACKING = 'one_finger_tracking' 103 ONE_FINGER_TO_EDGE = 'one_finger_to_edge' 104 TWO_FINGER_TRACKING = 'two_finger_tracking' 105 FINGER_CROSSING = 'finger_crossing' 106 ONE_FINGER_SWIPE = 'one_finger_swipe' 107 TWO_FINGER_SWIPE = 'two_finger_swipe' 108 PINCH_TO_ZOOM = 'pinch_to_zoom' 109 ONE_FINGER_TAP = 'one_finger_tap' 110 TWO_FINGER_TAP = 'two_finger_tap' 111 ONE_FINGER_PHYSICAL_CLICK = 'one_finger_physical_click' 112 TWO_FINGER_PHYSICAL_CLICK = 'two_fingers_physical_click' 113 THREE_FINGER_PHYSICAL_CLICK = 'three_fingers_physical_click' 114 FOUR_FINGER_PHYSICAL_CLICK = 'four_fingers_physical_click' 115 FIVE_FINGER_PHYSICAL_CLICK = 'five_fingers_physical_click' 116 STATIONARY_FINGER_NOT_AFFECTED_BY_2ND_FINGER_TAPS = \ 117 'stationary_finger_not_affected_by_2nd_finger_taps' 118 FAT_FINGER_MOVE_WITH_RESTING_FINGER = 'fat_finger_move_with_resting_finger' 119 DRAG_EDGE_THUMB = 'drag_edge_thumb' 120 TWO_CLOSE_FINGERS_TRACKING = 'two_close_fingers_tracking' 121 RESTING_FINGER_PLUS_2ND_FINGER_MOVE = 'resting_finger_plus_2nd_finger_move' 122 TWO_FAT_FINGERS_TRACKING = 'two_fat_fingers_tracking' 123 FIRST_FINGER_TRACKING_AND_SECOND_FINGER_TAPS = \ 124 'first_finger_tracking_and_second_finger_taps' 125 DRUMROLL = 'drumroll' 126 RAPID_TAPS = 'rapid_taps_20' 127 ONE_FINGER_TRACKING_FROM_CENTER = 'one_finger_tracking_from_center' 128 DRAG_LATENCY = 'drag_latency' 129 # This following gesture is for pressure calibration. 130 PRESSURE_CALIBRATION = 'pressure_calibration' 131 132 # The gaps in MM required between fingertips for these tests 133 FINGER_CROSSING_GAP_MM = 1 134 FAT_FINGER_AND_STATIONARY_FINGER_GAP_MM = 1 135 136 # This denotes the list of the numbers of fingers for physical click tests. 137 # It corresponds to ONE/TWO/THREE/FOUR/FIVE_FINGER_PHYSICAL_CLICK defined above. 138 fingers_physical_click = [1, 2, 3, 4, 5] 139 140 141 # Define the complete list 142 gesture_names_complete = { 143 DEV.TOUCHPAD: [ 144 NOISE_LINE, 145 NOISE_STATIONARY, 146 ONE_FINGER_TRACKING, 147 ONE_FINGER_TO_EDGE, 148 TWO_FINGER_TRACKING, 149 FINGER_CROSSING, 150 ONE_FINGER_SWIPE, 151 ONE_FINGER_TRACKING_FROM_CENTER, 152 TWO_FINGER_SWIPE, 153 PINCH_TO_ZOOM, 154 ONE_FINGER_TAP, 155 TWO_FINGER_TAP, 156 ONE_FINGER_PHYSICAL_CLICK, 157 TWO_FINGER_PHYSICAL_CLICK, 158 THREE_FINGER_PHYSICAL_CLICK, 159 FOUR_FINGER_PHYSICAL_CLICK, 160 FIVE_FINGER_PHYSICAL_CLICK, 161 STATIONARY_FINGER_NOT_AFFECTED_BY_2ND_FINGER_TAPS, 162 FAT_FINGER_MOVE_WITH_RESTING_FINGER, 163 DRAG_EDGE_THUMB, 164 TWO_CLOSE_FINGERS_TRACKING, 165 RESTING_FINGER_PLUS_2ND_FINGER_MOVE, 166 TWO_FAT_FINGERS_TRACKING, 167 FIRST_FINGER_TRACKING_AND_SECOND_FINGER_TAPS, 168 DRUMROLL, 169 RAPID_TAPS, 170 DRAG_LATENCY, 171 ], 172 DEV.TOUCHSCREEN: [ 173 NOISE_LINE, 174 NOISE_STATIONARY, 175 ONE_FINGER_TRACKING, 176 ONE_FINGER_TO_EDGE, 177 TWO_FINGER_TRACKING, 178 FINGER_CROSSING, 179 ONE_FINGER_SWIPE, 180 ONE_FINGER_TRACKING_FROM_CENTER, 181 TWO_FINGER_SWIPE, 182 PINCH_TO_ZOOM, 183 ONE_FINGER_TAP, 184 TWO_FINGER_TAP, 185 STATIONARY_FINGER_NOT_AFFECTED_BY_2ND_FINGER_TAPS, 186 FAT_FINGER_MOVE_WITH_RESTING_FINGER, 187 DRAG_EDGE_THUMB, 188 TWO_CLOSE_FINGERS_TRACKING, 189 RESTING_FINGER_PLUS_2ND_FINGER_MOVE, 190 TWO_FAT_FINGERS_TRACKING, 191 FIRST_FINGER_TRACKING_AND_SECOND_FINGER_TAPS, 192 DRUMROLL, 193 RAPID_TAPS, 194 DRAG_LATENCY, 195 ], 196 } 197 198 199 # Define what gestures the robot can perform. 200 # This also defines the order for the robot to perform the gestures. 201 # Basically, two-fingers gestures follow one-finger gestures. 202 robot_capability_list = [ 203 NOISE_LINE, 204 NOISE_STATIONARY, 205 ONE_FINGER_TRACKING, 206 ONE_FINGER_TO_EDGE, 207 ONE_FINGER_SWIPE, 208 ONE_FINGER_TRACKING_FROM_CENTER, 209 ONE_FINGER_TAP, 210 RAPID_TAPS, 211 TWO_FINGER_TRACKING, 212 TWO_CLOSE_FINGERS_TRACKING, 213 TWO_FINGER_SWIPE, 214 TWO_FINGER_TAP, 215 STATIONARY_FINGER_NOT_AFFECTED_BY_2ND_FINGER_TAPS, 216 FIRST_FINGER_TRACKING_AND_SECOND_FINGER_TAPS, 217 RESTING_FINGER_PLUS_2ND_FINGER_MOVE, 218 FINGER_CROSSING, 219 PINCH_TO_ZOOM, 220 DRUMROLL, 221 TWO_FAT_FINGERS_TRACKING, 222 FAT_FINGER_MOVE_WITH_RESTING_FINGER, 223 ONE_FINGER_PHYSICAL_CLICK, 224 TWO_FINGER_PHYSICAL_CLICK, 225 THREE_FINGER_PHYSICAL_CLICK, 226 FOUR_FINGER_PHYSICAL_CLICK, 227 ] 228 229 NO_FINGER = None 230 TINY_FINGER = 0 231 NORMAL_FINGER = 1 232 LARGE_FINGER = 2 233 FAT_FINGER = 3 234 ALL_FINGERTIP_SIZES = [TINY_FINGER, NORMAL_FINGER, LARGE_FINGER, FAT_FINGER] 235 FINGERTIP_DIAMETER_MM = {TINY_FINGER: 8, NORMAL_FINGER: 10, 236 LARGE_FINGER: 12, FAT_FINGER: 14} 237 238 custom_tips_required = { 239 DRAG_LATENCY: [NO_FINGER, NO_FINGER, FAT_FINGER, NO_FINGER], 240 ONE_FINGER_PHYSICAL_CLICK: [NORMAL_FINGER, NO_FINGER, NO_FINGER, NO_FINGER], 241 TWO_FINGER_PHYSICAL_CLICK: [NO_FINGER, NORMAL_FINGER, NO_FINGER, 242 NORMAL_FINGER], 243 THREE_FINGER_PHYSICAL_CLICK: [NO_FINGER, NORMAL_FINGER, NORMAL_FINGER, 244 NORMAL_FINGER], 245 TWO_FAT_FINGERS_TRACKING: [FAT_FINGER, FAT_FINGER, FAT_FINGER, FAT_FINGER], 246 FAT_FINGER_MOVE_WITH_RESTING_FINGER: [NORMAL_FINGER, NO_FINGER, 247 FAT_FINGER, NO_FINGER], 248 FINGER_CROSSING: [NORMAL_FINGER, NO_FINGER, NORMAL_FINGER, NO_FINGER], 249 NOISE_LINE: [NO_FINGER, NORMAL_FINGER, NO_FINGER, NO_FINGER], 250 NOISE_STATIONARY: [NORMAL_FINGER, NO_FINGER, NO_FINGER, NO_FINGER], 251 NOISE_STATIONARY_EXTENDED: [NORMAL_FINGER, NO_FINGER, NO_FINGER, NO_FINGER], 252 } 253 default_tips_required = [NORMAL_FINGER, NORMAL_FINGER, 254 NORMAL_FINGER, NORMAL_FINGER] 255 finger_tips_required = defaultdict(lambda:default_tips_required, 256 custom_tips_required) 257 258 def get_gesture_names_for_robot(device): 259 """Get the gesture names that a robot can do for a specified device.""" 260 return [gesture for gesture in robot_capability_list 261 if gesture in gesture_names_complete[device]] 262 263 264 # Define the list of one-finger and two-finger gestures to test using the robot. 265 gesture_names_robot = { 266 DEV.TOUCHPAD: get_gesture_names_for_robot(DEV.TOUCHPAD), 267 DEV.TOUCHSCREEN: get_gesture_names_for_robot(DEV.TOUCHSCREEN), 268 } 269 270 gesture_names_quickstep = [DRAG_LATENCY] 271 272 # Define the list of gestures that require a function generator to run 273 gesture_names_fngenerator_required = [NOISE_LINE, NOISE_STATIONARY, 274 NOISE_STATIONARY_EXTENDED] 275 276 # Define the list of gestures to test in NOISE mode. 277 gesture_names_noise_extended = [NOISE_STATIONARY_EXTENDED] 278 279 280 # Define the gesture for pressure calibration 281 gesture_names_calibration = [PRESSURE_CALIBRATION,] 282 283 # Define the relative segment weights of a validator. 284 # For example, LinearityMiddleValidator : LinearityBothEndsValidator = 7 : 3 285 segment_weights = {VAL.BEGIN: 0.15, 286 VAL.MIDDLE: 0.7, 287 VAL.END: 0.15, 288 VAL.BOTH_ENDS: 0.15 + 0.15, 289 VAL.WHOLE: 0.15 + 0.7 + 0.15, 290 } 291 292 293 # Define the validator score weights 294 weight_rare = 1 295 weight_common = 2 296 weight_critical = 3 297 validator_weights = {'CountPacketsValidator': weight_common, 298 'CountTrackingIDNormalFingerValidator': weight_critical, 299 'CountTrackingIDFatFingerValidator': weight_rare, 300 'DragLatencyValidator': weight_critical, 301 'DrumrollValidator': weight_rare, 302 'LinearityNormalFingerValidator': weight_common, 303 'LinearityFatFingerValidator': weight_rare, 304 'MtbSanityValidator': weight_critical, 305 'NoGapValidator': weight_common, 306 'NoReversedMotionValidator': weight_common, 307 'PhysicalClickValidator': weight_critical, 308 'PinchValidator': weight_common, 309 'RangeValidator': weight_common, 310 'ReportRateValidator': weight_common, 311 'HysteresisValidator': weight_common, 312 'StationaryFingerValidator': weight_common, 313 'StationaryTapValidator': weight_common, 314 } 315 316 317 # Define the gesture list that the user needs to perform in the test suite. 318 def get_gesture_dict(): 319 """Define the dictionary for all gestures.""" 320 gesture_dict = { 321 NOISE_STATIONARY: 322 Gesture( 323 name=NOISE_STATIONARY, 324 variations=((GV.LOW_FREQUENCY, GV.MED_FREQUENCY, GV.HIGH_FREQUENCY), 325 (GV.HALF_AMPLITUDE, GV.MAX_AMPLITUDE), 326 (GV.SQUARE_WAVE,), 327 (GV.TL, GV.TR, GV.BL, GV.BR, GV.TS, GV.BS, GV.LS, GV.RS, 328 GV.CENTER), 329 ), 330 prompt='Hold one finger on the {3} of the touch surface with a ' 331 '{0} {1} {2} in noise.', 332 subprompt={ 333 GV.TL: ('top left corner',), 334 GV.TR: ('top right corner',), 335 GV.BL: ('bottom left corner',), 336 GV.BR: ('bottom right corner',), 337 GV.TS: ('top edge',), 338 GV.BS: ('bottom side',), 339 GV.LS: ('left hand side',), 340 GV.RS: ('right hand side',), 341 GV.CENTER: ('center',), 342 GV.LOW_FREQUENCY: ('5kHz',), 343 GV.MED_FREQUENCY: ('500kHz',), 344 GV.HIGH_FREQUENCY: ('1MHz',), 345 GV.HALF_AMPLITUDE: ('10Vpp',), 346 GV.MAX_AMPLITUDE: ('20Vpp',), 347 GV.SQUARE_WAVE: ('square wave',), 348 }, 349 validators=( 350 DiscardInitialSecondsValidator( 351 CountTrackingIDNormalFingerValidator('== 1')), 352 DiscardInitialSecondsValidator( 353 StationaryTapValidator(stationary_tap_criteria, slot=0)), 354 ), 355 ), 356 NOISE_LINE: 357 Gesture( 358 name=NOISE_LINE, 359 variations=((GV.LOW_FREQUENCY, GV.MED_FREQUENCY, GV.HIGH_FREQUENCY), 360 (GV.HALF_AMPLITUDE, GV.MAX_AMPLITUDE), 361 (GV.SQUARE_WAVE,), 362 (GV.BLTR,), 363 (GV.NORMAL,), 364 ), 365 prompt='Draw a straight line from {3} with a {0} {1} {2} in noise.', 366 subprompt={ 367 GV.LOW_FREQUENCY: ('5kHz',), 368 GV.MED_FREQUENCY: ('500kHz',), 369 GV.HIGH_FREQUENCY: ('1MHz',), 370 GV.HALF_AMPLITUDE: ('10Vpp',), 371 GV.MAX_AMPLITUDE: ('20Vpp',), 372 GV.SQUARE_WAVE: ('square wave',), 373 GV.NORMAL: ('',), 374 GV.BLTR: ('bottom left to top right',), 375 }, 376 validators=( 377 DiscardInitialSecondsValidator( 378 CountTrackingIDNormalFingerValidator('== 1')), 379 DiscardInitialSecondsValidator( 380 LinearityNormalFingerValidator(linearity_criteria, finger=0, 381 segments=VAL.MIDDLE)), 382 DiscardInitialSecondsValidator( 383 NoGapValidator(no_gap_criteria, slot=0)), 384 DiscardInitialSecondsValidator( 385 NoReversedMotionValidator(no_reversed_motion_criteria, 386 slots=0, segments=VAL.MIDDLE)), 387 DiscardInitialSecondsValidator( 388 NoReversedMotionValidator(no_reversed_motion_criteria, 389 slots=0, segments=VAL.BOTH_ENDS)), 390 DiscardInitialSecondsValidator( 391 ReportRateValidator(report_rate_criteria)), 392 ), 393 ), 394 NOISE_STATIONARY_EXTENDED: 395 Gesture( 396 name=NOISE_STATIONARY_EXTENDED, 397 variations=(tuple(GV.EXTENDED_FREQUENCIES), 398 (GV.MAX_AMPLITUDE,), 399 (GV.SQUARE_WAVE,), 400 (GV.CENTER,), 401 ), 402 prompt='Hold one finger on the {3} of the touch surface with a ' 403 '{0} {1} {2} in noise.', 404 subprompt=dict({ 405 GV.CENTER: ('center',), 406 GV.MAX_AMPLITUDE: ('20Vpp',), 407 GV.SQUARE_WAVE: ('square wave',), 408 }.items() + 409 {freq: (freq,) for freq in GV.EXTENDED_FREQUENCIES}.items()), 410 validators=( 411 DiscardInitialSecondsValidator( 412 CountTrackingIDNormalFingerValidator('== 1')), 413 DiscardInitialSecondsValidator( 414 StationaryTapValidator(stationary_tap_criteria, slot=0)), 415 ), 416 ), 417 ONE_FINGER_TRACKING: 418 Gesture( 419 name=ONE_FINGER_TRACKING, 420 variations=((GV.LR, GV.RL, GV.TB, GV.BT, GV.BLTR, GV.TRBL), 421 (GV.SLOW, GV.NORMAL), 422 ), 423 prompt='Take {2} to draw a straight, {0} line {1} using a ruler.', 424 subprompt={ 425 GV.LR: ('horizontal', 'from left to right',), 426 GV.RL: ('horizontal', 'from right to left',), 427 GV.TB: ('vertical', 'from top to bottom',), 428 GV.BT: ('vertical', 'from bottom to top',), 429 GV.BLTR: ('diagonal', 'from bottom left to top right',), 430 GV.TRBL: ('diagonal', 'from top right to bottom left',), 431 GV.SLOW: ('3 seconds',), 432 GV.NORMAL: ('1 second',), 433 }, 434 validators=( 435 CountTrackingIDNormalFingerValidator('== 1'), 436 LinearityNormalFingerValidator(linearity_criteria, finger=0, 437 segments=VAL.MIDDLE), 438 NoGapValidator(no_gap_criteria, slot=0), 439 NoReversedMotionValidator(no_reversed_motion_criteria, slots=0, 440 segments=VAL.MIDDLE), 441 NoReversedMotionValidator(no_reversed_motion_criteria, slots=0, 442 segments=VAL.BOTH_ENDS), 443 ReportRateValidator(report_rate_criteria), 444 ), 445 ), 446 447 ONE_FINGER_TO_EDGE: 448 Gesture( 449 name=ONE_FINGER_TO_EDGE, 450 variations=((GV.CL, GV.CR, GV.CT, GV.CB), 451 (GV.SLOW,), 452 ), 453 prompt='Take {2} to draw a striaght {0} line {1}.', 454 subprompt={ 455 GV.CL: ('horizontal', 'from the center off left edge',), 456 GV.CR: ('horizontal', 'from the center off right edge',), 457 GV.CT: ('vertical', 'from the center off top edge',), 458 GV.CB: ('vertical', 'from the center off bottom edge',), 459 GV.SLOW: ('2 seconds',), 460 }, 461 validators=( 462 CountTrackingIDNormalFingerValidator('== 1'), 463 LinearityNormalFingerValidator(linearity_criteria, finger=0, 464 segments=VAL.MIDDLE), 465 NoGapValidator(no_gap_criteria, slot=0), 466 NoReversedMotionValidator(no_reversed_motion_criteria, slots=0), 467 RangeValidator(range_criteria), 468 ReportRateValidator(report_rate_criteria), 469 ), 470 ), 471 472 TWO_FINGER_TRACKING: 473 Gesture( 474 name=TWO_FINGER_TRACKING, 475 variations=((GV.LR, GV.RL, GV.TB, GV.BT, GV.BLTR, GV.TRBL), 476 (GV.SLOW, GV.NORMAL), 477 ), 478 prompt='Take {2} to draw a {0} line {1} using a ruler ' 479 'with TWO fingers at the same time.', 480 subprompt={ 481 GV.LR: ('horizontal', 'from left to right',), 482 GV.RL: ('horizontal', 'from right to left',), 483 GV.TB: ('vertical', 'from top to bottom',), 484 GV.BT: ('vertical', 'from bottom to top',), 485 GV.BLTR: ('diagonal', 'from bottom left to top right',), 486 GV.TRBL: ('diagonal', 'from top right to bottom left',), 487 GV.SLOW: ('3 seconds',), 488 GV.NORMAL: ('1 second',), 489 }, 490 validators=( 491 CountTrackingIDNormalFingerValidator('== 2'), 492 LinearityNormalFingerValidator(linearity_criteria, finger=0, 493 segments=VAL.MIDDLE), 494 LinearityNormalFingerValidator(linearity_criteria, finger=1, 495 segments=VAL.MIDDLE), 496 NoGapValidator(no_gap_criteria, slot=0), 497 NoGapValidator(no_gap_criteria, slot=1), 498 NoReversedMotionValidator(no_reversed_motion_criteria, slots=0), 499 NoReversedMotionValidator(no_reversed_motion_criteria, slots=1), 500 ReportRateValidator(report_rate_criteria), 501 ), 502 ), 503 504 FINGER_CROSSING: 505 Gesture( 506 # also covers stationary_finger_not_affected_by_2nd_moving_finger 507 name=FINGER_CROSSING, 508 variations=((GV.LR, GV.RL, GV.TB, GV.BT, GV.BLTR, GV.TRBL), 509 (GV.SLOW, GV.NORMAL), 510 ), 511 prompt='Place one stationary finger near the center of the ' 512 'touch surface, then take {2} to draw a straight line ' 513 '{0} {1} with a second finger', 514 subprompt={ 515 GV.LR: ('from left to right', 'above the stationary finger'), 516 GV.RL: ('from right to left', 'below the stationary finger'), 517 GV.TB: ('from top to bottom', 518 'on the right to the stationary finger'), 519 GV.BT: ('from bottom to top', 520 'on the left to the stationary finger'), 521 GV.BLTR: ('from the bottom left to the top right', 522 'above the stationary finger',), 523 GV.TRBL: ('from the top right to the bottom left', 524 'below the stationary finger'), 525 GV.SLOW: ('3 seconds',), 526 GV.NORMAL: ('1 second',), 527 }, 528 validators=( 529 CountTrackingIDNormalFingerValidator('== 2'), 530 NoGapValidator(no_gap_criteria, slot=1), 531 NoReversedMotionValidator(no_reversed_motion_criteria, slots=1), 532 ReportRateValidator(report_rate_criteria, finger=1), 533 StationaryFingerValidator(stationary_finger_criteria, slot=0), 534 ), 535 ), 536 537 ONE_FINGER_SWIPE: 538 Gesture( 539 name=ONE_FINGER_SWIPE, 540 variations=(GV.BLTR, GV.TRBL), 541 prompt='Use ONE finger to quickly swipe {0}.', 542 subprompt={ 543 GV.BLTR: ('from the bottom left to the top right',), 544 GV.TRBL: ('from the top right to the bottom left',), 545 }, 546 validators=( 547 CountPacketsValidator(count_packets_criteria, slot=0), 548 CountTrackingIDNormalFingerValidator('== 1'), 549 NoReversedMotionValidator(no_reversed_motion_criteria, slots=0), 550 ReportRateValidator(report_rate_criteria), 551 ), 552 ), 553 554 TWO_FINGER_SWIPE: 555 Gesture( 556 name=TWO_FINGER_SWIPE, 557 variations=(GV.TB, GV.BT), 558 prompt='Use TWO fingers to quickly swipe {0}.', 559 subprompt={ 560 GV.TB: ('from top to bottom',), 561 GV.BT: ('from bottom to top',), 562 }, 563 validators=( 564 CountPacketsValidator(count_packets_criteria, slot=0), 565 CountPacketsValidator(count_packets_criteria, slot=1), 566 CountTrackingIDNormalFingerValidator('== 2'), 567 NoReversedMotionValidator(no_reversed_motion_criteria, slots=0), 568 NoReversedMotionValidator(no_reversed_motion_criteria, slots=1), 569 ReportRateValidator(report_rate_criteria), 570 ), 571 ), 572 573 PINCH_TO_ZOOM: 574 Gesture( 575 name=PINCH_TO_ZOOM, 576 variations=(GV.ZOOM_IN, GV.ZOOM_OUT), 577 prompt='Using two fingers, preform a "{0}" pinch by bringing' 578 'your fingers {1}.', 579 subprompt={ 580 GV.ZOOM_IN: ('zoom in', 'farther apart'), 581 GV.ZOOM_OUT: ('zoom out', 'closer together'), 582 }, 583 validators=( 584 CountTrackingIDNormalFingerValidator('== 2'), 585 PinchValidator(pinch_criteria), 586 ReportRateValidator(report_rate_criteria), 587 ), 588 ), 589 590 ONE_FINGER_TAP: 591 Gesture( 592 name=ONE_FINGER_TAP, 593 variations=(GV.TL, GV.TR, GV.BL, GV.BR, GV.TS, GV.BS, GV.LS, GV.RS, 594 GV.CENTER), 595 prompt='Use one finger to tap on the {0} of the touch surface.', 596 subprompt={ 597 GV.TL: ('top left corner',), 598 GV.TR: ('top right corner',), 599 GV.BL: ('bottom left corner',), 600 GV.BR: ('bottom right corner',), 601 GV.TS: ('top edge',), 602 GV.BS: ('bottom side',), 603 GV.LS: ('left hand side',), 604 GV.RS: ('right hand side',), 605 GV.CENTER: ('center',), 606 }, 607 validators=( 608 CountTrackingIDNormalFingerValidator('== 1'), 609 StationaryTapValidator(stationary_tap_criteria, slot=0), 610 ), 611 ), 612 613 TWO_FINGER_TAP: 614 Gesture( 615 name=TWO_FINGER_TAP, 616 variations=(GV.HORIZONTAL, GV.VERTICAL, GV.DIAGONAL), 617 prompt='Use two fingers aligned {0} to tap the center of the ' 618 'touch surface.', 619 subprompt={ 620 GV.HORIZONTAL: ('horizontally',), 621 GV.VERTICAL: ('vertically',), 622 GV.DIAGONAL: ('diagonally',), 623 }, 624 validators=( 625 CountTrackingIDNormalFingerValidator('== 2'), 626 StationaryTapValidator(stationary_tap_criteria, slot=0), 627 StationaryTapValidator(stationary_tap_criteria, slot=1), 628 ), 629 ), 630 631 ONE_FINGER_PHYSICAL_CLICK: 632 Gesture( 633 name=ONE_FINGER_PHYSICAL_CLICK, 634 variations=(GV.CENTER, GV.BL, GV.BS, GV.BR), 635 prompt='Use one finger to physically click the {0} of the ' 636 'touch surface.', 637 subprompt={ 638 GV.CENTER: ('center',), 639 GV.BL: ('bottom left corner',), 640 GV.BS: ('bottom side',), 641 GV.BR: ('bottom right corner',), 642 }, 643 validators=( 644 CountTrackingIDNormalFingerValidator('== 1'), 645 PhysicalClickValidator('== 1', fingers=1), 646 StationaryTapValidator(stationary_tap_criteria, slot=0), 647 ), 648 ), 649 650 TWO_FINGER_PHYSICAL_CLICK: 651 Gesture( 652 name=TWO_FINGER_PHYSICAL_CLICK, 653 variations=None, 654 prompt='Use two fingers physically click the center of the ' 655 'touch surface.', 656 subprompt=None, 657 validators=( 658 CountTrackingIDNormalFingerValidator('== 2'), 659 PhysicalClickValidator('== 1', fingers=2), 660 StationaryTapValidator(stationary_tap_criteria, slot=0), 661 StationaryTapValidator(stationary_tap_criteria, slot=1), 662 ), 663 ), 664 665 THREE_FINGER_PHYSICAL_CLICK: 666 Gesture( 667 name=THREE_FINGER_PHYSICAL_CLICK, 668 variations=None, 669 prompt='Use three fingers to physically click ' 670 'the center of the touch surface.', 671 subprompt=None, 672 validators=( 673 CountTrackingIDNormalFingerValidator('== 3'), 674 PhysicalClickValidator('== 1', fingers=3), 675 ), 676 ), 677 678 FOUR_FINGER_PHYSICAL_CLICK: 679 Gesture( 680 name=FOUR_FINGER_PHYSICAL_CLICK, 681 variations=None, 682 prompt='Use four fingers to physically click ' 683 'the center of the touch surface.', 684 subprompt=None, 685 validators=( 686 CountTrackingIDNormalFingerValidator('== 4'), 687 PhysicalClickValidator('== 1', fingers=4), 688 ), 689 ), 690 691 FIVE_FINGER_PHYSICAL_CLICK: 692 Gesture( 693 name=FIVE_FINGER_PHYSICAL_CLICK, 694 variations=None, 695 prompt='Use five fingers to physically click ' 696 'the center of the touch surface.', 697 subprompt=None, 698 validators=( 699 CountTrackingIDNormalFingerValidator('== 5'), 700 PhysicalClickValidator('== 1', fingers=5), 701 ), 702 ), 703 704 STATIONARY_FINGER_NOT_AFFECTED_BY_2ND_FINGER_TAPS: 705 Gesture( 706 name=STATIONARY_FINGER_NOT_AFFECTED_BY_2ND_FINGER_TAPS, 707 variations=(GV.AROUND,), 708 prompt='Place your one stationary finger in the middle of the ' 709 'touch surface, and use a second finger to tap ' 710 'all around it many times (50)', 711 subprompt=None, 712 validators=( 713 CountTrackingIDNormalFingerValidator('>= 25'), 714 StationaryFingerValidator(stationary_finger_criteria, slot=0), 715 ), 716 ), 717 718 FAT_FINGER_MOVE_WITH_RESTING_FINGER: 719 Gesture( 720 name=FAT_FINGER_MOVE_WITH_RESTING_FINGER, 721 variations=(GV.LR, GV.RL, GV.TB, GV.BT), 722 prompt='With a stationary finger on the {0} of the touch surface, ' 723 'draw a straight line with a FAT finger {1} {2} it.', 724 subprompt={ 725 GV.LR: ('center', 'from left to right', 'below'), 726 GV.RL: ('bottom edge', 'from right to left', 'above'), 727 GV.TB: ('center', 'from top to bottom', 'on the right to'), 728 GV.BT: ('center', 'from bottom to top', 'on the left to'), 729 }, 730 validators=( 731 CountTrackingIDFatFingerValidator('== 2'), 732 LinearityFatFingerValidator(relaxed_linearity_criteria, 733 finger=1, segments=VAL.MIDDLE), 734 NoGapValidator(no_gap_criteria, slot=1), 735 NoReversedMotionValidator(no_reversed_motion_criteria, slots=1), 736 ReportRateValidator(report_rate_criteria, finger=1), 737 StationaryFingerValidator(stationary_finger_criteria, slot=0), 738 ), 739 ), 740 741 DRAG_EDGE_THUMB: 742 Gesture( 743 name=DRAG_EDGE_THUMB, 744 variations=(GV.LR, GV.RL, GV.TB, GV.BT), 745 prompt='Drag the edge of your thumb {0} in a straight line ' 746 'across the touch surface', 747 subprompt={ 748 GV.LR: ('horizontally from left to right',), 749 GV.RL: ('horizontally from right to left',), 750 GV.TB: ('vertically from top to bottom',), 751 GV.BT: ('vertically from bottom to top',), 752 }, 753 validators=( 754 CountTrackingIDFatFingerValidator('== 1'), 755 LinearityFatFingerValidator(relaxed_linearity_criteria, 756 finger=0, segments=VAL.MIDDLE), 757 NoGapValidator(no_gap_criteria, slot=0), 758 NoReversedMotionValidator(no_reversed_motion_criteria, slots=0), 759 ReportRateValidator(report_rate_criteria), 760 ), 761 ), 762 763 TWO_CLOSE_FINGERS_TRACKING: 764 Gesture( 765 name=TWO_CLOSE_FINGERS_TRACKING, 766 variations=(GV.LR, GV.TB, GV.TLBR), 767 prompt='With two fingers close together (lightly touching each ' 768 'other) in a two finger scrolling gesture, draw a {0} ' 769 'line {1}.', 770 subprompt={ 771 GV.LR: ('horizontal', 'from left to right',), 772 GV.TB: ('vertical', 'from top to bottom',), 773 GV.TLBR: ('diagonal', 'from the top left to the bottom right',), 774 }, 775 validators=( 776 CountTrackingIDFatFingerValidator('== 2'), 777 LinearityFatFingerValidator(relaxed_linearity_criteria, 778 finger=0, segments=VAL.MIDDLE), 779 LinearityFatFingerValidator(relaxed_linearity_criteria, 780 finger=1, segments=VAL.MIDDLE), 781 NoGapValidator(no_gap_criteria, slot=0), 782 NoReversedMotionValidator(no_reversed_motion_criteria, slots=0), 783 ReportRateValidator(report_rate_criteria), 784 ), 785 ), 786 787 RESTING_FINGER_PLUS_2ND_FINGER_MOVE: 788 Gesture( 789 name=RESTING_FINGER_PLUS_2ND_FINGER_MOVE, 790 variations=((GV.TLBR, GV.BRTL), 791 (GV.SLOW,), 792 ), 793 prompt='With a stationary finger in the bottom left corner, take ' 794 '{1} to draw a straight line {0} with a second finger.', 795 subprompt={ 796 GV.TLBR: ('from the top left to the bottom right',), 797 GV.BRTL: ('from the bottom right to the top left',), 798 GV.SLOW: ('3 seconds',), 799 }, 800 validators=( 801 CountTrackingIDNormalFingerValidator('== 2'), 802 LinearityFatFingerValidator(relaxed_linearity_criteria, 803 finger=1, segments=VAL.MIDDLE), 804 NoGapValidator(no_gap_criteria, slot=1), 805 NoReversedMotionValidator(no_reversed_motion_criteria, slots=1), 806 ReportRateValidator(report_rate_criteria, finger=1), 807 StationaryFingerValidator(stationary_finger_criteria, slot=0), 808 ), 809 ), 810 811 TWO_FAT_FINGERS_TRACKING: 812 Gesture( 813 name=TWO_FAT_FINGERS_TRACKING, 814 variations=(GV.LR, GV.RL), 815 prompt='Use two FAT fingers separated by about 1cm to draw ' 816 'a straight line {0}.', 817 subprompt={ 818 GV.LR: ('from left to right',), 819 GV.RL: ('from right to left',), 820 }, 821 validators=( 822 CountTrackingIDFatFingerValidator('== 2'), 823 LinearityFatFingerValidator(relaxed_linearity_criteria, 824 finger=0, segments=VAL.MIDDLE), 825 LinearityFatFingerValidator(relaxed_linearity_criteria, 826 finger=1, segments=VAL.MIDDLE), 827 NoGapValidator(no_gap_criteria, slot=0), 828 NoGapValidator(no_gap_criteria, slot=1), 829 NoReversedMotionValidator(no_reversed_motion_criteria, slots=0), 830 NoReversedMotionValidator(no_reversed_motion_criteria, slots=1), 831 ReportRateValidator(report_rate_criteria), 832 ), 833 ), 834 835 FIRST_FINGER_TRACKING_AND_SECOND_FINGER_TAPS: 836 Gesture( 837 name=FIRST_FINGER_TRACKING_AND_SECOND_FINGER_TAPS, 838 variations=(GV.TLBR, GV.BRTL), 839 prompt='While drawing a straight line {0} slowly (~3 seconds), ' 840 'tap the bottom left corner with a second finger ' 841 'gently 3 times.', 842 subprompt={ 843 GV.TLBR: ('from top left to bottom right',), 844 GV.BRTL: ('from bottom right to top left',), 845 }, 846 validators=( 847 CountTrackingIDNormalFingerValidator('== 4'), 848 LinearityFatFingerValidator(relaxed_linearity_criteria, 849 finger=0, segments=VAL.MIDDLE), 850 NoGapValidator(no_gap_criteria, slot=0), 851 NoReversedMotionValidator(no_reversed_motion_criteria, slots=0), 852 ReportRateValidator(report_rate_criteria), 853 ), 854 ), 855 856 DRUMROLL: 857 Gesture( 858 name=DRUMROLL, 859 variations=(GV.FAST, ), 860 prompt='Use the index and middle finger of one hand to make a ' 861 '"drum roll" {0} by alternately tapping each finger ' 862 'for 5 seconds.', 863 subprompt={ 864 GV.FAST: ('as fast as possible',), 865 }, 866 validators=( 867 CountTrackingIDNormalFingerValidator('>= 5'), 868 DrumrollValidator(drumroll_criteria), 869 ), 870 timeout = 2000, 871 ), 872 873 RAPID_TAPS: 874 Gesture( 875 name=RAPID_TAPS, 876 variations=(GV.TL, GV.BR, GV.CENTER), 877 prompt='Tap the {0} of the touch surface 20 times quickly', 878 subprompt={ 879 GV.TL: ('top left corner',), 880 GV.TS: ('top edge',), 881 GV.TR: ('top right corner',), 882 GV.LS: ('left edge',), 883 GV.CENTER: ('center',), 884 GV.RS: ('right edge',), 885 GV.BL: ('bottom left corner',), 886 GV.BS: ('bottom edge',), 887 GV.BR: ('bottom right corner',), 888 }, 889 validators=( 890 CountTrackingIDNormalFingerValidator('== 20'), 891 ), 892 timeout = 2000, 893 ), 894 895 ONE_FINGER_TRACKING_FROM_CENTER: 896 Gesture( 897 name=ONE_FINGER_TRACKING_FROM_CENTER, 898 variations=((GV.CR, GV.CT, GV.CUL, GV.CLL), 899 (GV.SLOW, GV.NORMAL), 900 ), 901 prompt='Place a stationary finger on the center of the touch ' 902 'surface for about 1 second, and then take {2} to draw a ' 903 '{0} line {1}.', 904 subprompt={ 905 GV.CR: ('horizontal', 'to the right',), 906 GV.CT: ('vertical', 'to the top',), 907 GV.CUL: ('diagonal', 'to the upper left',), 908 GV.CLL: ('diagonal', 'to the lower left',), 909 GV.SLOW: ('2 seconds',), 910 GV.NORMAL: ('1 second',), 911 }, 912 validators=( 913 HysteresisValidator(hysteresis_criteria, finger=0), 914 ), 915 ), 916 917 DRAG_LATENCY: 918 Gesture( 919 name=DRAG_LATENCY, 920 variations=None, 921 prompt='Run one finger back and forth across the pad making sure ' 922 'to break the laser completely on each pass. Make at least ' 923 'twenty passes.', 924 subprompt=None, 925 validators=( 926 CountTrackingIDNormalFingerValidator('== 1'), 927 DragLatencyValidator(drag_latency_criteria), 928 ), 929 ), 930 931 PRESSURE_CALIBRATION: 932 Gesture( 933 name=PRESSURE_CALIBRATION, 934 variations=(GV.SIZE0, GV.SIZE1, GV.SIZE2, GV.SIZE3, GV.SIZE4, 935 GV.SIZE5, GV.SIZE6, ), 936 prompt='Draw circles continuously for 5 seconds ' 937 'using the metal finger of size {0}.', 938 subprompt={ 939 GV.SIZE0: ('0 (the smallest size)',), 940 GV.SIZE1: ('1',), 941 GV.SIZE2: ('2',), 942 GV.SIZE3: ('3',), 943 GV.SIZE4: ('4',), 944 GV.SIZE5: ('5',), 945 GV.SIZE6: ('6 (the largest size)',), 946 }, 947 validators=( 948 CountTrackingIDNormalFingerValidator('== 1'), 949 ), 950 ), 951 } 952 return gesture_dict 953 954 955 class FileName: 956 """A dummy class to hold the attributes in a test file name.""" 957 pass 958 filename = FileName() 959 filename.sep = '-' 960 filename.ext = 'dat' 961 962 963 class Gesture: 964 """A class defines the structure of Gesture.""" 965 # define the default timeout (in milli-seconds) when performing a gesture. 966 # A gesture is considered done when finger is lifted for this time interval. 967 TIMEOUT = int(1000/80*10) 968 969 def __init__(self, name=None, variations=None, prompt=None, subprompt=None, 970 validators=None, timeout=TIMEOUT): 971 self.name = name 972 self.variations = variations 973 self.prompt = prompt 974 self.subprompt = subprompt 975 self.validators = validators 976 self.timeout = timeout 977