-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMain_Occupancy_SLAM.cpp
186 lines (168 loc) · 7.5 KB
/
Main_Occupancy_SLAM.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
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#include <iostream>
#include <string>
#include <vector>
#include "MyStruct.h"
#include "SubFuncs.h"
ParamStruct SetParam();
int main() {
ParamStruct ValParam = SetParam();
SetParametersFromFile("../config.txt", ValParam);
std::cout << "Enter the names of the input files (range of scan (must), initialization poses (option, if not using odometry inputs as initialization), and odometry inputs (option, if exit), separated by spaces: ";
std::string input;
std::getline(std::cin, input);
std::vector<std::string> filenames;
std::string delimiter = " ";
size_t pos = 0;
while ((pos = input.find(delimiter)) != std::string::npos) {
std::string filename = input.substr(0, pos);
filenames.push_back(filename);
input.erase(0, pos + delimiter.length());
}
filenames.push_back(input);
if (ValParam.ModeOdom){
if (ValParam.PosefromOdom){
if (filenames.size() != 2) {
std::cout << "The number of input files is not 2 (range and odometry inputs). Please check the input files." << std::endl;
return 0;}
} else {
if (filenames.size() != 3) {
std::cout << "The number of input files is not 3 (range, initialization poses, and odometry inputs). Please check the input files." << std::endl;
return 0;}
}
} else {
if (filenames.size() != 2) {
std::cout << "The number of input files is not 2 (range and initialization poses). Please check the input files." << std::endl;
return 0;}
}
std::vector<double> VecRange;
loadTxTData(filenames[0],VecRange,ValParam);
Eigen::VectorXd VecRangeT = VectorToEigenVec(VecRange);
Eigen::MatrixXd Range = VecRangeT.reshaped(ValParam.NumBeam,VecRangeT.size()/ValParam.NumBeam).transpose();
auto start = std::chrono::high_resolution_clock::now(); // Start
std::vector<Eigen::ArrayXd> ScanXY(Range.rows());
std::vector<Eigen::ArrayXd> ScanOdd(Range.rows());
FuncConvertObs(Range, ScanXY, ScanOdd, ValParam);
auto end = std::chrono::high_resolution_clock::now(); // End
double elapsed_time_sec = std::chrono::duration_cast<std::chrono::duration<double>>(end - start).count();
std::cout << "Preprocessing, Elapsed time: " << elapsed_time_sec << " seconds " << std::endl;
// Load the data from the input files and store it in vectors
std::vector<std::vector<double>> fileData;
filenames.erase(filenames.begin(), filenames.begin()+1);
loadFileData(filenames, fileData, ValParam);
Eigen::MatrixXd MatrixOdom;
Eigen::MatrixXd Pose;
if (filenames.size()==1){
if (ValParam.ModeOdom){
Eigen::VectorXd VecOdom = VectorToEigenVec(fileData[0]);
MatrixOdom = VecOdom.reshaped(3,VecOdom.size()/3).transpose();
FuncPosefromOdom(MatrixOdom, Pose);
} else{
Eigen::VectorXd VecPose = VectorToEigenVec(fileData[0]);
Pose = VecPose.reshaped(3,VecPose.size()/3).transpose();
}
} else if (filenames.size()==2){
Eigen::VectorXd VecPose = VectorToEigenVec(fileData[0]);
Pose = VecPose.reshaped(3,VecPose.size()/3).transpose();
Eigen::VectorXd VecOdom = VectorToEigenVec(fileData[1]);
MatrixOdom = VecOdom.reshaped(3,VecOdom.size()/3).transpose();
} else{
std::cout << "The number of input files is wrong. Please check the input files." << std::endl;
return 0;
}
Eigen::MatrixXd PoseGT;
if (ValParam.EvaluateGT){
std::cout << "Enter the names of the PoseGT: ";
std::string PoseGTInput;
std::getline(std::cin, PoseGTInput);
std::vector<double> PoseGTData;
loadTxTData(PoseGTInput,PoseGTData,ValParam);
Eigen::VectorXd VecPoseGT = VectorToEigenVec(PoseGTData);
PoseGT = VecPoseGT.reshaped(3,VecPoseGT.size()/3).transpose();
FuncEval(Pose, PoseGT, ValParam);
}
if (ValParam.ModeKeyFrame){
int NumPose = Pose.rows();
int NumSelect = floor((NumPose/ValParam.KeyframeRate)) + 1;
std::vector<Eigen::ArrayXd> ScanXYTem(NumSelect);
std::vector<Eigen::ArrayXd> ScanOddTem(NumSelect);
Eigen::MatrixXd PoseTem(NumSelect,3), PoseGTTem(NumSelect,3);
Eigen::MatrixXd OdomTem(NumSelect,3);
if (ValParam.ModeOdom){
if (ValParam.EvaluateGT){
FuncKeyFrameSelectionOdom(Pose, PoseTem, PoseGT, PoseGTTem, MatrixOdom, OdomTem, ScanXY, ScanOdd, ScanXYTem, ScanOddTem, ValParam);
PoseGT.resize(NumSelect, 3);
PoseGT = PoseGTTem;
}
else{
FuncKeyFrameSelectionOdom(Pose, PoseTem, MatrixOdom, OdomTem, ScanXY, ScanOdd, ScanXYTem, ScanOddTem, ValParam);
}
MatrixOdom.resize(NumSelect, 3);
MatrixOdom = OdomTem;
}
else{
if (ValParam.EvaluateGT){
FuncKeyFrameSelection(Pose, PoseTem, PoseGT, PoseGTTem, ScanXY, ScanOdd, ScanXYTem, ScanOddTem, ValParam);
PoseGT.resize(NumSelect, 3);
PoseGT = PoseGTTem;
}
else{
FuncKeyFrameSelection(Pose, PoseTem, ScanXY, ScanOdd, ScanXYTem, ScanOddTem, ValParam);
}
}
ScanXY.resize(NumSelect);
ScanOdd.resize(NumSelect);
ScanXY = ScanXYTem;
ScanOdd = ScanOddTem;
Pose.resize(NumSelect, 3);
Pose = PoseTem;
}
// Shown Initial Map
Eigen::MatrixXd ShowMap = FuncInitialiseGridMapToShow(Pose,ScanXY,ScanOdd,ValParam);
std::cout << "The Initial Occupancy Map, to continue, press any key." << std::endl;
FuncShowMapPress(ShowMap);
std::vector<Eigen::ArrayXd> LowScanXY(ScanXY.size());
std::vector<Eigen::ArrayXd> LowScanOdd(ScanOdd.size());
if (ValParam.ModeMulti){
ValParam.Sizei = ValParam.Sizei / ValParam.DownRate;
ValParam.Sizej = ValParam.Sizej / ValParam.DownRate;
ValParam.Scale = ValParam.Scale * ValParam.DownRate;
FuncLowSampleScan(ScanXY, ScanOdd, LowScanXY, LowScanOdd, ValParam);
}
else
{
LowScanXY = ScanXY;
LowScanOdd = ScanOdd;
}
start = std::chrono::high_resolution_clock::now(); // Start
auto [Map, N] = FuncInitialiseGridMap(Pose,LowScanXY,LowScanOdd,ValParam);
Eigen::SparseMatrix<double> HH = FuncMapConst(ValParam);
FuncSmoothN2(N, HH, ValParam);
if (ValParam.ModeOdom && ValParam.WeightO!=0)
{
if (ValParam.EvaluateGT)
{
FuncLeastSquaresOdom(Map, N, Pose, PoseGT, MatrixOdom, ScanXY, ScanOdd, LowScanXY, LowScanOdd, HH, ValParam);
}
else
{
FuncLeastSquaresOdom(Map, N, Pose, MatrixOdom, ScanXY, ScanOdd, LowScanXY, LowScanOdd, HH, ValParam);
}
}
else{
if (ValParam.EvaluateGT)
{
FuncLeastSquares(Map, N, Pose, PoseGT, ScanXY, ScanOdd, LowScanXY, LowScanOdd, HH, ValParam);
}
else
{
FuncLeastSquares(Map, N, Pose, ScanXY, ScanOdd, LowScanXY, LowScanOdd, HH, ValParam);
}
}
end = std::chrono::high_resolution_clock::now(); // End
elapsed_time_sec = std::chrono::duration_cast<std::chrono::duration<double>>(end - start).count();
std::cout << "Optimization End, Elapsed time: " << elapsed_time_sec << " seconds " << std::endl;
Eigen::MatrixXd OptimizedMap = FuncInitialiseGridMapToShowFinal(Pose,ScanXY,ScanOdd,ValParam);
std::cout << "The Optimized Occupancy Map, to end, press any key." << std::endl;
FuncShowMapPress(OptimizedMap);
return 0;
}