Real-Time Tuning
HORUS handles real-time automatically. Set your rate, HORUS does the rest:
horus.run(Node(tick=my_controller, rate=1000))
No configuration needed. HORUS auto-detects your system's RT capabilities and uses the best available: SCHED_FIFO priority, memory locking, CPU pinning, lock-free IPC — all built in. No external packages required.
This page covers optional tuning for users who want the lowest possible jitter.
Check Your System
horus doctor
The Real-Time section shows what HORUS detected:
Real-Time
✓ PREEMPT_RT active, jitter ±10μs
or
⚠ Standard kernel, jitter ±100μs (run `horus setup-rt` for ±20μs)
For detailed RT status:
horus setup-rt --check
HORUS Real-Time Setup
Kernel: Linux 6.8.0-generic
⚠ PREEMPT_RT: not detected
✓ SCHED_FIFO: available (priority 1-99)
⚠ Memory locking: limited
ℹ CPU cores: 8
ℹ Isolated CPUs: none
ℹ Estimated jitter: ±100μs
Install RT Kernel (Optional)
If you need tighter timing (force control, high-bandwidth servo loops):
sudo horus setup-rt
This command:
- Detects your Linux distribution (Ubuntu, Debian, Fedora, Arch)
- Installs the RT kernel package from your distro's repository
- Configures memory lock limits (
/etc/security/limits.d/99-horus-rt.conf) - Suggests CPU core isolation for dedicated RT threads
Requires a reboot after install. Run horus setup-rt --check to verify.
To undo: sudo horus setup-rt --undo
Expected Performance
| Setup | Jitter (p99) | Good For |
|---|---|---|
| Standard Linux | ±200μs | Position control, ML policy deployment, navigation |
+ RT kernel (horus setup-rt) | ±20-80μs | Force control, humanoid balance, high-rate servos |
| + CPU isolation | ±10-30μs | High-bandwidth servo loops, multi-joint coordination |
Most robots work fine without any tuning. The standard Linux setup handles position control, velocity control, ML policy deployment, and navigation at rates up to 1kHz.
What HORUS Does Automatically
When you set rate=1000, HORUS internally:
- Detects if PREEMPT_RT is available and uses it
- Sets
SCHED_FIFOthread priority for RT nodes - Calls
mlockall()to prevent page faults - Pre-faults 256KB of stack memory
- Pins RT threads to isolated CPU cores (if available)
- Sets budget to 80% of period (800μs for 1kHz)
- Sets deadline to 95% of period (950μs for 1kHz)
- Enables graduated watchdog (warn at 3 misses, isolate at 10, kill at 20)
You never need to configure any of this. Override only if you have specific requirements:
Node(
tick=my_controller,
rate=1000, # 1kHz tick rate
budget=300 * us, # Override: 300μs budget (default: 800μs)
core=6, # Override: pin to CPU 6
on_miss="skip", # Override: skip missed ticks (default: warn)
)
See Also
- Benchmarks — Measured IPC latency and throughput
- Performance Optimization — General optimization guide
- Execution Classes — RT, Compute, Event, AsyncIo, BestEffort
- Safety Monitor — Graduated watchdog and deadline enforcement