-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSimulation.h
163 lines (135 loc) · 4.58 KB
/
Simulation.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
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
#include <iostream>
#include "PartiallyKnownGrid.h"
#include "Timer.h"
class Simulation {
public:
Simulation(PartiallyKnownGrid* grid) {
grid_ = grid;
wait_time_ = 100;
wait_for_confirmation_ = false;
}
~Simulation(){}
void SetStepsPerSecond(double n) {
wait_time_ = 1000.0/n;
}
void SetConfirmationAfterEachMove(bool confirmation) {
wait_for_confirmation_ = confirmation;
}
void Simulate(bool adaptive, bool larger_g) {
GridPathPlanner planner(grid_, grid_->GetGoalLocation(), adaptive, larger_g);
Timer t;
// Start simulation
int steps = 0;
int total_expansions = 0;
double total_time = 0;
grid_->Reset();
grid_->DrawGrid();
while (!grid_->GoalReached()) { // loop until the robot find the target or dies
bool clear_terminal = true;
if (clear_terminal) {
#if defined(_WIN32) || defined(_WIN64)
system("cls");
#else
system("clear");
#endif
}
grid_->DrawGrid();
if (adaptive)
std::cout<<"Adaptive A*, ";
else
std::cout<<"Forward A*, ";
if (larger_g)
std::cout<<"large g";
else
std::cout<<"small g";
std::cout<<std::endl;
std::cout<<"Current location: "<<grid_->GetCurrentLocation()<<std::endl;
std::cout<<"Heuristic distance to destination: "<<planner.GetHValue(grid_->GetCurrentLocation())<<std::endl;
t.StartTimer();
std::vector<xyLoc> path;
planner.FindPath(grid_->GetCurrentLocation(), path);
double time = t.GetElapsedTime();
total_time += time;
int expansions = planner.GetNumExpansionsFromLastSearch();
total_expansions += expansions;
// Verify path.
if (!ValidatePath(grid_->GetCurrentLocation(), grid_->GetGoalLocation(), path)){
std::cout<<"Stopping simulation due to invalid path..."<<std::endl;
return;
}
std::cout<<std::endl;
std::cout<<"Search statistics"<<std::endl;
std::cout<<"-----------------"<<std::endl;
std::cout<<"Path length to destination: "<<path.size()-1<<std::endl;
std::cout<<"Number of expansions: "<<expansions<<std::endl;
std::cout<<"Search (and update) time (ms): "<<1000*time<<std::endl;
if (adaptive)
std::cout<<"Updated heuristic distance to destination: "<<planner.GetHValue(grid_->GetCurrentLocation())<<std::endl;
xyLoc move_to = path[1];
steps++;
std::cout<<"Step "<<steps<<": "<<grid_->GetCurrentLocation()<<" -> "<<move_to<<std::endl;
// Call the simulator to move your robot and count the steps
bool valid_move = grid_->MoveTo(move_to);
if (!valid_move) {
std::cout<<"Stopping simulation due to invalid move..."<<std::endl;
return;
}
if (wait_for_confirmation_)
while (std::cin.get() != '\n');
// TODO: Wait for console input
#if defined(_WIN32) || defined(_WIN64)
Sleep(wait_time_);
#else
//*
struct timespec req, rem;
req.tv_nsec = 1000000*wait_time_;
req.tv_sec = 0;
nanosleep(&req, &rem);
/*/
usleep(1000*wait_time_);
//*/
#endif
}
std::cout<<"Target found in "<<steps<<" steps !!!"<<std::endl;
std::cout<<"Average number of expansions: "<<total_expansions/(double)steps<<std::endl;
std::cout<<"Average search (and update) time (ms): "<<1000*total_time/(double)steps<<std::endl;
}
private:
PartiallyKnownGrid* grid_;
bool adaptive_;
double wait_time_;
bool wait_for_confirmation_;
bool ValidatePath(xyLoc s, xyLoc t, std::vector<xyLoc> & path) {
if (path.size() == 0) {
std::cout<<"Path is empty!"<<std::endl;
return false;
}
if (!(s == path.front())) {
std::cout<<"The path should start at "<<s<<"!"<<std::endl;
return false;
}
if (!(t == path.back())) {
std::cout<<"The path should end at "<<t<<"!"<<std::endl;
return false;
}
for (int i = 0; i < path.size()-1; i++) {
if (!grid_->IsValidLocation(path[i+1])) {
std::cout<<"Cell "<<path[i+1]<<" on the path is out of bounds!"<<std::endl;
return false;
}
if (grid_->IsBlocked(path[i+1])) {
std::cout<<"Cell "<<path[i+1]<<" on the path is blocked!"<<std::endl;
return false;
}
if (!(path[i] == path[i+1])) {
int dx = abs(path[i].x - path[i+1].x);
int dy = abs(path[i].y - path[i+1].y);
if (dx + dy > 1) {
std::cout<<"Invalid move on path: "<<s<<" to "<<t<<"!"<<std::endl;
return false;
}
}
}
return true;
}
};