Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
historyManager.hpp
Go to the documentation of this file.
00001 
00009 #ifndef HISTORYMANAGER_HPP_
00010 #define HISTORYMANAGER_HPP_
00011 
00012 #include "rtslam/mapAbstract.hpp"
00013 #include "rtslam/mapObject.hpp"
00014 
00015 /*
00016 L'idée est donc ici non pas de faire du full slam, mais de garder quand meme quelques poses.
00017 Le parse idéalement suivra une progression géométrique.
00018 Et pour ne pas trop compliquer la gestion de ces états, on va essayer de ne pas trop ajouter ou retirer brutalement,
00019 mais plutot les faire glisser... Imaginons trois timepoint : 1s, 10s, 100s
00020 Au début on n'a que l'état courant, puis au coup d'après on ajoute un
00021 nouvel état courant par duplication, et on laisse glisser le premier dans le passé... quand celui dans le passé
00022 atteint le premier timepoint 1s, on duplique alors l'état courant à nouveau, pendant que l'autre part vers le
00023 timepoint suivant 10s, puisqu'il n'y en avait pas déjà en "voyage", sinon il n'y en a qu'un sur 10 qui passe.
00024 L'idée est qu'il y en ait toujours un entre 0 et 1s, un entre 1 et 10s, et un entre 10 et 100s.
00025 Dès qu'un état atteint un timepoint, il place un flag d'autorisation de passage au timepoint précédent, et selon
00026 le flag d'autorisation de passage de son timepoint il continue ou est supprimé.
00027 
00028 Maintenant comment dupliquer un état ? L'idée est que ces keyframes constituent des ancres de mémoire, les corrélations
00029 croisées avec le reste de l'état suffisent-elles à le définir, ou faut-il ajouter son timestamp dans l'état ? Il n'y a
00030 pas besoin de l'estimer donc normalement pas besoin de l'y mettre. Mais on ne pourra plus y toucher donc c'est vraiment
00031 ses corrélation croisées qui vont le définir.
00032 
00033 Du coup pour dupliquer, on met exactement les memes covariances, mais que met-on pour la covariance entre l'état et
00034 l'état dupliqué ? L'identité, puisqu'ils sont identiques ? Mais ça va les obliger à rester identique, ce que l'on ne
00035 veut pas, puisque si un état va continuer à représenter un timestamp fixe, l'autre va évoluer dans le temps... mais
00036 ce n'est pas juste la prédiction qui fait ça ? Après tout avec  les amers c'est pareil, ça veut juste dire que si je
00037 corrige un gros coup mon état, ça va aussi corriger celui juste avant, mais si je le fais évoluer très loin il va perdre
00038 sa corrélation avec le vieil état... donc oui a priori il faut mettre une cross corrélation complète.
00039 
00040 L'autre question c'est de quoi est ce qu'on garde un historique, juste la pose, tout l'état, un entre deux ?
00041 La pose c'est le plus important, clairement, c'est ce qui détermine l'observation des amers, et plus on met
00042 de choses plus ça va remplir l'état (une pose c'est un amer, un état entier c'est trois amers, si on garde trois
00043 éléments dans l'historiques ça fait 3 contre 9 déjà...)
00044 Mais d'un autre coté si on veut aider la consistance de l'estimation des biais par ex ça peut etre utile de les
00045 mettre... Justement si on lui dit que ça ne bouge pas, et qu'on ne le fait donc pas bouger avec le prédicition,
00046 est-ce que réellement le fait de l'avoir en double completement corrélé va l'empecher de devenir inconsistent ?
00047 
00048 On pourrait faire un hybride aussi, en garder 1 ou 2 avec tout, et 2 ou 3 autres avec juste la pose...
00049 
00050 
00051  */
00052 namespace jafar {
00053   namespace rtslam {
00054 
00055 
00056     class HistoryManagerAbstract
00057     {
00058       protected:
00059         map_ptr_t map;
00060         jblas::ind_array ia_state;
00061 
00062         jblas::ind_array duplicate()
00063         {
00064           jblas::ind_array ia_newstate = map->reserveStates(ia_state.size());
00065           ublas::project(map->x(), ia_newstate) = ublas::project(map->x(), ia_state);
00066           ublas::project(map->P(), ia_state, ia_newstate) = ublas::project(map->P(), ia_state, ia_state); // full correlation
00067           ublas::project(map->P(), ia_newstate, map->ia_used_states()) = ublas::project(map->P(), ia_state, map->ia_used_states());
00068           return ia_newstate;
00069         }
00070 
00071       public:
00072         HistoryManagerAbstract(map_ptr_t map, jblas::ind_array ia_state):
00073           map(map), ia_state(ia_state) {}
00074         virtual void process(double date) = 0;
00075         virtual void print() = 0;
00076     };
00077 
00078 
00082     class HistoryManagerSparse: public HistoryManagerAbstract
00083     {
00084       protected:
00085         struct State { double date; jblas::ind_array ia; };
00086 
00087         struct Gate { double delay_end, delay; State *state; };
00088         typedef std::vector<Gate> GateVector;
00089         GateVector gates;
00090 
00091         double start_date;
00092         double end_date;
00093         bool ended;
00094         double first_gate_factor;
00095         double last_date;
00096         bool processed;
00097 
00098         double horizon_date;
00099 
00100       public:
00107         HistoryManagerSparse(map_ptr_t map, jblas::ind_array ia_state, double first, double factor, int count):
00108           HistoryManagerAbstract(map, ia_state)
00109         {
00110           double delay = first;
00111           for(int i = 0; i < count; ++i) { gates.push_back((Gate){delay,0.0,NULL}); delay *= factor; }
00112           horizon_date = -1;
00113           ended = false;
00114           first_gate_factor = gates.back().delay_end / (gates.back().delay_end - gates.front().delay_end);
00115         }
00116 
00117 /*        HistoryManagerSparse(map_ptr_t map, jblas::ind_array ia_state, std::vector<double> delays):
00118           HistoryManagerAbstract(map, ia_state),
00119           delays(delays) {}
00120 */
00121 
00122         /*
00123          * The idea there is to duplicate the current state when the last state has passed the first gate,
00124          * and then each gate passes its state to the next gate until one is deleted.
00125          * This ensures that each gate always has an associated state in the interval with the previous gate.
00126          */
00127         void process(double date)
00128         {
00129           last_date = date;
00130           processed = false;
00131 
00132           // if first time just initialize
00133           if (horizon_date < 0)
00134           {
00135             start_date = date;
00136             end_date = date + gates.back().delay_end;
00137             for(GateVector::iterator it = gates.begin(); it != gates.end(); ++it)
00138             {
00139               it->state = new State();
00140               it->state->date = date;
00141               it->state->ia = duplicate();
00142             }
00143             horizon_date = date;
00144             return;
00145           }
00146 
00147           // first, check whether there is a state between now and the first gate
00148           // if has, don't do anything, otherwise duplicate and maintain other states
00149           if (date >= horizon_date)
00150           {
00151             processed = true;
00152             // scale the delays if not ended
00153             if (!ended)
00154             {
00155               double scale = date - start_date;
00156               if (date > end_date) { scale = gates.back().delay_end; first_gate_factor = 1.0; ended = true; }
00157               for(GateVector::iterator it = gates.begin(); it != gates.end(); ++it)
00158                 it->delay = it->delay_end * scale/gates.back().delay_end;
00159             }
00160 
00161             State *new_state = new State();
00162             new_state->date = date;
00163 
00164             State *state_to_pass = new_state;
00165             for(GateVector::iterator it = gates.begin(); it != gates.end(); ++it)
00166             {
00167               if (it->state->date <= date - it->delay)
00168               { // switch current state with the one that is passed
00169                 State *tmp = state_to_pass;
00170                 state_to_pass = it->state;
00171                 it->state = tmp;
00172               } else
00173                 break;
00174             }
00175 
00176             // delete state_to_pass
00177             map->liberateStates(state_to_pass->ia);
00178             delete state_to_pass;
00179             // duplicate state
00180             new_state->ia = duplicate();
00181             // compute horizon_date
00182             horizon_date = date + gates.front().delay * first_gate_factor;
00183           }
00184         }
00185 
00186         void print()
00187         {
00188           const int cwidth = 150;
00189           double dwidth = gates[gates.size()-1].delay_end + gates[gates.size()-2].delay_end;
00190 
00191           printf("%7.3f%c", last_date-start_date, processed ? '*' : ' ');
00192           //std::cout << std::fixed << std::setw(7) << std::setprecision(3) << last_date-start_date << (processed ? "*" : " ") << std::setprecision(6); std::cout.unsetf(std::ios_base::floatfield);
00193           int pos = 8;
00194           for(GateVector::reverse_iterator it = gates.rbegin(); it != gates.rend(); ++it)
00195           {
00196             int p = cwidth - (int)(it->delay * cwidth/dwidth + 0.5) - pos;
00197             for(int i = 0; i < p-1; ++i) std::cout << " ";
00198             if (p != 0) std::cout << "@";
00199             pos += p;
00200           }
00201           int p = cwidth - pos + 1;
00202           for(int i = 0; i < p-1; ++i) std::cout << " ";
00203           std::cout << "|" << std::endl;
00204 
00205           pos = 0;
00206           for(GateVector::reverse_iterator it = gates.rbegin(); it != gates.rend(); ++it)
00207           {
00208             int p = cwidth - (int)((last_date - it->state->date) * cwidth/dwidth + 0.5) - pos;
00209             for(int i = 0; i < p-1; ++i) std::cout << " ";
00210             if (p != 0) std::cout << "X";
00211             pos += p;
00212           }
00213           std::cout << std::endl;
00214 
00215 /*
00216           std::cout << "Gates: ";
00217           for(GateVector::reverse_iterator it = gates.rbegin(); it != gates.rend(); ++it)
00218             std::cout << it->delay << " ; ";
00219           std::cout << "States: ";
00220           for(GateVector::reverse_iterator it = gates.rbegin(); it != gates.rend(); ++it)
00221             std::cout << last_date - it->state->date << " ; ";
00222           std::cout << "Horizon: " << horizon_date;
00223           std::cout << std::endl;
00224 */
00225         }
00226 
00227     };
00228 
00229 
00230 
00231 
00232 
00233   }
00234 }
00235 
00236 #endif // #ifndef HISTORYMANAGER_HPP_
00237 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:26 for Jafar by doxygen 1.7.6.1
LAAS-CNRS