机器人正逆运动学求解C语言实现(基于DH参数法)

一、核心代码框架

#include <stdio.h>
#include <math.h>

#define PI 3.14159265358979323846

// DH参数结构体
typedef struct {
    double a;   // 连杆长度
    double alpha; // 连杆扭转角
    double d;   // 连杆偏移量
    double theta; // 关节角
} DH_Param;

// 齐次变换矩阵(4x4)
typedef struct {
    double m[4][4];
} TransformMatrix;

// 正运动学计算(关节角→末端位姿)
void ForwardKinematics(DH_Param *dh, int dof, double *angles, TransformMatrix *result) {
    TransformMatrix T = {{{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}}}; // 单位矩阵
    for (int i=0; i<dof; i++) {
        double theta = dh[i].theta + angles[i] * PI/180.0; // 转换为弧度
        double cos_theta = cos(theta);
        double sin_theta = sin(theta);
        double cos_alpha = cos(dh[i].alpha * PI/180.0);
        double sin_alpha = sin(dh[i].alpha * PI/180.0);

        // 计算当前关节的齐次变换矩阵
        TransformMatrix Ti = {
            .m[0][0] = cos_theta,          .m[0][1] = -sin_theta*cos_alpha, .m[0][2] = sin_theta*sin_alpha, .m[0][3] = dh[i].a*cos_theta,
            .m[1][0] = sin_theta,          .m[1][1] = cos_theta*cos_alpha,   .m[1][2] = -cos_theta*sin_alpha, .m[1][3] = dh[i].a*sin_theta,
            .m[2][0] = 0,                .m[2][1] = sin_alpha,              .m[2][2] = cos_alpha,           .m[2][3] = dh[i].d,
            .m[3][0] = 0,                .m[3][1] = 0,                      .m[3][2] = 0,                   .m[3][3] = 1
        };

        // 矩阵连乘
        TransformMatrix temp;
        for (int r=0; r<4; r++) {
            for (int c=0; c<4; c++) {
                temp.m[r][c] = 0;
                for (int k=0; k<4; k++) {
                    temp.m[r][c] += T.m[r][k] * Ti.m[k][c];
                }
            }
        }
        T = temp;
    }
    *result = T;
}

// 逆运动学求解(末端位姿→关节角)- 几何法示例
int InverseKinematics(TransformMatrix target, DH_Param *dh, int dof, double *angles) {
    // 示例:2自由度平面机械臂(需根据实际DH参数修改)
    double x = target.m[0][3];
    double y = target.m[1][3];
    
    // 基座到末端距离
    double L1 = dh[0].a + dh[1].a;
    double L2 = dh[2].a;

    // 几何法解算(需处理奇异点)
    double theta2 = acos((x*x + y*y - L1*L1 - L2*L2) / (2*L1*L2));
    if (isnan(theta2)) return -1; // 无解

    double theta1 = atan2(y, x) - atan2(L2*sin(theta2), L1 + L2*cos(theta2));
    
    angles[0] = theta1 * 180/PI;
    angles[1] = theta2 * 180/PI;
    return 0; // 成功
}

int main() {
    // DH参数定义(示例:2自由度平面机械臂)
    DH_Param dh[3] = {
        {0.2, 0, 0.1, 0},    // 基座到关节1
        {0.3, 0, 0, 0},      // 关节1到关节2
        {0.1, -90, 0, 0}     // 关节2到末端(含90°扭转)
    };
    
    // 正运动学测试
    double joint_angles[2] = {30, 45}; // 输入关节角(度)
    TransformMatrix T;
    ForwardKinematics(dh, 3, joint_angles, &T);
    printf("正运动学结果:\n");
    printf("X=%.2f, Y=%.2f, Z=%.2f\n", T.m[0][3], T.m[1][3], T.m[2][3]);

    // 逆运动学测试
    TransformMatrix target = {{{1,0,0,0.5},{0,1,0,0.3},{0,0,1,0.2},{0,0,0,1}}}; // 目标位姿
    double solved_angles[2] = {0};
    if (InverseKinematics(target, dh, 3, solved_angles) == 0) {
        printf("逆运动学解:[%.2f°, %.2f°]\n", solved_angles[0], solved_angles[1]);
    } else {
        printf("逆运动学无解\n");
    }
    
    return 0;
}

二、关键实现细节

  1. DH参数建模

    • 使用标准DH参数法建立运动学模型,每个关节对应一个DH_Param结构体

    • 参数说明:

      // 示例:UR5机械臂部分DH参数
      DH_Param dh_ur5[6] = {
          {0.089159, 0, 0.42500, 0},     // Base to Joint1
          {0.39225, 0, 0, -1.5708},      // Joint1 to Joint2
          {0.39225, 0, 0, 1.5708},       // Joint2 to Joint3
          {0.0819, 0, 0.305, 0},         // Joint3 to Joint4
          {0.0819, 0, 0.305, 0},         // Joint4 to Joint5
          {0.0819, 0, 0.0819, -3.1416}   // Joint5 to EndEffector
      };
      
  2. 矩阵运算优化

    • 使用四元数或欧拉角优化旋转矩阵计算(避免万向节锁)

    • 示例矩阵乘法优化:

      void MatrixMultiply(TransformMatrix *a, TransformMatrix *b, TransformMatrix *result) {
          for (int i=0; i<4; i++) {
              for (int j=0; j<4; j++) {
                  result->m[i][j] = 0;
                  for (int k=0; k<4; k++) {
                      result->m[i][j] += a->m[i][k] * b->m[k][j];
                  }
              }
          }
      }
      
  3. 逆运动学算法

    • 解析法:适用于结构简单的机械臂(如平面2-DOF)

    • 数值法:通用但计算量大(需设置收敛阈值)

      // 数值法逆运动学示例(牛顿迭代法)
      int NewtonRaphson(TransformMatrix target, DH_Param *dh, int dof, double *angles) {
          double eps = 1e-6;
          double delta[6] = {0};
          for (int iter=0; iter<100; iter++) {
              TransformMatrix T;
              ForwardKinematics(dh, dof, angles, &T);
              // 计算雅可比矩阵(此处需实现)
              // Update delta using Jacobian inverse
              // angles += delta;
              if (Norm(delta) < eps) return 0;
          }
          return -1;
      }
      

三、扩展功能实现

  1. 多坐标系支持

    typedef struct {
        TransformMatrix base;    // 基坐标系
        TransformMatrix tool;    // 工具坐标系
        TransformMatrix work;    // 工作坐标系
    } RobotCoordinateSystem;
    
    void SetWorkFrame(RobotCoordinateSystem *rcs, TransformMatrix *wf) {
        MatrixMultiply(&rcs->base, wf, &rcs->work);
    }
    
  2. 实时运动规划

    // 三次样条插值轨迹生成
    void SplineInterpolation(TransformMatrix start, TransformMatrix end, double duration, TransformMatrix *path) {
        double t;
        for (t=0; t<=duration; t+=0.01) {
            path->m[0][3] = start.m[0][3] + (end.m[0][3]-start.m[0][3])*t/duration;
            path->m[1][3] = start.m[1][3] + (end.m[1][3]-start.m[1][3])*t/duration;
            path->m[2][3] = start.m[2][3] + (end.m[2][3]-start.m[2][3])*t/duration;
        }
    }
    

参考代码 机器人正、逆运动学求解源代码 www.youwenfan.com/contentcnr/101886.html

四、调试与验证

  1. 运动学验证

    void ValidateKinematics() {
        // 正运动学闭环验证
        TransformMatrix T;
        ForwardKinematics(dh, 6, joint_angles, &T);
        double solved_angles[6] = {0};
        InverseKinematics(T, dh, 6, solved_angles);
    
        double error = 0;
        for (int i=0; i<6; i++) {
            error += fabs(joint_angles[i] - solved_angles[i]);
        }
        printf("逆运动学误差:%.4f°\n", error/6.0);
    }
    
  2. 性能优化技巧

    • 使用查表法加速三角函数计算

    • 采用SIMD指令优化矩阵运算

    • 多线程分离运动学计算与控制循环


五、工程应用建议

  1. 硬件适配

    • STM32平台:使用CMSIS-NN加速矩阵运算

    • ROS系统:集成MoveIt!框架进行运动规划

    • 工业控制器:采用Power PMAC的C语言运动子程序

  2. 安全机制

    // 关节限位检查
    int CheckJointLimits(double *angles) {
        static const double min_limit[6] = {-180,-120,-90,-180,-120,-90};
        static const double max_limit[6] = {180,120,90,180,120,90};
        for (int i=0; i<6; i++) {
            if (angles[i] < min_limit[i] || angles[i] > max_limit[i]) {
                printf("关节%d超限!\n", i+1);
                return -1;
            }
        }
        return 0;
    }
    

通过上述方案,可实现机器人正逆运动学的快速开发与验证。实际应用中需根据具体机械结构调整DH参数,并添加实时性保障机制。

posted @ 2026-03-04 16:52  晃悠人生  阅读(0)  评论(0)    收藏  举报