Trapezoidal Velocity Profile — Robotics/Trajectory Generation
Robotics/Trajectory_Generation/Trapezoidal_Velocity_Profile · 0 input / 0 output port(s) at insert · exports to Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text
Description#
The block's own DESCRIPTION_HTML, rendered verbatim — the same text the config dialog's info panel and the library navigator show. Fix a wrong sentence in the block's .cpp (R-D9), never here.
Trapezoidal Velocity Profile
Robotics / Trajectory Generation
The bounded-velocity point-to-point profile: a source that walks from q₀ to qf as fast as a velocity limit and an acceleration limit allow, in three segments – accelerate, cruise, decelerate – and then holds. It is what a motion controller commands when the machine, not the move time, sets the pace.
With D = |qf − q₀|, the peak velocity actually reached is v = min(vmax, √(D·amax)), and the segment times follow: ta = v/amax, tc = (D − v·ta)/v, T = 2ta + tc.
Ports
This block is a source: it has no inputs and takes its time from its own local clock, so it produces the same profile wherever it is dropped.
- q – the position command, [1,1].
- qd – the velocity command, [1,1]. This is the trapezoid the block is named for: a ramp up, a flat top at ±v, a ramp down.
- qdd – the acceleration command, [1,1]. It is ±amax, then 0, then ∓amax, then 0 – piecewise constant, and it steps.
Parameters
- Start Position – q₀, held before the move and at t = 0.
- End Position – qf, reached at t = T and held after it. It may be below q₀; the profile runs downhill and every output changes sign with it.
- Max Velocity – vmax, the flat top of the trapezoid. It must be strictly positive. If the move is too short to reach it the profile becomes a triangle – see the notes.
- Max Acceleration – amax, the slope of the ramps. It must be strictly positive.
- Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.
Code export
All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text.
All four parameters are baked into the emitted body at export time rather than exposed as tunable parameters on the generated core. The segment times, the peak velocity and the signed acceleration are solved once and enter as constants, so no generated core divides, takes a square root, or searches for the segment it is in – it compares against two or three numbers. Retuning the profile means re-exporting it.
The three HDL targets are simulation-only: they carry the profile in
real and quantize only at the port boundary. The arithmetic itself would be
synthesizable fixed point – it is comparisons and multiply-add – but the clock
is not: like every time-driven source in this library it reads the testbench-advanced
sim_time.
Simulink bridge
None, measured rather than assumed: point-to-point trajectory blocks ship in the
Robotics System Toolbox, which is not installed on this machine (robotics,
nav and shared_robotics are all absent from
matlabroot/toolbox). The profile is easy to rebuild there from a Clock and a
MATLAB Function block carrying the four segment cases above.
Notes
- Algebraic and stateless – a pure function of simulation time, so it runs correctly under either solver and carries no state to seed.
- The triangle case is not an error. When the move is too short to reach vmax – that is, when D·amax ≤ vmax² – the cruise segment vanishes, the peak velocity is √(D·amax) instead of vmax, and the velocity command is a triangle rather than a trapezoid. Both limits are still respected.
- The deceleration segment is computed backwards from T, as the mirror of the acceleration one, so the profile arrives at qf exactly rather than at the sum of three roundings.
- q̈ steps. Nothing bounds jerk here, so the acceleration command jumps at each segment boundary. Use S Curve Profile where that matters, or Quintic Trajectory where the move TIME is what you want to set rather than the limits.
- A zero-length move is not a special case: with qf = q₀ the duration is zero and the block holds (q₀, 0, 0) from the first sample.
- No state space – the block has no input to be linear in.
Code facts#
| Fact | Value |
|---|---|
| registered type | Robotics/Trajectory_Generation/Trapezoidal_Velocity_Profile |
| family | Robotics/Trajectory_Generation |
| solver environment class | ICoreBlock_0_Robotics_1_Trajectory_Generation_2_Trapezoidal_Velocity_Profile |
| source | src/ICoreSDK/ICoreBlockLibrary/Blocks/Robotics/Trajectory_Generation/Trapezoidal_Velocity_Profile/ICoreBlock_0_Robotics_1_Trajectory_Generation_2_Trapezoidal_Velocity_Profile.cpp |
| header | src/ICoreSDK/ICoreBlockLibrary/Blocks/Robotics/Trajectory_Generation/Trapezoidal_Velocity_Profile/ICoreBlock_0_Robotics_1_Trajectory_Generation_2_Trapezoidal_Velocity_Profile.h |
| default size on canvas | 150 × 90 px |
| ports at insert | ? in, ? out |
| code generators implemented | Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text |
Ports#
| # | Direction | Signal type | Description label |
|---|---|---|---|
| 1 | out | ICoreDouble | q |
| 2 | out | ICoreDouble | qd |
| 3 | out | ICoreDouble | qdd |
Ports the constructor creates. A block whose port list changes with its configuration adds or removes ports at load time; the count above is the one a freshly inserted block has.
Configuration variables#
| Config variable | Default | Simulink parameter |
|---|---|---|
Start Position | 0 | — |
End Position | 1 | — |
Max Velocity | 0.5 | — |
Max Acceleration | 1 | — |
Every block also carries Sampling Time (s) from ICoreBlockSolverEnvironment: zero or less inherits the solver's rate, a positive value runs the block at that period.
Simulink bridge#
| support | Support::None |
| Simulink path | — |
| port-count rule | PortsParam::None |
SampleTime parameter | yes |
Caveat (shown to the user): no Simulink equivalent available: point-to-point trajectory blocks ship in the Robotics System Toolbox, which is not installed. Rebuild it there from a Clock and a MATLAB Function block carrying the four segment cases this block states
Catalog contract: src/ICoreSDK/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h
Description vs code#
The lists agree. check_block_descriptions.py finds no disagreement between the description's Ports, Parameters, Code export and Simulink bridge lists and the code's.
The verdict above is
tools/docs/check_block_descriptions.py(P7.1), which compares LISTS. It cannot read a sentence: "stateless" on a block with a state, an initial-value semantic the recursion does not implement, a "not synthesizable" caveat the HDL banner contradicts. That is the agent audit (P7.3) on BLOCK_DESCRIPTION_AUDIT.md, and this tool's green is not a substitute for one.
File banner (developer view)#
The top comment of the block's .cpp — the maths, the realization and the export strategy, addressed to whoever changes it. It must not contradict the description above (P7.5).
Trapezoidal Velocity Profile — accelerate, cruise, decelerate, hold; as a source The segment times are derived from CONFIG once (see Profile below) and baked into the emitted body as constants, so no generated core divides, searches or integrates. Both the shape of the branch chain and the expression in every arm are built ONCE, in chainCode() and phaseExpr(), and every one of the eleven implementations - the C++ reference included - is a rendering of those two functions with its own keywords. That is what keeps a four-way branch from drifting in one of eleven places.
⚠ The cruise arm is EMITTED ONLY WHEN IT EXISTS. In the degenerate triangle (the velocity limit is never reached) tc is exactly zero and the emitted core is a three-way chain - a different body, which is why the two cases are separate rigs rather than two values.
Sample results#
Plotted: free — No input: the block run alone
Category source · sample time 0.1 · 60 steps · commit ccf005c8 · produced by docsSample --out <folder> --steps 60 · data docs/generated/samples/Robotics__Trajectory_Generation__Trapezoidal_Velocity_Profile.json · the SVG is generated from those numbers by tools/docs/plot_svg.py, so it is a run and not a drawing (R-D10).