Control Messages (C++)

All control types in horus::msg::. Include via <horus/msg/control.hpp>.

Quick Reference

TypeSizeKey FieldsUse Case
CmdVel16 Blinear (m/s), angular (rad/s)Mobile robot velocity
MotorCommand56 Bmotor_id, mode, target, max_velocity, max_acceleration, feed_forward, enableSingle motor
ServoCommand24 Bservo_id, position (rad), speed (0-1), enableServo actuator
DifferentialDriveCommand40 Bleft_velocity, right_velocity (rad/s), max_acceleration, enableTwo-wheel robot
PidConfig64 Bcontroller_id, kp, ki, kd, integral_limit, output_limit, anti_windupPID tuning
TrajectoryPoint136 Bposition[3], velocity[3], acceleration[3], orientation[4], angular_velocity[3], time_from_startPath following
JointCommand928 Bjoint_names[16][32], joint_count, positions[16], velocities[16], efforts[16], modes[16]Joint-level control

CmdVel — The Most Common Message

16 bytes. Used by virtually every mobile robot:

// Publishing velocity commands
auto pub = sched.advertise<horus::msg::CmdVel>("cmd_vel");

horus::msg::CmdVel cmd{};
cmd.linear = 0.3f;    // 0.3 m/s forward
cmd.angular = 0.0f;   // no turning
cmd.timestamp_ns = 0;
pub.send(cmd);

// Loan pattern
auto sample = pub.loan();
sample->linear = 0.5f;
sample->angular = -0.1f;  // slight right turn
pub.publish(std::move(sample));

MotorCommand — Single Motor Control

horus::msg::MotorCommand cmd{};
cmd.motor_id = 0;
cmd.mode = 0;                    // 0=velocity, 1=position, 2=torque, 3=voltage
cmd.target = 100.0;              // target value, units depend on mode
cmd.max_velocity = 200.0;        // used in position mode
cmd.max_acceleration = 50.0;
cmd.feed_forward = 0.0;
cmd.enable = 1;
cmd.timestamp_ns = 0;

PidConfig — Runtime Gain Tuning

Send PID gains as a message (allows live tuning from another node).

Inside a Node, advertise returns a Publisher<T>* that the node owns and keeps alive, so publishing goes through ->; the scheduler's advertise instead returns a Publisher<T> by value, published through .:

class GainTuner : public horus::Node {
public:
    GainTuner(horus::Params& params) : Node("tuner"), params_(params) {
        pid_pub_ = advertise<horus::msg::PidConfig>("pid.config");
    }

    void tick() override {
        horus::msg::PidConfig cfg{};
        cfg.kp = params_.get<double>("kp", 1.0);   // gains are double, not float
        cfg.ki = params_.get<double>("ki", 0.1);
        cfg.kd = params_.get<double>("kd", 0.05);
        cfg.integral_limit = 10.0;
        cfg.output_limit = 100.0;
        cfg.anti_windup = 1;
        pid_pub_->send(cfg);
    }

private:
    horus::Params& params_;
    horus::Publisher<horus::msg::PidConfig>* pid_pub_;
};

See Also