kf Python library

The kf library has a number of objects useful for building performance control scripts and GUIs. It is included in several zip packages and the individual files can be browsed at kf.

Core Modules (non-GUI)

kf.sim

Simulators for offline motion control testing.

class kf.sim.SimWinch(count=4)[source]

Representation of a current multi-axis physical winch set. This object is analogous to QtSerialWinch and implements the same command API. Note that a larger performance setup could use multiple winch sets or simulators in coordination.

This simulator does not calculate any line or fabric dynamics, it only runs dynamic path generators comparable to those in the firmware.

increment_target(axis, offset)[source]

Add a signed offset to one or more target positions. The units are dimensionless ‘steps’. If using a microstepping driver, these may be less than a physical motor step.

Parameters:
  • axis – either a integer axis number or list of axis numbers
  • position – either a integer step offset or list of step offsets
positions()[source]

Return a list of the current winch positions.

set_freq_damping(axis, freq, ratio)[source]

Set the second order model resonance parameters for one or more path generators. Note that the same parameters are applied to all specified axes, unlike the target setting functions.

Parameters:
  • axis – either a integer axis number or list of axis numbers
  • freq – scalar specifying the frequency in Hz
  • ratio – scalar specifying the damping ratio, e.g. 1.0 at critical damping.
set_target(axis, position)[source]

Set the target position of one or more axes. N.B. that capstan winches can slip, so there is no guarantee of an repeatable line position, just the capstan itself.

Parameters:
  • axis – either a integer axis number or list of axis numbers
  • positions – either a integer step position or list of step positions
set_velocity(axis, velocity)[source]

Set the constant velocity of one or more targets.

Parameters:
  • axis – either a integer axis number or list of axis numbers
  • velocity – either an integer velocity or list of integer velocities
update_for_interval(interval)[source]

Run the simulators for the given interval, which may include one or more integration steps.

kf.winch

Interfaces to hardware winch systems. Uses the QtSerialPort module for communication event processing using the Qt event loop.

class kf.winch.QtSerialWinch[source]

Class to manage a serial connection to a hardware winch system using Qt QSerialPort object for data transport. The data protocol is based on the StepperWinch Arduino sketch.

available_ports()[source]

Return a list of names of available serial ports.

close()[source]

Shut down the serial connection to the Arduino.

data_received(data)[source]
increment_target(axis, offset)[source]

Add a signed offset to one or more winch target positions.

Parameters:
  • axis – either a integer axis number or list of axis numbers
  • offset – either a integer step offset or list of step offsets
motor_enable(value=True)[source]

Issue a command to enable or disable the stepper motor drivers.

open()[source]

Open the serial port and initialize communications. If the port is already open, this will close it first. If the current name is None, this will not open anything. Returns True if the port is open, else False.

ping()[source]
read_input()[source]
set_and_open_port(name)[source]
set_freq_damping(axis, freq, ratio)[source]

Set the second order model resonance parameters for one or more path generators. Note that the same parameters are applied to all specified axes, unlike the target setting functions.

Parameters:
  • axis – either a integer axis number or list of axis numbers
  • freq – scalar specifying the frequency in Hz
  • ratio – scalar specifying the damping ratio, e.g. 1.0 at critical damping.
set_port(name)[source]
set_target(axis, position)[source]

Set the absolute target position for one or more winch axes.

Parameters:
  • axis – either a integer axis number or list of axis numbers
  • positions – either a integer step position or list of step positions
set_velocity(axis, velocity)[source]

Set the constant velocity of one or more target positions.

Parameters:
  • axis – either a integer axis number or list of axis numbers
  • velocity – either an integer velocity or list of integer velocities
status_message()[source]
write(data)[source]

kf.path

Path generator objects for simulating low-level motion control.

class kf.path.Path[source]

Representation of the current path generator for a single winch. This keeps the physical calculations separate from the graphics. This reimplements the functionality of Path.h and Path.cpp in the StepperWinch Arduino sketch. The model is based on a second-order simple harmonic oscillator.

The command API should be kept compatible with the winch interface class which transmits commands over a serial port to an Arduino-based winch.

increment_target(offset)[source]

Add a signed offset to the target position. The units are dimensionless ‘steps’. If using a microstepping driver, these may be less than a physical motor step.

set_freq_damping(freq, damping)[source]

Convenience function to set second order model gains in terms of natural frequency and damping ratio. The frequency is in Hz, the damping ratio is 1.0 at critical damping.

set_target(position)[source]

Set the absolute target position in dimensionless units.

set_velocity(velocity)[source]

Set the constant velocity of the target in units/sec

step(dt)[source]
update_for_interval(interval)[source]

Run the simulator for the given interval, which may include one or more integration steps.

kf.midi

Objects related to MIDI event processing.

class kf.midi.MIDIEncoder[source]

Abstract class for composing MIDI messages.

channel_pressure(channel, value)[source]

Send a Channel Pressure (aftertouch) message.

Parameters:
  • channel – MIDI channel, integer on [1,16]
  • value – MIDI value, integer on [0,127]
control_change(channel, controller, value)[source]

Send a Controller Change message.

Parameters:
  • channel – MIDI channel, integer on [1,16]
  • controller – MIDI controller index, integer on [0,127]
  • value – MIDI value, integer on [0,127]
message(message)[source]

Overridable method to output a single MIDI message.

Parameters:message – list of integers constituting a MIDI message
note_off(channel, note, velocity=0)[source]

Send a Note On message.

Parameters:
  • channel – MIDI channel, integer on [1,16]
  • note – MIDI note, integer on [0,127]
  • velocity – optional MIDI velocity, integer on [0,127], normally zero, default zero
note_on(channel, note, velocity)[source]

Send a Note On message.

Parameters:
  • channel – MIDI channel, integer on [1,16]
  • note – MIDI note, integer on [0,127]
  • velocity – MIDI velocity, integer on [0,127]
polyphonic_key_pressure(channel, key, pressure)[source]

Send a Polyphonic Key Pressure message.

Parameters:
  • channel – MIDI channel, integer on [1,16]
  • note – MIDI note, integer on [0,127]
  • pressure – MIDI aftertouch, integer on [0,127]
class kf.midi.MIDIProcessor[source]

Abstract class for processing MIDI events. Provides a callback for the specific MIDI events we use in our systems so this may be subclassed to implement a MIDI stream processor. This defines an informal protocol for MIDI input. This may be extended to more event times as needed.

channel_pressure(channel, value)[source]

Function to receive messages starting with 0xD0 through 0xDF.

Parameters:
  • channel – integer from 1 to 16
  • value – integer from 0 to 127
control_change(channel, control, value)[source]

Function to receive messages starting with 0xB0 through 0xBF.

Parameters:
  • channel – integer from 1 to 16
  • control – integer from 0 to 127; some have special meanings
  • value – integer from 0 to 127
decode_message(message)[source]

Decode a MIDI message expressed as a list of integers and perform callbacks for recognized message types.

Parameters:message – list of integers containing a single MIDI message
decode_mpd218_cc(cc)[source]

Interpret a MPD218 knob control change event as a knob index and bank position. The MPD218 uses a non-contiguous set of channel indices so this normalizes the result. The knob index ranges from 1 to 6 matching the knob labels. Bank 0 is the A bank, bank 1 is the B bank, bank 2 is the C bank.

Parameters:cc – an integer MIDI control channel identifier
Returns:(knob, bank)
decode_mpd218_key(key)[source]

Interpret a MPD218 pad event key value as a row, column, and bank position. Row 0 is the front/bottom row (Pads 1-4), row 3 is the back/top row (Pads 13-16). Column 0 is the left, column 3 is the right. Bank 0 is the A bank, bank 1 is the B bank, bank 2 is the C bank.

Parameters:key – an integer MIDI note value
Returns:(row, column, bank)
note_off(channel, key, velocity)[source]

Function to receive messages starting with 0x80 through 0x8F.

Parameters:
  • channel – integer from 1 to 16
  • key – integer from 0 to 127
  • velocity – integer from 0 to 127
note_on(channel, key, velocity)[source]

Function to receive messages starting with 0x90 through 0x9F.

Parameters:
  • channel – integer from 1 to 16
  • key – integer from 0 to 127
  • velocity – integer from 0 to 127
polyphonic_key_pressure(channel, key, value)[source]

Function to receive messages starting with 0xA0 through 0xAF.

Parameters:
  • channel – integer from 1 to 16
  • key – integer from 0 to 127
  • value – integer from 0 to 127
class kf.midi.QtMIDIListener[source]

Object to manage a MIDI input connection.

connect_midi_processor(processor)[source]

Attach an object to receive MIDI input events, generally a subclass of MIDIProcessor.

get_midi_port_names()[source]

Return a list of unique names for the current MIDI input ports. Duplicate names are modified to guarantee the uniqueness condition.

open_MIDI_input(name)[source]

Open the MIDI in port with the given name (a string). If the port is already open, this will close it first.

class kf.midi.QtMIDISender[source]

Object to manage a MIDI output connection using rtmidi.

get_midi_port_names()[source]

Return a list of names of the current MIDI output ports.

message(message)[source]

Send a single MIDI message.

Parameters:message – list of integers constituting a MIDI message
open_MIDI_output(name)[source]

Open the MIDI out port with the given name (a string). If the port is already open, this will close it first.

kf.osc

Objects related to OSC messaging.

class kf.osc.QtOSCListener(port=3762, host='localhost')[source]

Object to manage a OSC network input. This uses a Qt QUdpSocket to receive messages from the main Qt event loop and a pythonosc dispatcher to decode OSC messages and distribute them to callbacks. Messages are delivered on the main thread. This requires a pythonosc version of at least 1.7.0 so the dispatcher can be used in this way.

Parameters:
  • port – optional UDP port number to which to receive, defaults to 3761
  • host – optional hostname or IP address to which to receive, defaults to localhost
map_handler(address, callback)[source]

Add an address template string to the dispatch map.

message_received()[source]

Callback attached to the port readyRead signal to process incoming UDP packets.

open_receiver()[source]

Create a UDP socket, bind it to the desired port, and set up callbacks to process messages upon receipt. This may be called again after the port address has changed and will create a new socket.

set_OSC_port(address, portnum)[source]

Called to configure a new network address. If the port is already open it is closed and a new port opened with the new address.

unknown_message(msgaddr, *args)[source]

Default handler for unrecognized OSC messages.

class kf.osc.QtOSCSender(port=3762, host='localhost')[source]

Object to manage a OSC network output. This is a thin wrapper around the pythonosc SimpleUDPClient to allow this object to close and reopen the port at will while retaining its identity in the application.

Parameters:
  • port – optional UDP port number to which to send, defaults to 3762
  • host – optional hostname or IP address to which to send, defaults to localhost
open_sender()[source]

Create a UDP client with the chosen destination address. This may be called again after the port address has changed and will create a new socket.

send(address, *args)[source]

Send a UDP packet containing a single OSC message to the predesignated host address and UDP port number.

Parameters:
  • address – an OSC ‘address’ string beginning with a forward slash
  • args – optional arguments, which must be primitive types convertible to OSC message data types
set_OSC_port(address, portnum)[source]

Called to configure a new destination network address. If the port is already open it is closed and a new port opened with the new address.

kf.dmx

Objects related to DMX lighting control.

class kf.dmx.ColorInterpolator(fixtures, channels_per_fixture)[source]
current_dmx_values()[source]

Return a universe of 8-bit integer DMX values with the current colors mapped to the specific fixture channel configuration.

current_rgb_values()[source]

Return a list of 8-bit integer (red, green, blue) values with the current color for each fixture.

set_channel_target(fixture, channel, value)[source]

Update a specific color channel target for the given fixture using the current opacity. The output will change to the new target over the current transition interval. Note that the opacity blends between the current color and the given color, not the current target and the given color.

set_color_target(fixture, color)[source]

Update the color target for the given fixture using the current opacity. The output will change to the new targets over the current transition interval. Note that the opacity blends between the current color and the given color, not the current target and the given color.

set_current_color(fixture, color)[source]

Set a fixture to the given color without a transition. The next update cycle will output the color.

set_dmx_value(channel, value)[source]

Set a single DMX channel to the given value without a transition. The next update cycle will output the color. This function performs the inverse of the fixture->DMX mapping in current_dmx_values().

update_for_interval(interval)[source]

Polling function to update internal state. Returns true if the DMX outputs should be updated.

class kf.dmx.QtDMXUSBPro[source]

Class to manage a serial connection to an ENTTEC DMXUSB PRO for DMX lighting control output. Uses the Qt QSerialPort object for data transport. This currently only supports output, although the device is capable of receiving DMX. For details on the device, please see https://www.enttec.com/range/controls/dmx-usb-interfaces/

available_ports()[source]

Return a list of names of available serial ports.

close()[source]

Shut down the serial connection to the DMX device.

open()[source]

Open the serial port and initialize communications. If the port is already open, this will close it first. If the current name is None, this will not open anything. Returns True if the port is open, else False.

set_and_open_port(name)[source]
set_channel(channel, value)[source]

Set a single channel value and update the hardware.

Parameters:
  • start – zero-based index of channel to update
  • value – 8-bit integer value
set_channels(start, values)[source]

Set a range of channels and update the hardware.

Parameters:
  • start – zero-based index of first channel to update
  • values – list or numpy array of 8-bit integer values
set_port(name)[source]
set_size(channels)[source]

Set the size of the DMX ‘universe’. The value is limited to the valid range of [25,512]. Each channel is an 8-bit value transmitted on the DMX bus; typically each fixture occupies several sequential channels at a start address configured on the fixture.

Generator Modules (non-GUI)

kf.loops

Generators to simulate ‘MIDI tape loops’. The viewer classes can be found in QtConcentricLoops.

class kf.loops.ConcentricLoops(channels=7)[source]

Simulation of a set of concentric tape loops, each moving at a specified constant linear velocity.

angles()[source]

Return an iterable of the current tape loop marker angles (in degrees) for rendering.

connect_cycle_listener(callback)[source]

Connect a callback to receive events when a loop completes a cycle. The function will receive arguments (channel, time) where channel is a zero-based integer index and time is in simulated seconds.

set_speed(axis, speed)[source]

Set the speeds of one or more generator channels.

Parameters:
  • axis – either a integer axis number or list of axis numbers
  • speed – either a scalar speed or a list of speeds
update_for_interval(interval)[source]

Run the simulator for the given interval, generating callbacks for any events created within the interval.

kf.orbits

Generators to simulate orbit system dynamics. The viewer classes can be found in QtOrbits.

class kf.orbits.Orbits(channels=20)[source]

Simulation of a set of particles orbiting around fixed attractors.

connect_boundary_collision_listener(callback)[source]
get_particles_and_bodies()[source]
set_applied_force(tangential, radial)[source]
set_damping(b)[source]
set_gravity(g)[source]
update_for_interval(interval)[source]

Run the simulator for the given interval, which may include one or more integration steps.

kf.waves

Generators to simulate wave system dynamics. The viewer classes can be found in QtWaves.

class kf.waves.Waves1D(channels=5, samples=20)[source]

Simulation of a set of one-dimensional wave systems.

Parameters:
  • channels – number of wave systems to simulate
  • samples – number of sample points in each system
connect_rising_edge_listener(callback)[source]
get_positions()[source]

Return a (W, N) matrix of node position values where W is the number of waves and N is the number of samples.

set_all_damping(b)[source]
set_all_period(period)[source]
update_for_interval(interval)[source]

Run the simulator for the given interval, which may include one or more integration steps.

Core GUI Modules

kf.QtConfig

PyQt5 widgets to create configuration fields and forms.

class kf.QtConfig.QtConfigComboBox(callback=None, default='<no selection>')[source]

Composite widget enabling a user to select an item from a drop down list.

Parameters:
  • callback – function called with argument (string)
  • default – name of initial selection, defaults to ‘<no selection>’
current_item()[source]
select_item(name)[source]

Called to programmatically select an item; updates the display and applies the callback.

set_items(names)[source]
class kf.QtConfig.QtConfigFileButtons(delegate=None, path=None, extension='config')[source]

Composite widget with buttons to control loading and saving a configuration file.

class kf.QtConfig.QtConfigForm[source]

Composite widget to display a form of user-configuration entries.

addField(prompt, widget)[source]

Add a row to the configuration form.

Parameters:
  • prompt – string of text to display on the left
  • widget – a widget to both display status and receive and validate input
class kf.QtConfig.QtConfigOSCPort(callback=None, address='localhost', portnum=3761)[source]

Composite widget enabling a user to configure an address:portnum field.

Parameters:
  • callback – function called with arguments (address-string, port-integer)
  • address – host address string, defaults to ‘localhost’
  • portnum – UDP port integer, defaults to 3761
get_OSC_port()[source]
set_OSC_port(address, portnum)[source]

Set the network address and port display as if entered, validating the result and applying the callback.

validate_input()[source]

Called when the user finishes entering text into the line editor.

class kf.QtConfig.QtConfigText(callback, value=None)[source]

Composite widget enabling a user to configure an field of unvalidated text.

Parameters:
  • callback – function called with argument (string)
  • value – initial string, defaults to None which shows as blank
validate_input()[source]

Called when the user finishes entering text into the line editor.

kf.QtLog

PyQt5 widgets to show and control logging output.

class kf.QtLog.QtLog(level=None, logger=None)[source]

Composite widget including log text output and control widgets.

Parameters:
  • level – initial logging level, defaults to logging.WARNING
  • logger – logger object to which to attach, defaults to root logger
flush_and_remove_memory_handler(mem_handler)[source]
get_logging_level()[source]
set_logging_level(title)[source]

Set the current logging level and level display.

write(string)[source]

Write output to the log text area. This enables this object to be used as a stream for printing.

kf.QtMPD218

A PyQt5 GUI to simulate an Akai MPD218 MIDI controller. The actual controller has pressure-sensitive pads, so the simulation is approximate, this is only intended for testing offline without the physical controller.

class kf.QtMPD218.QtMPD218[source]

A composite window providing a simulated MPD218 drum pad interface. Generated MIDI events are emitted as normal Python callbacks to a user-provided MIDI processor object.

buttonPressed(button)[source]
buttonReleased(button)[source]
connect_midi_processor(processor)[source]
dialMoved(dial, value)[source]
setupUi()[source]
timer_tick()[source]

kf.QtWinch

PyQt5 widgets to render cartoons of winch and line systems.

class kf.QtWinch.QtWinchCartoon[source]

Custom widget representing a single winch as a 2D cartoon view.

paintEvent(e)[source]
update_position(position)[source]
class kf.QtWinch.QtWinchSet(count=4)[source]

Composite widget representing a set of winches as a 2D cartoon view.

winches()[source]

Return a list of QtWinch objects contained in the set.

kf.QtDMX

PyQt5 GUI objects for DMX lighting control and display.

class kf.QtDMX.QtDMXColors(fixtures=3)[source]

A graphical widget to display a set of RGB color fields. Note that the relationship between DMX channels and fixture colors depends on the specific fixtures and assigned addresses, so this mapping must be handled in user code.

Parameters:fixtures – optional number of simulated fixtures, defaults to 3
get_fixture_count()[source]
paintEvent(e)[source]
set_channel(fixture, channel, value)[source]

Change a single color channel within a single fixture.

set_color(fixture, color)[source]

Change the color of a single fixture.

set_colors(colors)[source]
set_fixture_count(fixtures)[source]
class kf.QtDMX.QtDMXControls(channels=12, callback=None)[source]

A composite window providing a set of DMX channel sliders.

Parameters:
  • channels – optional count of channels to control, defaults to 12
  • callback – optional callable which receives (channel, value) arguments
connect_callback(callback)[source]

Connect a callback to receive slider updates as (channel, value) arguments.

get_channel_count()[source]
set_channel(channel, value)[source]

Change the position and value of a channel slider without issuing callbacks. This allows the set of sliders to be used as an output status display without creating infinite call loops.

set_channel_count(channels)[source]

Adjust the UI for a different number of DMX channels.

set_channels(start, values)[source]

Change the position and value of a set of channel sliders without issuing callbacks. This allows the set of sliders to be used as an output status display without creating infinite call loops.

Optional GUI Modules

kf.QtPlotter

PyQt5 widgets to render a 2D suspended plotter system based on winch-driven lines.

class kf.QtPlotter.QtPlotterCartoon[source]

Custom widget representing a single plotter as a 2D cartoon view.

paintEvent(e)[source]
update_positions(positions)[source]

kf.QtPanelScene

PyQt5 widgets to render a stage scene with multiple panels suspended on winch-driven lines.

class kf.QtPanelScene.QtPanelScene[source]

Custom widget representing a stage scene as a 2D cartoon view.

paintEvent(e)[source]

Subclass implementation of parent QWidget class callback to repaint the graphics.

set_intensity(axis, intensity)[source]

Set the visual intensity of each stage lighting channel. This is actually implemented by changing the opacity of the rendered gradient ellipse representing the light.

Parameters:
  • axis – either a integer axis number or list of axis numbers
  • intensity – float or list of floats with values ranging from 0.0 (dark) to 1.0 (full bright)
update_positions(positions)[source]

kf.QtConcentricLoops

PyQt5 widgets to render ‘MIDI tape loop’ generator graphics.

class kf.QtConcentricLoops.QtConcentricLoops(channels=7)[source]

Custom widget representing a MIDI ‘tape loop’ generator.

paintEvent(e)[source]

Subclass implementation of parent QWidget class callback to repaint the graphics.

update_positions(positions)[source]

kf.QtOrbits

PyQt5 widgets to render a particle orbit system.

class kf.QtOrbits.QtOrbits(channels=4)[source]

Custom widget representing a particle orbit system generator.

paintEvent(e)[source]

Subclass implementation of parent QWidget class callback to repaint the graphics.

update_attractors(attractors)[source]
update_positions(positions)[source]

kf.QtWaves

PyQt5 widgets to render wave generator systems.

class kf.QtWaves.QtWaves1D(channels=1)[source]

Custom widget representing a 1D wave system generator.

paintEvent(e)[source]

Subclass implementation of parent QWidget class callback to repaint the graphics.

update_positions(positions)[source]

Update the wave display with a (W, N) numpy matrix of position values.