Lookup
Lookup maps an input to an output through a table of points, interpolating straight lines between them.6 minute read
Lookup maps an input to an output through a table of points, interpolating
straight lines between them. Outside the table the output is held at the
nearest end value — it never extrapolates.
Use it to linearise a sensor, to schedule a gain against speed, or to describe any relationship that is easier to measure than to write down.
flowchart LR
i1(["input"]) --> B["Lookup"]
p1(["x"]) --> B
p2(["y"]) --> B
p3(["numPoints"]) --> B
p4(["gain"]) --> B
p5(["useSortedData"]) --> B
B --> o1(["output"])
B --> o2(["index"])
xmust increase strictly, left to right. If any value is equal to or less than the one before it, the output is 0 — silently, with nothing to tell you the table was rejected. Since 0 is also a perfectly good output value, check your table’s order first whenever the output reads 0.
numPointsdefaults to 0, and an unconfigured block outputs 0. Set it to how many of yourxandyentries are real.
The table has a fixed maximum size, set when the controller is built — usually 7 points. A larger
numPointsis silently reduced to it, and the ceiling is not published, so count your points against what you were given.
Signals
Inputs
| Path | Unit | Range | Description |
|---|---|---|---|
input |
input unit | unbounded | The value to look up. Outside the table the output clamps to the nearest end. A value that is not a valid number freezes the output at its last value. |
Outputs
| Path | Unit | Description |
|---|---|---|
output |
output unit | The interpolated result, scaled by gain. Reads 0 when the table is empty or rejected. |
index |
- | Which table segment was used last. Diagnostic — it is the block’s internal search position, not a measurement. |
Parameters
| Path | Unit | Default | Range | Effect |
|---|---|---|---|---|
numPoints |
- | 0 | 0 to the built-in maximum | How many entries of x and y are real. At 0 the output is 0. At 1 the output is gain × y[0] whatever the input. Values above the maximum are silently reduced. |
x |
input unit | zeros | strictly increasing | The input values of the table. Any entry not greater than the one before it makes the output 0. |
y |
output unit | zeros | unbounded | The output value at each corresponding x. |
gain |
- | 1.0 | unbounded | Multiplies every y value. Use it to rescale the whole table without editing it. |
useSortedData |
- | false | - | Lets the block remember where it looked last, so a slowly moving input searches less. Makes no difference to the answer. At the usual table sizes it makes no measurable difference to the cost either. |
All are persistent and survive a controller restart. No parameters exist below this block.
Setup
- Measure or calculate the relationship you want, at as many points as your table allows.
- Write the input values into
x, in increasing order, and the matching output values intoy. - Set
numPointsto how many entries you filled. - Leave
gainat 1. - Sweep
inputacross the range and confirmoutputtraces the shape you expect. - If
outputreads 0 everywhere, eithernumPointsis 0 or yourxvalues are not strictly increasing. Check both. - Check the ends: below the first
xthe output should hold at the firsty, above the last it should hold at the last.
Tuning
- Put your points where the curve bends. Even spacing wastes points on the straight sections.
- Always include a point at each end of the range you care about. Outside the table the output goes flat, and a client tracing an unexpected plateau is usually looking at a table that stops too early.
- Check the interpolation error at the midpoint of your widest segment — that is where a piecewise-linear fit is worst.
- Use
gainto rescale the whole table, for a unit change or a calibration factor, rather than re-entering everyy. - If the table is a sensor linearisation, take the measurements at the same temperature and load you will run at.
- Nothing here depends on the task rate, and both the interpolation and the clamping are exact.
The flat sections at each end are the clamping, not a fault.
| Symptom | Cause | Action |
|---|---|---|
| The output is 0 everywhere | numPoints is 0 — the default — or x is not strictly increasing |
Check both. Nothing reports which |
| The output is 0 and my table looks fine | Two x entries are equal, which counts as not increasing |
They must be strictly increasing |
| The output is a constant | numPoints is 1, so the output is always gain × y[0] |
Set it to your real point count |
| The output goes flat at each end | Expected: the block clamps rather than extrapolating | Add points further out |
| Only part of my table is used | numPoints is smaller than the entries you filled |
Raise it |
numPoints reads back lower than I set |
It exceeded the built-in maximum and was reduced | Use fewer points, or a larger instance |
| The output is scaled wrongly | gain multiplies every y |
Check it is 1 unless you meant otherwise |
| The output has visible corners | Expected: the table is straight lines between points | Add points where the curve bends |
| The output froze | The input is not a valid number, which holds the last output | Fix the upstream signal |
| The output jumped when I edited the table | Expected: edits take effect on the next cycle, with no fade | Edit while the machine is stopped |
index moves around unexpectedly |
It is the internal search position, not a measurement | Ignore it |
Turning on useSortedData changed the answer |
It should not — it only changes how the block searches | Report it |
| I need extrapolation beyond the table | Not possible — the block clamps | Extend the table |
| I need more points | The maximum is fixed when the controller is built | Rebuild with a larger instance |
| I need this on several signals | Not possible — this block is single channel | Use one instance per signal |
A starting point for a five-point sensor linearisation:
numPoints = 5
x = [0.0, 1.0, 2.0, 3.0, 4.0]
y = <your measured outputs at those inputs>
gain = 1.0
useSortedData = false
Limits and errors
| Limit | Set by | What happens | Reported |
|---|---|---|---|
| Interpolation | The table | Straight lines between adjacent points, exact | output |
| Outside the table | Fixed | Clamped to the first or last y. There is no extrapolation |
Not reported |
x ordering |
Checked | Must be strictly increasing over the first numPoints. Otherwise the output is 0 |
Not reported — 0 is also a valid result |
numPoints above the maximum |
Checked | Silently reduced to the maximum every cycle, so the block never reads past its table | Read the value back |
| Maximum point count | Fixed at build time | Not published. Usually 7 | Not reported |
numPoints of 0 |
Checked | Output is 0 | Not reported |
numPoints of 1 |
Checked | Output is gain × y[0] for any input |
Not reported |
gain |
Nothing | Not checked. Multiplies every y, including on the one-point path — but not on either zero path |
Not reported |
| Values that are not numbers | Nothing | Not checked. Such an input holds the previous output rather than propagating | Not reported |
| Table edits | The tree | Take effect on the very next cycle, with no fade or filtering | Not reported |
| Channel count | Fixed | One signal 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).