40 using namespace gtsam;
53 size_t maxLoopCount = 8000;
59 size_t updateFrequency = 3;
61 size_t maxNrHypotheses = 10;
63 size_t reLinearizationFrequency = 10;
65 double marginalThreshold = 0.9999;
77 size_t loopCounter,
size_t keyS,
size_t keyT,
81 auto f0 = std::make_shared<BetweenFactor<Pose2>>(
83 auto f1 = std::make_shared<BetweenFactor<Pose2>>(
94 size_t numMeasurements,
size_t keyS,
size_t keyT,
const DiscreteKey&
m,
95 const std::vector<Pose2>& poseArray)
const {
96 auto f0 = std::make_shared<BetweenFactor<Pose2>>(
98 auto f1 = std::make_shared<BetweenFactor<Pose2>>(
104 return mixtureFactor;
109 std::cout <<
"Smoother update: " << newFactors_.
size() << std::endl;
111 clock_t beforeUpdate = clock();
112 smoother_.
update(newFactors_, initial_, maxNrHypotheses);
113 clock_t afterUpdate = clock();
116 return afterUpdate - beforeUpdate;
121 std::cout <<
"================= Re-Initialize: " << allFactors_.
size()
123 clock_t beforeUpdate = clock();
125 auto linearized = allFactors_.
linearize(initial_);
126 auto bayesNet = linearized->eliminateSequential();
130 clock_t afterUpdate = clock();
131 std::cout <<
"Took " << (afterUpdate - beforeUpdate) / CLOCKS_PER_SEC
132 <<
" seconds." << std::endl;
133 return afterUpdate - beforeUpdate;
139 : dataset_(
filename), smoother_(marginalThreshold) {}
144 size_t discreteCount = 0, index = 0, loopCount = 0, updateCount = 0;
146 std::list<double> timeList;
149 Pose2 priorPose(0, 0, 0);
150 initial_.
insert(
X(0), priorPose);
155 auto time = smootherUpdate(maxNrHypotheses);
156 std::vector<std::pair<size_t, double>> smootherUpdateTimes;
157 smootherUpdateTimes.push_back({index,
time});
160 size_t numberOfHybridFactors = 0;
164 size_t keyS = 0, keyT = 0;
165 clock_t startTime = clock();
167 std::vector<Pose2> poseArray;
168 std::pair<size_t, size_t>
keys;
170 while (dataset_.
next(&poseArray, &
keys) && index < maxLoopCount) {
173 size_t numMeasurements = poseArray.size();
176 Pose2 odomPose = poseArray[0];
177 if (keyS == keyT - 1) {
179 if (numMeasurements > 1) {
183 hybridOdometryFactor(numMeasurements, keyS, keyT,
m, poseArray);
186 numberOfHybridFactors += 1;
187 std::cout <<
"mixtureFactor: " << keyS <<
" " << keyT << std::endl;
197 hybridLoopClosureFactor(loopCount, keyS, keyT, odomPose);
199 std::cout <<
"Loop closure: " << keyS <<
" " << keyT << std::endl;
200 newFactors_.
add(loopFactor);
201 numberOfHybridFactors += 1;
205 if (numberOfHybridFactors >= updateFrequency) {
206 auto time = smootherUpdate(maxNrHypotheses);
207 smootherUpdateTimes.push_back({index,
time});
208 numberOfHybridFactors = 0;
211 if (updateCount % reLinearizationFrequency == 0) {
217 if (keyS == keyT - 1) {
218 clock_t curTime = clock();
219 timeList.push_back(curTime - startTime);
223 if (index % 100 == 0) {
224 std::cout <<
"Index: " << index << std::endl;
225 if (!timeList.empty()) {
226 std::cout <<
"Acc_time: " << timeList.back() / CLOCKS_PER_SEC
227 <<
" seconds" << std::endl;
238 time = smootherUpdate(maxNrHypotheses);
239 smootherUpdateTimes.push_back({index,
time});
242 gttic_(HybridSmootherOptimize);
244 gttoc_(HybridSmootherOptimize);
251 clock_t endTime = clock();
252 clock_t totalTime = endTime - startTime;
253 std::cout <<
"Total time: " << totalTime / CLOCKS_PER_SEC <<
" seconds"
260 std::ofstream outfileTime;
261 std::string timeFileName =
"Hybrid_City10000_time.txt";
262 outfileTime.open(timeFileName);
263 for (
auto accTime : timeList) {
264 outfileTime << accTime / CLOCKS_PER_SEC << std::endl;
267 std::cout <<
"Output " << timeFileName <<
" file." << std::endl;
269 std::ofstream timingFile;
270 std::string timingFileName =
"Hybrid_City10000_timing.txt";
271 timingFile.open(timingFileName);
272 for (
size_t i = 0;
i < smootherUpdateTimes.size();
i++) {
273 auto p = smootherUpdateTimes.at(
i);
274 timingFile <<
p.first <<
", " <<
p.second / CLOCKS_PER_SEC << std::endl;
277 std::cout <<
"Wrote timing information to " << timingFileName << std::endl;
284 size_t& updateFrequency,
size_t& maxNrHypotheses) {
285 for (
int i = 1;
i < argc; ++
i) {
286 std::string
arg = argv[
i];
287 if (
arg ==
"--max-loop-count" &&
i + 1 < argc) {
288 maxLoopCount = std::stoul(argv[++
i]);
289 }
else if (
arg ==
"--update-frequency" &&
i + 1 < argc) {
290 updateFrequency = std::stoul(argv[++
i]);
291 }
else if (
arg ==
"--max-nr-hypotheses" &&
i + 1 < argc) {
292 maxNrHypotheses = std::stoul(argv[++
i]);
293 }
else if (
arg ==
"--help") {
294 std::cout <<
"Usage: " << argv[0] <<
" [options]\n"
296 <<
" --max-loop-count <value> Set the maximum loop "
297 "count (default: 3000)\n"
298 <<
" --update-frequency <value> Set the update frequency "
300 <<
" --max-nr-hypotheses <value> Set the maximum number of "
301 "hypotheses (default: 10)\n"
302 <<
" --help Show this help message\n";
310 int main(
int argc,
char* argv[]) {