Skip to content

Algorithm White-Box

Understand how the motion planner works — from jerk-limited trajectory generation to multi-axis synchronization and path planning.

Contract Map

The kernel's algorithm layer has six approved contracts, documented in algorithm-contracts.md. The three you'll encounter first:

Contract What It Solves Key File
Single-axis OTG Time-optimal S-curve (7-segment jerk word) core/otg/time_optimal.h
solve_fixed_time Multi-axis sync to a shared duration core/otg/time_optimal.h
Group path motion Scalar path law (TOPP-RA + jerk layer) core/plan/path.h

Reading the OTG Solver

The single-axis online trajectory generator (OTG) finds the minimum-time jerk-limited profile from any initial state (p, v, a) to a target state.

The jerk input u(t) switches between {+j, 0, -j}, producing up to 7 segments. The solver enumerates feasible switch structures and picks the fastest.

To see it in action, look at the optimality oracle test (CTest target plcopen_core_otg_optimality_oracle):

core/test/otg_optimality_oracle.cpp

This file contains:

  • A grammar-generated switch-structure enumeration table — valid jerk-word combinations built at runtime from the Pontryagin bang/singular transition graph
  • A Newton shooting oracle that independently solves the same problem to verify the solver's output
  • Six-domain excess-cycle baselines — regular, pin-boundary, bump, nonzero initial acceleration, nonzero target acceleration, and both nonzero

A separate smoke test, core/test/otg_oracle.cpp (plcopen_core_otg_oracle), checks integration consistency of sampled profiles.

Reading the Compliance Matrices

Each PLCopen standard part has a compliance matrix — a table mapping every specified function block to its implementation status and test coverage.

Honest numbers first: Part 1 has 43/43 facades and C4 closes D-01..D-20, while formal B/E/V supplier declarations remain open. Part 4 has 68/68 same-name facades with explicit partial E/O and mode boundaries. Part 5 C5 closes 11/11 standard facades plus 45 B + 102 E machine-readable declarations and software-verifiable semantics. These are software facts, not PLCopen approval or hardware-performance claims.

Start here:

Known Boundaries

Not everything in the PLCopen spec is implemented. The known boundaries registry declares every intentional deviation, simplification, or limitation as a numbered KB entry. Each entry states:

  • What the boundary is
  • Why it exists
  • How it manifests to the user
  • Whether and when it will be lifted

ST Bytecode VM

The IEC 61131-3 ST layer is itself a white-box algorithm surface. It is split into two domains:

  • Load domain (compile()Program): recursive-descent front end with statement-level error recovery and stable diagnostic codes; may allocate, must never crash (fuzz-gated against arbitrary bytes).
  • Cycle domain (Instance::load()scan(budget)): a deterministic stack-machine interpreter with an instruction-count watchdog. All memory is laid out at load() time into a caller-owned fixed buffer — the scan path obeys the same RT rules as the motion kernel.

Determinism is enforced in CI: golden programs must produce identical bytecode anchor hashes across platforms. Spec: st-l0-semantics.md, usage: core/st/README.md.

Architecture Layers

The kernel separates concerns into an L0-L7 ladder with strict dependency rules — each layer only depends on layers below it. Beside the ladder sit two support libraries, kin (FK/IK, depends on geom/rt) and stream (OTG-filtered streaming input, depends on otg/rt), consumed by L5 only. On the outer ring, the st language layer and L7 adapters are two parallel pure-sink facades. L0-L4 plus kin/stream carry zero PLCopen semantics and can be used independently for raw trajectory generation.

See the diagrams on the home page and the full design doc: architecture.md

Test Target What It Covers
plcopen_core_rt_tests Core RT tests (axis, group, FB, sync, probe, IO)
plcopen_core_otg_fuzz Random-input OTG fuzzing
plcopen_core_otg_oracle Sampled-profile integration consistency smoke
plcopen_core_otg_optimality_oracle PMP switch-structure exhaustive + Newton shooting
plcopen_core_topp_*_oracle Path-law (TOPP) oracle cross-validation
plcopen_core_stream_fastpath_oracle Streaming OTG-filter fast-path oracle
plcopen_core_st_l0_* ST compiler / runtime / 50 golden programs / quality (cross-platform bytecode anchor hashes, gated in CI)
plcopen_core_st_l1a_* ST type system + conversion matrix (three-way check)
plcopen_core_st_fuzz_smoke ST front-end fuzzing (crash-free on arbitrary bytes)
plcopen_core_benchmark Cycle-budget benchmarks
plcopen_core_replay_* Golden waveform regression (18 fixtures)

Run all tests:

cmake -S . -B build -DPLCOPEN_BUILD_TESTS=ON
cmake --build build --config Release
ctest --test-dir build --build-config Release --output-on-failure

Next Steps