BandPass1
BandPass1 passes a band of frequencies and rejects everything slower and everything faster.8 minute read
BandPass1 passes a band of frequencies and rejects everything slower and
everything faster. The band is set by two independent cut-offs rather than by a
centre frequency, so you set its low edge and its high edge separately. Unlike
the other filters here, its passband gain is not 1 — the output is scaled
by omegaHighPass, so moving the low edge of the band also rescales the
output.
flowchart LR
i1(["input — signal to filter"]) --> B["BandPass1"]
i2(["disable"]) --> B
i3(["reset"]) --> B
B --> o1(["output — content inside the band"])
B --> o2(["outputDot — rate inside the band"])
B --> o3(["isEnabled"])
$f = \omega/2\pi$ —
omegaHighPass1 rad/s is a 0.16 Hz low edge,omegaLowPass10 rad/s a 1.6 Hz high edge. Passband gain isomegaHighPassitself, so the defaults happen to give gain 1. The peak is $-0.8$ dB at the defaults, not 0 dB, because a decade of separation is not wide enough for the two edges to stop interacting. Keep both cut-offs below 0.628/task period [s]; nothing in the block enforces that for you.
A channel whose input is exactly zero is reset to zero and stays there
until the input moves off zero. This block also has no automatic stability
limit — see Limits and errors before you write either cut-off.
Signals
Inputs
| Path | Unit | Range | Description |
|---|---|---|---|
input |
signal unit | unbounded, but exactly 0.0 triggers a reset | The signal to filter. One element per channel; the channel count is fixed by the machine configuration. This path is treated as configuration rather than as a link target, so it survives a restart with whatever value it last held. |
disable |
- | - | True bypasses the filter: input passes straight to output. Use it for a runtime override from a supervisor; use enable for the configured intent. |
reset |
- | - | A rising value clears output and input to zero for every channel, once. It clears only part of the filter’s memory, so the output can move again immediately. Ignored while the block is bypassed, and consumed even then. |
Outputs
| Path | Unit | Description |
|---|---|---|
output |
signal unit × omegaHighPass |
The content of input inside the band, one element per channel. Equals input exactly while bypassed. Starts from zero after every controller start. This path is writable and survives a restart, but the block overwrites it on the next cycle it runs. |
outputDot |
signal unit per second | The rate of the filtered signal. It matches the rate of output only while damping is 0. It is not updated while the block is bypassed and holds its last value indefinitely. |
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 |
|---|---|---|---|---|
damping |
- | 0.0 | 0 – 0.9 in practice | Slows the high edge of the band. 0 leaves it at omegaLowPass; 0.5 halves it. At 1.0 the output freezes and above 1.0 it runs away — see Limits and errors. Prefer lowering omegaLowPass instead. |
omegaHighPass |
rad/s | 1.0 (0.16 Hz) | 0.1 – 0.628/task period [s] | Low edge of the band, and the filter’s gain. Raising it rejects more slow content and multiplies the output by the same factor. Not checked — a value above the range diverges. |
omegaLowPass |
rad/s | 10.0 (1.6 Hz) | 0.1 – 0.628/task period [s] | High edge of the band. Lowering it rejects more fast content. Keep it at least a decade above omegaHighPass, or the band’s peak drops well below its nominal gain. Not checked — a value above the range diverges. |
enable |
- | true | - | False bypasses the filter: input passes through unchanged. |
All four parameters are persistent and survive a controller restart, and so do
input, output and outputDot. No parameters exist below this block.
Setup
-
Link the source signal into
inputand confirm on a trace thatinputfollows the source. If your source can sit at exactly zero, read the note under the diagram first. -
Set
enablefalse.outputequalsinputsample for sample andisEnabledreads false. -
Compute your task rate’s ceiling: 0.628 divided by the task period in seconds. That is 628 on a 1 ms task. Neither cut-off may exceed it.
-
Set
omegaHighPassto the low edge you want andomegaLowPassto the high edge, both below the ceiling from step 3 and at least a decade apart. Leavedampingat 0.Step 4 has no safety net. A cut-off above the ceiling makes the output grow without bound instead of being rejected. Check both values against step 3 before you set
enabletrue. -
Set
enabletrue.isEnabledreads true andoutputresponds to movement in the band. -
Feed a slow movement and confirm
outputstays near zero. Feed a fast movement and confirm the same. Feed one in the band and confirmoutputresponds. -
Divide
outputbyinputfor an in-band signal. The ratio should be close toomegaHighPass. That factor is what you compensate for downstream. -
Trace every element of
inputandoutput. An element that reads zero while the machine moves is either unwired or being reset by an exact-zero input.
Tuning
- Read the frequency you want to keep off a trace of
input, in Hz. SetomegaHighPassto $2\pi$ times about a third of it, andomegaLowPassto $2\pi$ times about three times it. - Check both against the ceiling from Setup step 3 every time you change either.
- Widen the band until the signal you want passes at full size. Narrow it until the content you want rejected is gone. Those two pull against each other, and the gap between them is the whole tuning.
- Measure the passband gain after every
omegaHighPasschange. The gain moves with it, so a wider band is also a quieter one. - Leave
dampingat 0. It duplicatesomegaLowPass— only the product of the two matters — and it has no safe upper limit. ChangeomegaLowPassinstead. - Re-check both cut-offs after any task-rate change. The ceiling scales with the task period, and a value that was safe on a fast task can diverge on a slow one.
Read the passband gain off any curve as its highest point, and the band edges as where it falls 3 dB below that.
| Symptom | Cause | Action |
|---|---|---|
output is a constant multiple of what you expected |
Expected: the passband gain is omegaHighPass, not 1 |
Scale downstream, or set omegaHighPass to 1 and set the low edge with omegaLowPass alone |
| The passband gain changed after you retuned the low edge | Expected: gain and low edge are the same parameter | Recompensate downstream after every omegaHighPass change |
output grew without bound until something tripped |
A cut-off above 0.628/task period, or damping above 1 |
Bring both cut-offs under the ceiling and damping to 0, then restart the controller |
output froze at a value and outputDot still reads non-zero |
damping is exactly 1 |
Set damping to 0 |
| A channel sits at zero and will not move | Its input is exactly 0.0, which resets that channel every cycle |
Confirm on a trace that input is non-zero; an unwired channel reads exactly zero |
| A channel dropped to zero mid-motion and recovered | Its input landed on exactly 0.0 for a cycle |
Expected with quantised or integer-derived signals; add a tiny offset upstream if it recurs |
| The peak is several dB below the gain you calculated | The two cut-offs are too close together | Separate them by at least a decade |
output does not respond to the movement you care about |
The band excludes it | Widen the band and re-check with step 3 of Tuning |
Slow drift is still on output |
Low edge too low | Raise omegaHighPass, and recompensate the gain |
Noise is still on output |
High edge too high | Lower omegaLowPass |
outputDot is frozen while the filter is bypassed |
Expected: it is not written on the bypass path | Gate any consumer of outputDot on isEnabled |
outputDot does not match the slope of output |
damping is not 0 |
Set damping to 0, or differentiate output downstream instead |
reset did nothing |
The block was bypassed at the time, and the reset was consumed | Enable the block first, then reset |
output moved again immediately after a reset |
Expected: a reset clears only part of the filter’s memory | Bypass the block for one cycle to clear it fully |
A large step on output after re-enabling |
Expected: the slow-content memory is cleared while bypassed, so the input’s offset appears once and washes out | Re-enable at rest, or gate the consumer off isEnabled |
output and outputDot came back after a restart with old values |
Expected: both are stored as configuration | Ignore them until the block has run one cycle |
| Some channels filter differently from others | Not possible — all channels share one band and one damping |
Use a separate filter per channel group |
A conservative starting point for isolating a 0.5 Hz oscillation on a 1 ms task, with the gain left at 1:
omegaHighPass = 1.0
omegaLowPass = 10.0
damping = 0.0
enable = true
This is a starting point, not a final tuning. Work step 1 with a trace of your own signal.
Limits and errors
| Limit | Set by | What happens | Reported |
|---|---|---|---|
omegaHighPass, omegaLowPass |
Nothing | Not checked. Both must stay under 0.628/task period [s] — 628 rad/s on a 1 ms task. Above that the output grows without bound instead of filtering, and only a controller restart clears it | Not reported |
damping |
Nothing | Not checked. At 1.0 the output freezes; above 1.0 it grows without bound. Keep it at 0 | Not reported |
input exactly 0.0 |
Fixed | That channel’s output and input are set to zero for that cycle, every cycle the condition holds |
Not reported; visible as a channel stuck at zero |
output, outputDot |
Nothing | Unbounded. Limit downstream if the consumer needs a bound | Not reported |
| Block state | reset, or a bypassed cycle |
reset clears part of the memory; a bypassed cycle clears the rest. There is no single action that clears all of it |
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).