When we first began experimenting, we found ourselves initially trying to create an interesting shape with our pleated sample, which ended up as a cone/shell shape for the fan pleats and a twisted fan shape for the herringbone pleats. After some initial puppeting, we then created a rig design that would allow for the cone shape to gracefully move up and down (and thus stretch and contract its pleats) and the twisted fan to approach the cone shape and interact with the larger piece.

Rigging Diagram

After creating the rig, we identified that we wanted to modify the code base to 1) allow for motions that were smaller than previously possible (and thus changed the velocity scaling for the middle rows) 2) much larger motions sweeping motions (and thus changed the velocity scaling for the outer two rows).

    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.
        if row == 0:
            delta = 60 * velocity

        if row == 1:
            delta = 2 * velocity

        if row == 2:
            delta = -2 * velocity

        if row == 3:
            delta = -60 * velocity

        if bank == 0 or bank == 1: # 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

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

We then also added functionality to knobs 3 and 4 that would allow for the frequency to be increased much higher than allowed previously by the system, as well as a damping ratio that would go well above 1 (to allow for us to essentially create a manual stop for the system).

def control_change(self, channel, cc, value):
        """Process a MIDI Control Change event."""
        knob, bank = self.decode_mpd218_cc(cc)
        log.debug("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

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

        elif knob == 3:
            self.frequency = 0.05 + 0.5 * value

        elif knob == 4:
            self.damping_ratio = 0.05 + 0.05 * value

        self.winches.set_freq_damping(self.all_axes, self.frequency, self.damping_ratio)
        self.display.set_status("Frequency: %f, damping ratio: %f" % (self.frequency, self.damping_ratio))
        return

Finally, we reduced the channel pressure scaling factor to allow for us to better fine tune the motion of the system.

 def channel_pressure(self, channel, pressure):
        """Process a MIDI Channel Pressure event."""
        velocities = [direction * 5 * pressure for direction in self.winch_dir]
        self.winches.set_velocity(self.all_axes, velocities)
        log.debug("aftertouch: %d, velocities: %s", pressure, velocities)