Official implementation of the paper:
Kinematics-Informed Reinforcement Learning for Unified Trajectory Optimization in CNC Interpolation
Jin Zhang, Mingyang Zhao, Bing Liu, Dong-Ming Yan, Xin Jiang
IEEE Transactions on Industrial Informatics, 2026. DOI: 10.1109/TII.2026.3736332
Corner smoothing and feedrate planning, decided jointly, one corner at a time.
Conventional CNC interpolation first smooths the corners of a linear toolpath and then plans the feedrate along the fixed geometry. KIRL merges the two stages into a segment-level Markov decision process. At corner
and the segment between consecutive junctions is the minimum-jerk quintic with these boundary states, available in closed form for any duration
The duration is the smallest one that keeps the segment inside the tolerance band and within the kinematic limits,
found by a one-dimensional search, and the policy learns to minimize the total machining time
Highlights:
- Unified — geometry and feedrate are optimized in a single decision process instead of two decoupled stages
- Analytic primitives — closed-form minimum-jerk quintics; feasibility reduces to a 1-D search over the duration
- Zero-shot generalization — one universal policy plans held-out toolpaths without retraining
- Real-time — 0.08–0.10 ms per junction on a single CPU core
- Machine-validated — planned trajectories executed in planar cutting experiments on a CNC machine
conda create -n kirl python=3.10 && conda activate kirl
pip install -r requirements.txtNumPy is the only required dependency; the network is shipped as plain arrays and evaluated as a NumPy forward pass. Numba is optional and enables the JIT-compiled solver used for the paper's timing results (tested: numba 0.68 with numpy 2.4).
Eight planar benchmark toolpaths designed by the authors, stored as data/<name>/data.txt (tab-separated XY, mm). The universal policy was trained on six of them; Golden Fish and Shark are held out and never seen during training.
bash run_all.sh # NumPy version, then Numba version if installed
python infer.py # NumPy reference planner, all eight toolpaths
python infer.py --paths golden_fish,shark # selected toolpaths
python numba/run.py # JIT-compiled solver (paper's timing setup)
python infer.py --paths dolphin --save-trajectory dolphin.npz # dense XY trajectoryFor each toolpath the output reports the machining time T_m next to the value in Table III, the realized extrema of contour deviation, velocity, acceleration and jerk (sampled every 0.01 ms) against the limits of Table I, the number of stop-at-corner fallbacks, and the wall-clock planning time.
import json
import numpy as np
from policy import Policy
from planner import Planner
planner = Planner(Policy("weights/policy.npz"),
json.load(open("weights/normalization.json")))
result = planner.run(np.loadtxt("data/shark/data.txt", delimiter="\t"))
result["total_time"], result["fallbacks"] # machining time (s), fallback count
result["segments"] # [(x_start, x_end, T), ...] per segmentFollowing Algorithm 1, the planner walks the toolpath corner by corner:
- Observe: build the 10-D state from progress, the boundary kinematic state in the segment's local frame, and the look-ahead geometry (Sec. III-B).
- Act: the policy places the junction point on the corner's angle bisector and chooses its velocity and acceleration (Sec. III-B).
- Solve: the quintic segment is fixed up to its duration
T; the smallest feasibleT(Eq. 15) is found by a linear scan followed by bisection, with feasibility checked by dense 0.5 ms sampling (Supplementary Sec. S5, S12). - Fallback: if no feasible segment exists, stop at the corner. This never triggers on the benchmark toolpaths.
Inference is deterministic (mean action), so all trajectory quantities are exactly reproducible; only wall-clock timings depend on the machine.
Kinematic limits (Table I): deviation ≤ 0.5 mm, velocity ≤ 10 mm/s, acceleration ≤ 100 mm/s², jerk ≤ 10000 mm/s³. * = held-out toolpath.
| Toolpath | Segments | T_m (s) | Paper | max d (mm) | max v | max a | max j | Fallbacks |
|---|---|---|---|---|---|---|---|---|
| Digit 3 | 326 | 47.985 | 47.985 | 0.118 | 9.40 | 100.0 | 8655 | 0 |
| Mermaid | 604 | 89.574 | 89.574 | 0.129 | 9.40 | 100.0 | 9864 | 0 |
| Unicorn | 483 | 72.557 | 72.557 | 0.154 | 9.38 | 100.0 | 10000 | 0 |
| Simple Wave | 240 | 35.171 | 35.171 | 0.017 | 10.00 | 100.0 | 9967 | 0 |
| Dolphin | 267 | 39.306 | 39.306 | 0.076 | 9.39 | 100.0 | 10000 | 0 |
| Manta Ray | 330 | 48.207 | 48.207 | 0.097 | 9.40 | 100.0 | 10000 | 0 |
| Golden Fish* | 382 | 56.323 | 56.323 | 0.126 | 9.41 | 100.0 | 8192 | 0 |
| Shark* | 244 | 36.284 | 36.284 | 0.120 | 9.40 | 100.0 | 8451 | 0 |
Planning time on a single CPU core:
| Version | Per junction | Per toolpath |
|---|---|---|
NumPy reference (infer.py) |
~1 ms | 0.2–0.6 s |
Numba JIT (numba/run.py), paper Sec. IV-D |
0.08–0.10 ms | 21–53 ms |
Both versions produce the same trajectories (segment durations agree within the 1e-5 s bisection tolerance). The NumPy version is kept free of compiled code so every step of Algorithm 1 can be read directly; the Numba version fuses the minimum-time search into one compiled kernel and is the configuration timed in the paper. See numba/README.md for details.
| File | Content |
|---|---|
run_all.sh |
runs both versions and prints both tables |
infer.py |
command-line entry point (NumPy version) |
planner.py |
toolpath geometry, constraint check, minimum-time search, Algorithm 1 |
quintic.py |
minimum-jerk quintic segments and their derivatives |
policy.py |
trained network as a NumPy forward pass |
weights/ |
universal-policy weights and observation-normalization bounds |
data/ |
eight benchmark toolpaths |
numba/ |
JIT-compiled minimum-time solver and its entry point |
@article{zhang2026kirl,
title = {Kinematics-Informed Reinforcement Learning for Unified Trajectory Optimization in CNC Interpolation},
author = {Zhang, Jin and Zhao, Mingyang and Liu, Bing and Yan, Dong-Ming and Jiang, Xin},
journal = {IEEE Transactions on Industrial Informatics},
year = {2026},
doi = {10.1109/TII.2026.3736332}
}This project is licensed under the MIT License. See LICENSE for details.
