@@ -19,7 +19,7 @@ public class Robot6RSphericalWrist : Robot
19
19
private readonly static Matrix4x4 T6G = Matrix4x4 . TRS ( Vector3 . zero , Quaternion . Euler ( 0 , - 90 , 0 ) , Vector3 . one ) ;
20
20
21
21
private Vector4 _p65 ;
22
- private float _l1 , _l2 , _delta ;
22
+ private float _link1 , _link2 , _link2Delta , _theta0Offset , _p05XZLength ;
23
23
private float _x , _y , _l , _alpha , _beta , _gamma ;
24
24
private Matrix4x4 _t01 , _t12 , _t23 , _t34 , _t03 , _t36 , _target ;
25
25
private Vector4 _p05 ;
@@ -74,35 +74,39 @@ public override IKSolution ComputeInverse(Matrix4x4 target, Configuration config
74
74
var solutionIndex = Clamp ( configuration . Index , 0 , DEFAULT_SOLUTIONS_COUNT - 1 ) ;
75
75
76
76
_p65 = new Vector4 ( 0 , - _frames [ 6 ] . Config . D , 0 , 1 ) ;
77
- _l1 = _frames [ 2 ] . Config . A ;
78
- _l2 = Sqrt ( _frames [ 4 ] . Config . D * _frames [ 4 ] . Config . D + _frames [ 3 ] . Config . A * _frames [ 3 ] . Config . A ) ;
79
- _delta = Atan2 ( _frames [ 3 ] . Config . A , _frames [ 4 ] . Config . D ) ;
77
+ _link1 = _frames [ 2 ] . Config . A ;
78
+ _link2 = Sqrt ( _frames [ 4 ] . Config . D * _frames [ 4 ] . Config . D + _frames [ 3 ] . Config . A * _frames [ 3 ] . Config . A ) ;
79
+ _link2Delta = Atan2 ( _frames [ 3 ] . Config . A , _frames [ 4 ] . Config . D ) ;
80
80
81
81
//NOTE: Original calculation is target = target * _flangeOffset * _t6G.inverse. Was simplified by target *= _t6G
82
82
target *= T6G ;
83
83
84
84
_p05 = target * _p65 ;
85
+
86
+ //NOTE: Offset on face view (typical for Stäubli)
87
+ _p05XZLength = Sqrt ( _p05 . x * _p05 . x + _p05 . z * _p05 . z ) ;
88
+ _theta0Offset = Asin ( _frames [ 3 ] . Config . D / _p05XZLength ) ;
85
89
86
90
_theta [ 0 ] = Atan2 ( - _p05 . x , _p05 . z ) ;
87
91
if ( float . IsNaN ( _theta [ 0 ] ) ) _theta [ 0 ] = 0 ;
88
- _theta [ 0 ] = solutionIndex < 4 ? _theta [ 0 ] : _theta [ 0 ] + PI ;
92
+ _theta [ 0 ] = solutionIndex < 4 ? _theta [ 0 ] - _theta0Offset : _theta [ 0 ] + PI + _theta0Offset ;
89
93
90
94
_x = _p05 . z * Cos ( _theta [ 0 ] ) - _p05 . x * Sin ( _theta [ 0 ] ) - _frames [ 1 ] . Config . A ;
91
95
_y = _p05 . y - _frames [ 1 ] . Config . D ;
92
96
_l = Sqrt ( _x * _x + _y * _y ) ;
93
- _alpha = Acos ( ( _l1 * _l1 + _l2 * _l2 - _l * _l ) / ( 2 * _l1 * _l2 ) ) ;
94
- _beta = Acos ( ( _l1 * _l1 - _l2 * _l2 + _l * _l ) / ( 2 * _l1 * _l ) ) ;
97
+ _alpha = Acos ( ( _link1 * _link1 + _link2 * _link2 - _l * _l ) / ( 2 * _link1 * _link2 ) ) ;
98
+ _beta = Acos ( ( _link1 * _link1 - _link2 * _link2 + _l * _l ) / ( 2 * _link1 * _l ) ) ;
95
99
_gamma = Atan2 ( _y , _x ) ;
96
100
97
101
if ( InverseIndex . Contains ( solutionIndex ) )
98
102
{
99
103
_theta [ 1 ] = PI * 0.5f - _gamma + _beta ;
100
- _theta [ 2 ] = PI * 0.5f + _delta + _alpha - 2 * PI ;
104
+ _theta [ 2 ] = PI * 0.5f + _link2Delta + _alpha - 2 * PI ;
101
105
}
102
106
else
103
107
{
104
108
_theta [ 1 ] = PI * 0.5f - _gamma - _beta ;
105
- _theta [ 2 ] = PI * 0.5f + _delta - _alpha ;
109
+ _theta [ 2 ] = PI * 0.5f + _link2Delta - _alpha ;
106
110
}
107
111
108
112
_t01 = HomogeneousMatrix . Create ( _frames [ 1 ] . Config , _joints [ 0 ] . Config , _theta [ 0 ] * Rad2Deg ) ;
0 commit comments