当前位置:   article > 正文

UnityVR--机械臂场景7-三自由度逆向解算2_unity实现abb机械臂逆运动学求解

unity实现abb机械臂逆运动学求解

上一篇逆解了三轴机械臂的三个重要偏转角度θT、θ1和θ2,现在我在场景中将它实现出来。

1. 在场景中建立三个空节点作为旋转轴,可以使用不同颜色的Icon标记一下。为了计算简单,将三个旋转轴之间的距离设置为1,即L1=L2=1,三者关系如下图,并在最大的手臂之上建立一个空节点Base,位置与Arm1相同,脚本就挂在Base上

  

 2. 为了计算方便,先将机械臂的姿态摆放至与前文分析中的初始姿态一致。旋转轴分别为Arm0,Arm1。另外在场景中建立一个目标物体Target,可以放置在距离Base点小于(L1+L2)的范围内。(图就不放了)

3. 按照前一篇的解算过程,写一个逆解函数,得到末端坐标(Target),解算出3个偏转角度。这个还比较容易,套公式就行:

  1. float[] I_K(float[] cartesion,float[] f_scara)
  2. {
  3. float sita_1, sita_2, sita_3, sita_T, X, Y, Z, W, A;
  4. X = cartesion[x];
  5. Y = cartesion[y];
  6. Z = cartesion[z];
  7. W = Mathf.Sqrt(X * X + Z * Z);
  8. A = Mathf.Sqrt(W * W + Y * Y);
  9. sita_T = Mathf.Acos(W / A);
  10. sita_1=Mathf.Acos((L1*L1+W*W+Y*Y-L2*L2)/(2*L1*A))+sita_T;
  11. sita_2 = Mathf.Acos((W * W + Y * Y - L1 * L1 - L2 * L2) / (2 * L1 * L2));
  12. sita_3 = Mathf.Acos(X/ W);
  13. sita_1 *= Mathf.Rad2Deg;//弧度转角度
  14. sita_2 *= Mathf.Rad2Deg;
  15. sita_3 *= Mathf.Rad2Deg;
  16. f_scara[0] = sita_1;
  17. f_scara[1] = sita_2;
  18. f_scara[2] = sita_3;
  19. return f_scara;
  20. }

4. 然后在Update中实现三个角度的偏转:

  1. Vector3 Euler0 = Arm0.transform.localEulerAngles;
  2. Euler0.z = f_scara[0];
  3. Arm0.transform.localEulerAngles = Euler0;
  4. Vector3 Euler1 = Arm1.transform.localEulerAngles;
  5. Euler1.z =f_scara[1];
  6. Arm1.transform.localEulerAngles = Euler1;
  7. Vector3 Euler2 =transform.localEulerAngles;//这个是Base的偏转
  8. Euler2.y = f_scara[2];
  9. base. transform.localEulerAngles = Euler2;

5.测试:

将脚本挂在Base节点上,并拖入相应的节点,运行程序。

 

一开始还好,手爪Hand(黄球)还能够随着目标(Target)移动,后来就尴尬了,在Z轴正方向和Y轴负方向的区域,手爪反而向着目标的负方向移动了。

 检查一下,当Target位置为(1,1,1)时,输出sita_1,sita_2,sita_3的实际角度发现,sita_1,sita_2与计算值相符,而sita_3应该是绕Y轴旋转-45°(左手坐标)。

  要解决这个问题,我的设想是:以机械臂基座(也就是Base)为坐标原点的零时坐标系中,在1、2象限中需要将sita_3的偏转角度反向,而3、4象限不需要。

因此,sita_3的偏移角度的代码修改:

  1. Vector3 euler2 = Base.transform.localEulerAngles;
  2. euler2.y = F_scara[2]*Mathf.Sign(Base.position.z-Target.position.z);
  3. //Target和Base的Z向差,取它的正负号
  4. Base.localEulerAngles = euler2;

 

 运行没有问题,如果不动Target,拖动Base节点也是一样的。

5. 全文如下:

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class Robot_Cartesion : MonoBehaviour
  5. {
  6. public Transform Base,Arm0,Arm1,Hand,Target; //拖入机械臂的4个主要节点
  7. public Transform Target; //拖入目标物体
  8. private float L1,L2;
  9. private float[] cartesion = new float[3], f_scara = new float[3];
  10. int x = 0,y = 1,z = 2;
  11. void Start()
  12. {
  13. L1 = Vector3.Distance(Arm0.position, Arm1.position);
  14. L2 = Vector3.Distance(Arm1.position, Hand.position);
  15. }
  16. void Update()
  17. {
  18. //基座到目标的直线距离
  19. float length2 = Vector3.Distance(transform.position, Target.position);
  20. if(length2>L1+L2||length2<L1-L2)
  21. Debug.Log("超过抓取范围");
  22. else
  23. {
  24. cartesion[x] = Target.position.x - Base.position.x;
  25. cartesion[y] = Target.position.y - Base.position.y;
  26. cartesion[z] = Target.position.z - Base.position.z;
  27. F_scara=I_K(cartesion, F_scara);
  28. }
  29. Vector3 euler0 = Arm0.transform.localEulerAngles;
  30. euler0.z = F_scara[0];
  31. Arm0.localEulerAngles = euler0;
  32. Vector3 euler1 = Arm1.transform.localEulerAngles;
  33. euler1.z = -F_scara[1];
  34. Arm1.localEulerAngles = euler1;
  35. Vector3 euler2 = Base.transform.localEulerAngles;
  36. euler2.y = F_scara[2]*Mathf.Sign(Base.position.z-Target.position.z);
  37. //Target和Base的Z向差,取它的正负号
  38. Base.localEulerAngles = euler2;
  39. }
  40. float[] I_K(float[] cartesion,float[] f_scara)
  41. {
  42. float sita_1, sita_2, sita_3, sita_T, X, Y, Z, W, A;
  43. X = cartesion[x];
  44. Y = cartesion[y];
  45. Z = cartesion[z];
  46. W = Mathf.Sqrt(X * X + Z * Z);
  47. A = Mathf.Sqrt(W * W + Y * Y);
  48. sita_T = Mathf.Acos(W / A);
  49. sita_1=Mathf.Acos((L1*L1+W*W+Y*Y-L2*L2)/(2*L1*A))+sita_T;
  50. sita_2 = Mathf.Acos((W * W + Y * Y - L1 * L1 - L2 * L2) / (2 * L1 * L2));
  51. sita_3 = Mathf.Acos(X/ W);
  52. sita_1 *= Mathf.Rad2Deg;
  53. sita_2 *= Mathf.Rad2Deg;
  54. sita_3 *= Mathf.Rad2Deg;
  55. f_scara[0] = sita_1;
  56. f_scara[1] = sita_2;
  57. f_scara[2] = sita_3;
  58. return f_scara;
  59. }
  60. }

本文中的方法,参照了grbl控制3轴机械臂 原理 实现 (二) 之3D机械臂模拟及实现_ourkix的博客

加入自己的瞎琢磨,比较粗陋。且由于数学模型与实际模型的坐标差异,解决办法也许不是最优解,希望以后有空再改进。

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号