When it was time to implement our code on the capstan, we ran into several technical difficulties with the laptop we were using, as well as the capstan itself. Theoretically, our code works, as it seems to run on the simulator just fine. But we couldn’t seem to push it through to the capstan.

Our rigging drawing:

And our attempt to puppet the fabric manually, to demonstrate the effect we wanted to achieve.

def note_on(self, channel, key, velocity):
        """Process a MIDI Note On event."""
        log.debug("ControlLogic received note on: %d, %d", key, velocity)
        row, col, bank = self.decode_mpd218_key(key)

        # Each column maps to a specific winch.
        # Rows 0 and 1 move forward, rows 2 and 3 move backward.
        # The middle rows make small motions, the outer rows make larger motions.
        delta = 5 * velocity if row <= 1 else -5 * velocity
        if row == 0 or row == 3:
            delta = delta * 8
        
        if bank == 0: # bank A or B directly control the winches
            self.winches.increment_target(col, delta)
            self.winch_dir[col] = 1 if delta &gt; 0 else -1 if delta < 0 else 0
            self.pulsing[col] = 0 # reset pulsing on this winch

        elif bank == 1:
            if row == 0 or row == 3:
                self.frequency = random.uniform(0.05, 10)
                self.winches.set_freq_damping(self.all_axes, self.frequency, self.damping_ratio)
            elif row == 1:
                delta = random.randint(velocity, velocity*5)
            else:
                delta = -(random.randint(velocity, velocity*5))
            self.winches.increment_target(col, delta)
            self.winch_dir[col] = 1 if delta &gt; 0 else -1 if delta < 0 else 0
            self.pulsing[col] = 0 # reset pulsing on this winch

        else: # bank C pads instead invoke the metronome oscillation
            self.pulsing[col] = delta//8
            log.debug("Pulsing array now %s", self.pulsing)