aboutsummaryrefslogtreecommitdiff
path: root/docs/new-fixture.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/new-fixture.rst')
-rw-r--r--docs/new-fixture.rst162
1 files changed, 162 insertions, 0 deletions
diff --git a/docs/new-fixture.rst b/docs/new-fixture.rst
new file mode 100644
index 0000000..dc55601
--- /dev/null
+++ b/docs/new-fixture.rst
@@ -0,0 +1,162 @@
+===========================
+Defining a new fixture type
+===========================
+
+To create a new fixture definition ("personality file"), use the
+``define-fixture`` macro from ``(starlet fixture)``::
+
+ (define-fixture fixture-class-name
+ (fixture-attributes
+ list of attributes ...)
+ scanout code ...)
+
+The ``fixture-class-name`` should be a GOOPS class name (in triangular
+brackets) for the fixture class, of the form ``<manufacturer-model-mode>``,
+for example ``<robe-dl7s-mode3>`` for a Robe DL7S profile in mode 3.
+
+Each attribute follows one of the following forms::
+
+ (attr-continuous intensity '(0 100) 0)
+ (attr-colour colour white)
+ (attr-list prism '(#f 3 5) #f)
+
+In all cases, you need to provide the name of the attribute. The available
+attribute names are enumerated in module (starlet attributes) - please add new
+names if you need, but use the available names if possible. The last argument
+in each ``attr-`` form is always the default value for the attribute.
+
+For ``attr-continuous``, you need to give the range of possible values. For
+``attr-list``, you need to give a list of the possible discrete values. For
+``attr-colour``, the value is always a Starlet colour object.
+
+The list of attributes is followed by the `scanout code`. This code will be
+called to convert the attribute values into DMX values.
+
+Retrieve the current values with calls of the form ``(get-attr intensity)``,
+and set DMX values using ``(set-chan8 nn val)``, where ``val`` is the DMX value
+(0 to 255) and ``nn`` is the channel number. The channel numbers are indexed
+from 1, i.e. ``(set-chan8 1 255)`` will set the fixture's base DMX address to
+255.
+
+There is also ``(set-chan16 nn val)``, which will set a pair of values to a
+16-bit value between 0 and 65535. The lower channel address will get the most
+significant byte or 'coarse' value.
+
+Note that you don't need access (nor do you get access) to the fixture
+instance itself. The routines ``get-attr``, ``set-chan8`` and ``set-chan16``
+automatically know which fixture is being worked on at the time of the
+procedure call.
+
+
+Tips
+====
+
+The fixture class name should include enough of the fixture's name to
+disambiguate it from other products by the same manufacturer. For example
+<stairville-octagon-theater-cw-ww> includes ``cw-ww`` to distinguish the
+`CW/WW` (cold/warm wash) variant from the `CW/WW/A` (cold/warm/amber wash)
+variant, which has a different channel layout.
+
+Use the standard names (see below) for attributes as far as possible. This
+means that, for example, the same knob on a MIDI control surface can control
+the same attribute across a range of different fixtures. Note the UK-style
+spelling of some of the attributes (e.g. ``colour``).
+
+In spite of the above paragraph, use the exact manufacturer's spelling for the
+fixture name itself.
+
+Put the fixture definition into a separate Guile module named
+``(starlet fixture-library <manufacturer> <fixture name>)``.
+If the fixture has multiple modes, create one fixture class for each and put
+them all in the same file.
+
+Use physically meaningful units where possible. For example, attribute
+``colour-temperature`` should be in Kelvin, not arbitrary units. This means
+that a set of different fixtures types can all be set to the same value. It
+also makes it easily possible to substitute one fixture for a different one
+without having to re-program the entire show.
+
+Be prepared to do some work in the scanout code. It's almost never as simple
+as a 1:1 translation from the attributes to DMX channels. Even the cheap
+5-channel LED cold/warm fixture in the example below includes some maths.
+
+
+Worked example
+==============
+
+Here is an annotated version of the definition for the
+`Stairville Octagon Theatre CW/WW <https://www.thomannmusic.com/stairville_octagon_theater_cw_ww_36x1w.htm>`_.
+The channels for this fixture are:
+
+ 1. Cold LED intensity (0-255 min-max)
+ 2. Warm LED intensity (0-255 min-max)
+ 3. Strobe (0-15 off, 16-255 slow-fast)
+ 4. Macro (0-15 direct control with channels 1&2,
+ 16-255 various pre-programmed colour temperatures)
+ 5. Overall intensity
+
+The approximate colour temperature range for the fixture is given in the
+manual as 2800K to 6400K. Temperatures in between will be achieved by mixing
+the cold and warm LEDs such that the sum is always constant. The midpoint
+colour temperature (4600K) will therefore correspond to 50% cold and 50% warm
+intensity.
+
+Note that this design choice reduces the absolute maximum intensity possible
+from this fixture, which would be achieved when channels 1, 2 and 5 are all at
+maximum. However, we gain the fact that the colour temperature and intensity
+parameters are orthogonal: changing temperature will not change the intensity,
+and vice-versa. Given that Starlet is a *theatrical* lighting control system,
+this kind of trade-off is preferable.
+
+We will totally ignore the pre-programmed colour temperatures in favour of
+having direct control over the cold and warm LED values. The manual does not
+even say what the pre-programmed temperatures are, so this is no loss at all.
+
+Unfortunately, the manual doesn't say what frequencies are meant be 'slow' and
+'fast' strobe. We'll assume that 'slow' is 1 Hz, and 'fast' is 25 Hz.
+
+Here is the code::
+
+ ;; Define a Guile module for the fixture
+ (define-module (starlet fixture-library stairville octagon-theater-cw-ww)
+
+ #:use-module (starlet fixture) ;; for define-fixture, attr-continuous etc
+ #:use-module (starlet scanout) ;; for set-chan8, get-attr etc
+ #:use-module (starlet utils) ;; for percent->dmxval8 etc
+ #:export (<stairville-octagon-theater-cw-ww>))
+
+ (define-fixture
+
+ ;; Name of the fixture class
+ <stairville-octagon-theater-cw-ww>
+
+ ;; List of attributes
+ (fixture-attributes
+ (attr-continuous intensity '(0 100) 0)
+ (attr-continuous colour-temperature '(2800 6400) 3200)
+ (attr-list strobe '(#f #t) #f)
+ (attr-continuous strobe-frequency '(1 25) 1))
+
+ ;; Scanout code follows
+
+ ;; Set unused macro channel to zero
+ (set-chan8 4 0)
+
+ ;; Set strobe channel
+ (if (get-attr strobe)
+ (set-chan8 3 (scale-and-clamp-to-range
+ (get-attr strobe-frequency)
+ '(1 25)
+ '(16 255)))
+ (set-chan8 3 0))
+
+ ;; Set intensity channel
+ (set-chan8 5 (percent->dmxval8 (get-attr intensity))))
+
+ ;; Set values of warm and cold LEDs according to colour temperature
+ (let ((coltemp (get-attr colour-temperature)))
+ (set-chan8 1 (scale-and-clamp-to-range coltemp '(2800 6400) '(0 255)))
+ (set-chan8 2 (scale-and-clamp-to-range coltemp '(2800 6400) '(255 0))))
+
+There are, of course, many more examples in ``guile/starlet/fixture-library``.
+