HighPass2
HighPass2 is the second-order washout filter.8 minute read
HighPass2 is the second-order washout filter. Feed it an acceleration and it
removes the sustained part — the part a platform cannot reproduce without
running out of travel — and returns the transient part, plus the velocity and
position that follow from it. The three outputs are three different
filters, not three views of one: output keeps the fast content, outputInt
keeps only content near the cut-off, and outputIInt keeps the slow content.
flowchart LR
i1(["input — acceleration to wash out"]) --> B["HighPass2"]
i2(["disable"]) --> B
B --> o1(["outputIInt — position, slow content only"])
B --> o2(["outputInt — velocity, cut-off content only"])
B --> o3(["output — acceleration, fast content only"])
B --> o4(["isEnabled"])
$f_c = \omega/2\pi$ —
omega6.283 rad/s is a 1 Hz cut-off.betais the damping ratio: 1.0 gives one small undershoot, below 1.0 the outputs ring at $\omega\sqrt{1-\beta^2}$ [rad/s].outputsettles to zero for any constant input.outputIntpeaks at the cut-off with gain $1/(2\beta\omega)$.outputIIntsettles to $1/\omega^2$ times a constant input — a factor of 0.025 at the default, so do not expect it to match the input’s magnitude.
Leave this block enabled. Disabling it does not idle it: output drops to
zero rather than passing the input through, and outputIInt drifts. It also
has no reset input — see Limits and errors.
Signals
Inputs
| Path | Unit | Range | Description |
|---|---|---|---|
input |
m/s² for a washout, or any signal unit | unbounded | The signal to wash out, normally an acceleration. One element per channel; the channel count is fixed by the machine configuration. |
disable |
- | - | True forces output to zero and leaves the other two outputs coasting. It is not a bypass and does not pass input through. Use enable for the configured intent, and read the note above before using either. |
Outputs
| Path | Unit | Description |
|---|---|---|
outputIInt |
m for a washout, or input unit × s² | Position. Keeps the slow content of input and settles to $1/\omega^2$ times a constant input. The smoothest of the three. Starts from zero after every controller start, and is never cleared once running. |
outputInt |
m/s for a washout, or input unit × s | Velocity. Keeps only content near the cut-off, and settles to zero for both a constant input and a very fast one. Starts from zero after every controller start. |
output |
m/s² for a washout, or the input unit | Acceleration. Keeps the fast content and settles to zero for a constant input. It is not smoothed — noise on input reaches it at full size and undelayed. Zero while disable is true or enable is false. |
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 sustained content and washes it out more slowly, so the platform travels further. Higher washes out sooner and the motion feels thinner. Out-of-range values are corrected silently — see Limits and errors. |
beta |
- | 1.0 | 0.1 – 2 | Damping ratio, shared by all channels. 1.0 gives one small undershoot and no ringing. Below 1.0 the outputs ring, badly below 0.5. Above 1.0 the washout is slower and gentler. Out-of-range values are corrected silently. |
enable |
- | true | - | False forces output to zero. It does not bypass the block. See the note under the diagram. |
All three parameters are persistent and survive a controller restart. The inputs and outputs do not; all three outputs start from zero. No parameters exist below this block.
Setup
-
Link the source signal:
…/model/commandedAcceleration→…/washout/input.inputfollows the source on a trace. -
Leave
enabletrue for the whole of setup. There is no useful idle state, and the outputs are already zero before any input arrives. -
Set
omegato 6.283 andbetato 1.0. Readomegaback; a lower value means your task rate capped it. -
Decide which output your consumer needs, and wire only that one. A platform position command takes
outputIInt; a velocity feedforward takesoutputInt; an accelerometer-matching path takesoutput. -
Apply a sustained acceleration on
inputand hold it.outputmust return to zero, andoutputIIntmust settle to a constant, not keep climbing.Step 5 is the check that the washout works. If
outputIIntkeeps climbing whileinputis held constant, stop and fix that before you connect a platform — it will run to its travel limit. -
Read the settled value of
outputIIntand divide it by the input you applied. It should be close to $1/\omega^2$. This confirms the scaling you have to compensate downstream. -
Trace every element of
inputand each output you use. An element that reads zero while the machine moves is an unwired channel.
Tuning
- Measure your consumer’s travel budget first, in metres. That budget, not the
feel of the motion, sets the lowest
omegayou can use. - Apply the largest sustained acceleration your application produces and read
the peak of
outputIInt. Raiseomegauntil that peak fits the budget with margin. - Leave
betaat 1.0 while you findomega. Damping and cut-off interact, and 1.0 is the setting with almost no undershoot. - Step the input and watch
outputreturn through zero. The undershoot is the platform being pulled back to centre; it is unavoidable in a washout. - If that return is too abrupt, raise
betatoward 2.0. If the motion feels dead, lowerbetatoward 0.7 — but never below 0.5 unless you intend ringing. - Re-check the travel budget after every
betachange. Damping changes the peak excursion as well as its shape. - 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. - Look at
outputon a trace before relying on it. It is unsmoothed, so it carries whatever noiseinputcarries.
Read the pull-back off any curve as its lowest point below zero.
| Symptom | Cause | Action |
|---|---|---|
outputIInt is far smaller than the input |
Expected: its steady gain is $1/\omega^2$, which is 0.025 at the default cut-off | Scale it downstream; there is no gain parameter in this block |
outputIInt keeps climbing while input is held constant |
The block is not running the washout — check isEnabled reads true |
Set enable true and disable false; a disabled block coasts instead of washing out |
outputIInt reached the platform’s travel limit |
Cut-off too low for the accelerations you are feeding it | Raise omega and re-check step 2 of Tuning |
output is noisy |
Expected: output is not smoothed, unlike the two integrals |
Filter input upstream, or take outputInt instead |
output sits at zero while input clearly has a value |
Expected for a constant input, since a constant has no fast content. Otherwise enable is false |
Read isEnabled; if it is true, this is normal washout behaviour |
| All three outputs ring after a step | beta below 1 |
Raise beta toward 1.0; ringing stops almost entirely at 1.0 |
| The motion pulls back too hard after a step | Damping too low for the feel you want | Raise beta toward 2.0, then re-check the travel budget |
| The motion feels dead and thin | Cut-off too high — the sustained content is being removed too soon | Lower omega, within the travel budget |
omega or beta reads back different from what you wrote |
Outside the accepted band | Read the value back and work within it; the task rate sets omega’s upper bound |
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 |
outputIInt sits at a large offset and will not return, even with input at zero |
The block’s state is off-centre and it has no reset | Restart the controller. Nothing in the parameter tree can clear it |
outputIInt drifted while the block was disabled |
Expected: a disabled block holds its velocity and keeps integrating it | Leave the block enabled; restart the controller to clear the drift |
| Some channels wash out faster than others | Not possible — all channels share one omega and one beta |
Use a separate washout per channel group |
| An output went to a non-numeric value and stays there | A non-numeric value reached input, omega or beta |
Fix the source, then restart the controller. Disabling the block does not clear it |
A conservative starting point for a motion-platform washout on a 1 ms task, with a generous travel budget:
omega = 6.283
beta = 1.0
enable = true
This is a starting point, not a final tuning. Work steps 1 and 2 with your own travel budget.
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 |
beta within 0.1 – 2 |
Fixed | A value outside the band is replaced by the nearest edge. Note the upper bound is 2, lower than the second-order low-pass filter’s | Silently; read beta back |
outputIInt, outputInt, output |
Nothing | Unbounded. outputIInt in particular has no travel limit of its own — bound it downstream before it reaches a platform |
Not reported |
| Block state | Nothing | There is no reset input and no way to clear the outputs in service. Once outputIInt is off-centre, only a controller restart returns it to zero |
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).