-
Notifications
You must be signed in to change notification settings - Fork 2
/
ValueSystem.cpp
89 lines (72 loc) · 2.64 KB
/
ValueSystem.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
#include "ValueSystem.h"
#define PI 3.14159265
CValueSystem::CValueSystem(CKheperaUtility * pUtil) : CThreadableBase(pUtil)
{
}
void CValueSystem::DoCycle()
{
// evaluate current results
SIOSet controllerResults = m_pUtil->GetLastNetworkResult();
SIOSet correction = Correct(controllerResults);
m_pUtil->SetCorrectedResult(correction);
}
SIOSet CValueSystem::Correct(SIOSet calculated)
{
// convert speed
SDirectionalSpeed directional = ToDirectional(calculated.speed);
int limit = 400; //SafetyDistance(directional.speed);
// evaluate sensor data in movement direction
int proximity;
if (abs(directional.angle) < PI / 2)
{ // front half
double subIndex = fmax(0, ((PI / 2 - (directional.angle)) / (PI / 5)) - 1);
proximity = fmax(calculated.sensors.data[(int)floor(subIndex)], calculated.sensors.data[(int)ceil(subIndex)]);
}
else if (abs(directional.angle) > (5 * PI / 6))
{ // mid back
proximity = fmax(calculated.sensors.data[6], calculated.sensors.data[7]);
}
else if (directional.angle > 0)
{ // left back
proximity = fmax(calculated.sensors.data[0], calculated.sensors.data[7]);
}
else
{ // right back
proximity = fmax(calculated.sensors.data[5], calculated.sensors.data[6]);
}
if (proximity > limit)
{ // don't go there, you'll collide!
// go anywhere else, just not there. Preferably forward-ish.
directional.angle += pow(-1, round(m_pUtil->GetUniformRandom(0,1))) * (PI/4 + m_pUtil->GetUniformRandom(-PI/4, PI/4));
}
if (directional.speed < MAX_SPEED/2)
{ // you're fine, go faster
directional.speed = abs(directional.speed) + m_pUtil->GetUniformRandom(0.5, 1);
directional.speed *= 1.2;
}
SIOSet correction = calculated;
correction.speed = ToComponents(directional);
return correction;
}
int CValueSystem::SafetyDistance(double speed)
{
int dist = 600 * (1 - (speed / (double)MAX_SPEED));
//int dist = fmin(900, CLOSE_SENSOR_VAL*exp(- speed / (double)MAX_SPEED));
return dist;
}
CValueSystem::SDirectionalSpeed CValueSystem::ToDirectional(SSpeed components)
{
SDirectionalSpeed directional;
double straight = (components.left + components.right) / 2; // cos(a)*v
double turn = components.right - straight; // sin(a)*v
directional.angle = atan2(turn, straight);
directional.speed = straight / cos(directional.angle);
return directional;
}
SSpeed CValueSystem::ToComponents(SDirectionalSpeed direction)
{
SSpeed components;
components.left = direction.speed * (cos(direction.angle) - sin(direction.angle));
components.right = direction.speed * (cos(direction.angle) + sin(direction.angle));
return components;
}