ConfigurationSelector
ConfigurationSelector holds up to five matrices of the same size and publishes whichever one you select.6 minute read
ConfigurationSelector holds up to five matrices of the same size and
publishes whichever one you select. All five can be edited while the controller
runs, so a gain set, a transformation or a model’s coefficients can be changed
and switched without rebuilding.
Set the matrix size to 1×1 and it becomes a five-way switch between single numbers.
flowchart LR
p0(["configurationIndex"]) --> B["ConfigurationSelector"]
p1(["configuration0"]) --> B
p2(["configuration1"]) --> B
p3(["configuration2"]) --> B
p4(["configuration3"]) --> B
p5(["configuration4"]) --> B
B --> o1(["output"])
The switch is instantaneous. The output steps to the new matrix on the same cycle the index changes — there is no fade. That is usually what you want for a set of coefficients, because a blend of two validated configurations is a third one nobody validated. If the block downstream cannot take a step, smooth it there.
Matrices are stored one column at a time, not one row at a time. For a 3×3, tree elements 0, 1, 2 are the first column, not the first row. Fill them in that order or you will get the transpose of the matrix you meant. This catches nearly everyone once.
An index above 4 silently selects
configuration0. Nothing reports that your request was rejected, so checkoutputmatches what you expected.
Signals
Outputs
| Path | Unit | Description |
|---|---|---|
output |
depends on use | The selected matrix, published one column at a time. Updated every cycle, so an edit to the active configuration appears on the next one. |
This block has no inputs. The selection and all five matrices are parameters, so everything about it is configured rather than driven.
Parameters
| Path | Unit | Default | Range | Effect |
|---|---|---|---|---|
configurationIndex |
- | 0 | 0 to 4 | Which configuration appears on the output. Anything above 4 silently selects configuration0. Persistent, so the controller comes back up on whichever configuration it was left on. |
configuration0 |
depends on use | zeros | unbounded | The matrix selected at index 0. Column-major — see the callout above. |
configuration1 |
depends on use | zeros | unbounded | The matrix selected at index 1. |
configuration2 |
depends on use | zeros | unbounded | The matrix selected at index 2. |
configuration3 |
depends on use | zeros | unbounded | The matrix selected at index 3. |
configuration4 |
depends on use | zeros | unbounded | The matrix selected at index 4. |
All are persistent and survive a controller restart. All five configurations exist whether or not you use them, and each is the full matrix size, so an unused configuration still occupies its place in the tree. No parameters exist below this block.
The matrix size is fixed when the controller is built and cannot be changed from the tree.
Setup
-
Work out the storage order for your matrix size before you write anything. For a 3×3, the nine values run down the first column, then the second, then the third.
-
Write your first matrix into
configuration0in that order. -
Read
outputback and confirm it matches. If it looks like the transpose of what you typed, you filled it row by row — refill it column by column. -
Fill the other configurations you need. Leave the rest at zero.
-
Set
configurationIndexand confirmoutputchanges to the matching matrix. -
Confirm the index survives a controller restart, and that the output comes back on the right configuration.
Whatever consumes
outputwill act on the new values immediately when you change the index — there is no fade. If that is a controller gain, the machine’s behaviour changes on that cycle.
Tuning
- There is nothing to tune in this block itself. The tuning lives in the matrices you put in it and in whatever consumes them.
- Use it to hold alternative tunings side by side: a cautious set in
configuration0, a production set inconfiguration1, a diagnostic set inconfiguration2. - Keep
configuration0as your safe fallback. It is what you get when the index is out of range, so it is the one that must always be sane. - Edit a configuration while the controller runs and the change reaches
outputon the next cycle — including the one currently selected. Editing the active configuration changes the machine’s behaviour immediately, one element at a time as you type them. Edit an inactive one and switch to it instead. - Verify each configuration by selecting it and reading
outputback, rather than trusting what you wrote. - Nothing here depends on the task rate, so none of this needs re-checking after a rate change.
The step is the point. Smooth it downstream if you need it smoothed.
| Symptom | Cause | Action |
|---|---|---|
| The matrix came back transposed | It was filled row by row; storage is column by column | Refill it column by column |
| The output does not match any configuration I set | The index is above 4, so configuration0 is selected |
Use 0 to 4 |
| Changing the index did nothing | The two configurations hold the same values, or the index is out of range both times | Read output back to see which is active |
| The machine’s behaviour changed while I was typing values | Expected: edits to the active configuration reach the output immediately | Edit an inactive configuration, then switch |
| The machine stepped when I changed the index | Expected: this block does not fade | Smooth it in the block downstream |
| The output was zeros at startup | The selected configuration is still all zeros | Fill it |
| A configuration I never use is cluttering the tree | Expected: all five always exist | Leave them at zero |
| The index reverted to something I did not set | It is persistent — it came back from the saved configuration | Set and save it deliberately |
| I need more than five | Not possible — five is fixed when the controller is built | Use a second instance |
| I need a different matrix size | Fixed when the controller is built | Rebuild |
| I need to fade between two configurations | Not possible here, and usually not wise | Put a switch downstream of this block |
A starting point for a 3×3 used to hold two gain sets:
configuration0 = <the cautious set, column by column>
configuration1 = <the production set, column by column>
configurationIndex = 0
Limits and errors
| Limit | Set by | What happens | Reported |
|---|---|---|---|
configurationIndex |
Checked | Anything above 4 selects configuration0. The block never reads outside its configurations |
Not reported — the fallback is silent |
| Storage order | Fixed | Every matrix, including output, is laid out one column at a time |
Not reported |
| Switching | Fixed | Instantaneous. The output steps on the same cycle the index changes | Not reported |
| Configuration edits | The tree | Reach output on the next cycle, including for the currently selected configuration |
Not reported |
| Configuration count | Fixed at five | Cannot be extended from the tree | Not reported |
| Matrix size | Fixed at build time | All five configurations and the output share one size | Not reported |
| Values that are not numbers | Nothing | Not checked. A bad value in the selected configuration is copied to the output | Not reported |
| Startup | Fixed | The output is set from the saved index before the first cycle runs, so it is never briefly zero | Not reported |
| Values | Nothing | No range checking of any kind. The matrices mean whatever the block downstream makes of them | 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).