HighPass1
HighPass1 removes the slow content of a signal and keeps the fast — sensor drift, a thermal offset, a load cell’s zero error.7 minute read
HighPass1 removes the slow content of a signal and keeps the fast — sensor
drift, a thermal offset, a load cell’s zero error. One cut-off frequency
governs every channel, and the channel count is fixed by the machine
configuration. Its steady output for a constant input is zero, not the
input: this block deletes the part of the signal that does not change.
flowchart LR
i1(["input — signal to wash out"]) --> B["HighPass1"]
i2(["disable"]) --> B
B --> o1(["output — fast content of the input"])
B --> o2(["isEnabled"])
$f_c = \omega/2\pi$ —
omega6.283 rad/s is a 1 Hz cut-off. Time constant $\tau = 1/\omega$ [s]: a step appears in full, then decays to 37% in $\tau$ and to 1% in $4.6,\tau$. At the cut-off: gain 0.71 and 45° of phase lead. Signals slower than the cut-off are removed; signals faster pass at gain 1. Choosingomegais choosing how slow “slow” means.
This block has no derivative output and no reset input. It also cannot be bypassed without restoring the offset it was removing — see the symptom table.
Signals
Inputs
| Path | Unit | Range | Description |
|---|---|---|---|
input |
signal unit | unbounded | The signal to wash out. One element per channel; the channel count is fixed by the machine configuration. |
disable |
- | - | True bypasses the filter: input passes straight to output, offset included. Use it for a runtime override from a supervisor; use enable for the configured intent. |
Outputs
| Path | Unit | Description |
|---|---|---|
output |
signal unit | The fast content of input, one element per channel. Settles to zero for any constant input. Equals input exactly while bypassed. Starts from the full value of input after every controller start, then washes out over $\tau$. |
isEnabled |
- | True when enable is true and disable is false. A single value for the whole block, not one per channel. |
Parameters
| Path | Unit | Default | Range | Effect |
|---|---|---|---|---|
omega |
rad/s | 6.283 (1 Hz) | 0.1 – 0.628/task period [s] | Cut-off, shared by all channels. Lower keeps more of the slow content and takes longer to wash a step out. Higher removes more, and starts eating the signal you wanted to keep. Out-of-range values are corrected silently — see Limits and errors. |
enable |
- | true | - | False bypasses the filter: input passes through unchanged, offset included. |
Both parameters are persistent and survive a controller restart. The inputs and outputs do not. No parameters exist below this block.
Setup
-
Link the source signal:
…/sensor/rawForce→…/forceWashout/input.inputfollows the source on a trace. -
Set
enablefalse.outputequalsinputsample for sample andisEnabledreads false. -
Set
omegato 300. Read it back; a lower value means your task rate capped it, and tells you the highest cut-off this task rate allows. -
Hold the machine still and note the constant value
inputsits at. That offset is what the block is going to remove. -
Set
enabletrue.outputstarts at the full value ofinput, then decays toward zero. Time that decay — it reaches 37% of the way at $\tau$.Step 5 injects the whole offset into whatever consumes
output. The filter starts from a clean state, so its first sample is the input in full. Enable it with the machine at rest and the consumer gated off. -
Hold the machine still again.
outputshould sit at zero, not at the offset from step 4. If it does not, the cut-off is too low for the drift you have. -
Trace every element of
inputandoutput. An element that reads zero while the machine moves is an unwired channel, not a washed-out one.
Tuning
- Decide the slowest signal you want to keep, in Hz. Set
omegato $2\pi$ times that frequency; everything slower than it will be removed. - Measure the drift you want gone. Read how long the offset takes to build on
a trace, in seconds;
omegamust be at least a few times $1/$that. - Check the two against each other. If the drift builds as fast as the signal you want to keep, no cut-off separates them and this block cannot help.
- Step the machine and read the decay off
output. The time to 37% is $\tau$, and $\tau$ is how long a genuine step survives before the filter eats it. - Confirm the steady state with the machine at rest:
outputat zero, not at an offset. - Re-check
omegaafter any task-rate change. The upper bound scales with the task period, so a slower task can clamp a cut-off that used to be accepted.
Read the time constant off any curve as the moment it crosses 0.37.
| Symptom | Cause | Action |
|---|---|---|
output sits at zero while input clearly has a value |
Expected: a constant input has no fast content, so there is nothing to pass | Confirm with a moving signal; if that also reads zero, the channel is unwired |
The offset is still on output at rest |
Cut-off too low for the drift | Raise omega; if the drift is as fast as your signal, this block cannot separate them |
| A genuine slow movement got deleted | Cut-off too high — the block cannot tell drift from slow signal | Lower omega, and accept that some drift stays |
output jumps to the full input value the moment the filter is enabled |
Expected: the block starts from a clean state, so the offset appears once and washes out over $\tau$ | Enable at rest, or gate the consumer off isEnabled plus a few $\tau$ |
The same jump every time disable is toggled off |
Expected: the same reason — the state is cleared while bypassed | Do not toggle the bypass during operation; leave enable set and use it as configuration |
Bypassing the filter put a large offset back on output |
Expected: bypass restores the input in full, including the DC the filter was removing | Bypass only when the consumer can accept the raw signal |
output overshoots the other way after a step |
Expected: the block removes the step’s steady part, so the output must return through zero | None; this is what a washout does |
omega reads back lower than written |
Outside the accepted band for this task rate | Raise the task rate or accept the cap |
omega reads back as 0.1 |
Written below the fixed lower bound | Write 0.1 or more; a slower washout is not available |
omega used to be accepted and now clamps |
The task period grew, so the upper bound fell | Raise the task rate back, or lower omega |
| You need the rate of the washed-out signal | The block publishes no derivative | Differentiate downstream, or filter first and difference after |
| Some channels wash out faster than others | Not possible — all channels share one omega |
Use a separate filter per channel group |
output went to a non-numeric value and stays there |
A non-numeric value reached input or omega |
Fix the source, then bypass the filter for one cycle — that clears its state |
A conservative starting point for washing thermal drift off a force signal on a 1 ms task, keeping everything above about 0.5 Hz:
omega = 3.14
enable = true
This is a starting point, not a final tuning. Work steps 1 to 3 with a trace of your own signal.
Limits and errors
| Limit | Set by | What happens | Reported |
|---|---|---|---|
omega ≥ 0.1 rad/s |
Fixed | A slower value is replaced by 0.1 rad/s | Silently; read omega back |
omega ≤ 0.628 / task period [s] |
Task rate — 628 rad/s on a 1 ms task, 62.8 rad/s on a 10 ms task | A faster value is replaced by the edge. This is what keeps the filter stable at any setting | Silently; read omega back |
output |
Nothing | Unbounded — a fast input reaches the output at full size. Limit it downstream if the consumer needs a bound | Not reported |
| Channel count | Machine configuration | Fixed once the controller starts; it cannot be changed at runtime | 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).