-
Notifications
You must be signed in to change notification settings - Fork 9
/
locationCalculator.h
121 lines (95 loc) · 2.87 KB
/
locationCalculator.h
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* Library for my ballbot, found at http://onewaytobalance.blogspot.com
*
* For a good explanation of the maths here, see
* http://onewaytobalance.blogspot.com.au/2015/12/omnidirectional-control.html
*
* Open sourced under the MIT License (see LICENSE.txt)
* (c) Brian Chen 2015
*/
#define SINDEG(a)(sin(a*PI/180))
#define COSDEG(a)(cos(a*PI/180))
class LocationCalculator{
public:
float v_x, v_y;
float v_x_rel, v_y_rel;
float w;
float x, y;
float theta; // current angle
LocationCalculator(float _R, float _theta_a, float _theta_b, float _theta_c,
float *_v_a, float *_v_b, float *_v_c){
R = _R;
theta_a = _theta_a;
theta_b = _theta_b;
theta_c = _theta_c;
v_a = _v_a;
v_b = _v_b;
v_c = _v_c;
s_a = SINDEG(theta_a); c_a = COSDEG(theta_a);
s_b = SINDEG(theta_b); c_b = COSDEG(theta_b);
s_c = SINDEG(theta_c); c_c = COSDEG(theta_c);
/* matrix stuff */
det = (c_c*s_a - c_b*s_a + c_a*s_b - c_c*s_b + c_b*s_c - c_a*s_c);
}
void update(unsigned long _dt, float rot){
v_x_rel = (c_b - c_c) * (*v_a)
+ (c_c - c_a) * (*v_b)
+ (c_a - c_b) * (*v_c);
v_x_rel /= det;
v_y_rel = (s_b - s_c) * (*v_a)
+ (s_c - s_a) * (*v_b)
+ (s_a - s_b) * (*v_c);
v_y_rel /= det;
// first transform velocities to real coordinates.
v_x = COSDEG(rot) * v_x_rel - SINDEG(rot) * v_y_rel;
v_y = SINDEG(rot) * v_x_rel + COSDEG(rot) * v_y_rel;
// now integrate
x += v_x * _dt / 1000000;
y += v_y * _dt / 1000000;
}
void update(unsigned long _dt){
float alpha = getRot(_dt);
update(_dt, alpha);
}
void update(float alpha){
unsigned long _dt = getDt();
update(_dt, alpha);
}
void update(){
unsigned long _dt = getDt();
float alpha = getRot(_dt);
update(_dt, alpha);
}
void zero(){
x = 0;
y = 0;
}
private:
elapsedMicros deltaT;
unsigned long dt; // in us
float theta_a, theta_b, theta_c;
float *v_a, *v_b, *v_c;
float R;
float s_a; float c_a;
float s_b; float c_b;
float s_c; float c_c;
float det;
float average_theta;
float alpha;
unsigned long getDt(){
dt = deltaT;
deltaT = 0;
return dt;
}
float getRot(unsigned long _dt){
w = (c_b*s_c - c_c*s_b) * (*v_a)
+ (c_c*s_a - c_a*s_c) * (*v_b)
+ (c_a*s_b - c_b*s_a) * (*v_c);
w = w / det / R; // in rad
w = w * 180 / PI; // in deg
// linear equations solved. Now integrate.
theta += w * _dt / 1000000;
if (theta >= 360) theta -= 360;
average_theta = theta - w * _dt / 1000000 / 2;
return -average_theta;
}
};