Go to the documentation of this file.00001 #include <string>
00002 #include <deque>
00003 #include <list>
00004 #include <map>
00005 #include <set>
00006 #include <fstream>
00007
00008
00009 #include <gmapping/utils/stat.h>
00010 #include <gmapping/gridfastslam/gridslamprocessor.h>
00011
00012 namespace GMapping {
00013
00014 using namespace std;
00015
00016 GridSlamProcessor::TNode::TNode(const OrientedPoint& p, double w, TNode* n, unsigned int c){
00017 pose=p;
00018 weight=w;
00019 childs=c;
00020 parent=n;
00021 reading=0;
00022 gweight=0;
00023 if (n){
00024 n->childs++;
00025 }
00026 flag=0;
00027 accWeight=0;
00028 }
00029
00030
00031 GridSlamProcessor::TNode::~TNode(){
00032 if (parent && (--parent->childs)<=0)
00033 delete parent;
00034 assert(!childs);
00035 }
00036
00037
00038
00039
00040 GridSlamProcessor::TNodeVector GridSlamProcessor::getTrajectories() const{
00041 TNodeVector v;
00042 TNodeMultimap parentCache;
00043 TNodeDeque border;
00044
00045 for (ParticleVector::const_iterator it=m_particles.begin(); it!=m_particles.end(); it++){
00046 TNode* node=it->node;
00047 while(node){
00048 node->flag=false;
00049 node=node->parent;
00050 }
00051 }
00052
00053 for (ParticleVector::const_iterator it=m_particles.begin(); it!=m_particles.end(); it++){
00054 TNode* newnode=new TNode(* (it->node) );
00055
00056 v.push_back(newnode);
00057 assert(newnode->childs==0);
00058 if (newnode->parent){
00059 parentCache.insert(make_pair(newnode->parent, newnode));
00060
00061 if (! newnode->parent->flag){
00062
00063 newnode->parent->flag=true;
00064 border.push_back(newnode->parent);
00065 }
00066 }
00067 }
00068
00069
00070
00071 while (! border.empty()){
00072
00073
00074 const TNode* node=border.front();
00075
00076 border.pop_front();
00077 if (! node)
00078 continue;
00079
00080 TNode* newnode=new TNode(*node);
00081 node->flag=false;
00082
00083
00084 pair<TNodeMultimap::iterator, TNodeMultimap::iterator> p=parentCache.equal_range(node);
00085 double childs=0;
00086 for (TNodeMultimap::iterator it=p.first; it!=p.second; it++){
00087 assert(it->second->parent==it->first);
00088 (it->second)->parent=newnode;
00089
00090 childs++;
00091 }
00093 parentCache.erase(p.first, p.second);
00094
00095 assert(childs==newnode->childs);
00096
00097
00098 if ( node->parent ){
00099 parentCache.insert(make_pair(node->parent, newnode));
00100 if(! node->parent->flag){
00101 border.push_back(node->parent);
00102 node->parent->flag=true;
00103 }
00104 }
00105
00106 }
00107
00108 for (unsigned int i=0; i<v.size(); i++){
00109 TNode* node= v[i];
00110 while (node){
00111
00112 node=node->parent;
00113 }
00114
00115 }
00116
00117 return v;
00118
00119 }
00120
00121 void GridSlamProcessor::integrateScanSequence(GridSlamProcessor::TNode* node){
00122
00123 TNode* aux=node;
00124 TNode* reversed=0;
00125 double count=0;
00126 while(aux!=0){
00127 TNode * newnode=new TNode(*aux);
00128 newnode->parent=reversed;
00129 reversed=newnode;
00130 aux=aux->parent;
00131 count++;
00132 }
00133
00134
00135 if (m_infoStream )
00136 m_infoStream << "Restoring State Nodes=" <<count << endl;
00137
00138
00139 aux=reversed;
00140 bool first=true;
00141 double oldWeight=0;
00142 OrientedPoint oldPose;
00143 while (aux!=0){
00144 if (first){
00145 oldPose=aux->pose;
00146 first=false;
00147 oldWeight=aux->weight;
00148 }
00149
00150 OrientedPoint dp=aux->pose-oldPose;
00151 double dw=aux->weight-oldWeight;
00152 oldPose=aux->pose;
00153
00154
00155 double * plainReading = new double[m_beams];
00156 for(unsigned int i=0; i<m_beams; i++)
00157 plainReading[i]=(*(aux->reading))[i];
00158
00159 for (ParticleVector::iterator it=m_particles.begin(); it!=m_particles.end(); it++){
00160
00161 double s=sin(oldPose.theta-it->pose.theta),
00162 c=cos(oldPose.theta-it->pose.theta);
00163
00164 it->pose.x+=c*dp.x-s*dp.y;
00165 it->pose.y+=s*dp.x+c*dp.y;
00166 it->pose.theta+=dp.theta;
00167 it->pose.theta=atan2(sin(it->pose.theta), cos(it->pose.theta));
00168
00169
00170 m_matcher.invalidateActiveArea();
00171 m_matcher.computeActiveArea(it->map, it->pose, plainReading);
00172 it->weight+=dw;
00173 it->weightSum+=dw;
00174
00175
00176
00177 it->node=new TNode(it->pose, 0.0, it->node);
00178
00179 }
00180
00181 delete [] plainReading;
00182 aux=aux->parent;
00183 }
00184
00185
00186 aux=reversed;
00187 while (reversed){
00188 aux=reversed;
00189 reversed=reversed->parent;
00190 delete aux;
00191 }
00192 }
00193
00194
00195
00196
00197
00198 void GridSlamProcessor::updateTreeWeights(bool weightsAlreadyNormalized){
00199
00200 if (!weightsAlreadyNormalized) {
00201 normalize();
00202 }
00203 resetTree();
00204 propagateWeights();
00205 }
00206
00207 void GridSlamProcessor::resetTree(){
00208
00209
00210 for (ParticleVector::iterator it=m_particles.begin(); it!=m_particles.end(); it++){
00211 TNode* n=it->node;
00212 while (n){
00213 n->accWeight=0;
00214 n->visitCounter=0;
00215 n=n->parent;
00216 }
00217 }
00218 }
00219
00220 double propagateWeight(GridSlamProcessor::TNode* n, double weight){
00221 if (!n)
00222 return weight;
00223 double w=0;
00224 n->visitCounter++;
00225 n->accWeight+=weight;
00226 if (n->visitCounter==n->childs){
00227 w=propagateWeight(n->parent,n->accWeight);
00228 }
00229 assert(n->visitCounter<=n->childs);
00230 return w;
00231 }
00232
00233 double GridSlamProcessor::propagateWeights(){
00234
00235
00236
00237
00238
00239 double lastNodeWeight=0;
00240
00241 double aw=0;
00242
00243 std::vector<double>::iterator w=m_weights.begin();
00244 for (ParticleVector::iterator it=m_particles.begin(); it!=m_particles.end(); it++){
00245 double weight=*w;
00246 aw+=weight;
00247 TNode * n=it->node;
00248 n->accWeight=weight;
00249 lastNodeWeight+=propagateWeight(n->parent,n->accWeight);
00250 w++;
00251 }
00252
00253 if (fabs(aw-1.0) > 0.0001 || fabs(lastNodeWeight-1.0) > 0.0001) {
00254 cerr << "ERROR: ";
00255 cerr << "root->accWeight=" << lastNodeWeight << " sum_leaf_weights=" << aw << endl;
00256 assert(0);
00257 }
00258 return lastNodeWeight;
00259 }
00260
00261 };
00262
00263