4自由度机械臂正逆解公式推导与代码实现

 忽略机械臂及末端执行器外观后对机械臂建模可得

图中:

P为底部圆盘半径,A1、A2、A3、A4为抽象出的机械臂各部分杆长

α 为末端控制器的俯仰角

上述计算过程设置 α 为常量,通常在实际执行过程中为保证机械臂有较大的抓取范围,则使用循

环将 α 值遍历 0° 到 180° ,求解机械臂舵机的转角。

最后取 α 为满足条件的第n/2或(n+1)/2个解(有合理解的下限 < α < 有合理解的上限)

 代码:

#include "math.h"
#include <stdio.h>
int main()
{
	
	float a1,a2,a3,a4;                  //a1为底部圆台高度 剩下三个为三个机械臂长度 
	float j1,j4,j2,j3;                      //四个姿态角
	float L,H,P;	             //L =a2*sin(j2) + a3*sin(j2 + j3);H = a2*cos(j2) + a3*cos(j2 + j3); P为底部圆盘半径R
	float j_all;	                             //j2,j3,j4之和
	float len,high;                       //总长度,总高度
	float Cosj3,Sinj3;                   //用来存储cosj3,sinj3数值
	float Cosj2,Sinj2;
	float K1,K2;
	float X,Y,Z;  	             //输入 (X,Y,Z)坐标
	int i;
	float n,m,q;
	n = 0;
	m = 0;
	q = 0;
	//目标点坐标(X,Y,Z)
	X = 0;
	Y = 18;
	Z = 0;

	P = 7.5;     //底部圆盘半径
	a1 = 12.1; 	//底部圆盘高度	            
	a2 = 8.2;    //机械臂长度
	a3 = 8.2;
	a4 = 18.5;

	
	if (X == 0) 
	    j1=90;
	else 
	    j1 = atan((Y+P)/X)*(57.3);

	for(i=0;i<=180;i++)
	{	
		j_all = 3.1415927*i/180;

		len = sqrt((Y+P)*(Y+P)+X*X);
		high = Z;
			
		L = len	- a4*sin(j_all);
		H = high - a4*cos(j_all) - a1;
		
		Cosj3 = ((L*L)+(H*H)-((a2)*(a2))-((a3)*(a3)))/(2*(a2)*(a3));
		Sinj3 = (sqrt(1-(Cosj3)*(Cosj3)));
		
		j3 = atan((Sinj3)/(Cosj3))*(57.3);
		
		K2 = a3*sin(j3/57.3);
		K1 = a2+a3*cos(j3/57.3);
		
		Cosj2 = (K2*L+K1*H)/(K1*K1+K2*K2);
		Sinj2 = (sqrt(1-(Cosj2)*(Cosj2)));
		
		j2 = atan((Sinj2)/(Cosj2))*57.3;
		j4 = j_all*57.3- j2 - j3;
		
		if(j2>=0&&j3>=0&&j4>=-90&&j2<=180&&j3<=180&&j4<=90)
		{
			n=n+1;
		}
    } 
   
   
   	for(i=0;i<=180;i++)
	{
		j_all = 3.1415927*i/180;
		
		len = sqrt((Y+P)*(Y+P)+X*X);
		high = Z;

		L = len	- a4*sin(j_all);
		H = high - a4*cos(j_all) - a1;
		
		Cosj3 = ((L*L)+(H*H)-((a2)*(a2))-((a3)*(a3)))/(2*(a2)*(a3));
		Sinj3 = (sqrt(1-(Cosj3)*(Cosj3)));
		
		j3 = atan((Sinj3)/(Cosj3))*(57.3);
		
		K2 = a3*sin(j3/57.3);
		K1 = a2+a3*cos(j3/57.3);
		
		Cosj2 = (K2*L+K1*H)/(K1*K1+K2*K2);
		Sinj2 = (sqrt(1-(Cosj2)*(Cosj2)));
		
		j2 = atan((Sinj2)/(Cosj2))*57.3;
		j4 = j_all*57.3- j2 - j3;
		
	    if(j2>=0&&j3>=0&&j4>=-90&&j2<=180&&j3<=180&&j4<=90)
		{
			m=m+1;
			if(m==n/2||m==(n+1)/2)
			{	
				break;
			}
		}
    }
   
   	printf("j1:%f,j2:%f\nj3:%f,j4:%f\n",j1,j2,j3,j4);
}

 

  • 19
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
由于六自由度机械臂的求逆解涉及到较为复杂的数学运算,因此需要一定的数学基础和编程能力。以下是一个简单的 MATLAB 代码示例,仅供参考。 假设六自由度机械臂的DH参数如下: a = [0, 0, 0, 0, 0, 0]; alpha = [-pi/2, pi/2, pi/2, -pi/2, -pi/2, 0]; d = [0, 0, 0.15, 0, 0.2, 0]; theta = [0, 0, 0, 0, 0, 0]; 其中,a、alpha、d、theta 分别表示 DH 参数表中的 a、alpha、d、theta,即连杆长度、连杆扭转角、连杆长度、连杆旋转角。假设当前机械臂末端执行器的位姿为: T = [0.7071, -0.7071, 0, 0.6; 0.7071, 0.7071, 0, 0.4; 0, 0, 1, 0.3; 0, 0, 0, 1]; 则求解六自由度机械臂逆解可以按照以下步骤进行: 1. 计算关节角 theta1 和 theta6: theta1 = atan2(T(2,4), T(1,4)); theta6 = atan2(sqrt(T(1,3)^2 + T(2,3)^2), T(3,3)); 2. 计算关节角 theta5 和 theta4: c1 = cos(theta1); s1 = sin(theta1); c6 = cos(theta6); s6 = sin(theta6); s5 = -T(1,3)*c1*s6 + T(2,3)*s1*s6 + T(3,3)*c6; theta5 = atan2(sqrt(1-s5^2), s5); c5 = cos(theta5); theta4 = atan2(T(3,2)/(s5*d(5)), -T(3,1)/(s5*d(5))) - theta5; 3. 计算关节角 theta2 和 theta3: c4 = cos(theta4); s4 = sin(theta4); c5 = cos(theta5); s5 = sin(theta5); c6 = cos(theta6); s6 = sin(theta6); R03 = T(1:3,1:3) * [c1*c4*c5-s1*s5, -c1*s4, c1*c4*s5+s1*c5; s1*c4*c5+c1*s5, c1*s4, s1*c4*s5-c1*c5; -s4*c5, -s5, -c4*s5]; P03 = [T(1,4) - d(6)*R03(1,3); T(2,4) - d(6)*R03(2,3); T(3,4) - d(6)*R03(3,3)]; theta2 = atan2(P03(2), P03(1)) - atan2(d(2)*s1, d(1)+d(2)*c1); L = sqrt(P03(1)^2 + P03(2)^2 - d(1)^2 - d(2)^2 - 2*d(1)*d(2)*c1); theta3 = atan2(P03(3), L) - atan2(sqrt(1-(P03(3)/L)^2), P03(3)/L); 4. 输出逆解: theta = [theta1, theta2, theta3, theta4, theta5, theta6]; disp(theta); 完整代码如下:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值