PVALimiters

PVALimiters is the multi-axis form of PVALimiter.
Current release

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. PvajLimiter is 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 PVALimiter describes, 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

  1. Read the length of inputs from the parameter tree and confirm it matches your axis count. It is fixed when the machine is built.

  2. 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².

  3. Set maxBrakingAcceleration at or below maxAcceleration in every channel. This is the one relationship that silently causes overshoot, per axis.

  4. Link inputs and, if your source produces them, inputsDot. Leave inputsDDot unlinked.

  5. Command a small move on one axis and confirm only that channel’s outputs element 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.

  6. Command a move that runs into a position limit on one axis. Confirm pLimActive goes true here, and that the same flag is true in that channel’s own sub-tree and false in the others.

  7. Expect one startup warning per channel about omega. It is normal — see pva-limiter.md.

Tuning

All the tuning is per channel and is described in pva-limiter.md. What is specific to this block:

  1. 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.
  2. Keep a written record of which sub-tree is which axis. The numbering starts at 1 and the array indices start at 0, so pvaLimiter01 is element 0.
  3. When the aggregate pLimActive goes true unexpectedly, walk the sub-trees and read each channel’s own pLimActive to find the axis. There is no faster route.
  4. Watch each channel’s currentMaxVel during a limit approach — it is the most informative signal in the block and there is one per axis.
  5. 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.

One channel following a 0.9 step: the position rises and settles at 0.9, thevelocity ramps up, holds at the 1.0 limit and returns to zero, and theacceleration saturates at both ends of themove.

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).