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
MotorCommand32 Btarget_velocity, target_position, kp, kd, max_effortSingle motor
ServoCommand24 Btarget_position, target_velocity, max_forceServo actuator
DifferentialDriveCommand16 Bleft_velocity, right_velocityTwo-wheel robot
PidConfig32 Bkp, ki, kd, integral_limit, derivative_filterPID tuning
TrajectoryPoint104 Bpositions[3], velocities[3], accelerations[3], effort[3]Path following
JointCommand88 Bjoint_id[32], target[3], velocity[3]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);

// Zero-copy with 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.target_velocity = 100.0f;    // RPM
cmd.target_position = 0.0f;      // not used in velocity mode
cmd.kp = 1.0f;                   // proportional gain
cmd.kd = 0.1f;                   // derivative gain
cmd.max_effort = 5.0f;           // max torque (Nm)
cmd.timestamp_ns = 0;

PidConfig — Runtime Gain Tuning

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

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 = static_cast<float>(params_.get<double>("kp", 1.0));
        cfg.ki = static_cast<float>(params_.get<double>("ki", 0.1));
        cfg.kd = static_cast<float>(params_.get<double>("kd", 0.05));
        cfg.integral_limit = 10.0f;
        cfg.derivative_filter = 0.8f;
        pid_pub_->send(cfg);
    }

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

See Also