-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathkinematic.cpp
74 lines (67 loc) · 1.99 KB
/
kinematic.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <math.h>
#include "kinematic.h"
/**
* Solves the al Kashi problem
*
* This gives the angles of a triangle side, knowing
* all the lengths of its sides.
*/
float alKashi(float a, float b, float c)
{
return acos(((a*a)+(b*b)-(c*c))/(2*a*b));
}
/**
* Compute the kinematics of the robot
*/
bool computeIK(float x, float y, float z,
float *a, float *b, float *c,
float l1, float l2, float l3)
{
// Alpha is simply the angle of the leg in the X/Y plane
float alpha = atan2(y, x);
// Distance between end of the leg and arm of the second motor,
// in the X/Y plane
float xp = sqrt(x*x+y*y)-l1;
if (xp < 0) {
xp = 0;
}
// Distance between second motor arm and the end of the leg,
// in the plane of the leg
float d = sqrt(pow(xp,2) + pow(z,2));
if (d > l2+l3) {
d = l2+l3;
}
// Knowing l2, l3 and d beta and gamma can be computed using
// the Al Kashi law
float beta = alKashi(l2, d, l3) - atan2(-z, xp);
float gamma = M_PI - alKashi(l2, l3, d);
if (!isnan(alpha) && !isnan(beta) && !isnan(gamma)) {
*a = RAD2DEG(alpha);
*b = RAD2DEG(beta);
*c = RAD2DEG(gamma);
return true;
} else {
return false;
}
}
void legFrame(float X, float Y, float *x, float *y, int leg, float l0)
{
switch (leg) {
case 0:
*x = cos(0*M_PI/2-M_PI/4)*X - sin(0*M_PI/2-M_PI/4)*Y - l0;
*y = sin(0*M_PI/2-M_PI/4)*X + cos(0*M_PI/2-M_PI/4)*Y;
break;
case 1:
*x = cos(1*M_PI/2-M_PI/4)*X - sin(1*M_PI/2-M_PI/4)*Y - l0;
*y = sin(1*M_PI/2-M_PI/4)*X + cos(1*M_PI/2-M_PI/4)*Y;
break;
case 2:
*x = cos(2*M_PI/2-M_PI/4)*X - sin(2*M_PI/2-M_PI/4)*Y - l0;
*y = sin(2*M_PI/2-M_PI/4)*X + cos(2*M_PI/2-M_PI/4)*Y;
break;
case 3:
*x = cos(3*M_PI/2-M_PI/4)*X - sin(3*M_PI/2-M_PI/4)*Y - l0;
*y = sin(3*M_PI/2-M_PI/4)*X + cos(3*M_PI/2-M_PI/4)*Y;
break;
}
}