Control Messages (C++)
All control types in horus::msg::. Include via <horus/msg/control.hpp>.
Quick Reference
| Type | Size | Key Fields | Use Case |
|---|---|---|---|
CmdVel | 16 B | linear (m/s), angular (rad/s) | Mobile robot velocity |
MotorCommand | 56 B | motor_id, mode, target, max_velocity, max_acceleration, feed_forward, enable | Single motor |
ServoCommand | 24 B | servo_id, position (rad), speed (0-1), enable | Servo actuator |
DifferentialDriveCommand | 40 B | left_velocity, right_velocity (rad/s), max_acceleration, enable | Two-wheel robot |
PidConfig | 64 B | controller_id, kp, ki, kd, integral_limit, output_limit, anti_windup | PID tuning |
TrajectoryPoint | 136 B | position[3], velocity[3], acceleration[3], orientation[4], angular_velocity[3], time_from_start | Path following |
JointCommand | 928 B | joint_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
- Sensor Messages — LaserScan, Imu, Odometry
- Tutorial 2: Motor Controller (C++) — a worked PID loop with anti-windup
- Message Types — field-by-field reference for every control message