C++ API Reference
The HORUS C++ API provides first-class access to the real-time scheduler, zero-copy IPC, services, and actions. The bindings are generated from the Rust core via a C FFI layer (horus_c.h), so the C++ API has identical semantics to Rust and Python -- same shared memory transport, same scheduling guarantees, same message types -- with one exception: the vision message types are not exposed to C++ (see Message Category Includes).
Rust: See Rust API Reference for the native API. Python: See Python API for the scripting API.
// simplified
#include <horus/horus.hpp>
using namespace horus::literals;
Quick Reference -- All Classes
Core
| Class | Header | Description |
|---|---|---|
Scheduler | scheduler.hpp | Real-time scheduler -- creates, configures, and runs nodes |
NodeBuilder | scheduler.hpp | Builder for configuring a node before registration |
Node | node.hpp | Base class for struct-based nodes (like Rust impl Node) |
LambdaNode | node.hpp | Declarative node with builder pattern (like Python horus.Node) |
Communication
| Class | Header | Description |
|---|---|---|
Publisher<T> | topic.hpp | Sends messages to a topic via zero-copy SHM |
Subscriber<T> | topic.hpp | Receives messages from a topic via zero-copy SHM |
LoanedSample<T> | topic.hpp | Writable sample to fill in and publish |
BorrowedSample<T> | topic.hpp | Read-only zero-copy buffer from subscribing |
Services and Actions
| Class | Header | Description |
|---|---|---|
ServiceClient | service.hpp | Synchronous request/response RPC client |
ServiceServer | service.hpp | Request/response RPC server with handler callback |
ActionClient | action.hpp | Long-running task client with goal tracking |
ActionServer | action.hpp | Long-running task server with accept/execute handlers |
GoalHandle | action.hpp | Handle to a running action goal |
GoalStatus | action.hpp | Enum: Pending, Active, Succeeded, Aborted, Canceled, Rejected |
Pools, Parameters, and Transforms
| Class | Header | Description |
|---|---|---|
TensorPool | pool.hpp | SHM-backed memory pool that tensors, images, and point clouds allocate from |
Tensor | pool.hpp | N-dimensional typed array allocated from a TensorPool |
Image | pool.hpp | Pool-backed camera frame -- width, height, encoding |
PointCloud | pool.hpp | Pool-backed point cloud -- N points x fields per point |
Params | params.hpp | Runtime parameter store with typed get/set by key |
TransformFrame | transform.hpp | Coordinate frame tree -- register, update, and look up frames |
Transform | transform.hpp | Translation + quaternion pair returned by TransformFrame::lookup |
horus::log | log.hpp | info / warn / error free functions |
horus::blackbox | blackbox.hpp | record(category, message) -- flight-recorder entries |
Support Types
| Type | Header | Description |
|---|---|---|
Frequency | duration.hpp | Frequency in Hertz, created via 100_hz literal |
Duration | duration.hpp | Alias for std::chrono::microseconds |
Miss | error.hpp | Deadline miss policy: Warn, Skip, SafeMode, Stop |
Include Patterns
Single Include (Recommended)
#include <horus/horus.hpp>
using namespace horus::literals; // 100_hz, 5_ms, 200_us
This pulls in all headers: scheduler, node, topic, messages, services, actions, pools, params, transforms, logging, blackbox, duration, and error types.
Selective Includes
#include <horus/scheduler.hpp> // Scheduler, NodeBuilder
#include <horus/node.hpp> // Node, LambdaNode
#include <horus/topic.hpp> // Publisher, Subscriber, LoanedSample, BorrowedSample
#include <horus/messages.hpp> // All 66 message structs (61 are topic-capable)
#include <horus/service.hpp> // ServiceClient, ServiceServer
#include <horus/action.hpp> // ActionClient, ActionServer, GoalHandle
#include <horus/duration.hpp> // Frequency, Duration, literals
Message Category Includes
#include <horus/msg/geometry.hpp> // Point3, Vector3, Quaternion, Twist, Pose2D, Pose3D, ...
#include <horus/msg/sensor.hpp> // LaserScan, Imu, Odometry, JointState, BatteryState, ...
#include <horus/msg/control.hpp> // CmdVel, MotorCommand, JointCommand, PidConfig, ...
#include <horus/msg/navigation.hpp> // NavGoal, GoalResult, Waypoint, NavPath, VelocityObstacle, PathPlan
#include <horus/msg/diagnostics.hpp> // Heartbeat, DiagnosticStatus, EmergencyStop, ...
#include <horus/msg/detection.hpp> // Detection, Detection3D, TrackedObject, Landmark, ...
#include <horus/msg/vision.hpp> // (defines no types -- see note below)
#include <horus/msg/force.hpp> // WrenchStamped, ForceCommand, ContactInfo, ...
#include <horus/msg/time.hpp> // Clock, TimeReference, SimSync, RateRequest
#include <horus/msg/input.hpp> // KeyboardInput, JoystickInput, AudioFrame
msg/vision.hpp exists and compiles, but it declares nothing: CameraInfo, RegionOfInterest and StereoInfo were withdrawn because the upstream Rust types are declared without #[repr(C)], so no C++ mirror of them can be guaranteed to match. horus::msg::CameraInfo is a compile error today.
Minimal Example
#include <horus/horus.hpp>
using namespace horus::literals;
int main() {
horus::Scheduler sched;
sched.tick_rate(100_hz)
.name("my_robot")
.prefer_rt();
auto cmd_pub = sched.advertise<horus::msg::CmdVel>("motor.cmd");
auto scan_sub = sched.subscribe<horus::msg::LaserScan>("lidar.scan");
sched.add("controller")
.rate(50_hz)
.budget(5_ms)
.on_miss(horus::Miss::Skip)
.tick([&] {
auto scan = scan_sub.recv();
if (!scan) return;
auto cmd = cmd_pub.loan();
cmd->linear = scan->get()->ranges[0] > 1.0f ? 0.5f : 0.0f;
cmd->angular = 0.0f;
cmd_pub.publish(std::move(cmd));
})
.build();
sched.spin(); // blocks until Ctrl+C
}
Build Integration
HORUS C++ projects use horus.toml as the single source of truth. The CLI generates CMakeLists.txt into .horus/:
# horus.toml
[package]
name = "my_robot"
version = "0.1.0"
standard = "c++17"
[dependencies]
horus = "0.1"
horus build # generates .horus/CMakeLists.txt, compiles
horus run # builds + runs
Duration and Frequency Literals
HORUS provides user-defined literals that match the Rust DurationExt trait. Import them with using namespace horus::literals;:
| Literal | Type | Example |
|---|---|---|
_hz | Frequency | 100_hz = 100 Hz tick rate |
_ms | Duration (microseconds) | 5_ms = 5000 us |
_us | Duration (microseconds) | 200_us = 200 us |
_ns | std::chrono::nanoseconds | 500_ns = 500 ns |
_s | Duration (microseconds) | 5_s = 5000000 us |
using namespace horus::literals;
auto freq = 100_hz; // Frequency(100.0)
auto dur = 5_ms; // std::chrono::microseconds(5000)
auto us = 200_us; // std::chrono::microseconds(200)
// Frequency helper methods
auto period = freq.period(); // 10000 us (10 ms)
auto budget = freq.budget_default(); // 8000 us (80% of period)
auto deadline = freq.deadline_default();// 9500 us (95% of period)
Cross-Language Equivalence
The C++ API mirrors Rust and Python exactly. Code written in one language can be ported line-by-line:
| Concept | Rust | C++ | Python |
|---|---|---|---|
| Scheduler | Scheduler::new() | horus::Scheduler() | horus.Scheduler() |
| Tick rate | .tick_rate(100.hz()) | .tick_rate(100_hz) | tick_rate=100 |
| Publish | topic.send(msg) | pub.send(msg) | node.send("topic", msg) |
| Subscribe | topic.recv() | sub.recv() | node.recv("topic") |
| Node | impl Node for T | class T : public horus::Node | horus.Node(name, tick) |
| Run | scheduler.run()? | sched.spin() | horus.run(node) |
All three languages share the same SHM transport. A Rust publisher and a C++ subscriber on the same topic communicate with zero serialization overhead.
Ownership and Move Semantics
All core types (Scheduler, Publisher<T>, Subscriber<T>, LoanedSample<T>, BorrowedSample<T>, ServiceClient, ServiceServer, ActionClient, ActionServer, GoalHandle) are move-only. Copy constructors and copy assignment are deleted. This matches Rust's ownership model -- each resource has exactly one owner.
auto pub = sched.advertise<horus::msg::CmdVel>("cmd");
// auto pub2 = pub; // COMPILE ERROR: copy deleted
auto pub2 = std::move(pub); // OK: ownership transferred
See Also
- Scheduler API -- Builder pattern, node registration, execution
- Node API -- Lifecycle, struct-based and lambda-based nodes
- Publisher and Subscriber API -- Shared-memory messaging, loan pattern
- Services and Actions API -- RPC and long-running tasks
- TensorPool, Image and PointCloud API -- Pool-backed tensors, camera frames, point clouds
- Runtime Parameters API -- Typed
get/setconfiguration at runtime - TransformFrame API -- Coordinate frame tree and transform lookups
- Logging and BlackBox API -- Structured logging and flight-recorder entries
- C++ Real-Time Guide -- Budget, deadline, miss policies, SCHED_FIFO
- C++ Error Handling -- Error types and recovery
- C++ Performance -- Benchmarks and optimization