40 for (
int ii = 0; ii < 5; ii++) {
92 double newLink1,
double newLink2,
double newLink3,
double newLink4,
121 double length =
sqrt(vector.
x * vector.
x + vector.
y * vector.
y + vector.
z * vector.
z);
123 result.
x = vector.
x / length;
124 result.
y = vector.
y / length;
125 result.
z = vector.
z / length;
127 printf(
"P2OS: Tried to normalise a vector of zero length.\n");
138 result.
x = pose.
o.
y * pose.
a.
z - pose.
a.
y * pose.
o.
z;
139 result.
y = pose.
o.
z * pose.
a.
x - pose.
a.
z * pose.
o.
x;
140 result.
z = pose.
o.
x * pose.
a.
y - pose.
a.
x * pose.
o.
y;
141 if (result.
x == 0 && result.
y == 0 && result.
z == 0) {
143 "P2OS: Approach and orientation cannot be the same vector" 144 "- their cross product cannot be zero.\n");
147 if (pose.
a.
y == 0 && pose.
a.
z == 0) {
156 result.
x = orient.
y * pose.
a.
z - pose.
a.
y * orient.
z;
157 result.
y = orient.
z * pose.
a.
x - pose.
a.
z * orient.
x;
158 result.
z = orient.
x * pose.
a.
y - pose.
a.
x * orient.
y;
165 printf(
"P: (%f, %f, %f)\tA: (%f, %f, %f)\tO: (%f, %f, %f)\tN: (%f, %f, %f)\n",
166 endEffector.
p.
x, endEffector.
p.
y, endEffector.
p.
z,
167 endEffector.
a.
x, endEffector.
a.
y, endEffector.
a.
z,
168 endEffector.
o.
x, endEffector.
o.
y, endEffector.
o.
z,
169 endEffector.
n.
x, endEffector.
n.
y, endEffector.
n.
z);
182 double adjustedJoints[5];
184 adjustedJoints[0] = (fromJoints[0] -
jointOffsets[0]) * -1;
186 adjustedJoints[2] = fromJoints[2] - jointOffsets[2];
187 adjustedJoints[3] = (fromJoints[3] - jointOffsets[3]) * -1;
188 adjustedJoints[4] = (fromJoints[4] - jointOffsets[4]) * -1;
209 double solutions[4][5];
214 solutions[0][0] = solutions[1][0] = temp;
216 solutions[2][0] = solutions[3][0] = temp;
220 double r = 0.0f, rz = 0.0f;
221 if (
sin(solutions[0][0]) < 0.1
f &&
sin(solutions[0][0]) > -0.1
f) {
229 temp = fmin(fmax(temp, -1.0
f), 1.0
f);
237 solutions[0][1] = temp + 2 * m1 * M_PI;
239 }
while ((solutions[0][1] < -(M_PI) || solutions[0][1] > M_PI));
242 temp = fmin(fmax(temp, -1.0
f), 1.0
f);
243 solutions[0][2] = M_PI -
acos(temp);
246 temp = fmin(fmax(temp, -1.0
f), 1.0
f);
247 temp =
atan2(rz, r) + acos(temp);
253 solutions[1][1] = temp + 2 * m1 * M_PI;
255 }
while ((solutions[1][1] < -(M_PI) || solutions[1][1] > M_PI));
256 temp = (
link2 *
link2 + link4 * link4 - r * r - rz * rz) / (2 *
link2 * link4);
257 temp = fmin(fmax(temp, -1.0
f), 1.0
f);
258 solutions[1][2] = -(M_PI) + acos(temp);
269 if (
sin(solutions[2][0]) < 0.1
f &&
sin(solutions[2][0]) > -0.1
f) {
277 temp = fmin(fmax(temp, -1.0
f), 1.0
f);
278 temp =
atan2(rz, r) - acos(temp);
284 solutions[2][1] = temp + 2 * m1 * M_PI;
286 }
while ((solutions[2][1] < -(M_PI) || solutions[2][1] > M_PI));
288 temp = (
link2 *
link2 + link4 * link4 - r * r - rz * rz) / (2 *
link2 * link4);
289 temp = fmin(fmax(temp, -1.0
f), 1.0
f);
290 solutions[2][2] = M_PI - acos(temp);
293 temp = fmin(fmax(temp, -1.0
f), 1.0
f);
294 temp =
atan2(rz, r) + acos(temp);
300 solutions[3][1] = temp + 2 * m1 * M_PI;
302 }
while ((solutions[3][1] < -(M_PI) || solutions[3][1] > M_PI));
303 temp = (
link2 *
link2 + link4 * link4 - r * r - rz * rz) / (2 *
link2 * link4);
304 temp = fmin(fmax(temp, -1.0
f), 1.0
f);
305 solutions[3][2] = -(M_PI) + acos(temp);
314 if (chosenSolution == -1) {
322 joints[2] = solutions[chosenSolution][2] + jointOffsets[2];
323 joints[3] = (solutions[chosenSolution][3] * -1) + jointOffsets[3];
324 joints[4] = (solutions[chosenSolution][4] * -1) + jointOffsets[4];
338 double cos1 =
cos(angles[0]);
339 double cos23 =
cos(angles[1] + angles[2]);
340 double sin1 =
sin(angles[0]);
341 double sin23 =
sin(angles[1] + angles[2]);
344 if (sin1 < -0.1f || sin1 > 0.1
f) {
345 angles[3] =
atan2(n.
z / cos23, -(n.
x + ((n.
z * cos1 * sin23) / cos23)) / sin1);
347 angles[3] =
atan2(n.
z / cos23, (n.
y + ((n.
z * sin1 * sin23) / cos23)) / cos1);
350 double cos4 =
cos(angles[3]);
351 double sin4 =
sin(angles[3]);
352 if (cos4 != 0 || sin23 != 0) {
353 angles[4] =
atan2(a.
z * cos23 * cos4 - o.
z * sin23, o.
z * cos23 * cos4 + a.
z * sin23);
355 angles[4] =
atan2(-(o.
x * cos1 + o.
y * sin1) / cos23, (o.
x * sin1 - o.
y * cos1) / sin4);
358 angles[4] =
atan2(-o.
z / sin23, a.
z / sin23);
360 double cos5 =
cos(angles[4]);
361 double sin5 =
sin(angles[4]);
362 if (cos5 > -0.1
f || cos5 < 0.1
f) {
363 angles[3] =
atan2((a.
x * sin1 - a.
y * cos1) / sin5, -(n.
x * sin1) + n.
y * cos1);
365 angles[3] =
atan2((o.
x * sin1 - o.
y * cos1) / cos5, -(n.
x * sin1) + n.
y * cos1);
384 for (
int ii = 0; ii < 4; ii++) {
385 double min = fmin(errors[0], fmin(errors[1], fmin(errors[2], errors[3])));
386 for (jj = 0; min != errors[jj]; jj++) {
392 for (
int ii = 0; ii < 4; ii++) {
412 double xOffset = solutionPos.
p.
x - fromPosition.
p.
x;
413 double yOffset = solutionPos.
p.
y - fromPosition.
p.
y;
414 double zOffset = solutionPos.
p.
z - fromPosition.
p.
z;
416 error =
sqrt(xOffset * xOffset + yOffset * yOffset + zOffset * zOffset);
430 double cos1 =
cos(angles[0]);
431 double cos2 =
cos(angles[1]);
432 double cos23 =
cos(angles[1] + angles[2]);
433 double cos4 =
cos(angles[3]);
434 double cos5 =
cos(angles[4]);
435 double sin1 =
sin(angles[0]);
436 double sin2 =
sin(angles[1]);
437 double sin23 =
sin(angles[1] + angles[2]);
438 double sin4 =
sin(angles[3]);
439 double sin5 =
sin(angles[4]);
442 ((cos1 * cos23 * cos5) + (sin1 * sin4 * sin5) - (cos1 * sin23 * cos4 * sin5)) +
445 ((sin1 * cos23 * cos5) + (cos1 * sin4 * sin5) - (sin1 * sin23 * cos4 * sin5)) +
447 result.
p.
z =
link5 * ((sin23 * cos5) + (cos23 * cos4 * sin5)) + (
link4 * sin23) + (
link2 * sin2);
449 result.
n.
x = -(sin1 * cos4) - (cos1 * sin23 * sin4);
450 result.
n.
y = (cos1 * cos4) - (sin1 * sin23 * sin4);
451 result.
n.
z = (cos23 * sin4);
453 result.
o.
x = -(cos1 * cos23 * sin5) + (sin1 * sin4 * cos5) - (cos1 * sin23 * cos4 * cos5);
454 result.
o.
y = -(sin1 * cos23 * sin5) - (cos1 * sin4 * cos5) - (sin1 * sin23 * cos4 * cos5);
455 result.
o.
z = -(sin23 * sin5) + (cos23 * cos4 * cos5);
457 result.
a.
x = (cos1 * cos23 * cos5) + (sin1 * sin4 * sin5) - (cos1 * sin23 * cos4 * sin5);
458 result.
a.
y = (sin1 * cos23 * cos5) + (cos1 * sin4 * sin5) - (sin1 * sin23 * cos4 * sin5);
459 result.
a.
z = (sin23 * cos5) + (cos23 * cos4 * sin5);
468 for (
int ii = 0; ii < 5; ii++) {
469 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)
double min(double a, double b)
INLINE Rall1d< T, V, S > sqrt(const Rall1d< T, V, S > &arg)
void SetP(const KineVector &newP)
void PrintEndEffector(const EndEffector &endEffector)
INLINE Rall1d< T, V, S > acos(const Rall1d< T, V, S > &x)
EndEffector CalcFKForJoints(const double angles[])
void CalcTheta4and5(double angles[], const EndEffector &fromPosition)
INLINE Rall1d< T, V, S > atan2(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
int ChooseSolution(const EndEffector &fromPosition, const double solutions[][5])
TFSIMD_FORCE_INLINE tfScalar length(const Quaternion &q)
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
void SetA(const KineVector &newA)
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
KineVector Normalise(const KineVector &vector)