# HORUS > HORUS Robotics Framework > Docs: https://docs.horusrobotics.dev > Repo: https://github.com/softmata/horus > Full AI docs: https://docs.horusrobotics.dev/llms-full.txt ## Overview HORUS is a Rust-first robotics framework with Python bindings (PyO3). Zero-copy shared memory IPC with sub-microsecond latency (87ns typical, 575x faster than ROS2). Deterministic real-time scheduling with 5 execution classes, 70+ standard message types, and lock-free coordinate transforms. ## Core Concepts - **Node** — Computational unit. Trait: `fn tick(&mut self)` (required), `fn init(&mut self) -> Result<()>` (optional), `fn shutdown(&mut self) -> Result<()>` (optional but CRITICAL for actuators). Lifecycle: init -> tick (loop) -> shutdown. - **Topic** — Zero-copy pub/sub channel. `Topic::::new("name")`, `.send(msg)`, `.recv() -> Option`, `.read_latest() -> Option` (requires T: Copy). Auto-selects optimal backend (10 variants from 3ns to 167ns). - **Scheduler** — Orchestrates node execution. `Scheduler::new().tick_rate(100.hz()).prefer_rt().add(node).order(0).rate(500.hz()).build()?.run()?` - **Messages** — 70+ POD types for zero-copy IPC. Geometry: Pose2D, Pose3D, Twist, Quaternion, Vector3. Sensors: Imu, LaserScan, Odometry, JointState. Control: CmdVel, MotorCommand, ServoCommand, TrajectoryPoint. Navigation: NavGoal, NavPath, OccupancyGrid. Vision: CompressedImage, CameraInfo. Detection: BoundingBox2D, Detection3D, LandmarkArray. Diagnostics: Heartbeat, EmergencyStop, SafetyStatus. - **TransformFrame** — Lock-free coordinate frame tree. `TransformFrame::new()`, `.register_frame("base_link", Some("world"))`, `.tf("source", "target")`. ~50-200ns lookups. - **Services** — Synchronous request/response RPC. `service! { AddTwo { request { a: i64, b: i64 } response { sum: i64 } } }` - **Actions** — Long-running goals with feedback. `action! { Navigate { goal { x: f64, y: f64 } feedback { distance: f64 } result { success: bool } } }` - **DurationExt** — Ergonomic duration/frequency: `100.hz()`, `200.us()`, `1.ms()`, `5.secs()` - **ExecutionClass** — Rt (auto from .rate()), Compute (rayon pool), Event("topic") (trigger-based), AsyncIo (tokio), BestEffort (default, main thread) - **Miss** — Deadline miss policy: Warn (log, continue), Skip (skip tick), SafeMode (call enter_safe_state()), Stop (halt scheduler) ## Safety Rules (CRITICAL -- AI MUST follow these when generating horus code) 1. ALWAYS implement `shutdown()` for actuator/motor nodes -- motors keep running on Ctrl+C without it. Send zero-velocity command and log shutdown. 2. ALWAYS call `recv()` every tick, even if you don't process every message -- skipping causes buffer overflow and stale data. Drain the buffer unconditionally. 3. NEVER use `std::thread::sleep()` in `tick()` -- it blocks the entire scheduler and all nodes. Use `.rate(N.hz())` on the node builder instead. 4. NEVER do blocking file I/O in `tick()` -- use `.async_io()` execution class for I/O-bound work, or move I/O to `init()`/`shutdown()`. 5. Use dots not slashes in topic names -- `"imu.data"` not `"imu/data"` (slashes break cross-platform shared memory paths). ## Minimal Working Example (Rust) ```rust use horus::prelude::*; // Publisher node: reads sensor data and publishes it struct Sensor { publisher: Topic, } impl Sensor { fn new() -> Result { Ok(Self { publisher: Topic::new("temperature")? }) } } impl Node for Sensor { fn name(&self) -> &str { "Sensor" } fn tick(&mut self) { self.publisher.send(22.5); } // SAFETY: Always implement shutdown, even for read-only sensors fn shutdown(&mut self) -> Result<()> { hlog!(info, "Sensor shutting down"); Ok(()) } } // Subscriber node: receives and processes data struct Monitor { subscriber: Topic, } impl Monitor { fn new() -> Result { Ok(Self { subscriber: Topic::new("temperature")? }) } } impl Node for Monitor { fn name(&self) -> &str { "Monitor" } fn tick(&mut self) { // SAFETY: Always call recv() every tick to drain the buffer if let Some(temp) = self.subscriber.recv() { println!("Temperature: {:.1} C", temp); } } } fn main() -> Result<()> { let mut scheduler = Scheduler::new(); // Lower order number = runs first in each tick scheduler.add(Sensor::new()?).order(0).build()?; scheduler.add(Monitor::new()?).order(1).build()?; scheduler.run() } ``` ## Minimal Working Example (Python) ```python import horus def sensor_tick(node): node.send("temperature", 22.5) def monitor_tick(node): # Always call get()/has_msg() every tick if node.has_msg("temperature"): temp = node.get("temperature") print(f"Temperature: {temp:.1f} C") horus.run( horus.Node("sensor", pubs=["temperature"], tick=sensor_tick), horus.Node("monitor", subs=["temperature"], tick=monitor_tick), ) ``` ## Multi-Rate Real-Time Example ```rust use horus::prelude::*; // Motor node with CRITICAL shutdown struct Motor { cmd: Topic, velocity: f32 } impl Motor { fn new() -> Result { Ok(Self { cmd: Topic::new("cmd_vel")?, velocity: 0.0 }) } } impl Node for Motor { fn name(&self) -> &str { "Motor" } fn tick(&mut self) { // SAFETY: recv() every tick to get latest command if let Some(v) = self.cmd.recv() { self.velocity = v; } // Apply velocity to hardware here } fn shutdown(&mut self) -> Result<()> { // SAFETY: CRITICAL -- stop motor before exit self.velocity = 0.0; hlog!(info, "Motor stopped safely"); Ok(()) } } fn main() -> Result<()> { let mut s = Scheduler::new(); s.add(Motor::new()?) .order(0) .rate(200.hz()) // 200Hz control loop -- auto-enables RT .on_miss(Miss::SafeMode) // Call enter_safe_state() on deadline miss .build()?; s.run() } ``` ## Node Builder API Reference ``` scheduler.add(node) .order(N) // Execution priority (lower = first) .rate(N.hz()) // Tick frequency -- auto-enables RT with budget=80%, deadline=95% of period .budget(Duration) // Override auto-budget .deadline(Duration) // Override auto-deadline .on_miss(Miss::Skip) // Deadline miss policy .compute() // ExecutionClass::Compute (rayon thread pool) .on("topic_name") // ExecutionClass::Event (triggered by topic publish) .async_io() // ExecutionClass::AsyncIo (tokio blocking pool) .monitoring(true) // Enable safety monitor for this node .prefer_rt() // Request RT scheduling (fallback to non-RT if unavailable) .require_rt() // Demand RT scheduling (fail if unavailable) .deterministic(true) // Sequential execution for reproducibility .max_deadline_misses(3) // Escalation threshold before degradation .cores(&[0, 1]) // CPU affinity pinning .with_profiling() // Enable timing profiler .with_blackbox(64) // Flight recorder buffer (MB) .verbose(false) // Suppress executor logs .build()? // Finalize and register ``` ## Scheduler Configuration ``` Scheduler::new() .tick_rate(1000.hz()) // Global tick rate .prefer_rt() // Enable RT features if available .require_rt() // Fail if RT not available .watchdog(500.ms()) // Watchdog timeout (graduated: Warning -> Unhealthy -> Isolated) .deterministic(true) // SimClock + fixed dt + seeded RNG .with_blackbox(64) // Flight recorder (MB) .with_recording() // Enable topic recording ``` ## Standard Message Types (Complete List) ### Geometry Pose2D (x,y,theta), Pose3D (position+quaternion), PoseStamped, PoseWithCovariance, Point3, Vector3, Quaternion, Twist, TwistWithCovariance, Accel, AccelStamped, TransformStamped ### Sensors Imu (orientation+angular_vel+linear_accel), LaserScan (360 ranges), Odometry (pose+twist+covariance), JointState (positions+velocities+efforts), BatteryState, RangeSensor, Temperature, MagneticField, FluidPressure, Illuminance, NavSatFix ### Control CmdVel (linear+angular velocity), MotorCommand (id+mode+target), ServoCommand (id+position+speed), DifferentialDriveCommand (left+right wheel velocities), JointCommand (16 joints max), PidConfig (Kp+Ki+Kd+limits), TrajectoryPoint (position+velocity+acceleration+time) ### Navigation NavGoal (target pose+tolerances+timeout), NavPath (256 waypoints max), OccupancyGrid (resolution+width+height+data), CostMap (grid+costs+inflation), PathPlan, Waypoint, GoalResult, VelocityObstacle ### Vision CompressedImage (format+data+dimensions), CameraInfo (distortion+camera_matrix+projection), RegionOfInterest, StereoInfo (baseline+depth_scale) ### Perception & Detection BoundingBox2D (x,y,w,h), BoundingBox3D (center+dimensions+rotation), Detection (bbox+confidence+class), Detection3D (bbox3d+velocity), TrackedObject, SegmentationMask, Landmark, Landmark3D, LandmarkArray (COCO 17-keypoint), PlaneDetection ### Force & Haptics WrenchStamped (force+torque vectors), ForceCommand, ImpedanceParameters (stiffness+damping), ContactInfo (state+force+normal), HapticFeedback ### Diagnostics Heartbeat, DiagnosticStatus (level+code+message), EmergencyStop (engaged+reason), SafetyStatus, ResourceUsage (cpu+memory+disk+network), NodeHeartbeat (state+health+tick_count+rate), DiagnosticReport ### Input JoystickInput (id+event+value), KeyboardInput (key+code+modifiers+pressed) ### Clock Clock (sim/wall/replay time + speed), TimeReference (external sync) ### Generic GenericMessage (256-byte inline + 3840-byte overflow, MessagePack serialized) ## Key Documentation Pages - Installation: https://docs.horusrobotics.dev/getting-started/installation - Quick Start (Rust): https://docs.horusrobotics.dev/getting-started/quick-start - Quick Start (Python): https://docs.horusrobotics.dev/getting-started/quick-start-python - Common Mistakes: https://docs.horusrobotics.dev/getting-started/common-mistakes - Node Concepts: https://docs.horusrobotics.dev/concepts/core-concepts-nodes - Topic API: https://docs.horusrobotics.dev/rust/api/topic - Scheduler API: https://docs.horusrobotics.dev/rust/api/scheduler - Messages Reference: https://docs.horusrobotics.dev/rust/api/messages - Python Bindings: https://docs.horusrobotics.dev/python/api/python-bindings - Tutorials: https://docs.horusrobotics.dev/tutorials - Real-Time Guide: https://docs.horusrobotics.dev/concepts/real-time - horus.toml Config: https://docs.horusrobotics.dev/concepts/horus-toml - TransformFrame: https://docs.horusrobotics.dev/concepts/transform-frame - Execution Classes: https://docs.horusrobotics.dev/concepts/execution-classes - Safety Monitor: https://docs.horusrobotics.dev/advanced/safety-monitor ## Project Setup ```bash # Install horus CLI curl -sSL https://get.horusrobotics.dev | bash # Create new Rust project horus new my_robot # Create new Python project horus new my_robot --python # Run project cd my_robot && horus run # Key CLI commands horus run # Build and run horus test # Run tests horus topic list # List active topics horus topic echo # Print topic messages horus node list # List running nodes horus monitor # Open web dashboard horus doctor # System diagnostics ``` ## horus.toml (Project Manifest) ```toml [package] name = "my_robot" version = "0.1.0" description = "My robot project" [dependencies] serde = "1.0" # Rust dep (auto-detected as crates.io) numpy = { version = "1.26", source = "pypi" } # Python dep [scripts] sim = "horus run --features sim" deploy = "horus deploy robot.local" [drivers] servo = { terra = "dynamixel" } lidar = { terra = "rplidar" } camera = { terra = "realsense" } ```