-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtiltcontroller.cpp
More file actions
168 lines (140 loc) · 4.5 KB
/
Copy pathtiltcontroller.cpp
File metadata and controls
168 lines (140 loc) · 4.5 KB
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include "tiltcontroller.h"
#include "opencv/cv.h"
TiltController::TiltController() : Controller()
{
tiltDelay = 0;
tiltActionTime = 0;
tiltStartTick = 0;
outputZero = 0;
}
/**
Initializes the tilt controller. We take the maximum and minimum output angles,
the delay between each tilt we perform and how long each tilt should last for.
@param outputMin_deg The minimum angle we can tilt to (in degrees)
@param outputMax_deg The maximum angle we can titl to (in deg)
@param tiltDelay The delay between tilts (in milliseconds)
@param tiltActionTime How long the tilt should last for (in milliseconds)
*/
TiltController::TiltController(int outputMin_deg, int outputMax_deg,
int outputZero,
double tiltDelay, double tiltActionTime,
double minimumPositionError) : TiltController()
{
SetOutputMax(outputMax_deg);
SetOutputMin(outputMin_deg);
this->minimumPositionError = minimumPositionError;
this->tiltDelay = tiltDelay;
this->tiltActionTime = tiltActionTime;
this->outputZero = outputZero;
}
/**
Wraps PositionControl(desPox_px, curPos_px)
*/
int TiltController::positionControl(int desPox_ps, int curPos_px,
double minimumPositionError)
{
setMinimumPositionError(minimumPositionError);
return positionControl(desPox_ps, curPos_px);
}
/**
Wraps PositionControl(curPos_px)
@param desPos_px The desired position (in pixels)
@param curPos_px The current position (in pixels)
*/
int TiltController::positionControl(int desPos_px, int curPos_px)
{
setDesiredPos_px(desPos_px);
return positionControl(curPos_px);
}
/**
Performs our position control for this axis. The goal is to tilt the axis to
outputMax_deg (or outputMin_deg) for tiltActionTime milliseconds and back to
zero, and then wait tiltDelay milliseconds, repeating until
desPos_px ~= curPos_px. We use the set error range to determine at which point
we stop attempting to tilt the ball. i.e If the ball position error is within
the set error range, we do nothing.
@param curPos_px The current position (in pixels)
*/
int TiltController::positionControl(int curPos_px)
{
this->curPos_px = curPos_px;
computeError();
double controlSignal = 0;
if (abs(error) <= minimumPositionError)
{
controlSignal = outputZero;
}
else
{
controlSignal = (double)GetTilt();
}
return (int)clampSaturation(controlSignal);
}
/**
Gets the tilt angle we should tilt at, using time based logic to determine if
we should tilt or not.
*/
int TiltController::GetTilt()
{
double currentTick = (double)cv::getTickCount();
double diff = (currentTick - tiltStartTick) * 1000 / cv::getTickFrequency();
/* Diff is now the time elapsed in milliseconds since the start of the last
tilt */
int tiltAngle = outputZero;
// If diff <= tiltActionTime, we are still inside a tilt action. So we tilt!
if (diff <= tiltActionTime)
{
tiltAngle = DetermineTiltAngle();
}
// If diff > tiltActionTime, but < tiltActionTime + tiltDelay, we are between
// tilts. We _NEED_ to explicitly return this so that we go back to the zero
// position after a tilt.
else if (diff > tiltActionTime && diff <= tiltActionTime + tiltDelay) {
tiltAngle = outputZero;
}
// If diff > tiltActionTime + tiltDelay, it's time to start tilting again
else if (diff > tiltActionTime + tiltDelay)
{
tiltAngle = DetermineTiltAngle();
// Update the tilt start tick to the current tick so we're back to a 0
// diff for future calculations
tiltStartTick = currentTick;
}
return tiltAngle;
}
/**
Determines which angle we should tilt at. If the ball error is > 0, we should
tilt to the minimum. If the ball error is < 0, we should tilt to the maximum.
*/
int TiltController::DetermineTiltAngle()
{
if (abs(error) <= minimumPositionError*2)
{
if (error > 0)
return GetOutputMin()+1;
else
return GetOutputMax()-1;
}
else if (error > 0)
return GetOutputMin();
else
return GetOutputMax();
}
/* Setters */
void TiltController::setTiltDelay(double tiltDelay)
{
this->tiltDelay = tiltDelay;
}
void TiltController::setTiltActionTime(double tiltActionTime)
{
this->tiltActionTime = tiltActionTime;
}
/* Getters */
double TiltController::getTiltDelay()
{
return this->tiltDelay;
}
double TiltController::getTiltActionTime()
{
return this->tiltActionTime;
}