-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsimulator.cpp
More file actions
149 lines (127 loc) · 3.99 KB
/
Copy pathsimulator.cpp
File metadata and controls
149 lines (127 loc) · 3.99 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
/*
Implemetation of simulator.h
*/
#include <math.h>
#include <algorithm>
#include <vector>
#include <iterator>
#include "simulator.h"
double distance(Coordinate a, Coordinate b)
{
return sqrt(pow(a.x - b.x,2) + pow(a.y - b.y,2));
}
double dotProduct(Coordinate a, Coordinate b)
{
return (double)a.x*b.x + a.y*b.y;
}
double angleTo(Coordinate a, Coordinate b)
{
double ret = atan2(b.y-a.y, b.x-a.x)*57.295779513;
return (ret<0) ? ret+360 : ret;
}
Simulator::Simulator() {}
bool Simulator::step()
{
UAV::incrementCounter();
time++;
std::cout << std::endl;
for (UAV &u : uavs)
{
if (u.active)
{
if (!avoid(&u))
{
// Calculate the angle between the uav and waypoint
double toWaypoint = angleTo(u.coor, u.curWaypoint);
// Calculate the amount to turn
double turn = fabs((double)toWaypoint - u.direction);
if (turn > 180)
turn = 360-turn;
if (turn > MAX_TURN)
turn = MAX_TURN;
// If the waypoint cannot be turned into, turn the other way
// 57.2957795131 rounded up to 60
double radius = 60/MAX_TURN*MAX_SPEED;
Coordinate centerA(sin(0.01745329252*u.direction)*radius, -1*cos(0.01745329252*u.direction)*radius);
Coordinate centerB(-1*centerA.x, -1*centerA.y);
centerA.x+=u.coor.x;
centerB.x+=u.coor.x;
centerA.y+=u.coor.y;
centerB.y+=u.coor.y;
if (distance(centerA, u.curWaypoint)<radius || distance(centerB, u.curWaypoint)<radius)
{
turn *= -1;
}
// Calculate the direction to turn
if (u.direction < 180)
{
if (toWaypoint > u.direction && toWaypoint < u.direction+180)
u.giveOrder(turn);
else
u.giveOrder(-1*turn);
}
else
{
if (toWaypoint < u.direction && toWaypoint > u.direction-180)
u.giveOrder(-1*turn);
else
u.giveOrder(turn);
}
}
if (distance(u.coor, u.curWaypoint) < WAYPOINT_SIZE)
{
if (time > 2 && visualize)
{
event temp;
temp.coor = Coordinate(u.curWaypoint.x, u.curWaypoint.y);
temp.time = 20;
temp.type = EVENT_REACHED_WAYPOINT;
events.push_back(temp);
}
u.nextWaypoint();
}
}
}
// Execute the orders and calculate near misses
for (UAV &u : uavs)
{
u.step();
for (UAV &v : uavs)
{
if (&u==&v)
break;
u.distToUAV[v.idno] = distance(u.coor, v.coor);
v.distToUAV[u.idno] = u.distToUAV[v.idno];
if (u.distToUAV[v.idno] < NEAR_MISS_SIZE && visualize)
{
event temp;
temp.coor = Coordinate((u.coor.x + v.coor.x)/2, (u.coor.y + v.coor.y)/2);
temp.time = 2;
temp.type = EVENT_NEAR_MISS;
events.push_back(temp);
}
}
}
// Manage the events to draw
for (int i = (int)events.size()-1; i>=0; i--)
{
events[i].time--;
if (events[i].time <= 0)
{
events.erase(events.begin()+i);
}
}
return true;
}
bool Simulator::avoid(UAV *u)
{
return inverseprop(u);
}
void Simulator::init(bool v)
{
visualize = v;
for (UAV &u : uavs)
{
u.distToUAV.resize(uavs.size());
}
}