3_机械臂位姿变换计算过程代码

1、aubo arcs sdk poseTrans 使用例子

先贴代码:

auto cur_pose = rpc_cli->getRobotInterface(robot_name)
            ->getRobotState()
            ->getTcpPose();


std::vectortarget_pose;
target_pose = {0, 0, 0.0, 0, 0.0, 1.0};
        


auto ready_pose_ = rpc_cli->getMath()
                   ->poseTrans(cur_pose, target_pose);

有了这部分代码,可以进一步说明与验证该接口。cur_pose是机械臂基于基坐标系的位置和姿态,毫米和弧度为单位,即p_from参数。对于target_pose参数,是对p_from进行的位置和姿态的变换,例子中target_pose表示位置不变,绕ry旋转1弧度。输出结果:

45ad4173c68a0dcf09de67e152aec7e7.png

后面姿态表示是欧拉角,旋转方向是ZYX。绕Z轴旋转,但是变的是ry。OK,现在我们有了方程的参考答案,接下来自己推导解算过程。

2、借助Eigen库计算位姿变换

先整理下条件,已知当前机械臂的欧拉角姿态和位置,还已知变换的位姿。但从《机器人学导论》中学到的只有表示位姿的4×4的齐次位姿矩阵,所以需要欧拉角转旋转矩阵。

// 初始化欧拉角(rpy),对应绕x轴,绕y轴,绕z轴的旋转角度
    Eigen::Vector3d euler_angle(pose_from.at(3) * DEG_TO_ARC,
                                pose_from.at(4) * DEG_TO_ARC,
                                pose_from.at(5) * DEG_TO_ARC);            


    // 使用Eigen库将欧拉角转换为旋转矩阵
    Eigen::Matrix3d rotation_matrix1;
    rotation_matrix1 = Eigen::AngleAxisd(euler_angle[2], Eigen::Vector3d::UnitZ()) *
                       Eigen::AngleAxisd(euler_angle[1], Eigen::Vector3d::UnitY())* 
                       Eigen::AngleAxisd(euler_angle[0], Eigen::Vector3d::UnitX());

上面转换也可以自己手写。

6dea4a97bab4901ad7a2a4cd2971583e.png

将位置与旋转矩阵姿态构造成齐次矩阵:

Eigen::Matrix     <double,            </double,3, 4> m3x4_to;
    Eigen::Matrix     <double,            </double,4, 4> m4x4_to;
    Eigen::Matrix     <double,            </double,4, 4> m4x4_ret;


    m3x4_to << rotation_matrix1_to, pos_to;
    cout << "m3x4_to is :\n" << m3x4_to << std::endl;// np.concatenate((a,b))


    m4x4_to << m3x4_to, homogeneous;
    m4x4_ret = m4x4*m4x4_to;


    cout << "m4x4_to is: \n" << m4x4_ret << std::endl;


    Eigen::Matrix   <double,  </double,3, 3> m3x3_ret = m4x4_ret.block(0, 0, 3, 3);
    cout << "m3x3_to ret is: \n" << m3x3_ret << std::endl;

将旋转矩阵变为欧拉角便于观察:

Eigen::Vector3d rotationMatrixToEulerAngles(Eigen::Matrix3d &R)
{
    assert(isRotationMatirx(R));
    double sy = sqrt(R(0,0) * R(0,0) + R(1,0) * R(1,0));
    bool singular = sy < 1e-6;
    double x, y, z;


    if (!singular){    
        x = atan2( R(2,1), R(2,2));
        y = atan2(-R(2,0), sy);
        z = atan2( R(1,0), R(0,0));
    }else{
        x = atan2(-R(1,2), R(1,1));
        y = atan2(-R(2,0), sy);
        z = 0;
    }
    return {x, y, z};
}

将上述组合,构建一个自己的myPoseTrans函数:

/**


 * @brief myPoseTrans


     * @param pose_from 起始位姿(空间向量)


     * @param pose_from_to 相对于起始位姿的姿态变化(空间向量)


     * @return 结果位姿 (空间向量)


 */


std::vectormyPoseTrans(const std::vector&pose_from,
                                const std::vector&pose_from_to)
{
    std::vector pose;
    // 初始化欧拉角(rpy),对应绕x轴,绕y轴,绕z轴的旋转角度
    Eigen::Vector3d euler_angle(pose_from.at(3) * DEG_TO_ARC,
                                pose_from.at(4) * DEG_TO_ARC,
                                pose_from.at(5) * DEG_TO_ARC);
    // 使用Eigen库将欧拉角转换为旋转矩阵
    Eigen::Matrix3d rotation_matrix1;
    rotation_matrix1 = Eigen::AngleAxisd(euler_angle[2], Eigen::Vector3d::UnitZ()) *
                       Eigen::AngleAxisd(euler_angle[1], Eigen::Vector3d::UnitY()) *
                       Eigen::AngleAxisd(euler_angle[0], Eigen::Vector3d::UnitX());    
     


    Eigen::MatrixXd pos(3,1);
    pos(0,0)= pose_from.at(0);
    pos(1,0)= pose_from.at(1);
    pos(2,0)= pose_from.at(2);


    Eigen::MatrixXd homogeneous(1,4);
    homogeneous(0,0)=0;
    homogeneous(0,1)=0;
    homogeneous(0,2)=0;
    homogeneous(0,3)=1;


    Eigen::Matrix     <double,            </double,3, 4> m3x4;
    Eigen::Matrix     <double,            </double,4, 4> m4x4;      


    m3x4 << rotation_matrix1, pos;
    cout << "m3x4 is :\n" << m3x4 << std::endl;// np.concatenate((a,b))


    m4x4 << m3x4, homogeneous;
    cout << "m4x4 is: \n" <


    Eigen::MatrixXd pos_to(3,1);
    pos_to(0,0)= pose_from_to.at(0);
    pos_to(1,0)= pose_from_to.at(1);
    pos_to(2,0)= pose_from_to.at(2);
    
    // 转化为弧度
    Eigen::Vector3d euler_angle_to(pose_from_to.at(3) * DEG_TO_ARC,
                                   pose_from_to.at(4) * DEG_TO_ARC,
                                   pose_from_to.at(5) * DEG_TO_ARC);    


    // 使用Eigen库将欧拉角转换为旋转矩阵
    Eigen::Matrix3d rotation_matrix1_to;
    rotation_matrix1_to = Eigen::AngleAxisd(euler_angle_to[2], Eigen::Vector3d::UnitZ()) *
                          Eigen::AngleAxisd(euler_angle_to[1], Eigen::Vector3d::UnitY()) *    
                          Eigen::AngleAxisd(euler_angle_to[0], Eigen::Vector3d::UnitX());
          
    Eigen::Matrix     <double,            </double,3, 4> m3x4_to;
    Eigen::Matrix     <double,            </double,4, 4> m4x4_to;
    Eigen::Matrix     <double,            </double,4, 4> m4x4_ret;
      


    m3x4_to << rotation_matrix1_to, pos_to;
    cout << "m3x4_to is :\n" << m3x4_to << std::endl;// np.concatenate((a,b))


    m4x4_to << m3x4_to, homogeneous;
    m4x4_ret = m4x4*m4x4_to;


    cout << "m4x4_to is: \n" << m4x4_ret << std::endl;     


    Eigen::Matrix     <double,            </double,3, 3> m3x3_ret = m4x4_ret.block(0, 0, 3, 3);
    cout << "m3x3_to ret is: \n" << m3x3_ret << std::endl;
    // 使用自定义函数将旋转矩阵转换为欧拉角
    Eigen::Vector3d eulerAngle2 = rotationMatrixToEulerAngles(m3x3_ret); // roll,pitch,yaw
    cout << "roll_2 pitch_2 yaw_2 = " << eulerAngle2[0] << " " << eulerAngle2[1]
         << " " << eulerAngle2[2] << endl << endl;




    pose.push_back(m4x4_ret(0,3));
    pose.push_back(m4x4_ret(1,3));
    pose.push_back(m4x4_ret(2,3));
    pose.push_back(eulerAngle2[0]*ARC_TO_DEG);
    pose.push_back(eulerAngle2[1]*ARC_TO_DEG);
    pose.push_back(eulerAngle2[2]*ARC_TO_DEG);


    return pose;
}

我的计算结果:    

0626a2c7f951cf6ae9feeb229599311a.png         

其他测试数据:

b88b0c70deb96a51708ffbd63c862ce0.png

81ea3a3e47b6de6e77237fa83594a676.png

欢迎关注:

17d1fd68f13a3d6307601351ac34763c.png

如需完整工程可在公众号后台留言“混合变换”。

四自由度机械臂逆解算是一个比较复杂的数学问题,需要用到向量、矩阵等高等数学知识。在编写C语言程序时,可以使用C语言中的数学库来完成计算。 具体步骤如下: 1. 根据机械臂的结构和运动学方程,推导出机械臂的运动学模型。 2. 根据机械臂的末端位置和姿态,求解机械臂的逆运动学问题,即求出每个关节的角度。 3. 利用C语言中的数学库,如math.h中的sin、cos函数等,将角度转化成弧度,并进行计算。 4. 最后将计算结果输出或者控制机械臂的运动。 以下是一个简单的四自由度机械臂逆解算的C语言程序示例: ``` #include <stdio.h> #include <math.h> int main() { float x, y, z, alpha, beta, gamma; float L1 = 1.0, L2 = 1.0, L3 = 1.0, L4 = 1.0; //四个关节的长度 printf("请输入机械臂末端的坐标(x,y,z):"); scanf("%f%f%f", &x, &y, &z); alpha = atan2(y, x); beta = atan2(sqrt(x*x+y*y-L1*L1), L1-z); gamma = atan2(L4*sin(beta), L3+L4*cos(beta)); float theta1 = alpha; float theta2 = M_PI/2 - beta - gamma; float theta3 = M_PI/2 - atan2(L4*sin(beta), L3+L4*cos(beta)); float theta4 = -alpha; printf("关节1角度: %f\n", theta1); printf("关节2角度: %f\n", theta2); printf("关节3角度: %f\n", theta3); printf("关节4角度: %f\n", theta4); return 0; } ``` 在上面的程序中,首先通过scanf函数获取机械臂末端的坐标,然后利用atan2函数求出alpha、beta、gamma三个角度。最后根据运动学模型和角度关系,计算出每个关节的角度,并输出结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值