S Curve Profile — Robotics/Trajectory Generation
Robotics/Trajectory_Generation/S_Curve_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.
S Curve Profile
Robotics / Trajectory Generation
The jerk-limited point-to-point profile – the seven-segment or “double-S” shape a production motion controller commands. It is Trapezoidal Velocity Profile with a jerk ramp spliced into every corner, so the acceleration command is continuous rather than stepping, and the machine is not shocked at each segment boundary.
- jerk +j – acceleration ramps from 0 to its peak.
- jerk 0 – acceleration held at its peak.
- jerk −j – acceleration ramps back to 0; velocity arrives at its peak.
- jerk 0 – cruise.
- jerk −j, 6. jerk 0, 7. jerk +j – the mirror image, decelerating to rest.
Ports
This block is a source: it has no inputs and takes its time from its own local clock.
- q – the position command, [1,1].
- qd – the velocity command, [1,1]. An S rather than a trapezoid: its corners are rounded by the jerk ramps.
- qdd – the acceleration command, [1,1]. Piecewise linear and continuous, which is the whole point of the block.
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₀.
- Max Velocity – vmax, strictly positive.
- Max Acceleration – amax, strictly positive.
- Max Jerk – jmax, strictly positive. This is what separates this block from Trapezoidal Velocity Profile: as it grows the profile approaches that block's, and as it shrinks the move stretches and softens.
- 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 five parameters are baked into the emitted body at export time rather than exposed as tunable parameters. The whole profile – the shape, the segment boundaries and each segment's starting state – is solved once and enters as constants, so no generated core takes a square root, a cube root or a division. Each segment is one cubic in the time since that segment began. 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 would be synthesizable
fixed point; the clock is not, since like every time-driven source here it reads the
testbench-advanced sim_time.
Simulink bridge
None, measured rather than assumed: jerk-limited 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 can be rebuilt there from a Clock and a
MATLAB Function block carrying the segment cases above.
Notes
- Algebraic and stateless – a pure function of simulation time.
- The move has four possible shapes, and all four are normal. Whether amax is reached and whether vmax is reached are independent questions: reaching both gives the full seven segments; reaching only the acceleration limit drops the cruise; reaching only the velocity limit drops the two constant-acceleration segments; reaching neither leaves four jerk ramps and nothing else. Every limit is respected in all four.
- The peak values are reported by the profile, not assumed. On a short move the velocity peaks below vmax and the acceleration may peak below amax; that is the profile obeying the jerk limit, not a failure to reach the others.
- It arrives exactly. Each segment is evaluated from its own start state, so q(T) = qf and q̇(T) = q̈(T) = 0 to within a rounding of the arithmetic rather than to within the sum of seven of them.
- 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/S_Curve_Profile |
| family | Robotics/Trajectory_Generation |
| solver environment class | ICoreBlock_0_Robotics_1_Trajectory_Generation_2_S_Curve_Profile |
| source | src/ICoreSDK/ICoreBlockLibrary/Blocks/Robotics/Trajectory_Generation/S_Curve_Profile/ICoreBlock_0_Robotics_1_Trajectory_Generation_2_S_Curve_Profile.cpp |
| header | src/ICoreSDK/ICoreBlockLibrary/Blocks/Robotics/Trajectory_Generation/S_Curve_Profile/ICoreBlock_0_Robotics_1_Trajectory_Generation_2_S_Curve_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 | — |
Max Jerk | 4 | — |
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: jerk-limited 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 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).
S Curve Profile — the jerk-limited seven-segment move, as a source Trapezoidal_Velocity_Profile's structure with a jerk ramp in every corner. The solver runs ONCE at config load: it decides the shape (7, 6, 5 or 4 segments), integrates the profile to get each segment's start state, and hands the generators a list. Every emitted arm is then the SAME cubic in tau = tt - ts with that segment's constants, so a seven-way branch is one expression rather than seven.
⚠ A segment of zero duration is not emitted at all, so the four shapes are four different generated bodies - which is why each has a rig of its own rather than being a retuning.
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__S_Curve_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).