GainSchedulingPVALimiter

GainSchedulingPVALimiter bounds a position reference in position, velocity, acceleration and jerk.
Current release

GainSchedulingPVALimiter bounds a position reference in position, velocity, acceleration and jerk. It uses a feedback loop whose gain is scheduled: when the trajectory runs into a limit the gain is reduced so the limited setpoint parks smoothly against the limit rather than fighting it, and once every signal is back inside its limits the gain returns to normal over gainReturnTime.

Deprecated — scheduled for removal. PvajLimiter is the only setpoint limiter that may be used for new work. This block is kept only until the last machine is off it, and will then be deleted. Plan the migration; do not start a new installation on it.

Its Limits01, Limits02, … leaf names were deliberately chosen to match these ones, so an existing configuration package and dashboard keep applying across the swap. The rest does not carry over. Settings/omega, Settings/positionGain, Settings/velocityGain, Settings/gainReturnTime, velocityFactor, gainOutput and the adaptive group have no counterpart — there is no gain scheduling and no input filter in the replacement. Config entries that set those leaves will not resolve. The important behavioural difference is the position limit:

Block How closely the position limit is held
PvajLimiter Exactly. No tolerance at all
This block To about 1e-6 — a soft limit, not a guarantee

Those figures come from a test that runs both against the same limit set. If your position limit is a safety boundary rather than a shaping preference, that difference is the reason to migrate.

flowchart LR
    i1(["input — unlimited position reference"]) --> B["GainSchedulingPVALimiter"]
    i2(["inputDot — unlimited velocity"]) --> B
    i3(["inputDDot — unlimited acceleration"]) --> B
    i4(["disable"]) --> B
    B --> o1(["output — limited position"])
    B --> o2(["outputDot — limited velocity"])
    B --> o3(["outputDDot — limited acceleration"])
    B --> o4(["gainOutput — the scheduled gain"])
    B --> o5(["isEnabled"])

Each channel also publishes State01, State02, … with six limit flags and an active flag, plus Limits01/activePositionLowerLimit and activePositionUpperLimit.

The scheduled gain falls toward zero while any limit is active and returns to 1 once everything is inside. gainReturnTime sets that recovery, but the gain is also smoothed, so the actual recovery takes about gainReturnTime ÷ 0.7 — roughly 2.9 s for a setting of 2.

Supply exact derivatives or none. This block’s gain schedule degrades when inputDot and inputDDot are differenced from a noisy input. If your motion source does not produce true derivatives, leave those inputs at zero.

This block cannot be configured from an application in C++ — its limits are reachable only through the parameter tree.

Signals

Inputs

Path Unit Range Description
input m or rad unbounded The unlimited position reference. One element per channel.
inputDot m/s or rad/s unbounded The unlimited velocity reference, used in the modes that take it.
inputDDot m/s² or rad/s² unbounded The unlimited acceleration reference.
disable - - True passes input straight to output. Use it for a runtime override; use enable for the configured intent.

Outputs

Path Unit Description
output m or rad The limited position. It settles against the limit rather than being clamped to it, so it may sit a fraction outside — see Limits and errors.
outputDot m/s or rad/s The limited velocity.
outputDDot m/s² or rad/s² The limited acceleration.
gainOutput - The scheduled gain, one element per channel. 1 while free, near zero while a limit is active, recovering in between. Watch this to see when the block is limiting and how long it takes to let go.
isEnabled - True when enable is true and disable is false.

Per channel, State01, State02, …: positionUpperLimitActive, positionLowerLimitActive, velocityUpperLimitActive, velocityLowerLimitActive, accelerationUpperLimitActive, accelerationLowerLimitActive and active.

Parameters

Block level: enable, and adaptive.

Settings holds the loop tuning:

Field Unit Description
positionGain 1/s² Position gain of the feedback loop.
velocityGain 1/s Velocity gain. The two together are really one bandwidth-and-damping choice.
gainReturnTime s How long the gain takes to recover after the last limit clears. Accepted range 0.1 – 5.0; outside that it is corrected and logged. The real recovery is about this divided by 0.7.
omega rad/s Cut-off of the input pre-filter.

Limits01, Limits02, … hold each channel’s limits:

Field Unit Description
positionLowerLimit, positionUpperLimit m or rad The position band. Soft — see Limits and errors.
velocityLimit m/s or rad/s Symmetric.
accelerationLimit m/s² or rad/s² Symmetric.
jerkLimit m/s³ or rad/s³ Symmetric.
mode - Which inputs are used and whether a pre-limit is applied. See below.
mode What the machine does
0 Position input only, with a pre-limit applied. The recommended value.
1 Position input, no pre-limit. The source records that this mode is not robust — avoid it.
2 Velocity and acceleration inputs are used as well.
3 Position input only, with the position limit applied as a taper rather than a clamp. See the note below.
4 Not used.

In mode 3 the limit is approached through a taper instead of a clamp. The taper begins one braking distance inside each active position limit:

Break-point offset $= V^2/2A$ [m], with $V$ velocityLimit and $A$ accelerationLimit — the distance an axis at full speed needs to stop at the acceleration limit. It is capped at half the width of the active band, so the two break points can never cross. On a band narrower than twice the braking distance the two meet in the middle and the taper degenerates into a hard limit, which is the correct behaviour for a band shorter than the stop it has to absorb.

Raising velocityLimit or lowering accelerationLimit therefore starts the taper further from the limit and softens the approach over a longer distance.

All parameters are persistent and survive a restart.

Setup

  1. Consider migrating first. If this is a new installation, use PvajLimiter. The rest of this page is for a machine that already runs this block.

  2. Set each channel’s position band, velocityLimit, accelerationLimit and jerkLimit.

  3. Set mode to 0.

  4. Set gainReturnTime to 2.0 and leave the two gains at whatever your configuration ships with.

  5. Set enable true. Command a move well inside the limits and confirm output tracks input and gainOutput stays at 1.

  6. Command a move that runs into a position limit. Confirm gainOutput falls, the matching State flag goes true, and output settles against the limit.

    Step 6 will let the setpoint sit slightly past the limit. That is how this block works — the limit is where the loop settles, not a wall. Leave margin, and if the boundary is a safety limit, migrate to PvajLimiter.

  7. Release the limit and time how long gainOutput takes to return to 1. It will be longer than gainReturnTime.

Tuning

  1. Set the four limits from the machine.
  2. Leave mode at 0. Mode 1 is documented in the source as not robust, and modes 2 and 3 change which inputs matter.
  3. Tune gainReturnTime for how quickly the block should let go after a limit event. Shorter recovers sooner and can re-enter the limit; longer keeps the setpoint soft for a while afterwards. The accepted range is 0.1 to 5.0.
  4. Leave positionGain and velocityGain alone unless tracking is visibly poor. They are a matched pair, and changing one without the other changes the loop’s damping.
  5. Watch gainOutput during commissioning. It is the clearest picture of what this block is doing: a dip means a limit was hit, and the width of the recovery is your gainReturnTime in practice.
  6. Supply inputDot and inputDDot only if they are exact. Differenced derivatives make the gain schedule behave worse than leaving them at zero.

Scheduled gain through a 0.6 s limit event at three return times: all threedrop to near zero while limiting, then recover to 1 — the shortest in about1.4 s and the longest still recovering after 3 s.

Read the recovery time off how long each curve takes to climb back to 1.

Symptom Cause Action
The setpoint sits slightly past a position limit Expected: this block’s position limit is soft — it settles against the limit rather than clamping Leave margin, or migrate to PvajLimiter
The machine passed the position limit by more than expected The soft limit plus the servo’s own following error Back the limits off, and consider migrating
The block behaves worse when the derivative inputs are wired Those derivatives are differenced rather than exact, and the gain schedule folds Leave inputDot and inputDDot at zero unless your source produces true values
Recovery after a limit takes longer than gainReturnTime Expected: the gain is smoothed as well as ramped, so recovery is about that time divided by 0.7 Shorten gainReturnTime
gainReturnTime reads back different from what was written It is outside the accepted 0.1 – 5.0 range and was corrected Write a value in range; the correction is logged
The setpoint keeps re-entering the limit gainReturnTime too short, so the gain recovers before the situation has Lengthen it
The setpoint stays soft long after the limit cleared gainReturnTime too long Shorten it
In mode 3 the setpoint starts easing off a long way before the limit Expected: the taper begins one braking distance $V^2/2A$ inside the limit Lower velocityLimit or raise accelerationLimit to shorten it
In mode 3 the limit behaves like a hard clamp with no taper at all Expected: the position band is narrower than twice the braking distance, so the two break points met in the middle Widen the band, or lower velocityLimit
Motion is rough or unstable near a limit mode is 1, which the source records as not robust Set mode to 0
The block cannot be configured from the application Expected: its limits are reachable only through the parameter tree Configure it in the configuration package
gainOutput never returns to 1 Some limit is still active — check the State flags for that channel Widen the limit, or fix what is commanding past it
The gain schedule resumed mid-recovery after a restart The gain is not reset at start Expected; it recovers on its own
I need the position limit guaranteed This block cannot do that Use PvajLimiter

A starting point for a channel with 1 m of travel:

enable                        = true
Settings/gainReturnTime       = 2.0
Limits01/positionLowerLimit   = -0.5
Limits01/positionUpperLimit   =  0.5
Limits01/velocityLimit        =  0.5
Limits01/accelerationLimit    =  5.0
Limits01/jerkLimit            = 50.0
Limits01/mode                 = 0

These are the block’s own defaults, and they are the limit set the comparison test uses.

Limits and errors

Limit Set by What happens Reported
output position The position band Soft. The setpoint settles against the limit and may sit about 1e-6 outside it. This is not a guarantee The State position flags
output velocity, acceleration Their limits Held to about 1e-9 The State velocity and acceleration flags
Jerk jerkLimit Bounded Not separately reported
gainReturnTime within 0.1 – 5.0 Fixed Corrected to the nearest edge Logged when corrected
Actual recovery time Fixed About gainReturnTime divided by 0.7, because the gain is smoothed as well as ramped Watch gainOutput
Derivative inputs Nothing Not checked. Differenced derivatives degrade the gain schedule — worse than supplying none Not reported
Configuration from C++ Not available The limits are writable only through the parameter tree Not applicable
The mechanism Not bounded This block bounds the setpoint. The machine passes the limit by its servo following error, on top of the soft limit above Not reported
Gain schedule state Nothing Not reset at start; it recovers on its own gainOutput
Channel count Machine configuration Fixed once the controller starts. Sub-trees are numbered from 1 Not reported

The block logs when it corrects a setting outside its accepted range. Every other condition above shows as a value on a trace, not as a message.


Verified against motorcortex-control3 3.32.1 (340db23).