amcl_imu.cc

00001 /*
00002  *  Player - One Hell of a Robot Server
00003  *  Copyright (C) 2000  Brian Gerkey   &  Kasper Stoy
00004  *                      gerkey@usc.edu    kaspers@robotics.usc.edu
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00022 //
00023 // Desc: AMCL imu  routines
00024 // Author: Andrew Howard
00025 // Date: 6 Feb 2003
00026 // CVS: $Id: amcl_imu.cc 2394 2004-09-07 00:20:48Z gerkey $
00027 //
00029 
00030 #ifdef HAVE_CONFIG_H
00031 #include "config.h"
00032 #endif
00033 
00034 #include "devicetable.h"
00035 #include "amcl_imu.h"
00036 
00037 
00039 // Default constructor
00040 AMCLImu::AMCLImu()
00041 {
00042   this->device = NULL;
00043   this->model = NULL;
00044   
00045   return;
00046 }
00047 
00048 
00050 // Load imu settings
00051 int AMCLImu::Load(ConfigFile* cf, int section)
00052 {
00053   // Device stuff
00054   this->imu_index = cf->ReadInt(section, "imu_index", -1);
00055   
00056   // Create the imu model
00057   this->model = imu_alloc();
00058 
00059   // Offset added to yaw (heading) values to get UTM (true) north
00060   this->utm_mag_dev = cf->ReadAngle(section, "imu_mag_dev", +13 * M_PI / 180);
00061 
00062   // Expect error in yaw (heading) values
00063   this->model->err_head = cf->ReadAngle(section, "imu_err_yaw", 10 * M_PI / 180);
00064 
00065   return 0;
00066 }
00067 
00068 
00070 // Unload the model
00071 int AMCLImu::Unload(void)
00072 {
00073   imu_free(this->model);
00074   this->model = NULL;
00075   
00076   return 0;
00077 }
00078 
00079 
00081 // Set up the imu
00082 int AMCLImu::Setup(void)
00083 {
00084   player_device_id_t id;
00085 
00086   // Subscribe to the Imu device
00087   id.code = PLAYER_POSITION3D_CODE;
00088   id.index = this->imu_index;
00089 
00090   this->device = deviceTable->GetDriver(id);
00091   if (!this->device)
00092   {
00093     PLAYER_ERROR("unable to locate suitable imu device");
00094     return -1;
00095   }
00096   if (this->device->Subscribe(this) != 0)
00097   {
00098     PLAYER_ERROR("unable to subscribe to imu device");
00099     return -1;
00100   }
00101 
00102   return 0;
00103 }
00104 
00105 
00107 // Shut down the imu
00108 int AMCLImu::Shutdown(void)
00109 {  
00110   this->device->Unsubscribe(this);
00111   this->device = NULL;
00112 
00113   return 0;
00114 }
00115 
00116 
00118 // Check for new imu data
00119 bool AMCLImu::GetData()
00120 {
00121   size_t size;
00122   player_position3d_data_t data;
00123   uint32_t tsec, tusec;
00124 
00125   // Get the imu device data
00126   size = this->device->GetData(this, (uint8_t*) &data, sizeof(data), &tsec, &tusec);
00127   if (size < sizeof(data))
00128     return false;
00129 
00130   if (tsec == this->tsec && tusec == this->tusec)
00131     return false;
00132 
00133   this->tsec = tsec;
00134   this->tusec = tusec;
00135 
00136   this->utm_head = ((int32_t) ntohl(data.yaw)) / 3600.0 * M_PI / 180;
00137   this->utm_head += this->utm_mag_dev;
00138   
00139   return true;
00140 }
00141 
00142 
00144 // Apply the imu sensor model
00145 bool AMCLImu::UpdateSensor(pf_t *pf)
00146 {
00147   // Check for new data
00148   if (!this->GetData())
00149     return false;
00150   
00151   printf("update imu %f\n", this->utm_head * 180 / M_PI);
00152   
00153   // Update the imu sensor model with the latest imu measurements
00154   imu_set_utm(this->model, this->utm_head);
00155 
00156   // Apply the imu sensor model
00157   pf_update_sensor(pf, (pf_sensor_model_fn_t) imu_sensor_model, this->model);  
00158 
00159   return true;
00160 }
00161 
00162 #ifdef INCLUDE_RTKGUI
00163 
00165 // Setup the GUI
00166 void AMCLImu::SetupGUI(rtk_canvas_t *canvas, rtk_fig_t *robot_fig)
00167 {
00168   this->fig = rtk_fig_create(canvas, NULL, 0);
00169   
00170   return;
00171 }
00172 
00173 
00175 // Shutdown the GUI
00176 void AMCLImu::ShutdownGUI(rtk_canvas_t *canvas, rtk_fig_t *robot_fig)
00177 {
00178   rtk_fig_destroy(this->fig);
00179   this->fig = NULL;
00180   
00181   return;
00182 }
00183 
00185 // Draw the imu values
00186 void AMCLImu::UpdateGUI(rtk_canvas_t *canvas, rtk_fig_t *robot_fig)
00187 {
00188   double ox, oy, oa;
00189   
00190   rtk_fig_clear(this->fig);
00191   rtk_fig_color_rgb32(this->fig, 0xFF00FF);
00192   rtk_fig_get_origin(robot_fig, &ox, &oy, &oa);
00193   rtk_fig_arrow(this->fig, ox, oy, this->utm_head + M_PI / 2, 1.0, 0.20);
00194   
00195   return;
00196 }
00197 
00198 #endif
00199 

Last updated 12 September 2005 21:38:45