Hyperdimensional Computing · Vector-Symbolic Architectures · Time-Optimal Trajectory Planning
Quick Start · Architecture · Trajectory Planning · HDC · VSA · Research · CLI · API
Nazgul is a unified C++/Python framework for robotics-grade trajectory planning and edge-efficient hyperdimensional computing. It brings together three worlds:
| Component | Language | Backing Library |
|---|---|---|
| Trajectory Planner | C++17 + Python | Eigen 3.4 (≤ 0.48 ms avg per plan, 6‑DoF) |
| HDC Engine | Python (PyTorch) | Arthedain‑1 HDC‑Glue, protocols, energy analysis |
| VSA Factory | Python (PyTorch) | Arthedain‑1 backends: MAP‑B/C/I, BSC, HRR, FHRR, BSDC |
| Research Pipeline | Python | Zotero API v3 → TF‑IDF → module‑to‑paper mapping |
Nazgul inherits the mathematically-verified switching‑time engine from LongTermPlanner (C++ port by JakobThumm) and imports the full HDC/VSA protocol stack, energy‑constant library, and literature pipeline from Arthedain.
# Requirements: Eigen 3.4, cmake ≥ 3.14, gcc/clang (C++17)
export EIGEN3_INCLUDE_DIR="/usr/include/eigen3/eigen-3.4.0"
mkdir build && cd build
cmake .. -DBUILD_TESTS=ON
make -j$(nproc)
ctest --output-on-failure#include <nazgul/nazgul_planner.h>
nazgul::NazgulPlanner ltp(
/* dof */ 6,
/* t_sample */ 0.001,
/* q_min */ {-3.1, -3.1, -3.1, -3.1, -3.1, -3.1},
/* q_max */ { 3.1, 3.1, 3.1, 3.1, 3.1, 3.1},
/* v_max */ {10.0, 10.0, 10.0, 10.0, 10.0, 10.0},
/* a_max */ { 2.0, 2.0, 2.0, 4.0, 4.0, 4.0},
/* j_max */ { 4.0, 4.0, 4.0, 4.0, 4.0, 2.0}
);
nazgul::Trajectory traj;
bool ok = ltp.planTrajectory(q_goal, q_0, v_0, a_0, traj);
// traj.q[joint][sample] — joint positions
// traj.v[joint][sample] — joint velocities
// traj.a[joint][sample] — joint accelerations
// traj.j[joint][sample] — joint jerkscd python
pip install -e ".[full]"import nazgul
# Trajectory planning
planner = nazgul.NazgulPlanner(dof=6)
ok, traj = planner.plan(q_goal=[0.5, -0.3, 1.0, 0.2, -0.8, 0.0],
q_0=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
# Encode trajectory to hypervector
hv = nazgul.encode_trajectory_to_hv(
[v for joint in traj.q for v in joint], dim=8192
)
# VSA operations
be = nazgul.get_backend("MAP_B", dim=10000)
bound = nazgul.hv_xor(be.generate(), be.generate())
similarity = nazgul.hamming_similarity(bound, be.generate())
# Research
idx = nazgul.build_research_index()
papers = idx.query("time-optimal jerk-limited trajectory planning")Click any thumbnail to open the fully interactive SVG figure (scroll = zoom, drag = pan, hover = tooltips).
System Architecture — five‑layer block diagram from Python API down to Zotero research data.
HDC Trajectory‑to‑Hypervector Encoding Pipeline — from raw 6‑DoF samples to binary hypervector, with 45 nm energy constants.
Time‑Optimal 7‑Phase Jerk‑Limited Trajectory Profile — graded evasion response with colour‑coded phases.
HDC Operation Energy vs Digital Baseline (45 nm CMOS) — Horowitz ISSCC 2014 energy constants.
Nazgul Planner Performance & Accuracy — planning time vs. degrees of freedom with position‑error inset.
Animated Trajectory Planning — 3‑DoF planar robot arm following a time‑optimal plan with live position / velocity / jerk charts.
Animated HDC Encoding Pipeline — particles flowing through trajectory‑sample → projection → binding stages with rolling energy counters.
Animated VSA Binding & Recovery — live MAP‑B XOR bind/unbind cycle with Hamming similarity gauge.
🖱️ Scroll = zoom | Drag = pan | Hover = tooltips
Generated by figures/generate_figures.py · screenshotted by figures/screenshot_figures.js
Each demo cycles through a full pipeline run. Click the GIF to open the live interactive version.
3‑DoF planar arm converging to a goal over a 6‑second time‑optimal trajectory. Right panel shows live position, velocity, and jerk for all three joints. Cycle: 6 s → replay.
40 particles streaming through the 4‑stage HDC encoding pipeline (ID‑Level Encode → Random Projection → Cyclic Binding). Energy bars track per‑operation cost in 45 nm CMOS. Rolling hypervector bit panel at bottom. Cycle: 8 s → replay.
MAP‑B binary sparse vectors: bind (a ⊕ b), check similarity, unbind (bound ⊕ b ← a), verify recovery ≈ 1.0. Phases advance every 1.5 s on a 6‑second auto‑loop.
GIFs recorded by figures/generate_gifs.js using Puppeteer + gif‑encoder‑2 at 15 fps.
nazgul/
├── include/nazgul/ # C++ headers
│ ├── nazgul_planner.h # Time-optimal multi-joint planner
│ └── roots.h # Companion-matrix polynomial root-finder
├── src/
│ └── nazgul_planner.cc # Planner implementation (827 lines)
├── cmake/
│ └── Config.cmake.in # CMake package export template
├── python/nazgul/
│ ├── __init__.py # Lazy-loading public API (36 exports)
│ ├── planner.py # C++ ctypes wrapper + pure-Python fallback
│ ├── hdc_integration.py # HDC protocols, energy analysis, operations
│ ├── vsa_integration.py # VSA factory registry, 8 backends
│ ├── research.py # Zotero → TF-IDF → module mapping
│ └── main.py # Unified CLI (plan, hdc, vsa, research)
├── tests/
│ ├── include/
│ │ └── nazgul_planner_fixture.h # GTest fixtures + exposed methods
│ └── src/
│ └── nazgul_planner_tests.cc # 8 test suites, 50+ scenarios
├── images/
│ ├── profile.svg # Standard jerk profile diagram
│ ├── modifiedJerkProfile.svg # Modified profile (braking to v_drive)
│ └── exampleTrajectory.svg # 6-DoF output example
├── CMakeLists.txt
├── python/pyproject.toml
└── README.md
The planner computes time-optimal, synchronized trajectories for multi-DoF robotic systems under velocity, acceleration, and jerk constraints.
A general time-optimal profile consists of seven phases of constant, maximal positive/negative, or zero jerk. The planner:
- Finds optimal switch times analytically for all 8 profile variants (phases 2, 4, 6 may collapse to zero).
- Identifies the slowest joint and time‑scales all other joints to synchronize arrival.
- Samples continuous profiles with sub‑sample fraction correction for high accuracy.
Additional profiles handle the case where a joint must slow down to reach v_drive (modified jerk profile):
| Metric | Value |
|---|---|
| Average runtime (6‑DoF) | 0.48 ms per plan |
| Worst-case runtime | 2.29 ms |
| Position accuracy (grid sweep) | 0.003 rad average |
| Worst-case position error | ≤ 0.015 rad |
| Polynomial root‑finding | Companion matrix (Eigen3 eigenvalues) |
Benchmarked on Intel Core i5‑6267U @ 2.9 GHz, MATLAB 2020a; C++ is faster.
All six joints reach the goal at the same time with zero terminal velocity and acceleration.
The HDC module provides structural protocols, energy analysis, and encoding operations based on the Arthedain‑1 HDC‑Glue specification (Sutor et al. 2022–2025).
from nazgul import HDEncoder, HDClassifier, HDMemory
# Duck-type any object: isinstance(obj, HDEncoder) == True
# if it has an encode(x: Tensor) -> Tensor method.| Operation | Energy | vs INT8 MAC |
|---|---|---|
| XOR binding | 0.10 pJ/bit | 46× more efficient |
| Popcount (Hamming) | 0.20 pJ/op | 23× |
| Bit‑accumulate (bundling) | 0.05 pJ/bit | 92× |
| Permute/shift | 0.01 pJ/bit | 460× |
| Reference: INT8 MAC | 4.60 pJ/op | 1× |
| Reference: SNN SynOp | 0.90 pJ/op | 5.1× |
Horowitz, ISSCC 2014. Nazgul's HDC operations achieve 46× energy reductions over digital multiply‑accumulate at the same process node.
from nazgul import encode_trajectory_to_hv
# Maps any sequence of floating-point trajectory values
# into a fixed‑dimension binary hypervector via
# random projection + cyclic permutation binding.
hv = encode_trajectory_to_hv(trajectory_data, dim=8192)
# Ready for similarity search, associative memory, or
# transformer‑free classification.The VSA module provides a factory‑pattern backend registry with 8 canonical algebras:
| Backend | Type | Binding | Bundling | Best For |
|---|---|---|---|---|
| MAP‑B | Binary sparse | XOR | Majority vote | Edge devices, CIM |
| BSC | Binary sparse | XOR | Threshold sum | Lowest power |
| MAP‑I | Integer | Mod‑sum | Addition | Higher capacity |
| MAP‑C | Complex | Element‑wise mult | Addition | Phase representations |
| HRR | Real dense | Circular convolution | Addition | Continuous vectors |
| FHRR | Complex dense | Circular convolution | Addition | Fourier‑domain ops |
| BSDC | Binary block‑sparse | Blockwise XOR | Blockwise add | Capacity/density tradeoff |
| BSDC‑SEG | Segmented BSDC | Segmented XOR | Segmented add | Hierarchical structures |
from nazgul import get_backend, hv_xor, hv_bundle, gen_hvs
be = get_backend("HRR", dim=4096, seed=42)
a, b = be.generate(), be.generate()
bound = be.bind(a, b)
recall = be.unbind(bound, b)
similarity = be.similarity(a, recall)
# similarity ≈ 1.0 for self‑inverse bind/unbindWhen Arthedain backends are unavailable, SimpleBinaryVSA provides a pure‑PyTorch fallback for MAP‑B and BSC — no external dependencies required.
Nazgul ingests the full Zotero‑to‑TF‑IDF‑to‑module‑mapping pipeline from Arthedain‑1:
Zotero API v3 → library_flat.json → TF‑IDF Index → Module Map
│ │ │ │
│ cache + flat JSON cosine sim AST extraction
│ │ │
fetch_library.py research/index_papers.py map_modules.py
# Fetch the latest papers
nazgul research my_user_id --fetch
# Semantic search
nazgul research "time-optimal jerk-limited" --tfidf --abstracts
# Map every Python module to its most relevant papers
nazgul research --map-modules --top-k 3
# Output:
# python/nazgul/planner.py:
# [2008] Kröger: On-Line Trajectory Generation … (score: 0.847)
# [2011] Ezair: High-Speed Trajectory Planning … (score: 0.791)
# [2022] Wen: Time-Optimal Trajectory Planning … (score: 0.763)from nazgul import ZoteroClient, ResearchIndex, TFIDFIndex, build_research_index
client = ZoteroClient.from_env()
papers = client.fetch_all()
idx = build_research_index(use_tfidf=True)
results = idx.query("hyperdimensional computing robotics", top_k=10)
for paper in results:
print(f"[{paper.year}] {paper.title}")nazgul plan --goal 0.5 -0.3 1.0 0.2 -0.8 0.0 --start 0 0 0 0 0 0 --dof 6 --encode-hv
nazgul research "FORCE learning" --tfidf --top-k 5 --abstracts
nazgul research --fetch --tfidf
nazgul research --map-modules --top-k 3
nazgul hdc --energy
nazgul hdc --encode 1.0 -2.5 3.14 0.0 --dim 10000
nazgul vsa --list
nazgul vsa --backend HRR --dim 4096 --generate 5
nazgul vsa --backend MAP_B --dim 10000 --checkcd build && cmake .. -DBUILD_TESTS=ON && make -j$(nproc) && ctest --output-on-failure| Test Suite | Scenarios | Coverage |
|---|---|---|
OptBrakingTest |
6 | Braking trajectories, bidirectional validation |
OptSwitchTimesTest |
9 | Optimal jerk switch times, all profile variants |
TrajectoryTestV0 |
9 | Full‑trajectory with v₀ = 0, a₀ = −1e‑8 |
TrajectoryTestV1 |
9 | Full‑trajectory with v₀ = 0, a₀ = +1e‑8 |
TrajectoryTestV2 |
9 | Fine‑grained a₀ from 1e‑1 → 1e‑9 |
TimeScalingTest |
12 | All 8 time‑scaling profile variants |
InitializationTest |
2 | 1‑DoF + 6‑DoF fixture sanity |
cd python && pip install -e ".[dev]" && pytest- Kröger, T. (2008) On-Line Trajectory Generation in Robotic Systems. Springer.
- Ezair, B. et al. (2011) High-Speed Trajectory Planning for Multi‑DOF Robots. IEEE T‑RO.
- Wen, J. et al. (2022) Time‑Optimal Trajectory Planning with Jerk Constraints. arXiv:2203.06701.
- Sutor, P. et al. (2022) Gluing Neural Networks Symbolically Through HDC. IJCNN 2022.
- Sutor, P. et al. (2025) HyPE: Hyperdimensional Propagation of Error. AGI 2025.
- Kleyko, D. et al. (2023) A Survey on HDC/VSA. ACM Computing Surveys.
- Kanerva, P. (2009) Hyperdimensional Computing. Cognitive Computation.
- Plate, T. (1995) Holographic Reduced Representations. IEEE T‑NN.
- Frady, E.P. et al. (2020) Resonator Networks for Factorization. NeurIPS 2020.
- Horowitz, M. (2014) Computing's Energy Problem. ISSCC 2014 — 45 nm CMOS energy per operation.
- Amrouch, H. et al. (2022) Brain‑Inspired HDC for Ultra‑Efficient Edge AI. CODES+ISSS 2022.
MIT License — see LICENSE.
Built by Enotrium.
C++ engine from LongTermPlanner by Yannick Burkhardt & Jakob Thumm.
HDC/VSA/Research modules integrated from Arthedain‑1.


