Choosing a Language

HORUS supports both Rust and Python. This guide helps you choose the right one for your project.


Quick Decision

Use Python if:

  • You're prototyping or experimenting
  • You're new to robotics programming
  • You want to integrate with ML/AI libraries (TensorFlow, PyTorch)
  • Development speed matters more than runtime performance

Use Rust if:

  • You need maximum performance
  • You're building production systems
  • You want compile-time safety guarantees
  • You're comfortable with Rust (or want to learn)

Side-by-Side Comparison

Hello World: Temperature Sensor

Python:

from horus import Node, Topic, Scheduler

class TempSensor(Node):
    def __init__(self):
        super().__init__("TempSensor")

    def init(self):
        self.pub_topic = Topic("temperature")

    def tick(self):
        temp = 25.0  # Read sensor
        self.pub_topic.send(temp)

scheduler = Scheduler()
scheduler.node(TempSensor()).order(5).build()
scheduler.run()

Rust:

use horus::prelude::*;

struct TempSensor {
    pub_topic: Topic<f32>,
}

impl TempSensor {
    fn new() -> Result<Self> {
        Ok(Self { pub_topic: Topic::new("temperature")? })
    }
}

impl Node for TempSensor {
    fn name(&self) -> &str { "TempSensor" }

    fn tick(&mut self) {
        let temp = 25.0;  // Read sensor
        self.pub_topic.send(temp);
    }
}

fn main() -> Result<()> {
    let mut scheduler = Scheduler::new();
    scheduler.add(TempSensor::new()?).order(5).build()?;
    scheduler.run()
}

Or with the Rust node! macro:

use horus::prelude::*;

node! {
    TempSensor {
        pub { temperature: f32 -> "temperature" }

        tick {
            let temp = 25.0;
            self.temperature.send(temp);
        }
    }
}

fn main() -> Result<()> {
    let mut scheduler = Scheduler::new();
    scheduler.add(TempSensor::new()).order(5).build()?;
    scheduler.run()
}

Detailed Comparison

AspectPythonRust
Learning curveEasySteeper
Setup time5 minutes10 minutes
Compile timeNoneA few seconds
Runtime performanceGoodExcellent
Memory safetyRuntime checksCompile-time guarantees
ML/AI integrationExcellent (numpy, torch, etc.)Limited
DebuggingSimple print debuggingMore tooling needed
Production readinessGood for prototypesProduction-grade

Performance Comparison

OperationPythonRustDifference
Node tick latency~10μs~1μs10x faster
Message send~2μs~400ns5x faster
Control loop (1kHz)AchievableEasy-
Control loop (10kHz)DifficultAchievable-

Bottom line: For most robotics applications, both are fast enough. Rust matters when you need:

  • Very high-frequency control (>1kHz)
  • Hard real-time guarantees
  • Minimal memory footprint

When to Choose Python

Rapid Prototyping

# Quick experiment - try different approaches fast
from horus import Node, Topic, Scheduler

class ExperimentalController(Node):
    def __init__(self):
        super().__init__("ExperimentalController")

    def init(self):
        self.sensor_sub = Topic("sensor")
        self.output_pub = Topic("output")

    def tick(self):
        input_val = self.sensor_sub.recv() or 0.0
        strategy = "aggressive"

        if strategy == "aggressive":
            output = input_val * 2.0
        else:
            output = input_val * 0.5
        self.output_pub.send(output)

Machine Learning Integration

import torch
from horus import Node, Topic, Scheduler

class MLController(Node):
    def __init__(self):
        super().__init__("MLController")
        self.model = torch.load("my_model.pt")

    def init(self):
        self.sensor_sub = Topic("sensor_data")
        self.output_pub = Topic("control_output")

    def tick(self):
        sensor_data = self.sensor_sub.recv()
        if sensor_data is not None:
            with torch.no_grad():
                output = self.model(torch.tensor(sensor_data))
            self.output_pub.send(output.item())

Education and Learning

Python's readable syntax makes it easier to understand robotics concepts without fighting the language.


When to Choose Rust

Production Deployments

// Rust catches bugs at compile time
impl Node for SafetyMonitor {
    fn tick(&mut self) {
        // Compiler ensures we handle all cases
        match self.check_safety() {
            SafetyStatus::OK => self.continue_operation(),
            SafetyStatus::Warning(msg) => self.log_warning(&msg),
            SafetyStatus::Critical(msg) => self.emergency_stop(&msg),
        }
    }
}

High-Frequency Control

// Rust can sustain 10kHz+ control loops
impl Node for MotorController {
    fn tick(&mut self) {
        // Microsecond-level timing is reliable
        let error = self.target - self.position;
        let output = self.pid.compute(error);
        self.motor.send(output);
    }
}

Resource-Constrained Environments

// Rust has minimal runtime overhead
// Perfect for embedded systems and single-board computers

Mixed Language Projects

You can use both languages in the same project! HORUS nodes communicate via shared memory, which works across languages.

Example: Python for AI, Rust for control

Loading diagram...
Mixed language project: Python for ML, Rust for control - connected via shared memory

Python ML node:

from horus import Node, Topic, Scheduler

class ObjectDetector(Node):
    def __init__(self):
        super().__init__("ObjectDetector")

    def init(self):
        self.camera_sub = Topic("camera")
        self.detection_pub = Topic("detections")

    def tick(self):
        camera_image = self.camera_sub.recv()
        if camera_image is not None:
            detections = model.detect(camera_image)
            self.detection_pub.send(detections)

Rust control node:

impl Node for NavigationController {
    fn tick(&mut self) {
        if let Some(detections) = self.detection_sub.recv() {
            // React to Python node's output
            self.plan_path(&detections);
        }
    }
}

Recommendation by Use Case

Use CaseRecommended Language
Learning HORUSPython
University projectPython
Hobby robotEither
Machine learning robotPython + Rust
Industrial automationRust
Drone/UAVRust
Research prototypePython
Competition robotRust
Product developmentRust

Getting Started

Ready to start with Python?

Ready to start with Rust?


Still Unsure?

Start with Python. It's faster to get something working, and you can always port critical parts to Rust later. HORUS makes it easy to mix languages.