644 lines
18 KiB
C++
644 lines
18 KiB
C++
/*****************************************************************
|
|
*
|
|
* This file is part of the GMAPPING project
|
|
*
|
|
* GMAPPING Copyright (c) 2004 Giorgio Grisetti,
|
|
* Cyrill Stachniss, and Wolfram Burgard
|
|
*
|
|
* This software is licensed under the "Creative Commons
|
|
* License (Attribution-NonCommercial-ShareAlike 2.0)"
|
|
* and is copyrighted by Giorgio Grisetti, Cyrill Stachniss,
|
|
* and Wolfram Burgard.
|
|
*
|
|
* Further information on this license can be found at:
|
|
* http://creativecommons.org/licenses/by-nc-sa/2.0/
|
|
*
|
|
* GMAPPING is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied
|
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE.
|
|
*
|
|
*****************************************************************/
|
|
|
|
|
|
#include "gsp_thread.h"
|
|
#include <utils/commandline.h>
|
|
#include <utils/stat.h>
|
|
#include <configfile/configfile.h>
|
|
|
|
#ifdef CARMEN_SUPPORT
|
|
#include <carmenwrapper/carmenwrapper.h>
|
|
#endif
|
|
|
|
#define DEBUG cout << __PRETTY_FUNCTION__
|
|
|
|
using namespace std;
|
|
|
|
int GridSlamProcessorThread::init(int argc, const char * const * argv){
|
|
m_argc=argc;
|
|
m_argv=argv;
|
|
std::string configfilename;
|
|
std::string ebuf="not_set";
|
|
|
|
CMD_PARSE_BEGIN_SILENT(1,argc);
|
|
parseStringSilent("-cfg",configfilename);
|
|
CMD_PARSE_END_SILENT;
|
|
|
|
if (configfilename.length()>0){
|
|
ConfigFile cfg(configfilename);
|
|
|
|
filename = (std::string) cfg.value("gfs","filename",filename);
|
|
outfilename = (std::string) cfg.value("gfs","outfilename",outfilename);
|
|
xmin = cfg.value("gfs","xmin", xmin);
|
|
xmax = cfg.value("gfs","xmax",xmax);
|
|
ymin = cfg.value("gfs","ymin",ymin);
|
|
ymax = cfg.value("gfs","ymax",ymax);
|
|
delta = cfg.value("gfs","delta",delta);
|
|
maxrange = cfg.value("gfs","maxrange",maxrange);
|
|
maxUrange = cfg.value("gfs","maxUrange",maxUrange);
|
|
regscore = cfg.value("gfs","regscore",regscore);
|
|
critscore = cfg.value("gfs","critscore",critscore);
|
|
kernelSize = cfg.value("gfs","kernelSize",kernelSize);
|
|
sigma = cfg.value("gfs","sigma",sigma);
|
|
iterations = cfg.value("gfs","iterations",iterations);
|
|
lstep = cfg.value("gfs","lstep",lstep);
|
|
astep = cfg.value("gfs","astep",astep);
|
|
maxMove = cfg.value("gfs","maxMove",maxMove);
|
|
srr = cfg.value("gfs","srr", srr);
|
|
srt = cfg.value("gfs","srt", srt);
|
|
str = cfg.value("gfs","str", str);
|
|
stt = cfg.value("gfs","stt", stt);
|
|
particles = cfg.value("gfs","particles",particles);
|
|
angularUpdate = cfg.value("gfs","angularUpdate", angularUpdate);
|
|
linearUpdate = cfg.value("gfs","linearUpdate", linearUpdate);
|
|
lsigma = cfg.value("gfs","lsigma", lsigma);
|
|
ogain = cfg.value("gfs","lobsGain", ogain);
|
|
lskip = (int)cfg.value("gfs","lskip", lskip);
|
|
mapUpdateTime = cfg.value("gfs","mapUpdate", mapUpdateTime);
|
|
randseed = cfg.value("gfs","randseed", randseed);
|
|
autosize = cfg.value("gfs","autosize", autosize);
|
|
readFromStdin = cfg.value("gfs","stdin", readFromStdin);
|
|
resampleThreshold = cfg.value("gfs","resampleThreshold", resampleThreshold);
|
|
skipMatching = cfg.value("gfs","skipMatching", skipMatching);
|
|
onLine = cfg.value("gfs","onLine", onLine);
|
|
generateMap = cfg.value("gfs","generateMap", generateMap);
|
|
m_minimumScore = cfg.value("gfs","minimumScore", m_minimumScore);
|
|
llsamplerange = cfg.value("gfs","llsamplerange", llsamplerange);
|
|
lasamplerange = cfg.value("gfs","lasamplerange",lasamplerange );
|
|
llsamplestep = cfg.value("gfs","llsamplestep", llsamplestep);
|
|
lasamplestep = cfg.value("gfs","lasamplestep", lasamplestep);
|
|
linearOdometryReliability = cfg.value("gfs","linearOdometryReliability",linearOdometryReliability);
|
|
angularOdometryReliability = cfg.value("gfs","angularOdometryReliability",angularOdometryReliability);
|
|
ebuf = (std::string) cfg.value("gfs","estrategy", ebuf);
|
|
considerOdometryCovariance = cfg.value("gfs","considerOdometryCovariance",considerOdometryCovariance);
|
|
|
|
}
|
|
|
|
|
|
CMD_PARSE_BEGIN(1,argc);
|
|
parseString("-cfg",configfilename); /* to avoid the warning*/
|
|
parseString("-filename",filename);
|
|
parseString("-outfilename",outfilename);
|
|
parseDouble("-xmin",xmin);
|
|
parseDouble("-xmax",xmax);
|
|
parseDouble("-ymin",ymin);
|
|
parseDouble("-ymax",ymax);
|
|
parseDouble("-delta",delta);
|
|
parseDouble("-maxrange",maxrange);
|
|
parseDouble("-maxUrange",maxUrange);
|
|
parseDouble("-regscore",regscore);
|
|
parseDouble("-critscore",critscore);
|
|
parseInt("-kernelSize",kernelSize);
|
|
parseDouble("-sigma",sigma);
|
|
parseInt("-iterations",iterations);
|
|
parseDouble("-lstep",lstep);
|
|
parseDouble("-astep",astep);
|
|
parseDouble("-maxMove",maxMove);
|
|
parseDouble("-srr", srr);
|
|
parseDouble("-srt", srt);
|
|
parseDouble("-str", str);
|
|
parseDouble("-stt", stt);
|
|
parseInt("-particles",particles);
|
|
parseDouble("-angularUpdate", angularUpdate);
|
|
parseDouble("-linearUpdate", linearUpdate);
|
|
parseDouble("-lsigma", lsigma);
|
|
parseDouble("-lobsGain", ogain);
|
|
parseInt("-lskip", lskip);
|
|
parseInt("-mapUpdate", mapUpdateTime);
|
|
parseInt("-randseed", randseed);
|
|
parseFlag("-autosize", autosize);
|
|
parseFlag("-stdin", readFromStdin);
|
|
parseDouble("-resampleThreshold", resampleThreshold);
|
|
parseFlag("-skipMatching", skipMatching);
|
|
parseFlag("-onLine", onLine);
|
|
parseFlag("-generateMap", generateMap);
|
|
parseDouble("-minimumScore", m_minimumScore);
|
|
parseDouble("-llsamplerange", llsamplerange);
|
|
parseDouble("-lasamplerange", lasamplerange);
|
|
parseDouble("-llsamplestep", llsamplestep);
|
|
parseDouble("-lasamplestep", lasamplestep);
|
|
parseDouble("-linearOdometryReliability",linearOdometryReliability);
|
|
parseDouble("-angularOdometryReliability",angularOdometryReliability);
|
|
parseString("-estrategy", ebuf);
|
|
|
|
parseFlag("-considerOdometryCovariance",considerOdometryCovariance);
|
|
CMD_PARSE_END;
|
|
|
|
if (filename.length() <=0){
|
|
cout << "no filename specified" << endl;
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int GridSlamProcessorThread::loadFiles(const char * fn){
|
|
if (onLine){
|
|
cout << " onLineProcessing" << endl;
|
|
return 0;
|
|
}
|
|
ifstream is;
|
|
if (fn)
|
|
is.open(fn);
|
|
else
|
|
is.open(filename.c_str());
|
|
if (! is){
|
|
cout << "no file found" << endl;
|
|
return -1;
|
|
}
|
|
|
|
CarmenConfiguration conf;
|
|
conf.load(is);
|
|
is.close();
|
|
|
|
sensorMap=conf.computeSensorMap();
|
|
|
|
if (input)
|
|
delete input;
|
|
|
|
if (! readFromStdin){
|
|
plainStream.open(filename.c_str());
|
|
input=new InputSensorStream(sensorMap, plainStream);
|
|
cout << "Plain Stream opened="<< (bool) plainStream << endl;
|
|
} else {
|
|
input=new InputSensorStream(sensorMap, cin);
|
|
cout << "Plain Stream opened on stdin" << endl;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
GridSlamProcessorThread::GridSlamProcessorThread(): GridSlamProcessor(cerr){
|
|
//This are the processor parameters
|
|
filename="";
|
|
outfilename="";
|
|
xmin=-100.;
|
|
ymin=-100.;
|
|
xmax=100.;
|
|
ymax=100.;
|
|
delta=0.05;
|
|
|
|
//scan matching parameters
|
|
sigma=0.05;
|
|
maxrange=80.;
|
|
maxUrange=80.;
|
|
regscore=1e4;
|
|
lstep=.05;
|
|
astep=.05;
|
|
kernelSize=1;
|
|
iterations=5;
|
|
critscore=0.;
|
|
maxMove=1.;
|
|
lsigma=.075;
|
|
ogain=3;
|
|
lskip=0;
|
|
autosize=false;
|
|
skipMatching=false;
|
|
|
|
//motion model parameters
|
|
srr=0.1, srt=0.1, str=0.1, stt=0.1;
|
|
//particle parameters
|
|
particles=30;
|
|
randseed=0;
|
|
|
|
//gfs parameters
|
|
angularUpdate=0.5;
|
|
linearUpdate=1;
|
|
resampleThreshold=0.5;
|
|
|
|
input=0;
|
|
|
|
pthread_mutex_init(&hp_mutex,0);
|
|
pthread_mutex_init(&ind_mutex,0);
|
|
pthread_mutex_init(&hist_mutex,0);
|
|
running=false;
|
|
eventBufferLength=0;
|
|
mapUpdateTime=5;
|
|
mapTimer=0;
|
|
readFromStdin=false;
|
|
onLine=false;
|
|
generateMap=false;
|
|
|
|
// This are the dafault settings for a grid map of 5 cm
|
|
llsamplerange=0.01;
|
|
llsamplestep=0.01;
|
|
lasamplerange=0.005;
|
|
lasamplestep=0.005;
|
|
linearOdometryReliability=0.;
|
|
angularOdometryReliability=0.;
|
|
|
|
considerOdometryCovariance=false;
|
|
/*
|
|
// This are the dafault settings for a grid map of 10 cm
|
|
m_llsamplerange=0.1;
|
|
m_llsamplestep=0.1;
|
|
m_lasamplerange=0.02;
|
|
m_lasamplestep=0.01;
|
|
*/
|
|
// This are the dafault settings for a grid map of 20/25 cm
|
|
/*
|
|
m_llsamplerange=0.2;
|
|
m_llsamplestep=0.1;
|
|
m_lasamplerange=0.02;
|
|
m_lasamplestep=0.01;
|
|
m_generateMap=false;
|
|
*/
|
|
|
|
|
|
}
|
|
|
|
GridSlamProcessorThread::~GridSlamProcessorThread(){
|
|
pthread_mutex_destroy(&hp_mutex);
|
|
pthread_mutex_destroy(&ind_mutex);
|
|
pthread_mutex_destroy(&hist_mutex);
|
|
|
|
for (deque<Event*>::const_iterator it=eventBuffer.begin(); it!=eventBuffer.end(); it++)
|
|
delete *it;
|
|
}
|
|
|
|
|
|
void * GridSlamProcessorThread::fastslamthread(GridSlamProcessorThread* gpt){
|
|
if (! gpt->input && ! gpt->onLine)
|
|
return 0;
|
|
|
|
|
|
//if started online retrieve the settings from the connection
|
|
#ifdef CARMEN_SUPPORT
|
|
if (gpt->onLine){
|
|
cout << "starting the process:" << endl;
|
|
CarmenWrapper::initializeIPC(gpt->m_argv[0]);
|
|
CarmenWrapper::start(gpt->m_argv[0]);
|
|
cout << "Waiting for retrieving the sensor map:" << endl;
|
|
while (! CarmenWrapper::sensorMapComputed()){
|
|
usleep(500000);
|
|
cout << "." << flush;
|
|
}
|
|
gpt->sensorMap=CarmenWrapper::sensorMap();
|
|
cout << "Connected " << endl;
|
|
}
|
|
#else
|
|
if (gpt->onLine){
|
|
cout << "FATAL ERROR: cannot run online without the carmen support" << endl;
|
|
DoneEvent *done=new DoneEvent;
|
|
gpt->addEvent(done);
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
gpt->setSensorMap(gpt->sensorMap);
|
|
gpt->setMatchingParameters(gpt->maxUrange, gpt->maxrange, gpt->sigma, gpt->kernelSize, gpt->lstep, gpt->astep, gpt->iterations, gpt->lsigma, gpt->ogain, gpt->lskip);
|
|
|
|
double xmin=gpt->xmin,
|
|
ymin=gpt->ymin,
|
|
xmax=gpt->xmax,
|
|
ymax=gpt->ymax;
|
|
|
|
OrientedPoint initialPose(0,0,0);
|
|
|
|
if (gpt->autosize){
|
|
if (gpt->readFromStdin || gpt->onLine)
|
|
cout << "Error, cant autosize form stdin" << endl;
|
|
SensorLog * log=new SensorLog(gpt->sensorMap);
|
|
ifstream is(gpt->filename.c_str());
|
|
log->load(is);
|
|
is.close();
|
|
initialPose=gpt->boundingBox(log, xmin, ymin, xmax, ymax);
|
|
delete log;
|
|
}
|
|
|
|
if( gpt->infoStream()){
|
|
gpt->infoStream() << " initialPose=" << initialPose.x << " " << initialPose.y << " " << initialPose.theta
|
|
<< cout << " xmin=" << xmin <<" ymin=" << ymin <<" xmax=" << xmax <<" ymax=" << ymax << endl;
|
|
}
|
|
gpt->setMotionModelParameters(gpt->srr, gpt->srt, gpt->str, gpt->stt);
|
|
gpt->setUpdateDistances(gpt->linearUpdate, gpt->angularUpdate, gpt->resampleThreshold);
|
|
gpt->setgenerateMap(gpt->generateMap);
|
|
gpt->GridSlamProcessor::init(gpt->particles, xmin, ymin, xmax, ymax, gpt->delta, initialPose);
|
|
gpt->setllsamplerange(gpt->llsamplerange);
|
|
gpt->setllsamplestep(gpt->llsamplestep);
|
|
gpt->setlasamplerange(gpt->llsamplerange);
|
|
gpt->setlasamplestep(gpt->llsamplestep);
|
|
|
|
#define printParam(n)\
|
|
gpt->outputStream() \
|
|
<< "PARAM " << \
|
|
#n \
|
|
<< " " << gpt->n << endl
|
|
|
|
if (gpt->outfilename.length()>0 ){
|
|
gpt->outputStream().open(gpt->outfilename.c_str());
|
|
printParam(filename);
|
|
printParam(outfilename);
|
|
printParam(xmin);
|
|
printParam(ymin);
|
|
printParam(xmax);
|
|
printParam(ymax);
|
|
printParam(delta);
|
|
|
|
//scan matching parameters
|
|
printParam(sigma);
|
|
printParam(maxrange);
|
|
printParam(maxUrange);
|
|
printParam(regscore);
|
|
printParam(lstep);
|
|
printParam(astep);
|
|
printParam(kernelSize);
|
|
printParam(iterations);
|
|
printParam(critscore);
|
|
printParam(maxMove);
|
|
printParam(lsigma);
|
|
printParam(ogain);
|
|
printParam(lskip);
|
|
printParam(autosize);
|
|
printParam(skipMatching);
|
|
|
|
//motion model parameters
|
|
printParam(srr);
|
|
printParam(srt);
|
|
printParam(str);
|
|
printParam(stt);
|
|
//particle parameters
|
|
printParam(particles);
|
|
printParam(randseed);
|
|
|
|
//gfs parameters
|
|
printParam(angularUpdate);
|
|
printParam(linearUpdate);
|
|
printParam(resampleThreshold);
|
|
|
|
printParam(llsamplerange);
|
|
printParam(lasamplerange);
|
|
printParam(llsamplestep);
|
|
printParam(lasamplestep);
|
|
}
|
|
#undef printParam
|
|
|
|
if (gpt->randseed!=0)
|
|
sampleGaussian(1,gpt->randseed);
|
|
if (!gpt->infoStream()){
|
|
cerr << "cant open info stream for writing by unuseful debug messages" << endl;
|
|
} else {
|
|
gpt->infoStream() << "setting randseed" << gpt->randseed<< endl;
|
|
}
|
|
|
|
|
|
#ifdef CARMEN_SUPPORT
|
|
list<RangeReading*> rrlist;
|
|
if (gpt->onLine){
|
|
RangeReading rr(0,0);
|
|
while (1){
|
|
while (CarmenWrapper::getReading(rr)){
|
|
RangeReading* nr=new RangeReading(rr);
|
|
rrlist.push_back(nr);
|
|
gpt->processScan(*nr);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
ofstream rawpath("rawpath.dat");
|
|
if (!gpt->onLine){
|
|
while(*(gpt->input) && gpt->running){
|
|
const SensorReading* r;
|
|
(*(gpt->input)) >> r;
|
|
if (! r)
|
|
continue;
|
|
const RangeReading* rr=dynamic_cast<const RangeReading*>(r);
|
|
if (rr && gpt->running){
|
|
const RangeSensor* rs=dynamic_cast<const RangeSensor*>(rr->getSensor());
|
|
assert (rs && rs->beams().size()==rr->size());
|
|
|
|
bool processed=gpt->processScan(*rr);
|
|
rawpath << rr->getPose().x << " " << rr->getPose().y << " " << rr->getPose().theta << endl;
|
|
if (0 && processed){
|
|
cerr << "Retrieving state .. ";
|
|
TNodeVector trajetories=gpt->getTrajectories();
|
|
cerr << "Done" << endl;
|
|
cerr << "Deleting Tree state .. ";
|
|
for (TNodeVector::iterator it=trajetories.begin(); it!=trajetories.end(); it++)
|
|
delete *it;
|
|
cerr << "Done" << endl;
|
|
}
|
|
// if (0 && processed){
|
|
// cerr << "generating copy" << endl;;
|
|
// GridSlamProcessor* m_gsp=gpt->clone();
|
|
// Map<double, DoubleArray2D, false>* pmap=m_gsp->getParticles()[0].map.toDoubleMap() ;
|
|
// cerr << "deleting" << endl;
|
|
// delete m_gsp;
|
|
// delete pmap;
|
|
// }
|
|
}
|
|
const OdometryReading* o=dynamic_cast<const OdometryReading*>(r);
|
|
if (o && gpt->running){
|
|
gpt->processTruePos(*o);
|
|
TruePosEvent* truepos=new TruePosEvent;
|
|
truepos->pose=o->getPose();
|
|
}
|
|
}
|
|
}
|
|
rawpath.close();
|
|
|
|
TNodeVector trajetories=gpt->getTrajectories();
|
|
cerr << "WRITING WEIGHTS" << endl;
|
|
int pnumber=0;
|
|
for (TNodeVector::iterator it=trajetories.begin(); it!=trajetories.end(); it++){
|
|
char buf[10];
|
|
sprintf(buf, "w-%03d.dat",pnumber);
|
|
ofstream weightsStream(buf);
|
|
GridSlamProcessor::TNode* n=*it;
|
|
double oldWeight=0, oldgWeight=0;
|
|
while (n!=0){
|
|
double w=n->weight-oldWeight;
|
|
double gw=n->gweight-oldgWeight;
|
|
oldWeight=n->weight;
|
|
oldgWeight=n->gweight;
|
|
weightsStream << w << " " << gw << endl;
|
|
n=n->parent;
|
|
}
|
|
weightsStream.close();
|
|
pnumber++;
|
|
cerr << buf << endl;
|
|
}
|
|
|
|
DoneEvent *done=new DoneEvent;
|
|
gpt->addEvent(done);
|
|
gpt->infoStream() << "Hallo, I am the gsp thread. I have finished. Do you think it is the case of checking for unlocked mutexes." << endl;
|
|
return 0;
|
|
}
|
|
|
|
std::vector<OrientedPoint> GridSlamProcessorThread::getHypotheses(){
|
|
pthread_mutex_lock(&hp_mutex);
|
|
std::vector<OrientedPoint> retval(hypotheses);
|
|
pthread_mutex_unlock(&hp_mutex);
|
|
return retval;
|
|
}
|
|
|
|
std::vector<unsigned int> GridSlamProcessorThread::getIndexes(){
|
|
pthread_mutex_lock(&ind_mutex);
|
|
std::vector<unsigned int> retval(indexes);
|
|
pthread_mutex_unlock(&ind_mutex);
|
|
return retval;
|
|
}
|
|
|
|
void GridSlamProcessorThread::start(){
|
|
if (running)
|
|
return;
|
|
running=true;
|
|
pthread_create(&gfs_thread, 0, (void * (*)(void *))fastslamthread, (void *) this);
|
|
}
|
|
|
|
void GridSlamProcessorThread::stop(){
|
|
if (! running){
|
|
cout << "PORCO CAZZO" << endl;
|
|
return;
|
|
}
|
|
running=false;
|
|
void * retval;
|
|
pthread_join(gfs_thread, &retval);
|
|
}
|
|
|
|
void GridSlamProcessorThread::onOdometryUpdate(){
|
|
pthread_mutex_lock(&hp_mutex);
|
|
hypotheses.clear();
|
|
weightSums.clear();
|
|
for (GridSlamProcessor::ParticleVector::const_iterator part=getParticles().begin(); part!=getParticles().end(); part++ ){
|
|
hypotheses.push_back(part->pose);
|
|
weightSums.push_back(part->weightSum);
|
|
}
|
|
|
|
ParticleMoveEvent* event=new ParticleMoveEvent;
|
|
event->scanmatched=false;
|
|
event->hypotheses=hypotheses;
|
|
event->weightSums=weightSums;
|
|
event->neff=m_neff;
|
|
pthread_mutex_unlock(&hp_mutex);
|
|
|
|
addEvent(event);
|
|
|
|
syncOdometryUpdate();
|
|
}
|
|
|
|
void GridSlamProcessorThread::onResampleUpdate(){
|
|
pthread_mutex_lock(&ind_mutex);
|
|
pthread_mutex_lock(&hp_mutex);
|
|
|
|
indexes=GridSlamProcessor::getIndexes();
|
|
|
|
assert (indexes.size()==getParticles().size());
|
|
ResampleEvent* event=new ResampleEvent;
|
|
event->indexes=indexes;
|
|
|
|
pthread_mutex_unlock(&hp_mutex);
|
|
pthread_mutex_unlock(&ind_mutex);
|
|
|
|
addEvent(event);
|
|
|
|
syncResampleUpdate();
|
|
}
|
|
|
|
void GridSlamProcessorThread::onScanmatchUpdate(){
|
|
pthread_mutex_lock(&hp_mutex);
|
|
hypotheses.clear();
|
|
weightSums.clear();
|
|
unsigned int bestIdx=0;
|
|
double bestWeight=-1e1000;
|
|
unsigned int idx=0;
|
|
for (GridSlamProcessor::ParticleVector::const_iterator part=getParticles().begin(); part!=getParticles().end(); part++ ){
|
|
hypotheses.push_back(part->pose);
|
|
weightSums.push_back(part->weightSum);
|
|
if(part->weightSum>bestWeight){
|
|
bestIdx=idx;
|
|
bestWeight=part->weightSum;
|
|
}
|
|
idx++;
|
|
}
|
|
|
|
ParticleMoveEvent* event=new ParticleMoveEvent;
|
|
event->scanmatched=true;
|
|
event->hypotheses=hypotheses;
|
|
event->weightSums=weightSums;
|
|
event->neff=m_neff;
|
|
addEvent(event);
|
|
|
|
if (! mapTimer){
|
|
MapEvent* event=new MapEvent;
|
|
event->index=bestIdx;
|
|
event->pmap=new ScanMatcherMap(getParticles()[bestIdx].map);
|
|
event->pose=getParticles()[bestIdx].pose;
|
|
addEvent(event);
|
|
}
|
|
|
|
mapTimer++;
|
|
mapTimer=mapTimer%mapUpdateTime;
|
|
|
|
pthread_mutex_unlock(&hp_mutex);
|
|
|
|
syncOdometryUpdate();
|
|
}
|
|
|
|
void GridSlamProcessorThread::syncOdometryUpdate(){
|
|
}
|
|
|
|
void GridSlamProcessorThread::syncResampleUpdate(){
|
|
}
|
|
|
|
void GridSlamProcessorThread::syncScanmatchUpdate(){
|
|
}
|
|
|
|
void GridSlamProcessorThread::addEvent(GridSlamProcessorThread::Event * e){
|
|
pthread_mutex_lock(&hist_mutex);
|
|
while (eventBuffer.size()>eventBufferLength){
|
|
Event* event=eventBuffer.front();
|
|
delete event;
|
|
eventBuffer.pop_front();
|
|
}
|
|
eventBuffer.push_back(e);
|
|
pthread_mutex_unlock(&hist_mutex);
|
|
}
|
|
|
|
GridSlamProcessorThread::EventDeque GridSlamProcessorThread::getEvents(){
|
|
pthread_mutex_lock(&hist_mutex);
|
|
EventDeque copy(eventBuffer);
|
|
eventBuffer.clear();
|
|
pthread_mutex_unlock(&hist_mutex);
|
|
return copy;
|
|
}
|
|
|
|
GridSlamProcessorThread::Event::~Event(){}
|
|
|
|
GridSlamProcessorThread::MapEvent::~MapEvent(){
|
|
if (pmap)
|
|
delete pmap;
|
|
}
|
|
|
|
void GridSlamProcessorThread::setEventBufferSize(unsigned int length){
|
|
eventBufferLength=length;
|
|
}
|
|
|
|
OrientedPoint GridSlamProcessorThread::boundingBox(SensorLog* log, double& xmin, double& ymin, double& xmax, double& ymax) const{
|
|
OrientedPoint initialPose(0,0,0);
|
|
initialPose=log->boundingBox(xmin, ymin, xmax, ymax);
|
|
xmin-=3*maxrange;
|
|
ymin-=3*maxrange;
|
|
xmax+=3*maxrange;
|
|
ymax+=3*maxrange;
|
|
return initialPose;
|
|
}
|