44 for (
int ii = 0; ii < 5; ii++)
125 double length = sqrt (vector.
x * vector.
x + vector.
y * vector.
y + vector.
z * vector.
z);
128 result.
x = vector.
x / length;
129 result.
y = vector.
y / length;
130 result.
z = vector.
z / length;
134 printf (
"P2OS: Tried to normalise a vector of zero length.");
145 result.
x = pose.
o.
y * pose.
a.
z - pose.
a.
y * pose.
o.
z;
146 result.
y = pose.
o.
z * pose.
a.
x - pose.
a.
z * pose.
o.
x;
147 result.
z = pose.
o.
x * pose.
a.
y - pose.
a.
x * pose.
o.
y;
148 if (result.
x == 0 && result.
y == 0 && result.
z == 0)
150 printf (
"P2OS: Approach and orientation cannot be the same vector - their cross product cannot be zero.");
153 if (pose.
a.
y == 0 && pose.
a.
z == 0)
165 result.
x = orient.
y * pose.
a.
z - pose.
a.
y * orient.
z;
166 result.
y = orient.
z * pose.
a.
x - pose.
a.
z * orient.
x;
167 result.
z = orient.
x * pose.
a.
y - pose.
a.
x * orient.
y;
174 printf (
"P: (%f, %f, %f)\tA: (%f, %f, %f)\tO: (%f, %f, %f)\tN: (%f, %f, %f)\n",
175 endEffector.
p.
x, endEffector.
p.
y, endEffector.
p.
z,
176 endEffector.
a.
x, endEffector.
a.
y, endEffector.
a.
z,
177 endEffector.
o.
x, endEffector.
o.
y, endEffector.
o.
z,
178 endEffector.
n.
x, endEffector.
n.
y, endEffector.
n.
z);
191 double adjustedJoints[5];
193 adjustedJoints[0] = (fromJoints[0] -
jointOffsets[0]) * -1;
195 adjustedJoints[2] = fromJoints[2] - jointOffsets[2];
196 adjustedJoints[3] = (fromJoints[3] - jointOffsets[3]) * -1;;
197 adjustedJoints[4] = (fromJoints[4] - jointOffsets[4]) * -1;;
218 double solutions[4][5];
223 solutions[0][0] = solutions[1][0] = temp;
225 solutions[2][0] = solutions[3][0] = temp;
229 double r = 0.0f, rz = 0.0f;
230 if (sin (solutions[0][0]) < 0.1f && sin(solutions[0][0]) > -0.1f)
232 r = ((p.
x - (
link5 * a.
x)) / cos (solutions[0][0])) -
link1;
236 r = ((p.
y - (
link5 * a.
y)) / sin (solutions[0][0])) -
link1;
241 temp = fmin (fmax (temp, -1.0f), 1.0f);
242 temp = atan2 (rz, r) - acos (temp);
248 printf (
"m1 > 1!\n");
251 solutions[0][1] = temp + 2 * m1 * M_PI;
254 while ((solutions[0][1] < -(M_PI) || solutions[0][1] > M_PI));
256 temp = fmin (fmax (temp, -1.0f), 1.0f);
257 solutions[0][2] = M_PI - acos (temp);
259 temp = (r * r + rz * rz +
link2 *
link2 - link4 *
link4) / (2 *
link2 * sqrt (r * r + rz * rz));
260 temp = fmin (fmax (temp, -1.0f), 1.0f);
261 temp = atan2 (rz, r) + acos (temp);
269 solutions[1][1] = temp + 2 * m1 * M_PI;
272 while ((solutions[1][1] < -(M_PI) || solutions[1][1] > M_PI));
273 temp = (
link2 *
link2 + link4 * link4 - r * r - rz * rz) / (2 *
link2 * link4);
274 temp = fmin (fmax (temp, -1.0f), 1.0f);
275 solutions[1][2] = -(M_PI) + acos (temp);
286 if (sin (solutions[2][0]) < 0.1f && sin(solutions[2][0]) > -0.1f)
288 r = (p.
x -
link5 * a.
x) / cos (solutions[2][0]) -
link1;
292 r = (p.
y -
link5 * a.
y) / sin (solutions[2][0]) -
link1;
296 temp = (r * r + rz * rz +
link2 *
link2 - link4 *
link4) / (2 *
link2 * sqrt (r * r + rz * rz));
297 temp = fmin (fmax (temp, -1.0f), 1.0f);
298 temp = atan2 (rz, r) - acos (temp);
306 solutions[2][1] = temp + 2 * m1 * M_PI;
309 while ((solutions[2][1] < -(M_PI) || solutions[2][1] > M_PI));
310 temp = (
link2 *
link2 + link4 * link4 - r * r - rz * rz) / (2 *
link2 * link4);
311 temp = fmin (fmax (temp, -1.0f), 1.0f);
312 solutions[2][2] = M_PI - acos (temp);
314 temp = (r * r + rz * rz +
link2 *
link2 - link4 *
link4) / (2 *
link2 * sqrt (r * r + rz * rz));
315 temp = fmin (fmax (temp, -1.0f), 1.0f);
316 temp = atan2 (rz, r) + acos (temp);
324 solutions[3][1] = temp + 2 * m1 * M_PI;
327 while ((solutions[3][1] < -(M_PI) || solutions[3][1] > M_PI));
328 temp = (
link2 *
link2 + link4 * link4 - r * r - rz * rz) / (2 *
link2 * link4);
329 temp = fmin (fmax (temp, -1.0f), 1.0f);
330 solutions[3][2] = -(M_PI) + acos (temp);
339 if (chosenSolution == -1)
346 joints[2] = solutions[chosenSolution][2] + jointOffsets[2];
347 joints[3] = (solutions[chosenSolution][3] * -1) + jointOffsets[3];
348 joints[4] = (solutions[chosenSolution][4] * -1) + jointOffsets[4];
362 double cos1 = cos (angles[0]);
363 double cos23 = cos (angles[1] + angles[2]);
364 double sin1 = sin (angles[0]);
365 double sin23 = sin (angles[1] + angles[2]);
369 if (sin1 < -0.1f || sin1 > 0.1f)
371 angles[3] = atan2 (n.
z / cos23, -(n.
x + ((n.
z * cos1 * sin23) / cos23)) / sin1);
375 angles[3] = atan2 (n.
z / cos23, (n.
y + ((n.
z * sin1 * sin23) / cos23)) / cos1);
378 double cos4 = cos (angles[3]);
379 double sin4 = sin (angles[3]);
380 if (cos4 != 0 || sin23 != 0)
382 angles[4] = atan2 (a.
z * cos23 * cos4 - o.
z * sin23, o.
z * cos23 * cos4 + a.
z * sin23);
386 angles[4] = atan2 (-(o.
x * cos1 + o.
y * sin1) / cos23, (o.
x * sin1 - o.
y * cos1) / sin4);
391 angles[4] = atan2 (-o.
z / sin23, a.
z / sin23);
393 double cos5 = cos (angles[4]);
394 double sin5 = sin (angles[4]);
395 if (cos5 > -0.1f || cos5 < 0.1f)
397 angles[3] = atan2 ((a.
x * sin1 - a.
y * cos1) / sin5, -(n.
x * sin1) + n.
y * cos1);
401 angles[3] = atan2 ((o.
x * sin1 - o.
y * cos1) / cos5, -(n.
x * sin1) + n.
y * cos1);
420 for (
int ii = 0; ii < 4; ii++)
422 double min = fmin (errors[0], fmin (errors[1], fmin(errors[2], errors[3])));
423 for (jj = 0; min != errors[jj]; jj++);
428 for (
int ii = 0; ii < 4; ii++)
450 double xOffset = solutionPos.
p.
x - fromPosition.
p.
x;
451 double yOffset = solutionPos.
p.
y - fromPosition.
p.
y;
452 double zOffset = solutionPos.
p.
z - fromPosition.
p.
z;
454 error = sqrt (xOffset * xOffset + yOffset * yOffset + zOffset * zOffset);
467 double cos1 = cos (angles[0]);
468 double cos2 = cos (angles[1]);
469 double cos23 = cos (angles[1] + angles[2]);
470 double cos4 = cos (angles[3]);
471 double cos5 = cos (angles[4]);
472 double sin1 = sin (angles[0]);
473 double sin2 = sin (angles[1]);
474 double sin23 = sin (angles[1] + angles[2]);
475 double sin4 = sin (angles[3]);
476 double sin5 = sin (angles[4]);
478 result.
p.
x =
link5 * ((cos1 * cos23 * cos5) + (sin1 * sin4 * sin5) - (cos1 * sin23 * cos4 * sin5)) +
480 result.
p.
y =
link5 * ((sin1 * cos23 * cos5) + (cos1 * sin4 * sin5) - (sin1 * sin23 * cos4 * sin5)) +
482 result.
p.
z =
link5 * ((sin23 * cos5) + (cos23 * cos4 * sin5)) + (
link4 * sin23) + (
link2 * sin2);
484 result.
n.
x = -(sin1 * cos4) - (cos1 * sin23 * sin4);
485 result.
n.
y = (cos1 * cos4) - (sin1 * sin23 * sin4);
486 result.
n.
z = (cos23 * sin4);
488 result.
o.
x = -(cos1 * cos23 * sin5) + (sin1 * sin4 * cos5) - (cos1 * sin23 * cos4 * cos5);
489 result.
o.
y = -(sin1 * cos23 * sin5) - (cos1 * sin4 * cos5) - (sin1 * sin23 * cos4 * cos5);
490 result.
o.
z = -(sin23 * sin5) + (cos23 * cos4 * cos5);
492 result.
a.
x = (cos1 * cos23 * cos5) + (sin1 * sin4 * sin5) - (cos1 * sin23 * cos4 * sin5);
493 result.
a.
y = (sin1 * cos23 * cos5) + (cos1 * sin4 * sin5) - (sin1 * sin23 * cos4 * sin5);
494 result.
a.
z = (sin23 * cos5) + (cos23 * cos4 * sin5);
503 for (
int ii = 0; ii < 5; ii++)
505 if (angles[ii] <
jointMin[ii] || angles[ii] >
jointMax[ii] || isnan(angles[ii]))
double CalcSolutionError(const double solution[], const EndEffector &fromPosition)
void CalculateFK(const double fromJoints[])
bool CalculateIK(const EndEffector &fromPosition)
void SetO(const KineVector &newO)
bool SolutionInRange(const double angles[])
void SetJointRange(unsigned int joint, double min, double max)
void SetOffset(unsigned int joint, double newOffset)
void SetLinkLengths(double newLink1, double newLink2, double newLink3, double newLink4, double newLink5)
void SetTheta(unsigned int index, double newVal)
void SetN(const KineVector &newN)
double GetTheta(unsigned int index)
KineVector CalculateN(const EndEffector &pose)
void SetP(const KineVector &newP)
void PrintEndEffector(const EndEffector &endEffector)
EndEffector CalcFKForJoints(const double angles[])
void CalcTheta4and5(double angles[], const EndEffector &fromPosition)
int ChooseSolution(const EndEffector &fromPosition, const double solutions[][5])
void SetA(const KineVector &newA)
KineVector Normalise(const KineVector &vector)