forked from Pitt-RAS/micromouse-2016
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMotionCalc.cpp
110 lines (97 loc) · 2.73 KB
/
MotionCalc.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
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
#include <Arduino.h>
#include "MotionCalc.h"
MotionCalc::MotionCalc (float temp_dTot, float temp_vMax, float temp_vStart, float temp_vEnd,
float temp_max_accel, float temp_max_decel) {
dTot = temp_dTot;
vMax = temp_vMax;
vStart = temp_vStart;
vEnd = temp_vEnd;
max_accel = temp_max_accel;
max_decel = temp_max_decel;
// make sure that accel and decel have the correct sign
if (max_accel < 0) {
max_accel *= -1;
}
if (max_decel > 0) {
max_decel *= -1;
}
// turn dTot into meters
dTot /= 1000;
// set constants from global. Do this a different way later to reference conf.h
if (((dTot < 0) && (vMax > 0)) || ((dTot > 0) && (vMax < 0))) {
vMax = -vMax;
}
if (vStart <= vMax) {
aStart = max_accel;
}
else {
aStart = max_decel;
}
if (vEnd <= vMax) {
aEnd = max_decel;
}
else {
aEnd = max_accel;
}
// do initial calculations
// set distances assuming there is room to reach max speed
dStart = (vMax * vMax - vStart * vStart) / (2 * aStart);
dEnd = (vEnd * vEnd - vMax * vMax) / (2 * aEnd);
tConst = 1000000 * (dTot - dStart - dEnd) / vMax;
// set distances if there is not space to reach max speed
if (tConst < 0) {
dStart = (vStart * vStart - vEnd * vEnd + 2 * aEnd * dTot) / (2 * aEnd - 2 * aStart);
dEnd = dTot - dStart;
vMax = sqrt(vStart * vStart + 2 * abs(aStart * dStart));
if (dTot < 0) {
vMax *= -1;
}
tConst = 0;
}
// calculate tStart and tEnd based on dStart and dEnd
tStart = (1000000 * (vMax - vStart) / aStart);
tEnd = (1000000 * (vEnd - vMax) / aEnd);
}
float MotionCalc::idealDistance (int elapsedTime) {
if (elapsedTime < tStart) {
return (elapsedTime / 1000 * (vStart + .5 * aStart * elapsedTime / 1000000));
}
else if (elapsedTime < (tStart + tConst)) {
return (dStart * 1000 + vMax * (elapsedTime - tStart) / 1000);
}
else if (elapsedTime < (tStart + tConst + tEnd)) {
float t = ((float)elapsedTime - tStart - tConst) / 1000000;
return (((dTot - dEnd) + (vMax * t + .5 * aEnd * t * t)) * 1000);
}
else {
return (dTot * 1000);
}
}
float MotionCalc::idealVelocity (int elapsedTime) {
if (elapsedTime <= tStart) {
return (vStart + aStart * elapsedTime / 1000000);
}
else if (elapsedTime < (tStart + tConst)) {
return (vMax);
}
else if (elapsedTime < (tStart + tConst + tEnd)) {
return (vMax + aEnd * (elapsedTime - tStart - tConst) / 1000000);
}
else {
return (vEnd);
}
}
float MotionCalc::idealAccel (int elapsedTime) {
if (elapsedTime <= tStart) {
return (aStart);
}
else if (elapsedTime < (tStart + tConst)) {
return (0);
}
else if (elapsedTime < (tStart + tConst + tEnd)) {
return (aEnd);
}
else {
return (0);
}
}