PVALimiters
PVALimiters is the multi-axis form of PVALimiter.7 minute read
PVALimiters is the multi-axis form of PVALimiter. It
takes array inputs, runs one independent limiter per channel, and returns array
outputs — so a multi-axis machine presents one block instead of several.
Each channel keeps its own limits. Every axis has a complete parameter set in its own sub-tree: its own travel range, speed, acceleration and tracking settings. This block only fans the signals out and gathers them back.
Deprecated — scheduled for removal.
PvajLimiteris the only setpoint limiter that may be used for new work, and it is natively multi-channel: one instance limits N axes, with every limit, switch and diagnostic per channel. This wrapper has no counterpart to port — give the replacement the channel count instead. This block is kept only until the last machine is off it, and will then be deleted.
The per-channel migration is the one described on
PVALimiter: the replacement has no input filter, so feed it
the setpoint directly and supply the derivatives on its own leaves.
flowchart LR
i1(["inputs — position references"]) --> B["PVALimiters"]
i2(["inputsDot — velocity references"]) --> B
i3(["inputsDDot — acceleration references"]) --> B
B --> o1(["outputs — limited positions"])
B --> o2(["outputsDot — limited velocities"])
B --> o3(["outputsDDot — limited accelerations"])
B --> o4(["pLimActive"])
B --> o5(["vLimActive"])
B --> o6(["aLimActive"])
B --> o7(["state"])
Each channel behaves exactly as
PVALimiterdescribes, including the square-root velocity envelope that decelerates an axis into its position limit. Read that page for the tuning — everything below is about the wrapper.
The three limiting flags are combined across channels. pLimActive true
means some axis is at its position envelope; it does not say which. To find
out, read the same flag inside each channel’s own sub-tree.
inputsDDot has no effect. The acceleration array is accepted and ignored
— the sub-limiters never receive it. Leave it unlinked.
This block has no enable, no disable and no isEnabled. To bypass one
axis, use disable inside that channel’s own sub-tree.
Signals
Inputs
| Path | Unit | Range | Description |
|---|---|---|---|
inputs |
m or rad | unbounded | Position references, one element per channel. Note the plural path names throughout this block. |
inputsDot |
m/s or rad/s | unbounded | Velocity references. They reach each channel’s limiter, and are used only where that channel has its own enablePVAInputs set. |
inputsDDot |
m/s² or rad/s² | - | Accepted and ignored. The acceleration array does not reach the per-channel limiters. Leave it unlinked. |
Outputs
| Path | Unit | Description |
|---|---|---|
outputs |
m or rad | The limited positions, one element per channel. Each starts from zero after a controller start and moves to its input under that channel’s limits. |
outputsDot |
m/s or rad/s | The limited velocities. |
outputsDDot |
m/s² or rad/s² | The limited accelerations. |
pLimActive |
- | True while at least one channel is being held back by its position envelope. |
vLimActive |
- | True while at least one channel is at its speed limit. |
aLimActive |
- | True while at least one channel is at its acceleration limit. Like the single-axis block, it is suppressed on any channel where a position or velocity limit is also active, so it under-reports. |
state |
- | The same three flags again, grouped. |
Parameters
There are no parameters at this level. Everything is configured per
channel, in the sub-trees pvaLimiter01, pvaLimiter02 and so on — one per
channel, numbered from 1 and always two digits.
Each of those carries the full set described in
pva-limiter.md: lowerLimit, upperLimit, maxVelocity,
maxAcceleration, maxBrakingAcceleration, omega, beta, enable,
disable, enablePLim and enablePVAInputs, along with that channel’s own
outputs and diagnostics.
Setup
-
Read the length of
inputsfrom the parameter tree and confirm it matches your axis count. It is fixed when the machine is built. -
Configure each channel’s sub-tree separately: travel limits, speed and acceleration for that axis. There is no shared setting — an axis you forget keeps the defaults of ±1, 1 m/s and 10 m/s².
-
Set
maxBrakingAccelerationat or belowmaxAccelerationin every channel. This is the one relationship that silently causes overshoot, per axis. -
Link
inputsand, if your source produces them,inputsDot. LeaveinputsDDotunlinked. -
Command a small move on one axis and confirm only that channel’s
outputselement responds.Step 5 is the check that the channels are independent. If moving one axis changes another’s output, the arrays are wired in the wrong order — and every limit you set afterwards will be applied to the wrong axis.
-
Command a move that runs into a position limit on one axis. Confirm
pLimActivegoes true here, and that the same flag is true in that channel’s own sub-tree and false in the others. -
Expect one startup warning per channel about
omega. It is normal — seepva-limiter.md.
Tuning
All the tuning is per channel and is described in
pva-limiter.md. What is specific to this block:
- Tune one axis at a time, in its own sub-tree, with the others held still. The aggregate flags cannot tell you which axis is limiting.
- Keep a written record of which sub-tree is which axis. The numbering starts
at 1 and the array indices start at 0, so
pvaLimiter01is element 0. - When the aggregate
pLimActivegoes true unexpectedly, walk the sub-trees and read each channel’s ownpLimActiveto find the axis. There is no faster route. - Watch each channel’s
currentMaxVelduring a limit approach — it is the most informative signal in the block and there is one per axis. - If several axes should move together and stop together, note that this block does not coordinate them: each is limited independently, so a limited axis falls behind and the path through space changes. Coordinate upstream if that matters.
Read each channel’s behaviour the same way; the axes do not interact.
| Symptom | Cause | Action |
|---|---|---|
| One axis behaves nothing like the others | That channel’s sub-tree was never configured, so it holds the defaults | Configure every channel |
| Moving one axis changed another’s output | The arrays are wired in the wrong order | Check the link order against the sub-tree numbering |
pLimActive is true and no axis looks limited |
Some axis is — the flag is combined across all of them | Read the same flag inside each channel’s sub-tree |
inputsDDot seems to have no effect |
Expected: it is not forwarded to the per-channel limiters | Leave it unlinked |
| An axis overshoots its position limit | That channel’s maxBrakingAcceleration is above its maxAcceleration |
Fix it in that channel’s sub-tree |
| Several axes fall out of step during a coordinated move | Expected: each axis is limited independently and a limited one falls behind | Coordinate the motion upstream |
| One warning per axis at every startup | Expected: each channel’s limiter corrects its own default omega |
Ignore, or set a finite omega in each sub-tree |
| I cannot switch the whole block off | Expected: there is no enable at this level | Set disable inside each channel’s sub-tree |
| The axes all made a move after a restart | Expected: each output starts at zero and travels to its input | Command actual positions first, or gate the consumers |
| The sub-tree numbering does not match my axis numbering | The sub-trees are numbered from 1; array elements from 0 | pvaLimiter01 is element 0 |
There is no block-level starting point to give — configure each channel from
pva-limiter.md’s starting point, with that axis’s own
travel, speed and acceleration.
Limits and errors
| Limit | Set by | What happens | Reported |
|---|---|---|---|
| Every per-channel limit | Each channel’s own sub-tree | Position, velocity and acceleration are bounded independently per axis, exactly as the single-axis block describes | That channel’s own flags |
inputsDDot |
Not forwarded | Accepted, stored, and never used | Not reported |
| Aggregate flags | Combined | Each is true when any channel’s is. The channel is not identified | Not reported; read the per-channel flags |
| Block-level enable | Not available | There is no enable, disable or isEnabled at this level |
Not applicable |
| Coordination between axes | None | Each axis is limited on its own. A limited axis falls behind and a multi-axis path is distorted | Not reported |
| Channel count | Machine configuration | Fixed once the controller starts. Read the array lengths to discover it | Not reported |
| Everything else | — | See pva-limiter.md, which applies per channel |
— |
The block itself raises no errors or warnings. Each channel’s limiter logs a
warning when it corrects its own omega, which with default settings happens
once per channel at startup.
Verified against motorcortex-control3 3.32.1 (340db23).