项目介绍

本项目是一款开源的 6 自由度桌面机械臂,有效负载 500g,重复定位精度±0.5mm,支持正逆运动学解算和笛卡尔空间轨迹规划。

技术参数

参数规格
自由度6 (J1-J6)
工作半径400mm
有效负载500g
重复精度±0.5mm
最大速度200mm/s
控制周期2ms

机械设计

结构方案

采用串联式 6 轴结构:

  • J1: 基座旋转 (±180°)
  • J2: 大臂俯仰 (-90°~+90°)
  • J3: 小臂俯仰 (-90°~+120°)
  • J4: 手腕旋转 (±180°)
  • J5: 手腕俯仰 (-90°~+90°)
  • J6: 末端旋转 (±180°)

3D 打印件

材料:PLA+ / PETG

  • 壁厚:3mm (关键部位 4mm)
  • 填充率:40%
  • 层厚:0.2mm

传动设计

关节传动方式减速比
J1同步带3:1
J2同步带4:1
J3同步带4:1
J4齿轮5:1
J5齿轮5:1
J6直连1:1

硬件系统

控制板

主控: STM32F429

  • 主频:180MHz
  • FPU: 硬件单双精度
  • 定时器:17 个

驱动: TMC2209

  • 静音步进驱动
  • 电流:0.2-1.5A
  • 微步:256 细分

编码器: AS5047P

  • 磁编码器
  • 分辨率:14 位
  • SPI 接口

电机配置

关节电机型号保持扭矩
J1NEMA170.5Nm
J2NEMA170.5Nm
J3NEMA170.5Nm
J4NEMA140.2Nm
J5NEMA140.2Nm
J6NEMA140.2Nm

运动学建模

D-H 参数表

关节θd(mm)a(mm)α(°)
J1θ1150090
J2θ202000
J3θ3018090
J4θ42200-90
J5θ50090
J6θ68000

正运动学

typedef struct {
    float x, y, z;
    float rx, ry, rz;
} Pose_t;

Pose_t forward_kinematics(float joints[6]) {
    Pose_t pose;
    
    // D-H 变换矩阵连乘
    // T = A1 * A2 * A3 * A4 * A5 * A6
    
    // 提取位置
    pose.x = T[0][3];
    pose.y = T[1][3];
    pose.z = T[2][3];
    
    // 提取姿态 (欧拉角)
    pose.rx = atan2(T[2][1], T[2][2]);
    pose.ry = atan2(-T[2][0], sqrt(T[2][1]*T[2][1] + T[2][2]*T[2][2]));
    pose.rz = atan2(T[1][0], T[0][0]);
    
    return pose;
}

逆运动学 (数值解法)

#define IK_MAX_ITERATIONS  100
#define IK_CONVERGENCE_TH  0.001

int inverse_kinematics(Pose_t target, float *joints) {
    float current_joints[6] = {0};
    float error;
    int iter = 0;
    
    while (iter < IK_MAX_ITERATIONS) {
        // 1. 计算当前位姿
        Pose_t current = forward_kinematics(current_joints);
        
        // 2. 计算误差
        error = sqrt(pow(target.x - current.x, 2) +
                     pow(target.y - current.y, 2) +
                     pow(target.z - current.z, 2));
        
        // 3. 收敛判断
        if (error < IK_CONVERGENCE_TH) {
            memcpy(joints, current_joints, sizeof(float)*6);
            return 0;  // 成功
        }
        
        // 4. 雅可比矩阵计算
        float J[6][6];
        compute_jacobian(current_joints, J);
        
        // 5. 计算关节增量 (伪逆)
        float dJ[6];
        float error_vec[6] = {
            target.x - current.x,
            target.y - current.y,
            target.z - current.z,
            target.rx - current.rx,
            target.ry - current.ry,
            target.rz - current.rz
        };
        
        // dJ = J^+ * error (伪逆)
        pseudo_inverse_multiply(J, error_vec, dJ);
        
        // 6. 更新关节角
        for (int i = 0; i < 6; i++) {
            current_joints[i] += 0.5 * dJ[i];  // 阻尼因子
        }
        
        iter++;
    }
    
    return -1;  // 失败
}

轨迹规划

关节空间规划

void joint_space_trajectory(float start[6], float end[6], 
                            float duration, float dt) {
    int steps = duration / dt;
    
    for (int i = 0; i <= steps; i++) {
        float t = (float)i / steps;
        
        // 五次多项式插值
        float s = 10*t*t*t - 15*t*t*t*t + 6*t*t*t*t*t;
        
        for (int j = 0; j < 6; j++) {
            float target = start[j] + (end[j] - start[j]) * s;
            motor_move_to(j, target);
        }
        
        delay_ms(dt * 1000);
    }
}

笛卡尔空间规划

void cartesian_trajectory(Pose_t start, Pose_t end, 
                          float duration, float dt) {
    int steps = duration / dt;
    
    for (int i = 0; i <= steps; i++) {
        float t = (float)i / steps;
        
        // 直线插值
        Pose_t current;
        current.x = start.x + (end.x - start.x) * t;
        current.y = start.y + (end.y - start.y) * t;
        current.z = start.z + (end.z - start.z) * t;
        
        // 姿态插值 (SLERP)
        slerp(&start.rx, &end.rx, t, &current.rx);
        slerp(&start.ry, &end.ry, t, &current.ry);
        slerp(&start.rz, &end.rz, t, &current.rz);
        
        // 逆运动学解算
        float joints[6];
        if (inverse_kinematics(current, joints) == 0) {
            for (int j = 0; j < 6; j++) {
                motor_move_to(j, joints[j]);
            }
        }
        
        delay_ms(dt * 1000);
    }
}

控制软件

实时控制循环

void control_loop_2ms(void) {
    static uint32_t cycle_count = 0;
    
    // 1. 读取编码器
    for (int i = 0; i < 6; i++) {
        joint_angle[i] = encoder_read(i);
    }
    
    // 2. 运动学解算
    if (trajectory_active) {
        trajectory_update(joint_angle);
    }
    
    // 3. PID 控制
    for (int i = 0; i < 6; i++) {
        float error = target_angle[i] - joint_angle[i];
        float pwm = pid_calc(&pid[i], error);
        stepper_set_pwm(i, pwm);
    }
    
    // 4. 限位检测
    check_limit_switches();
    
    // 5. 状态上报
    if (cycle_count % 10 == 0) {
        send_status_report();
    }
    
    cycle_count++;
}

G 代码解析器

void parse_gcode(char *line) {
    char cmd[10];
    float params[26];  // A-Z
    
    sscanf(line, "%s", cmd);
    
    if (strcmp(cmd, "G0") == 0 || strcmp(cmd, "G1") == 0) {
        // 直线运动
        parse_params(line, params);
        
        Pose_t target;
        target.x = params['X'-'A'];
        target.y = params['Y'-'A'];
        target.z = params['Z'-'A'];
        
        float feedrate = params['F'-'A'];
        
        cartesian_move(&target, feedrate);
    }
    else if (strcmp(cmd, "G2") == 0 || strcmp(cmd, "G3") == 0) {
        // 圆弧运动
        // ...
    }
}

调试与优化

问题 1:逆解不收敛

现象:某些位姿无法求解

原因:奇异点附近雅可比矩阵病态

解决

  1. 加入阻尼最小二乘法 (DLS)
  2. 奇异点检测与规避
  3. 多初始值尝试

问题 2:末端抖动

现象:定位后持续微抖

原因:PID 参数过强 + 机械间隙

解决

  1. 降低微分项
  2. 增加死区补偿
  3. 机械预紧消除间隙

问题 3:轨迹跟踪误差

现象:高速运动时轨迹偏差大

原因:前馈不足 + 控制带宽低

解决

  1. 加入速度/加速度前馈
  2. 提高控制频率 (1ms → 0.5ms)
  3. 优化轨迹平滑度

性能测试

定位精度测试

测试点理论值 (mm)实测值 (mm)误差 (mm)
P1(200, 0, 100)(199.6, 0.2, 99.8)0.45
P2(150, 100, 150)(149.7, 99.8, 150.3)0.42
P3(100, -150, 200)(99.5, -149.7, 199.6)0.58

重复定位精度

连续 100 次定位同一位置:

  • X 轴标准差:0.12mm
  • Y 轴标准差:0.15mm
  • Z 轴标准差:0.18mm
  • 重复精度: ±0.45mm (3σ)

应用案例

  1. 3D 打印: 加装挤出机实现 3D 打印
  2. 激光雕刻: 加装激光头进行雕刻
  3. 物料搬运: 加装夹爪进行分拣
  4. 视觉检测: 加装相机进行定位检测

开源资料

参考资源

资源类型链接说明
机械臂开源项目https://github.com/topics/robot-armGitHub 机械臂项目
机械图纸https://grabcad.com/library3D 模型下载平台
电路参考https://oshwhub.com/search?q=机械臂立创 EDA 开源
固件源码https://github.com/hexepods/Hexepod开源机器人固件
上位机软件https://github.com/RoboticsBlog/robotic-arm-controlPython 控制软件

推荐学习

总结

本项目完整实现了 6 自由度机械臂的机械设计、运动学建模、轨迹规划和控制软件。通过开源方式分享,为机器人学习提供实践平台。


项目周期:2 个月 | 代码量:8000 行 | 版本:v2.0