FAQs

Why Websockets and not DMX512 for prop control?

Asked by Dominic ...

The fundemental reason is the flexibility of the messaging format. Props need a lot more data namespace and value ranges than lighting fixtures.

We love DMX512 in the right place though, so we have a SWN-DMX unit that can pass events to DMX - more of this later.

Differences

DMX512 Essentially has a fixed data frame that passes a sequence of 512 channels where a value can range between 0-255. This is data in one direction.

The Set Wide Net uses Websockets to pass JSON formatted events. This gives an infinite namespace of devices each of which can use a rich data format.

Of great importantance is that props can publish their own events, this gives us two way communication.

Examples:

    
        {'e':'Counter1', 'd':{'target' : 'CounterValue', 'startvalue' : 47610000, 'direction' : 'reverse', 'rate' : 10, 'step' : 100 }} // Start Counting REVERSE at 47610000 10x faster rate in steps of 100 
        {'e':'LED1', 'd':{'sequence': [{'duty' : 100, 'rate' : 800},{'duty': 10, 'rate' : 100} ,{'duty':0,'rate' : 2000}]}}    // Fade 'egg' LED in a continous cycle from 100% to 10% to 0% at different rates
    

For more advanced behaviour we can use the Set Wide Net for Separations of concerns. A good example is simulation, where we can have a simple code block listening for events and responding to them.

You can see short video clip on this simulation example.

'Engine' Example

The code fragment below deals with two engine 'props' another fragment is listening to 'throttle' and 'load' controls which are practical props that an actor really interacts with. If the 'simulated' temperatures exceed limits the 'engine' prop will emit an 'Alarm' event. If the temperature increases to the 'failure' limit, the engines will shutdown, The 'Master Alarm' prop might listen for 'Alarm' events from the engines and emit a 'Master Alarm' event. The gauge and UI elements will for temperatures, revs, state etc and show them accordingly.

This is a simple example of how we can use the Set Wide Net to create a complex system.

    
        async def update_engine():
        alarm = False
        master_alarm = False
        engines = [engine1, engine2]
        while True:
    
            # Deal with the engines
            for engine in engines:
                engine.update()
                if abs(engine.temperature - engine.last_temperature) > 2:
                    message_queue.append({"e": engine.meter_temperature, "d": "{:.1F}".format(engine.temperature)})
                    engine.last_temperature = engine.temperature
                if abs(engine.rpm - engine.last_rpm) > 80:
                    message_queue.append({"e": engine.meter_rpm, "d": "{:.1F}".format(engine.rpm)})
                    engine.last_rpm = engine.rpm
                if engine.state != engine.last_state:
                    if engine.state == "Failure":
                        alarm = True
                        message_queue.append({"e": engine.failure_UI, "d": "visible"})
                    else:
                        if not alarm:
                            message_queue.append({"e": engine.failure_UI, "d": "hidden"})
    
            # Deal with the load meter
            if abs(engine1.load - engine1.last_load) > 0.05:
                message_queue.append({"e": "Stepper4", "d":  {"position" : int(engine1.load*100) }})
                engine1.last_load = engine1.load
    
            #deal with the Master Alarm
            master_alarm = False
            for engine in engines:
                if engine.state != engine.last_state:
                    if engine.state == "Alarm":
                        master_alarm = True
                        message_queue.append({"e": "UI4", "d": "visible"})
                    else:
                        if master_alarm == False:
                            message_queue.append({"e": "UI4", "d": "hidden"})
                    engine.last_state = engine.state
                        
            # rest a bit
            await asyncio.sleep(0.3)
    

You can see that different teams of prop makers can craft props that work in concert together whilst interacting with the actors such that the actors experience a script motivated realism.

Here's a tease of what we can do with DMX:

    
        {'e':'DMX512', 'd':{'channel' : 1, 'value' : 255}} // Turn on the first light to full brightness
    

And here's an example of our SWN-DMX unit performing autonomous actions on an event:

    
        {'e':'DMX1', 'd':{'fade': 4, 'channel' : 5, 'value' : 255}}
        {'e':'DMX1', 'd':{'fade': 2, 'channel' : 4, 'value' : 16}}
        {'e':'DMX1', 'd':{'fade': 1, 'channel' : 3, 'value' : 0}}
    

The above example shows 3 different channels of DMX fading to new values but at different rates. Once this event is received the SWN-DMX unit calculates all the intermediate values and sends the required DMX stream.

Can Automated Props be used in virtual production (VP)

Asked by Sian ...

The answer is YES, and there are many versions of yes.

Most VP is made using plates and scenes rendered by Unreal Engine onto volumes. Actors in front of the volume could use props in the conventional way, all our control systems will work.

However, it gets more interesting when one wants to integrate foreground, background, cinamatic lighting and off-screen elements like wind and smoke.

Here's a quick re-definition of props for this section of the FAQ:

UE can emit and consume Websocket events, in UE5.5 there is a blueprint for Websockets that's attached to running instance. This can be referenced by individual assets and UE actors. For example a light could controlled by an external event, or the distance of the camera from an asset can be published to the SWN.

Collisions are a useful example, collisions in UE could be published to the SWN so that physical props may react to them.

The difference in the events is that the SWN uses JSON formating and UE uses text, within UE, both Python and C++ can be used to parse JSON.

Just for fun - you could imagine our actors in a volume interacting with a screen which itself is rendering from another instance of UE, one could then use events to synchronise action between the background and foreground UE instances.