GainSchedulingPVALimiter
GainSchedulingPVALimiter bounds a position reference in position, velocity, acceleration and jerk.9 minute read
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.
PvajLimiteris 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.
gainReturnTimesets that recovery, but the gain is also smoothed, so the actual recovery takes aboutgainReturnTime÷ 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$
velocityLimitand $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
-
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. -
Set each channel’s position band,
velocityLimit,accelerationLimitandjerkLimit. -
Set
modeto 0. -
Set
gainReturnTimeto 2.0 and leave the two gains at whatever your configuration ships with. -
Set
enabletrue. Command a move well inside the limits and confirmoutputtracksinputandgainOutputstays at 1. -
Command a move that runs into a position limit. Confirm
gainOutputfalls, the matchingStateflag goes true, andoutputsettles 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. -
Release the limit and time how long
gainOutputtakes to return to 1. It will be longer thangainReturnTime.
Tuning
- Set the four limits from the machine.
- Leave
modeat 0. Mode 1 is documented in the source as not robust, and modes 2 and 3 change which inputs matter. - Tune
gainReturnTimefor 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. - Leave
positionGainandvelocityGainalone unless tracking is visibly poor. They are a matched pair, and changing one without the other changes the loop’s damping. - Watch
gainOutputduring 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 yourgainReturnTimein practice. - Supply
inputDotandinputDDotonly if they are exact. Differenced derivatives make the gain schedule behave worse than leaving them at zero.
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).