Goals:
Create an animation of two claws on the four motors.
Make the movement smooth and realistic
Make the arms look expressive and alive.

Outcome:
We defined 10 keyframes with the positions for all 4 winches. We implemented a timer that performs linear interpolation on the positions to reduce the jerking. We hard coded the frequency to be 1 and damping_ratio to be 1. We additionally disabled the knob function to force the frequency and damping_ratio to stay at 1.

To determine the keyframes, we added some print statements in the code to print the target positions, then used the MIDI pad to move the arms to each target position. We noted the values we liked as we went, and then added them into a list for keyframing after.

For the hardware, we made two arms with passive “mouths” that open and close as the arms swing around. Each arm is slightly unique, and we put feathers on them to make them look a bit more expressive and alive. The designs of the two arms were meant to be similar, but contrast each other slightly.

self.frequency = 1
self.damping_ratio = 1

       
class MainApp(rcp.app.MainApp):
    """Main application controller object holding any non-GUI related state."""
    def __init__(self):
        #..... other code from exercise3.py
        self.keyframes = [[0,0,0,0]]*10
        self.keyframes[0] = [0,0,0,0]
        self.keyframes[1] = [-81,-345,-483,-512]
        self.keyframes[2] = [-28,417,-41,-177]
        self.keyframes[3] = [395,459,-171,-277]
        self.keyframes[4] = [327,553,-319,-91]
        self.keyframes[5] = [-71,51,-409,-621]
        self.keyframes[6] = [283,459,-257,-684]
        self.keyframes[7] = [-104,577,-107,-107]
        self.keyframes[8] = [148,-82,-343,-576]
        self.keyframes[9] = [-202,-190,-464,12]

        # start the gesture timer
        N = 10
        self.gesture_interval = 1/N
        self.gesture_timer = QtCore.QTimer()
        self.gesture_timer.start(1000*self.gesture_interval)
        self.gesture_timer.timeout.connect(self.gesture_timer_tick)
        self.gesture_frame = 0  


def gesture_timer_tick(self):
        N = 10
        gesture_idx = self.gesture_frame//N % 10
        if self.gesture_frame < 10 * N:
            print("starting animation in {}".format((10*N-self.gesture_frame)//N))           
            self.gesture_frame += 1
            return

        targets = self.keyframes[gesture_idx]
        next_targets = self.keyframes[(gesture_idx + 1) % 10]
        interp = (self.gesture_frame % N) / N
        print(interp)

        real_targs = [0]*4
        for i in range(0,len(targets)):        
            real_targs[i] = (1-interp)*targets[i] + interp*next_targets[i]

        print("idx: {}; target: {}".format(gesture_idx, real_targs))
        self.gesture_frame += 1

        self.winches[0].set_target([0,1,2,3], real_targs)