ChannelSelector

ChannelSelector stores a set of values and fades its output between them as the selection changes.
3.30–3.34

ChannelSelector stores a set of values and fades its output between them as the selection changes. Pick a channel by number, or by raising its enable flag.

Use it to switch a gain, a speed limit or a mode setpoint between preset values without stepping the machine.

It switches between stored numbers, not between live signals. The values live in channelValue, a persistent parameter array you configure. To blend two live signals, use SimpleSwitch instead.

flowchart LR
    i1(["channelEnable"]) --> B["ChannelSelector"]
    i2(["timeScaleFactor"]) --> B
    p1(["channelValue"]) --> B
    p2(["useChannelNumberSelection"]) --> B
    p3(["channelNumberSelection"]) --> B
    p4(["defaultChannel"]) --> B
    B --> o1(["output"])
    B --> o2(["activeChannel"])
    B --> o3(["faderValue"])
    B --> o4(["channelPriority"])

channelPriority does nothing. It is published, and it is filled in with a value per channel at startup, but the block never reads it. When you select by enable flags, the highest-numbered enabled channel wins — put the channel that should take precedence last.

Changing the selection mid-fade is safe. The block always fades from wherever the output currently is, so a change part-way through picks up cleanly with no step.

Signals

Inputs

Path Unit Range Description
channelEnable - true or false per channel Which channels are available. The highest-numbered enabled channel is the one selected. Ignored when useChannelNumberSelection is true. Every flag is cleared at startup, so your application must rewrite them after each restart.
timeScaleFactor - above 0 Speeds up or slows down the fade while it runs. 0 freezes it. Reset to 1 every time the controller starts. A negative value leaves the output stuck.

Outputs

Path Unit Description
output signal unit The single blended value. One output, whatever the channel count.
activeChannel - Which channel the output is heading for, counting from 0.
faderValue - How far through the fade, 0 at the departure value and 1 on arrival. The straight-line fraction even when the shape is cosine.
channelPriority - Published but not used by anything. See the callout above.

Parameters

Path Unit Default Range Effect
channelValue signal unit zeros unbounded The stored value for each channel. This is what the output fades to. Writable at run time.
useChannelNumberSelection - false - When true, the selection comes from channelNumberSelection and channelEnable is ignored.
channelNumberSelection - 0 0 to one below the channel count Which channel to select, when the mode above is true. A value equal to the channel count is wrongly accepted and reads past the end of the value list — the output then becomes meaningless. Stay within range.
defaultChannel - 0 0 to one below the channel count Which channel is enabled at startup. Not range-checked — a value outside the channel count corrupts memory before the first cycle. Set it carefully.
fadeTime s 5.0 one task period to 10 How long the output takes to reach a newly selected value. Above 10 is silently reduced to 10, with a warning in the log.
fadeType - 0 0 or 1 0 straight line, 1 cosine. Both take the same time.

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

Setup

  1. Decide how many channels you need. The channel count is fixed when the controller is built and defaults to 2.

  2. Write the value for each channel into channelValue.

  3. Set defaultChannel to the channel that should be active at startup. Check it is within the channel count — this one is not validated.

  4. Set fadeTime. Start with a second or two.

  5. Choose a selection mode:

    • By number — set useChannelNumberSelection true and write channelNumberSelection. Simpler, and the mode that is fully validated.
    • By flags — leave it false and raise channelEnable per channel, remembering the highest-numbered enabled channel wins.
  6. Start the controller and confirm activeChannel matches what you asked for and output settles on that channel’s value.

    The output is not stable until one fade time after startup. The block always starts a fade at start, even when the destination is the value it is already on. Do not act on output until faderValue reaches 1.

  7. Change the selection and watch output travel to the new value.

Tuning

  1. Trace channelValue and output together. The gap between the current and next value is the size of the change the fade will produce.
  2. Set fadeTime from that gap and what the machine downstream can take.
  3. Use the cosine shape unless you need the shortest transit — it has the same duration but no rate step at either end.
  4. Watch activeChannel to confirm the selection is what you intended. With flag selection this is where a wrong assumption about priority shows up.
  5. If you need to pause a change part-way, set timeScaleFactor to 0. The blend freezes exactly where it is and resumes when you set it back.
  6. Change the selection mid-fade freely — the block re-departs from wherever the output is.
  7. fadeTime is in seconds, so a task-rate change does not move it. But timeScaleFactor returns to 1 after every restart.

The output moving between three stored channel values as the selectionchanges. Each change starts a fresh fade from wherever the output currently is;the cosine shape eases at both ends.

The fade always starts from the output, never from the previous channel’s value.

Symptom Cause Action
The wrong channel was selected With flag selection the highest-numbered enabled channel wins, not the highest priority Reorder your channels, or select by number
Setting channelPriority changed nothing Expected: the block does not read it Use channel order, or select by number
The output is nonsense and stays that way channelNumberSelection equals the channel count, which reads past the end of the value list Use 0 to one below the count
The controller misbehaved from startup defaultChannel is outside the channel count, which is not validated Set it within range
The output moved right after startup Expected: the block always fades once at start Wait for faderValue to reach 1
The enable flags were cleared after a restart Expected: all flags are cleared at startup Rewrite them from your application
The fade is shorter than I asked for A time above 10 is reduced to 10 Check the log; 10 seconds is the maximum
A log warning mentions fade time, but I changed the channel number The range check reuses the fade-time message Check channelNumberSelection too
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 output stuck and never arrives timeScaleFactor is negative, which is not rejected Write a positive value
A rate step at the start or end of a fade The straight-line shape does that Set fadeType to 1
A signal scaled by faderValue does not match Expected: faderValue is the straight-line fraction Apply the same cosine yourself
I need to blend two live signals This block switches stored values only Use SimpleSwitch
I need more channels The count is fixed when the controller is built Rebuild, or use a second instance

A starting point for a three-channel speed preset:

channelValue              = [0.1, 0.5, 1.0]
useChannelNumberSelection = true
channelNumberSelection    = 0
defaultChannel            = 0
fadeTime                  = 1.0
fadeType                  = 1

Limits and errors

Limit Set by What happens Reported
Selection by flags channelEnable The highest-numbered enabled channel wins. Priority is not consulted activeChannel
channelPriority Fixed Published and never read. Setting it has no effect Not applicable
channelNumberSelection Partly checked Clamped, but one too high — a value equal to the channel count is accepted and reads past the end of the value list Logged, with the wrong message text
defaultChannel Nothing Not checked at all. A value outside the channel count writes outside the enable array at startup Not reported
Fade duration fadeTime The output reaches the selected value in that time, divided by timeScaleFactor faderValue
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
Departure point Fixed Every fade starts from the current output, so a mid-fade change is continuous Not reported
timeScaleFactor Nothing Not checked. 0 freezes; negative leaves the output stuck short of the target Not reported
timeScaleFactor persistence Fixed Forced to 1 at every controller start Not reported
Startup Fixed Every enable flag is cleared, the default channel is enabled, and one fade always runs faderValue
Values that are not numbers Nothing Not caught by the range checks Not reported
Output count Fixed One output, whatever the channel count Not reported
Channel count Fixed at build time Cannot be changed from the tree Not reported

The block logs a warning when the fade time or the channel number is written out of range — both using the fade-time wording. Every other condition above shows as a value on a trace, or not at all.


Verified against motorcortex-control3 3.30.0 (bc348fd).