LowPass2

LowPass2 smooths a noisy signal with a second-order filter: twice the roll-off of a first-order filter, and a damping setting that decides whether the output overshoots.
3.30–3.34

LowPass2 smooths a noisy signal with a second-order filter: twice the roll-off of a first-order filter, and a damping setting that decides whether the output overshoots. One cut-off and one damping govern every channel. It publishes the whole derivative stack — value, velocity, acceleration and jerk — so a setpoint path can take all four from one block.

flowchart LR
    i1(["input — signal to smooth"]) --> B["LowPass2"]
    i2(["disable"]) --> B
    i3(["vaLimiterDisable"]) --> B
    B --> o1(["output — smoothed signal"])
    B --> o2(["outputDot — velocity of the output"])
    B --> o3(["outputDDot — acceleration of the output"])
    B --> o4(["outputDDDot — jerk of the output"])
    B --> o5(["isEnabled"])
    B --> o6(["vaLimiterIsEnabled"])

$f_c = \omega/2\pi$ — omega 6.283 rad/s is a 1 Hz cut-off. beta is the damping ratio: overshoot is $e^{-\pi\beta/\sqrt{1-\beta^2}}$, so 37% at beta 0.3, 16% at 0.5, and none at 1.0 or above. Ringing frequency is $\omega\sqrt{1-\beta^2}$ [rad/s]. At the cut-off the gain is $1/(2\beta)$ — above 1 for any beta below 0.5, so a low damping amplifies rather than removes. Phase lag at the cut-off is 90°, twice a first-order filter’s, and that lag is the trade.

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.
vaLimiterDisable - - True switches the velocity and acceleration limiter off, leaving the filter itself running. Use it for a runtime override; use vaLimiterEnable 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 Velocity of output. While the filter runs this is integrated, not differenced, so it is as smooth as output. While bypassed it becomes a raw difference over one task period.
outputDDot signal unit per second² Acceleration of output, and the quantity the limiter acts on. While bypassed it becomes a raw difference of outputDot.
outputDDDot signal unit per second³ Jerk of output. Always a raw difference, so it is by far the noisiest output and lags the others by one task period. Treat it as diagnostic, not as a control signal.
isEnabled - True when enable is true and disable is false. A single value for the whole block, not one per channel.
vaLimiterIsEnabled - True when vaLimiterEnable is true and vaLimiterDisable is false. It does not tell you the limiter is currently cutting, only that it is switched on.

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.
beta - 1.0 0.1 – 10 Damping ratio, shared by all channels. Below 1 the output overshoots and rings; below 0.5 it amplifies at the cut-off. Above 1 it is slower and never overshoots. Out-of-range values are corrected silently.
vaLimiterMaxAcc signal unit per second² 1.0 must be positive Largest acceleration the limiter allows. Not validated — see Limits and errors. Only has effect while vaLimiterIsEnabled is true.
vaLimiterMaxVel signal unit per second 1.0 must be positive Largest velocity the limiter allows. Where this and vaLimiterMaxAcc conflict, the velocity bound wins. Not validated. Only has effect while vaLimiterIsEnabled is true.
enable - true - False bypasses the filter: input passes through unchanged.
vaLimiterEnable - false - True switches on the velocity and acceleration limiter. Set both bounds to real machine values before you turn this on.

All six parameters are persistent and survive a controller restart. The inputs and outputs do not; output starts from zero. No parameters exist below this block.

Setup

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

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

  3. Leave vaLimiterEnable false for the whole of setup. The limiter’s default bounds of 1.0 will throttle any real machine signal.

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

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

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

    Step 6 changes what the controller sees. A second-order filter costs twice the phase lag of a first-order one at the same cut-off. Lower the cut-off with the axis at rest before trying it in motion.

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

  8. Only if you want the block to shape motion as well as smooth it: set vaLimiterMaxAcc and vaLimiterMaxVel to your machine’s real bounds, then set vaLimiterEnable true and confirm vaLimiterIsEnabled reads true.

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, then lower it until the ripple is gone.
  2. Leave beta at 1.0 while you find omega. Damping and cut-off interact, and 1.0 is the setting with no overshoot.
  3. Step the source and measure the overshoot on output. If you want a faster response and can accept overshoot, lower beta toward 0.5. Never go below 0.5 unless you intend a resonant peak — below it the filter amplifies at the cut-off instead of cutting.
  4. Measure the delay you have bought. Step the source and read the time output takes to reach 90% of the step. Keep it below a tenth of the response time of the loop consuming output.
  5. Check the loop in motion, not at rest. Delay costs phase margin only while the axis moves fast enough to need it.
  6. 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.
  7. If you are using outputDDot or outputDDDot, look at them on a trace before you rely on them. Each derivative multiplies the remaining noise, and jerk is differenced rather than filtered.

Step response at three damping settings with the cut-off held at 6.283 rad/s:beta 0.3 overshoots to 1.37 and rings, beta 1.0 rises to 1.0 with no overshoot,and beta 3.0 has reached only 0.8 after 1.5 s.

Read the overshoot off any curve as its highest point above 1.0.

Symptom Cause Action
Noise still present on output Cut-off too high Halve omega, then re-check the loop for softness
output overshoots the step and rings beta below 1 Raise beta toward 1.0; ringing stops entirely at 1.0
Noise at the cut-off got worse after enabling beta below 0.5, so the filter has a resonant peak Raise beta to 1.0
output reaches its target far too slowly beta well above 1, or omega too low Lower beta toward 1.0 first, then raise omega
Loop went soft, hunts or oscillates after enabling Delay too high — a second-order filter costs twice the lag Double omega, or use a first-order filter instead
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
The axis crawls the moment vaLimiterEnable goes true The limiter’s default bounds are 1.0, not machine values Set vaLimiterMaxAcc and vaLimiterMaxVel first, then re-enable
Motion is clipped and you cannot tell whether the limiter did it Expected: no output reports the limiter cutting Set vaLimiterEnable false and compare; that is the only way to tell
The axis runs away in one direction with the limiter on A negative or zero value in vaLimiterMaxAcc Write a positive value; negatives are accepted and are unsafe
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
One large spike on outputDot, outputDDot and outputDDDot the moment the filter is bypassed Expected: while bypassed the derivatives are raw differences over one task period Gate every consumer of the derivative stack on isEnabled
A brief ring on output after re-enabling the filter Expected: the filter resumes with the velocity it measured while bypassed Re-enable while the axis is at rest, or accept a settle of about $1/(\beta\omega)$ seconds
outputDDDot is unusably noisy Expected: jerk is differenced, not filtered Use it for diagnosis only; filter it downstream if a consumer needs it
Some channels smooth more than others Not possible — all channels share one omega and one beta Use a separate filter per channel group
output went to a non-numeric value and stays there A non-numeric value reached input, omega or beta Fix the source; the block cannot recover its own state, so restart the controller

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

omega            = 60.0
beta             = 1.0
vaLimiterEnable  = false

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
beta within 0.1 – 10 Fixed A value outside the band is replaced by the nearest edge Silently; read beta back
vaLimiterMaxAcc, vaLimiterMaxVel Nothing Not checked. Zero and negative values are accepted, and a negative acceleration bound drives the output away in one direction until something else stops it Not reported
output Nothing while the limiter is off; vaLimiterMaxVel and vaLimiterMaxAcc shape it while the limiter is on Unbounded in position either way — the limiter bounds rate, not travel. Limit position downstream if the consumer needs a bound Not reported
outputDot, outputDDot, outputDDDot 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).