SimpleSwitch

SimpleSwitch cross-fades between two sets of signals.
3.30–3.34

SimpleSwitch cross-fades between two sets of signals. A boolean picks which set you want and the output travels there over a configured time, in a straight line or along a smooth cosine.

Use it to hand a machine over between two sources — two setpoint generators, two controllers, manual and automatic — without a step at the changeover.

flowchart LR
    i1(["input1 — selected when toggle is false"]) --> B["SimpleSwitch"]
    i2(["input2 — selected when toggle is true"]) --> B
    i3(["toggle"]) --> B
    i4(["doInstantToggle"]) --> B
    B --> o1(["output"])
    B --> o2(["isOn"])
    B --> o3(["isOff"])
    B --> o4(["faderValue"])

Fading in and fading out are configured separately — their own times and their own shapes. A switch can ease in gently over two seconds and drop back in a tenth of one.

The fade is on the mixing fraction, not on the signals. If input1 and input2 are both moving, the output is a blend of two moving signals, and its rate of change during the fade is not bounded by anything you set here. Use SoftSwitch when the output’s velocity and acceleration must stay within limits.

Signals

Inputs

Path Unit Range Description
input1 signal unit unbounded The set selected when toggle is false. This is where the block starts.
input2 signal unit unbounded The set selected when toggle is true.
toggle - true or false Which input the output should travel to. A level, not a pulse — hold it. Flipping it back mid-fade reverses the fade from wherever it had got to.
doInstantToggle - true or false While true, the output snaps to the selected input every cycle with no fade. Also a level: leave it true and the switch never fades again.

Outputs

Path Unit Description
output signal unit The blend. Same number of channels as the inputs.
isOn - The fade to input2 has completed. Goes true a few cycles before faderValue actually reaches 1.
isOff - The fade to input1 has completed. Starts true.
faderValue - How far through the fade, 0 at input1 and 1 at input2. This is the straight-line fraction even when the fade shape is cosine, so scaling another signal by it will not match this switch’s own shape.

Parameters

Path Unit Default Range Effect
fadeInTime s 5.0 one task period to 10 How long it takes to travel to input2. Values above 10 are silently reduced to 10, with a warning in the log.
fadeOutTime s 5.0 one task period to 10 How long it takes to travel back to input1. Same ceiling.
fadeInType - 0 0 or 1 The shape of the fade to input2. 0 straight line, 1 cosine.
fadeOutType - 0 0 or 1 The shape of the fade back to input1.
timeScaleFactor - 1.0 0 upward Speeds up or slows down the fade while it runs. 0 freezes the switch mid-fade, which is a useful way to hold a handover. Reset to 1 every time the controller starts, so a saved value is not kept.

All are persistent and survive a controller restart, except that timeScaleFactor is forced back to 1 at startup. No parameters exist below this block.

fadeInType / fadeOutType What the machine does When to use it
0 straight line The output moves at a constant rate, then stops dead Fast handovers, or when the signals are already smooth
1 cosine The output eases away from one input and eases into the other Anywhere a step in rate would be felt. Same duration as the straight line — only the shape changes

Setup

  1. Connect the two signal sets to input1 and input2. They must have the same number of channels.

  2. Leave toggle false. Confirm output matches input1 and isOff is true.

  3. Set fadeInTime and fadeOutTime. Start slow — a second or two.

  4. Set both shapes to 1 unless you have a reason not to. The cosine costs nothing and removes the rate step at each end.

  5. Set toggle true and watch output travel to input2.

    Step 5 hands the machine over to whatever input2 is carrying. If the two inputs differ, the machine moves the difference over the fade time. Check what input2 is holding before you flip the toggle.

  6. Confirm isOn goes true and output matches input2.

  7. Set toggle back to false and confirm it travels back over fadeOutTime.

Tuning

  1. Trace both inputs together before switching. The size of the gap between them is the size of the motion the fade will produce.
  2. Set the fade time from that gap and what the machine can take: the average rate is the gap divided by the fade time.
  3. Use the cosine shape unless you need the shortest possible transit. It has the same duration but no rate step at either end, so the peak rate is higher in the middle and zero at both ends.
  4. Fade out is usually the more urgent direction. It is normal to set fadeOutTime much shorter than fadeInTime.
  5. Watch faderValue to see the fade progress. Remember it is the straight-line fraction, so with the cosine shape the output will lag it early and lead it late.
  6. If a handover must be able to pause, use timeScaleFactor. Setting it to 0 freezes the blend exactly where it is.
  7. Fade times are in seconds, so a task-rate change does not move them — but the lower bound of one task period does change.

The output travelling from input1 to input2 over a 0.4 second fade. Thestraight-line shape moves at a constant rate and stops abruptly; the cosineeases away from input1 and into input2, taking the sametime.

Both shapes arrive together. Only the way they get there differs.

Symptom Cause Action
The machine moved when I flipped the toggle Expected: the two inputs held different values Match them before switching, or lengthen the fade
The output stepped instead of fading doInstantToggle is true Set it false — it is a level, not a pulse
The fade is shorter than I asked for fadeInTime above 10 is reduced to 10 Check the log; 10 seconds is the maximum
The fade time reads back as 10 Same cause Split the handover, or fade a scaling signal instead
The fade time reads back as a tiny number A value below one task period was raised to it Write a longer time
The fade is slower or faster than the time I set timeScaleFactor is not 1 Set it to 1
timeScaleFactor reverted after a restart Expected: it is forced to 1 at startup Set it from your application after start
The fade froze part-way timeScaleFactor is 0 Set it above 0
The switch stuck at one end and will not come back timeScaleFactor is negative, which is not rejected Write a positive value
A rate step at the start or end of the fade The straight-line shape does that Set the type to 1
The output jerked mid-fade One of the inputs moved during the fade — the block does not limit that Use SoftSwitch if the output’s rate must stay bounded
I reversed the toggle mid-fade and it went back from where it was Expected, and usually what you want Nothing
isOn went true slightly early Expected: the completion test has a small tolerance Watch faderValue for the exact end
A signal scaled by faderValue does not match the fade Expected: faderValue is the straight-line fraction, not the shaped one Apply the same cosine yourself
The output is all zeros An input is not connected — unconnected inputs read 0 Check both
Everything became invalid and stayed that way A fade time that is not a number is not caught by the range check Rewrite the fade times

A starting point for a handover between two setpoint sources:

fadeInTime      = 2.0
fadeOutTime     = 0.5
fadeInType      = 1
fadeOutType     = 1
timeScaleFactor = 1.0

Limits and errors

Limit Set by What happens Reported
Fade duration fadeInTime, fadeOutTime The blend reaches the far end in exactly that time, divided by timeScaleFactor faderValue, isOn, isOff
Fade time range Fixed at one task period to 10 s Out-of-range values are clamped and written back Logged as a warning, once per write
Output rate during a fade Nothing Not limited. The output’s rate is the gap between the inputs divided by the fade time, plus whatever the inputs are doing themselves Not reported
timeScaleFactor Nothing Not checked. 0 freezes the fade; a negative value runs it backwards until it sticks at an end Not reported
timeScaleFactor persistence Fixed Forced to 1 at every controller start, discarding a saved value Not reported
Fade shape fadeInType, fadeOutType Independent per direction. Both take the same time Not reported
faderValue Fixed Always the unshaped fraction, whatever the shape in use Not applicable
doInstantToggle The input A level. While true, every cycle snaps to the selected input faderValue reads 0 or 1
Values that are not numbers Nothing Not caught by the range check. A bad fade time makes the output invalid permanently Not reported
Startup state Fixed The output starts on input1 and isOff starts true isOff
Channel count Fixed at build time Both inputs and the output share one channel count Not reported

The block logs a warning when a fade time is written outside its range. Every other condition above shows as a value on a trace, or not at all.


Verified against motorcortex-control3 3.30.0 (bc348fd).