Fader

Fader moves its output smoothly to whatever value its input holds, over a configured fade time, and publishes the matching velocity and acceleration as it goes.
3.30–3.34

Fader moves its output smoothly to whatever value its input holds, over a configured fade time, and publishes the matching velocity and acceleration as it goes.

Write a new number to input and the output travels there. Write another before it arrives and the fade blends into the new target rather than restarting — the output, its velocity and its acceleration all stay continuous.

flowchart LR
    i1(["input"]) --> B["Fader"]
    i2(["timeScaleFactor"]) --> B
    i3(["timeScaleFactorDot"]) --> B
    B --> o1(["output"])
    B --> o2(["outputDot"])
    B --> o3(["outputDDot"])
    B --> o4(["done"])
    B --> o5(["delaying"])
    B --> o6(["numTargets"])

The fade time is what you set. Unlike SetpointGenerator, this block does not work out how fast it may go — it takes exactly fadeTime seconds whatever the distance, so a large jump means a fast move. Size fadeTime from the largest jump you expect.

Targets queue up. Each change to input adds one. When the queue is full the oldest is dropped, and the only sign is that numTargets stops growing. Watch it if your application writes targets quickly.

Four of the parameters below may not exist on your instance. fadeTime, delayTime, jerkFactor and accelerationFactor are hidden when the block that contains this fader controls them itself. If you cannot find them, they are being set for you.

Signals

Inputs

Path Unit Range Description
input signal unit unbounded The target. A change queues a new fade; writing the same value again does nothing. Compared exactly, so an input that dithers in its last digit will queue a target every cycle and keep the queue full. Feed it settled values.
timeScaleFactor - any Stretches the fade’s clock. 1 is normal, 0.5 is half speed, 0 freezes the fade exactly where it is and nothing is lost — it resumes when you set it back. A negative value is used as its magnitude; the fade does not run backwards.
timeScaleFactorDot 1/s any How fast timeScaleFactor is itself changing. Set this whenever you ramp the scale factor, or the published acceleration will be wrong.

Outputs

Path Unit Description
output signal unit The value on its way to the target.
outputDot signal unit per second Its velocity — this really is the rate of change of output, including across a retarget.
outputDDot signal unit per second² Its acceleration.
done - The queue is empty and the output has arrived. Starts true.
delaying - The newest target is still waiting out its delay and has not started moving.
numTargets - How many targets are queued. If this stops growing while you keep writing, the oldest are being dropped.

Parameters

Path Unit Default Range Effect
faderType - 0 0 or 1 Which profile shape. See the table below. Changing it while a fade is running switches that fade’s shape part-way, which produces a kink — change it only when done is true.
maxTargets - 10 1 upward How many targets may be queued. Values below 1 are treated as 1. When the queue is full the oldest target is dropped and its position becomes the new starting point.
applyTimeScaleToDelay - true - Whether timeScaleFactor stretches delayTime as well as the fade itself.
fadeTime s 1.0 above 0 How long the fade takes, whatever the distance. Negative values are used as their magnitude and written back. A fade shorter than one task period snaps instead.
delayTime s 0.0 0 upward How long to wait after a new target before moving. Negatives are used as their magnitude.
jerkFactor - 0.333 0 to 0.5 Only used by the jerk-limited shape. The fraction of the profile spent changing acceleration. Values outside the range are clamped and written back.
accelerationFactor - 0.429 0 to 0.5 Only used by the jerk-limited shape. The fraction spent accelerating. Also clamped and written back.

All are persistent and survive a controller restart. No parameters exist below this block.

faderType What the machine does Parameters that matter
0 quintic Position, velocity and acceleration all start and end at zero. The smoothest shape, and the default fadeTime
1 jerk-limited Reaches its acceleration and velocity plateaus and holds them, so more of the move happens at full speed fadeTime, jerkFactor, accelerationFactor

Setup

  1. Have your application seed the fader at the machine’s current value before enabling anything downstream, so the first fade does not start from zero.

  2. Set fadeTime from the largest jump you expect and what the machine can take at that distance.

  3. Leave faderType at 0 for a first pass.

  4. Write a small change to input and watch output travel there.

    Step 4 moves the machine, over fadeTime seconds regardless of how far it has to go. Start with a small change.

  5. Confirm done goes false at the start and true on arrival.

  6. Write a second target while the first is still moving. output should bend towards the new value with no step in outputDot.

  7. Check numTargets grows and falls back to 0.

Tuning

  1. fadeTime is the only number that matters for most uses. Set it from the biggest jump: the peak velocity is roughly twice the distance divided by the fade time for the quintic shape.
  2. If the fade is smooth but too slow for small jumps and too fast for large ones, this block is the wrong one — SetpointGenerator derives its duration from velocity and acceleration limits instead.
  3. Switch to the jerk-limited shape if you need more of the move spent at full speed. It reaches its plateaus and holds them, so it covers ground faster for the same duration.
  4. With the jerk-limited shape, tune jerkFactor and accelerationFactor together. Both are fractions of the profile and both cap at 0.5. The pairs 0.333 with 0.333, and 0.333 with 0.429, are the two standard settings.
  5. Use delayTime when several faders should start together after a common trigger. Decide whether the delay should stretch with the time scale and set applyTimeScaleToDelay to match.
  6. Use timeScaleFactor for a speed override. Ramp it rather than stepping it, and set timeScaleFactorDot while you do, or outputDDot will be wrong for as long as the ramp lasts.
  7. Raise maxTargets if your application writes targets faster than the fades complete, and watch numTargets to see whether the queue is filling.

A single fade compared with one that receives a second target part-way. Theretargeted output bends towards the new value instead of restarting, and itsvelocity stays smooth right through the change.

The velocity trace has no step where the second target arrives. That continuity is what this block is for.

Symptom Cause Action
A large jump moved much faster than a small one Expected: every fade takes fadeTime regardless of distance Use SetpointGenerator if you need a velocity limit
The move was instant fadeTime plus delayTime is under one task period Lengthen fadeTime
A kink appeared mid-fade faderType was changed while a fade was running Change it only when done is true
numTargets stopped growing while I kept writing The queue is full and the oldest targets are being dropped Raise maxTargets, or write less often
The output jumped to an unexpected place An old target was dropped from a full queue, moving the starting point Same
The output never settles input is dithering, so a new target is queued every cycle Feed it settled values
Everything became invalid and stayed that way An input that is not a number queues a target every cycle Fix the upstream signal
The fade froze part-way timeScaleFactor is 0 Set it above 0. Nothing was lost — it resumes
I set a negative timeScaleFactor and it went forwards anyway Expected: the magnitude is used This block cannot run backwards
outputDDot was wrong while I changed the speed override timeScaleFactorDot was left at 0 Set it while ramping timeScaleFactor
outputDot disagrees with output It should not — this block carries derivatives correctly Check what is consuming them
The delay did not scale with the override applyTimeScaleToDelay is false Set it true
fadeTime reads back positive after I wrote a negative Expected: the magnitude is used Write positive values
jerkFactor reads back as 0.5 Expected: it is capped at 0.5 Use a value in range
The first fade went to the wrong place The fader was not seeded at the machine’s value Seed it from your application before enabling
A fade resumed after a restart The queue is not cleared at startup Seed the fader after every start
I cannot find fadeTime in the tree The block containing this fader controls it Set it there instead
I need this on several channels Not possible — this block is single channel Use one instance per channel

A starting point:

fadeTime              = 1.0
delayTime             = 0.0
faderType             = 0
maxTargets            = 10
applyTimeScaleToDelay = true

Limits and errors

Limit Set by What happens Reported
Fade duration fadeTime Exactly that long, whatever the distance. Not derived from any velocity or acceleration limit done
Output velocity Nothing Not limited. It is whatever the distance and fade time imply outputDot
Sub-cycle fades Checked A fadeTime plus delayTime under one scaled task period snaps to the target done stays true
fadeTime, delayTime signs Checked Negatives are used as their magnitude and written back Read the values back
jerkFactor, accelerationFactor Checked Clamped to 0 to 0.5 and written back Read the values back
maxTargets Checked Forced to at least 1. When the queue is full the oldest target is dropped and its position becomes the new start numTargets
timeScaleFactor Partly checked Negatives are negated. 0 freezes the fade with nothing lost Not reported
timeScaleFactorDot Nothing Not checked. Leaving it at 0 while ramping the scale makes outputDDot wrong Not reported
faderType mid-fade Nothing Not guarded. An in-flight fade switches shape and keeps the old shape’s timing, producing a kink Not reported
Values that are not numbers Nothing Not checked. Such an input queues a new target every cycle numTargets sits at its maximum
Startup Fixed The queue is not cleared, so a fade in flight resumes after a restart done, numTargets
Channel count Fixed One channel per instance, always Not reported

This block logs nothing, ever. Every condition above shows as a value on a trace, or not at all.


Verified against motorcortex-control3 3.30.0 (bc348fd).