amcl_odom.cc
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00022 
00023 
00024 
00025 
00026 
00027 
00029 
00030 #ifdef HAVE_CONFIG_H
00031 #include "config.h"
00032 #endif
00033 
00034 #include <sys/types.h> 
00035 #include <math.h>
00036 
00037 #include <libplayercore/playercore.h>
00038 #include <libplayercore/error.h>
00039 #include "amcl_odom.h"
00040 
00042 
00043 AMCLOdom::AMCLOdom(AdaptiveMCL & aAMCL, player_devaddr_t addr) : AMCLSensor(aAMCL)
00044 {
00045   this->odom_dev = NULL;
00046   this->action_pdf = NULL;
00047   this->odom_addr = addr;
00048   
00049   return;
00050 }
00051 
00052 
00054 
00055 int AMCLOdom::Load(ConfigFile* cf, int section)
00056 {
00057   this->time = 0.0;
00058 
00059   this->drift = pf_matrix_zero();
00060 
00061   this->drift.m[0][0] = cf->ReadTupleFloat(section, "odom_drift[0]", 0, 0.20);
00062   this->drift.m[0][1] = cf->ReadTupleFloat(section, "odom_drift[0]", 1, 0.00);
00063   this->drift.m[0][2] = cf->ReadTupleFloat(section, "odom_drift[0]", 2, 0.00); 
00064 
00065   this->drift.m[1][0] = cf->ReadTupleFloat(section, "odom_drift[1]", 0, 0.00);
00066   this->drift.m[1][1] = cf->ReadTupleFloat(section, "odom_drift[1]", 1, 0.20);
00067   this->drift.m[1][2] = cf->ReadTupleFloat(section, "odom_drift[1]", 2, 0.00);
00068 
00069   this->drift.m[2][0] = cf->ReadTupleFloat(section, "odom_drift[2]", 0, 0.20);
00070   this->drift.m[2][1] = cf->ReadTupleFloat(section, "odom_drift[2]", 1, 0.00);
00071   this->drift.m[2][2] = cf->ReadTupleFloat(section, "odom_drift[2]", 2, 0.20);
00072 
00073   return 0;
00074 }
00075 
00076 
00078 
00079 int AMCLOdom::Unload(void)
00080 {  
00081   return 0;
00082 }
00083 
00084 
00086 
00087 int AMCLOdom::Setup(void)
00088 {
00089   
00090   this->odom_dev = deviceTable->GetDevice(this->odom_addr);
00091   if (!this->odom_dev)
00092   {
00093     PLAYER_ERROR("unable to locate suitable position driver");
00094     return -1;
00095   }
00096   if (this->odom_dev->Subscribe(AMCL.InQueue) != 0)
00097   {
00098     PLAYER_ERROR("unable to subscribe to position device");
00099     return -1;
00100   }
00101   
00102   return 0;
00103 }
00104 
00105 
00107 
00108 int AMCLOdom::Shutdown(void)
00109 {
00110   
00111   this->odom_dev->Unsubscribe(AMCL.InQueue);
00112   this->odom_dev = NULL;
00113   
00114   return 0;
00115 }
00116 
00117 
00119 
00120 
00121 
00122 int AMCLOdom::ProcessMessage(QueuePointer &resp_queue, 
00123                                      player_msghdr * hdr, 
00124                                      void * idata)
00125 {
00126   pf_vector_t pose;
00127   AMCLOdomData *ndata;
00128 
00129   if(!Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA,
00130                             PLAYER_POSITION2D_DATA_STATE, this->odom_addr))
00131   {
00132     return -1;
00133   }
00134 
00135   player_position2d_data_t* data = reinterpret_cast<player_position2d_data_t*> (idata);
00136 
00137   
00138   pose.v[0] = data->pos.px;
00139   pose.v[1] = data->pos.py;
00140   pose.v[2] = data->pos.pa;
00141 
00142   
00143          
00144 
00145   ndata = new AMCLOdomData;
00146 
00147   ndata->sensor = this;
00148   ndata->time = hdr->timestamp;
00149 
00150   ndata->pose = pose;
00151   ndata->delta = pf_vector_zero();
00152 
00153   this->time = hdr->timestamp;
00154 
00155   AMCL.Push(ndata);
00156     
00157   return 0;
00158 }
00159 
00160 
00162 
00163 bool AMCLOdom::UpdateAction(pf_t *pf, AMCLSensorData *data)
00164 {
00165   AMCLOdomData *ndata;
00166   pf_vector_t x;
00167   pf_matrix_t cx;
00168   double ux, uy, ua;
00169   ndata = (AMCLOdomData*) data;
00170 
00171   
00172 
00173 
00174 
00175 
00176          
00177   
00178   x = ndata->delta;
00179   
00180   
00181   
00182   ux = this->drift.m[0][0] * x.v[0];
00183   uy = this->drift.m[1][1] * x.v[1];
00184   ua = this->drift.m[2][0] * fabs(x.v[0])
00185     + this->drift.m[2][1] * fabs(x.v[1])
00186     + this->drift.m[2][2] * fabs(x.v[2]);
00187 
00188   cx = pf_matrix_zero();
00189   cx.m[0][0] = ux * ux;
00190   cx.m[1][1] = uy * uy;
00191   cx.m[2][2] = ua * ua;
00192 
00193   
00194   
00195   
00196   this->action_pdf = pf_pdf_gaussian_alloc(x, cx); 
00197 
00198   
00199   pf_update_action(pf, (pf_action_model_fn_t) ActionModel, this);  
00200 
00201   
00202   pf_pdf_gaussian_free(this->action_pdf);
00203   this->action_pdf = NULL;
00204   
00205   return true;
00206 }
00207 
00208 
00210 
00211 void 
00212 AMCLOdom::ActionModel(AMCLOdom *self, pf_sample_set_t* set)
00213 {
00214   int i;
00215   pf_vector_t z;
00216   pf_sample_t *sample;
00217 
00218   
00219   for (i = 0; i < set->sample_count; i++)
00220   {
00221     sample = set->samples + i;
00222     z = pf_pdf_gaussian_sample(self->action_pdf);
00223     sample->pose = pf_vector_coord_add(z, sample->pose);
00224     sample->weight = 1.0 / set->sample_count;
00225   }
00226 }
00227 
00228 
00229 #ifdef INCLUDE_RTKGUI
00230 
00232 
00233 void AMCLOdom::SetupGUI(rtk_canvas_t *canvas, rtk_fig_t *robot_fig)
00234 {
00235   return;
00236 }
00237 
00238 
00240 
00241 void AMCLOdom::ShutdownGUI(rtk_canvas_t *canvas, rtk_fig_t *robot_fig)
00242 {
00243   return;
00244 }
00245 
00246 #endif
 
| 
Last updated 12 September 2005 21:38:45
 |