Our initial goal was to make an double pendulum arm that had a much wider range of motion. This would enable us to create two actors that can occupy a wider range of “closenesses”. Essentially the goal was to create a mechanism that would be more flexible and facilitate more of our creative ideas. This would hopefully help us make any interaction we wanted the arms to have.

We took the general RR arm shown in Garth’s first example and re-assembled it to be able to access a much larger portion of it’s workspace. This involved moving the base link attachment to just above the right stepper. Now the left stepper drives the base link with piano wire, and the right stepper drives the second link also with piano wire. This structure minimizes the change in distance from the stepper to the base of the arm it’s driving over the range of robot configurations.

In the process of testing this, we found that the system operated much like a human arm, and the range of motion was fluid until the elbow would be hyper extended. The major surprise was that the system could perform a motion that resembled a elbow breaking and then being able to bend as if the human arm was reversed. We wrote code that simplified the ‘multi-step’ stepper control required to perform this motion at the press of a button.

We were interested in the way that this robot can access greater than 180 degrees of motion, and yet it looks like the robot’s elbow breaks to get from one half of the range to the other. It almost looks painful, which is a big discovery that will allow us to convey emotion in an interaction for Thursday.

    def note_on(self, channel, key, velocity):
        """Process a MIDI Note On event."""
        log.debug("WinchMIDILogic received note on: %d, %d", key, velocity)
        row, col, bank = self.decode_mpd218_key(key)
        print("row" + str(row) + "col" + str(col) + "bank" + str(bank) + "\n")
        # Each pair of pads maps to a single winch.  Each bank can address up to 8 winches (two sets).
        winch_index = 8*bank + 4*(row // 2) + col

        #4 is the top two rows left to right first   right motor ccw 45 degrees
        #5 is the top two rows left to right second  both motors ccw 45 degrees
        #6 is the top two rows left to right third   right motor cw 45 degrees
        #7 is the top two rows left to right fourth  left motor cw 45 degrees

        if winch_index == 4:
            self.increment_target(1,-600)
        elif winch_index == 5:
            self.increment_target(1,-400)
            self.increment_target(0,-400)
        elif winch_index == 6:
            self.increment_target(1,400)
        elif winch_index == 7:
            self.increment_target(0,400)
        # Apply a non-linear scaling to the velocity.
        delta = int(velocity**1.6 * 0.125)
        if row == 1:
            delta = -delta
        self.increment_target(winch_index, delta)
        return
    
    def note_off(self, channel, key, velocity):
        """Process a MIDI Note Off event."""
        log.debug("WinchMIDILogic received note off: %d, %d", key, velocity)
        row, col, bank = self.decode_mpd218_key(key)
        return

    def control_change(self, channel, cc, value):
        """Process a MIDI Control Change event."""
        knob, bank = self.decode_mpd218_cc(cc)
        log.debug("Winch control change %d on knob %d bank %d", cc, knob, bank)

        if knob == 1: # Knob #1 on MPD218, use to control resonant frequency
            #self.frequency = 0.05 + 0.1 * value
            self.frequency = 5.00
            self.set_freq_damping()

        elif knob == 2: # Knob #2 on on MPD218, use to control damping ratio
            #self.damping_ratio = 0.05 + 0.01 * value
            self.damping_ratio = 1.32
            self.set_freq_damping()