@@ -29,6 +29,16 @@ struct haldata {
2929 hal_real_t a2 , a3 , d3 , d4 , d6 ;
3030} * haldata = NULL ;
3131
32+ /* the difference of two angles, brought into (-pi, pi] so that a joint a
33+ whole turn from the formula still matches it */
34+ static double angleDiff (double a , double b )
35+ {
36+ double d = a - b ;
37+ while (d > PM_PI ) { d -= 2 * PM_PI ; }
38+ while (d <= - PM_PI ) { d += 2 * PM_PI ; }
39+ return d ;
40+ }
41+
3242/* The flange orientation for a joint set: the ISO 9787 mechanical interface
3343 frame, whose z points out of the interface towards the work. Shared by the
3444 forward kinematics and the tool frame so the two cannot drift apart. */
@@ -152,16 +162,16 @@ static int pumaKinematicsForward(const double * joint,
152162 * iflags = 0 ;
153163
154164 /* Set shoulder-up flag if necessary */
155- if (fabs (joint [0 ]* PM_PI /180 - atan2 (hom .tran .y , hom .tran .x ) +
156- atan2 (PUMA_D3 , - sqrt (sumSq ))) < FLAG_FUZZ )
165+ if (fabs (angleDiff ( joint [0 ]* PM_PI /180 , atan2 (hom .tran .y , hom .tran .x ) -
166+ atan2 (PUMA_D3 , - sqrt (sumSq )))) < FLAG_FUZZ )
157167 {
158168 * iflags |= PUMA_SHOULDER_RIGHT ;
159169 }
160170
161171 /* Set elbow down flag if necessary */
162- if (fabs (joint [2 ]* PM_PI /180 - atan2 (PUMA_A3 , PUMA_D4 ) +
172+ if (fabs (angleDiff ( joint [2 ]* PM_PI /180 , atan2 (PUMA_A3 , PUMA_D4 ) -
163173 atan2 (k , - sqrt (PUMA_A3 * PUMA_A3 +
164- PUMA_D4 * PUMA_D4 - k * k ))) < FLAG_FUZZ )
174+ PUMA_D4 * PUMA_D4 - k * k )))) < FLAG_FUZZ )
165175 {
166176 * iflags |= PUMA_ELBOW_DOWN ;
167177 }
@@ -177,7 +187,7 @@ static int pumaKinematicsForward(const double * joint,
177187
178188 /* if not singular set wrist flip flag if necessary */
179189 else {
180- if (! (fabs (joint [3 ]* PM_PI /180 - atan2 (t1 , t2 )) < FLAG_FUZZ ))
190+ if (! (fabs (angleDiff ( joint [3 ]* PM_PI /180 , atan2 (t1 , t2 ) )) < FLAG_FUZZ ))
181191 {
182192 * iflags |= PUMA_WRIST_FLIP ;
183193 }
0 commit comments