跳转到内容

核心接口与数据类型

Sender 类负责通过 UDP 向机器人发送关节控制指令和模式切换命令。

Sender* send_cmd = new Sender("192.168.1.120", 43893); ///< 指定机器人 IP 和端口
void SendCmd(RobotCmd& robot_cmd); ///< 发送 12 关节控制指令
void ControlGet(uint32_t mode); ///< 控制权切换:SDK(2) 或 ROBOT(1)
void RobotStateInit(void); ///< 所有关节回零并获取控制权
void AllJointBackZero(void); ///< 所有关节回零
void SetCmd(uint32_t code, uint32_t value); ///< 发送原始命令码
模式常量说明
SDK 控制SDK (值为 2)SDK 拥有控制权,可下发关节指令
机器人控制ROBOT (值为 1)归还控制权给底层控制器

Receiver 类负责通过 UDP 接收机器人上报的状态数据。

Receiver* robot_data_recv = new Receiver(); ///< 创建接收器
robot_data_recv->StartWork(); ///< 启动接收线程
RobotData& data = robot_data_recv->GetState(); ///< 获取最新状态引用
void OnMessageUpdate(uint32_t code) {
if (code == 0x0906) {
is_message_updated_ = true; ///< 标记已收到机器人数据
}
}
robot_data_recv->RegisterCallBack(OnMessageUpdate);

回调函数在每次收到机器人数据更新时被调用,参数 code 为 0x0906 表示关节数据更新事件。

建议在确认收到机器人数据后再下发控制指令:

if (is_message_updated_) {
send_cmd->SendCmd(robot_joint_cmd);
}

DRTimer 基于 Linux timerfd + epoll 实现毫秒级精度的定时控制。

DRTimer set_timer;
set_timer.TimeInit(1); ///< 初始化,周期 1ms
double start_time = set_timer.GetCurrentTime(); ///< 获取当前时间
if (set_timer.TimerInterrupt() == true) { continue; } ///< 等待定时中断
double now_time = set_timer.GetIntervalTime(start_time); ///< 获取相对时间(秒)

所有数据类型定义在 robot_types.h 中。

typedef struct {
float position; ///< 关节位置(单位:rad)
float velocity; ///< 关节速度(单位:rad/s)
float torque; ///< 关节力矩(单位:Nm)
float temperature; ///< 电机温度(单位:°C)
} JointData;
typedef struct {
float position; ///< 目标位置(单位:rad)
float velocity; ///< 目标速度(单位:rad/s)
float torque; ///< 前馈力矩(单位:Nm)
float kp; ///< 位置刚度增益
float kd; ///< 速度阻尼增益
} JointCmd;
struct ImuData {
int32_t timestamp; ///< 时间戳(ms)
float angle_roll; ///< 横滚角(°)
float angle_pitch; ///< 俯仰角(°)
float angle_yaw; ///< 偏航角(°)
float angular_velocity_roll; ///< 横滚角速度(°/s)
float angular_velocity_pitch; ///< 俯仰角速度(°/s)
float angular_velocity_yaw; ///< 偏航角速度(°/s)
float acc_x; ///< X 轴加速度(m/s²)
float acc_y; ///< Y 轴加速度(m/s²)
float acc_z; ///< Z 轴加速度(m/s²)
};
typedef struct {
uint32_t tick; ///< 运行周期计数
ImuData imu; ///< IMU 数据
LegData joint_data; ///< 12 关节状态数据
ContactForce contact_force; ///< 四足接触力数据
} RobotData;

12 个关节的统一排列顺序为:

索引关节名称所属腿
0FL_HipX左前腿
1FL_HipY左前腿
2FL_Knee左前腿
3FR_HipX右前腿
4FR_HipY右前腿
5FR_Knee右前腿
6HL_HipX左后腿
7HL_HipY左后腿
8HL_Knee左后腿
9HR_HipX右后腿
10HR_HipY右后腿
11HR_Knee右后腿

也可通过腿部结构体访问:

robot_data->joint_data.fl_leg[3] ///< 左前腿 3 个关节
robot_data->joint_data.fr_leg[3] ///< 右前腿 3 个关节
robot_data->joint_data.hl_leg[3] ///< 左后腿 3 个关节
robot_data->joint_data.hr_leg[3] ///< 右后腿 3 个关节
robot_data->contact_force.fl_leg[] ///< 左前足端 X/Y/Z 三轴接触力
robot_data->contact_force.fr_leg[] ///< 右前足端 X/Y/Z 三轴接触力
robot_data->contact_force.hl_leg[] ///< 左后足端 X/Y/Z 三轴接触力
robot_data->contact_force.hr_leg[] ///< 右后足端 X/Y/Z 三轴接触力
robot_data->contact_force.leg_force[] ///< 全部 12 维接触力

提示: 在大多数应用场景中,仅使用 Z 方向的接触力。