| # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """ This is a tapping script for Touchbot II |
| |
| When you run this script, the robot will perform a customizable tap action |
| on the touchpad. This essentially consists of tapping repeatedly with a series |
| of fingers in a certain location on the pad. |
| |
| The gesture takes in a position to move the hand to, a list of which fingers |
| to do the tap or drumroll with, and the number of taps to perform. |
| x, y coordinates in the range from 0.0->1.0 |
| angle in degrees |
| finger distance in mm that specifies how far apart the hand should open |
| Which fingers the robot should be used as a list of 4 booleans |
| Top right, Top Left, Bottom Left, Bottom Right |
| 'tap' or 'drumroll' |
| |
| The robot will move to that position, then tap the fingers as specified. For |
| a drumroll it alternates tapping each one in turn, for a regular 'tap' all of |
| the fingers descend at once. |
| |
| Example: |
| To do a standard 2 finger drumroll in the center of the pad 20mm apart |
| Python drumroll.py lumpy.p 0.5 0.5 45 20 0 1 0 1 50 drumroll |
| |
| To tap 3 fingers 20 times in the top left corner of the pad 30mm apart |
| Python drumroll.py lumpy.p 0.1 0.3 0 30 0 1 1 1 20 tap |
| """ |
| |
| import math |
| import sys |
| import time |
| from touchbotII import Touchbot, Device, PositionArg |
| |
| |
| try: |
| # Parse the command line arguments |
| device = Device(sys.argv[1]) |
| pos = PositionArg(*[float(v) for v in sys.argv[2:6]]) |
| fingers = [int(arg) for arg in sys.argv[6:10]] |
| num_taps = int(sys.argv[10]) |
| is_drumroll = (sys.argv[11] == 'drumroll') |
| delay = 0.0 |
| if len(sys.argv) > 12: |
| delay = float(sys.argv[12]) |
| except: |
| print ('Usage: python %s device.p position fingers num_taps [tap|drumroll]' |
| % __file__) |
| print ' * position is formatted as x y angle finger_distance' |
| print ' * finger_states: a list of 4 values (1s and 0s)' |
| print ' * the number of individual taps to make' |
| print |
| print 'For a standard 2 finger drumroll in the center you might do:' |
| print 'python %s link.p 0.5 0.5 45 20 0 1 0 1 50 drumroll' % __file__ |
| sys.exit(1) |
| |
| print 'Executing the tap gesture defined by:' |
| print '\tPosition: %s' % str(pos) |
| print '\tFingers: %s' % str(fingers) |
| print '\tNum taps: %d' % num_taps |
| print '\tDrumroll?: %s' % str(is_drumroll) |
| |
| num_fingers = sum(fingers) |
| if num_fingers < 1: |
| print 'You must specify at least 1 finger to use' |
| sys.exit(1) |
| |
| # Connect to the robot and configure the profile to move slowly |
| bot = Touchbot() |
| bot.SetSpeed(Touchbot.SPEED_SLOW) |
| |
| # Convert the point specifications into something the robot understands |
| abs_pos = device.RelativePosToAbsolutePos((pos.x, pos.y), angle=pos.angle) |
| |
| # For one finger taps, compensate to center the finger |
| abs_pos = bot.CenterIfSingleFinger(fingers, abs_pos, pos.finger_distance) |
| |
| # Go to the starting point and prepare for the drumroll |
| bot.SetFingerStates([0, 0, 0, 0]) |
| bot.SetCartesian(abs_pos, pos.finger_distance, blocking=True) |
| |
| # Commence the tapping |
| fingers_tapping = [i for i, v in enumerate(fingers) if v] |
| |
| next_finger = 0 |
| last_state = [0, 0, 0, 0] |
| for tap_num in range(num_taps): |
| if num_fingers > 1 and is_drumroll: |
| finger_number = fingers_tapping[next_finger % len(fingers_tapping)] |
| next_states = [1 if i == finger_number else 0 |
| for i in range(len(Touchbot.ALL_FINGERS))] |
| middle_states = [1 if (l or n) else 0 |
| for l, n in zip(last_state, next_states)] |
| |
| # Start the new finger moving down before lifting up the last one |
| bot.SetFingerStates(middle_states) |
| time.sleep(Touchbot.MINIMUM_FINGER_EXTENSION_TIME / 2) |
| # Now start to lift the finger that was on the pad before |
| bot.SetFingerStates(next_states) |
| time.sleep(Touchbot.MINIMUM_FINGER_EXTENSION_TIME / 2) |
| |
| last_state = next_states |
| next_finger += 1 |
| else: |
| bot.SetFingerStates(fingers) |
| # The pressure is split across all the fingers, so they are slower to |
| # extend if there are multiples being used at once |
| time.sleep(Touchbot.MINIMUM_FINGER_EXTENSION_TIME * num_fingers |
| + delay) |
| bot.SetFingerStates([0, 0, 0, 0]) |
| time.sleep(Touchbot.MINIMUM_FINGER_EXTENSION_TIME) |
| |
| # Make sure all the fingers are lifted up when it's done |
| bot.SetFingerStates([0, 0, 0, 0]) |