LowPass1

LowPass1 smooths a noisy signal before a controller consumes it.
3.30–3.34

LowPass1 smooths a noisy signal before a controller consumes it. One cut-off frequency governs every channel, and the channel count is fixed by the machine configuration. It also publishes the rate of change of its own smoothed output, so you never have to differentiate output yourself.

flowchart LR
    i1(["input — signal to smooth"]) --> B["LowPass1"]
    i2(["disable"]) --> B
    B --> o1(["output — smoothed signal"])
    B --> o2(["outputDot — rate of the smoothed signal"])
    B --> o3(["isEnabled"])

$f_c = \omega/2\pi$ — omega 6.283 rad/s is a 1 Hz cut-off. Time constant $\tau = 1/\omega$ [s]: 63% of a step in $\tau$, 90% in $2.3,\tau$, 99% in $4.6,\tau$. At the cut-off: gain 0.71, lag 45°, which is a delay of $0.125/f_c$ [s]. Below the cut-off the delay is $\tau$. That delay is the whole trade of this block.

Signals

Inputs

Path Unit Range Description
input signal unit unbounded The signal to smooth. One element per channel; the channel count is fixed by the machine configuration.
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.

Outputs

Path Unit Description
output signal unit The smoothed signal, one element per channel. Equals input exactly while bypassed. Starts from zero after every controller start, and is not cleared by a stop.
outputDot signal unit per second The rate of change of output, one element per channel. While bypassed this becomes the raw sample-to-sample difference of input divided by the task period — see the symptom table.
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 removes more noise and adds more delay. Out-of-range values are corrected silently — see Limits and errors.
enable - true - False bypasses the filter: input passes through unchanged.

omega and enable are persistent — both survive a controller restart. The inputs and outputs do not; input and disable return to their linked sources and output starts from zero. No parameters exist below this block.

Setup

  1. Link the source signal: …/actuator/actualVelocity → …/velocityFilter/input. input follows the source on a trace.

  2. Set enable false. output equals input sample for sample and isEnabled reads false.

  3. Set omega to 300. Read it back; a lower value means your task rate capped it, and tells you the highest cut-off this task rate allows.

  4. Set enable true. isEnabled reads true and output still tracks input closely, with the noise still visible.

  5. Halve omega in steps, watching the noise and the loop consuming it. Stop one step above where that loop feels soft or hunts.

    Step 5 changes what the controller sees. Lower the cut-off with the axis at rest before trying it in motion — the added delay can destabilise a tightly tuned loop.

  6. Trace every element of input and output. An element that reads zero while the machine moves is an unwired channel, not a filtered one.

Tuning

  1. Read the frequency of the ripple you want gone, in Hz, off a trace of input. Set omega to $2\pi$ times that frequency as a starting point, then lower it until the ripple is gone.
  2. Measure the delay you have bought. Step the source and read the time output takes to cross 63% of the step; that time is $\tau$, and the delay below the cut-off equals it.
  3. Keep that delay below a tenth of the response time of the loop consuming output. Above that, the loop pays for the smoothing in stability.
  4. Check the loop in motion, not at rest. Delay costs phase margin only while the axis is moving fast enough to need it.
  5. Re-check omega after 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.
  6. If you need the noise gone and the delay, fix the noise at its source — shielding, grounding, or a higher-resolution sensor. No cut-off gives you both.

Step response at three cut-offs: omega 30 reaches the step almost at once,omega 6.283 crosses 63% at 0.16 s, and omega 2 is still climbing after asecond.

Read the time constant off any curve as the moment it crosses 0.63.

Symptom Cause Action
Noise still present on output Cut-off too high Halve omega, then re-check the loop for softness
Loop went soft, hunts or oscillates after enabling Delay too high for the loop Double omega; if the noise returns, fix it at the source
Setpoint tracking lags behind the command The block is in the command path, not the feedback path Raise omega, or move the filter onto the measurement only
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 filter is not available
omega used to be accepted and now clamps The task period grew, so the upper bound fell Raise omega’s task rate back, or lower omega
output ramps from zero for a second after every start Expected: the filter starts from zero Gate the consumer off isEnabled plus a short delay
output stays at zero while the signal moves Channel unwired — an unwired element reads zero Trace input element by element and link every one
outputDot shows one large spike the moment the filter is bypassed Expected: while bypassed, outputDot is a raw difference over one task period Gate any consumer of outputDot on isEnabled
output follows input exactly, with no smoothing at all enable is false, or disable is true Read isEnabled; it tells you which of the two is holding the bypass
Some channels smooth more 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; the block cannot recover its own state, so restart the controller

A conservative starting point for a velocity signal on a 1 ms task, feeding a position loop with a 100 ms response time:

omega  = 60.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
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 — whatever the input carries reaches the output. Limit it downstream if the consumer needs a bound Not reported
outputDot Nothing Unbounded, and largest on the cycle the bypass engages 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).