Polynomial
Polynomial evaluates a polynomial in its input: $y = a_0 + a_1u + a_2u^2 + \dots$.6 minute read
Polynomial evaluates a polynomial in its input:
$y = a_0 + a_1u + a_2u^2 + \dots$. Its usual job is linearising a sensor —
fit a curve to the sensor’s error offline, put the coefficients here, and the
reading comes out proportional to the quantity it measures.
flowchart LR
i1(["input — the raw value"]) --> B["Polynomial"]
i2(["disable"]) --> B
B --> o1(["output — the corrected value"])
B --> o2(["isEnabled"])
coefficients[0]is the constant term and is always added.coefficients[1]multiplies the input,coefficients[2]the input squared, and so on up toorder. So an identity correction isorder= 1 with coefficients0, 1.
Never write order larger than the coefficient array. The block does not
check it, and a value past the end makes it read memory that is not part of the
array. Find the ceiling with Setup step 2.
order = 0 gives zero, not the constant term. For a fixed offset use
order = 1 with coefficients offset, 0.
Disabling this block outputs zero, not the input — and it writes zero into
input too. In a sensor chain that takes everything downstream to zero with
it.
Signals
Inputs
| Path | Unit | Range | Description |
|---|---|---|---|
input |
raw sensor unit | unbounded | The value to correct. A single value, not an array. The block writes zero here on every disabled cycle, so a trace reads zero while it is off. |
Outputs
| Path | Unit | Description |
|---|---|---|
output |
corrected unit | The polynomial evaluated at input. Zero — not the input — while disabled, and zero whenever order is 0. |
isEnabled |
- | True when enable is true and disable is false. It does not mean the block is producing output: order = 0 gives zero while this still reads true. |
Parameters
| Path | Unit | Default | Range | Effect |
|---|---|---|---|---|
enable |
- | true | - | False makes the output zero. |
order |
- | 1 | 1 up to the array length minus 1 | How many powers of the input to use. Not checked — a value past the array length reads out of bounds. 0 gives zero output. |
coefficients |
mixed | 0 in every element | any | The coefficients, constant term first. Element 1 multiplies the input, element 2 the input squared, and so on. |
Both persistent parameters survive a controller restart, which is how a calibration ships with a machine. No parameters exist below this block.
Setup
-
Fit the polynomial offline against known reference values. Two or three terms is usually enough; a high order fits noise rather than the sensor.
-
Find the coefficient array’s length by reading it back from the parameter tree.
ordermust stay at least one below it. -
Write
orderfirst, thencoefficients. Writing the order afterwards from an application clears the coefficients you just set. -
Write the coefficients with the constant term in element 0.
-
Apply a known reference value to the sensor and check
outputreads the right corrected value. Repeat at three or four points across the range — one point cannot tell a good fit from a bad one.Step 5 is the only check that the fit is right. A polynomial that is correct at the point you tested and wrong everywhere else looks exactly like a working correction until the machine moves.
-
Confirm
outputmatchesinputat the point where your correction should be neutral.
Tuning
There is nothing to tune at runtime — the coefficients are a calibration.
- Take measurements across the whole working range, not just the middle. A polynomial is worst at the ends.
- Use the lowest order that fits. Each extra term makes the curve wilder outside the range you measured.
- Check the behaviour beyond your measured range. A cubic that fits well from 0 to 10 can be badly wrong at 15, and there is no limiter here.
- Re-check the fit after any change to the sensor or its mounting.
- Nothing here depends on the task rate.
Read the correction as the vertical distance from the straight line.
| Symptom | Cause | Action |
|---|---|---|
The output is zero and isEnabled reads true |
order is 0 |
Set order to 1 or more; for a constant, use order 1 with coefficients offset, 0 |
| The output is zero and the block is disabled | Expected: it outputs zero rather than passing through | Enable it; if a sensor chain went dead, this is why |
input reads zero on a trace |
You are looking at a disabled cycle — the block zeroes its own input | Enable it before judging the link |
| The coefficients went to zero after setting the order from an application | Setting the order clears the coefficient array | Write order first, then the coefficients |
| The correction is right at one point and wrong elsewhere | The fit was made from too few points | Re-fit across the whole range, per Tuning step 1 |
| The output goes wildly wrong beyond the measured range | Expected: a polynomial diverges outside where it was fitted | Lower the order, or bound the output downstream |
| The output is very large or non-numeric for a large input | A high power of a large input overflows | Lower the order, or scale the input first |
| Nothing seems to change when I raise the order | The higher coefficients are zero | Write them |
The controller behaves strangely after writing a large order |
It was written past the coefficient array’s length, which reads out of bounds | Keep order below the array length; restart the controller |
| The correction is inverted | The coefficient signs are wrong, or the constant term is in the wrong element | Element 0 is the constant term |
| A non-numeric input produced a non-numeric output that then cleared | Expected: the block holds no state and recovers at once | Fix the source |
| You need this on several channels | Not possible — this block is single channel | Use one instance per channel |
A starting point for an identity correction, which is what the block ships with:
enable = true
order = 1
coefficients = 0.0, 1.0
A second-order correction with a small offset:
order = 2
coefficients = -0.05, 1.02, 0.003
Limits and errors
| Limit | Set by | What happens | Reported |
|---|---|---|---|
order below the coefficient array’s length |
Nothing | Not checked. A larger value reads past the end of the array, which is undefined and can crash or produce nonsense. Discover the length by reading coefficients back |
Not reported |
order = 0 |
Fixed | The output is zero, not the constant term | Not reported; isEnabled still reads true |
output |
Nothing | Unbounded. A high order and a large input grow very quickly. Limit it downstream if the consumer needs a bound | Not reported |
| Fit quality | Nothing | Not checked, and cannot be. A polynomial that is wrong outside the range you fitted looks correct inside it | Not reported |
| Disabled behaviour | Fixed | Output zero, not a pass-through, and input is zeroed too |
Not reported |
| Non-numeric input | Nothing | Produces a non-numeric output. The block is stateless and recovers immediately | Not reported |
| Channel count | Fixed | One channel per instance, always | Not reported |
The block raises no errors or warnings and logs nothing. Every failure above shows as a value on a trace, not as a message.
Verified against motorcortex-control3 3.30.0 (bc348fd).