⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 amcl.cc

📁 机器人仿真平台,和stage配合运行
💻 CC
📖 第 1 页 / 共 3 页
字号:
/* *  Player - One Hell of a Robot Server *  Copyright (C) 2000  Brian Gerkey   &  Kasper Stoy *                      gerkey@usc.edu    kaspers@robotics.usc.edu * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program 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.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * *//////////////////////////////////////////////////////////////////////////////// Desc: Adaptive Monte-Carlo localization// Author: Andrew Howard// Date: 6 Feb 2003// CVS: $Id: amcl.cc,v 1.13.2.8 2003/05/23 20:57:24 inspectorg Exp $//// Theory of operation://  TODO//// Requires: position (odometry), laser, sonar// Provides: localization/////////////////////////////////////////////////////////////////////////////#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <assert.h>#include <errno.h>#include <string.h>#include <math.h>#include <stdlib.h>       // for atoi(3)#include <sys/types.h>#include <netinet/in.h>   // for htons(3)#include <unistd.h>#include <sys/time.h>#define PLAYER_ENABLE_TRACE 0#define PLAYER_ENABLE_MSG 1#include "player.h"#include "device.h"#include "devicetable.h"#include "drivertable.h"#include "pf/pf.h"#include "map/map.h"#include "models/odometry.h"#include "models/sonar.h"#include "models/laser.h"#ifdef INCLUDE_RTKGUI#include "rtk.h"#endif// Combined sensor datatypedef struct{  // Data time-stamp (odometric)  uint32_t odom_time_sec, odom_time_usec;      // Odometric pose  pf_vector_t odom_pose;  // Sonar ranges  int srange_count;  double sranges[PLAYER_SONAR_MAX_SAMPLES];  // Laser ranges  int range_count;  double ranges[PLAYER_LASER_MAX_SAMPLES][2];  } amcl_sensor_data_t;// Pose hypothesistypedef struct{  // Total weight (weights sum to 1)  double weight;  // Mean of pose esimate  pf_vector_t pf_pose_mean;  // Covariance of pose estimate  pf_matrix_t pf_pose_cov;  } amcl_hyp_t;// Incremental navigation driverclass AdaptiveMCL : public CDevice{  ///////////////////////////////////////////////////////////////////////////  // Top half methods; these methods run in the server thread  ///////////////////////////////////////////////////////////////////////////  // Constructor  public: AdaptiveMCL(char* interface, ConfigFile* cf, int section);  // Destructor  public: virtual ~AdaptiveMCL(void);  // Setup/shutdown routines.  public: virtual int Setup(void);  public: virtual int Shutdown(void);#ifdef INCLUDE_RTKGUI  // Set up the GUI  private: int SetupGUI(void);  private: int ShutdownGUI(void);#endif  // Set up the odometry device  private: int SetupOdom(void);  private: int ShutdownOdom(void);  // Get the current odometric pose  private: void GetOdomData(amcl_sensor_data_t *data);  // Set up the sonar device  private: int SetupSonar(void);  private: int ShutdownSonar(void);  // Check for new sonar data  private: void GetSonarData(amcl_sensor_data_t *data);  // Set up the laser device  private: int SetupLaser(void);  private: int ShutdownLaser(void);  // Check for new laser data  private: void GetLaserData(amcl_sensor_data_t *data);  // Get the current pose  private: virtual size_t GetData(void* client, unsigned char* dest, size_t len,                                  uint32_t* time_sec, uint32_t* time_usec);  ///////////////////////////////////////////////////////////////////////////  // Middle methods: these methods facilitate communication between the top  // and bottom halfs.  ///////////////////////////////////////////////////////////////////////////  // Push data onto the filter queue  private: void Push(amcl_sensor_data_t *data);  // Pop data from the filter queue  private: int Pop(amcl_sensor_data_t *data);  ///////////////////////////////////////////////////////////////////////////  // Bottom half methods; these methods run in the device thread  ///////////////////////////////////////////////////////////////////////////    // Main function for device thread.  private: virtual void Main(void);  // Initialize the filter  private: void InitFilter(pf_vector_t pose_mean, pf_matrix_t pose_cov);  // Update the filter with new sensor data  private: void UpdateFilter(amcl_sensor_data_t *data);#ifdef INCLUDE_RTKGUI  // Draw the current best pose estimate  private: void DrawPoseEst();  // Draw the sonar values  private: void DrawSonarData(amcl_sensor_data_t *data);#endif  // Process requests.  Returns 1 if the configuration has changed.  private: int HandleRequests(void);  // Handle geometry requests.  private: void HandleGetGeom(void *client, void *request, int len);  // Handle the set pose request  private: void HandleSetPose(void *client, void *request, int len);  // Handle map info request  private: void HandleGetMapInfo(void *client, void *request, int len);  // Handle map data request  private: void HandleGetMapData(void *client, void *request, int len);  ///////////////////////////////////////////////////////////////////////////  // Properties  ///////////////////////////////////////////////////////////////////////////  // Odometry device info  private: CDevice *odom;  private: int odom_index;  // Sonar device info  private: CDevice *sonar;  private: int sonar_index;  // Sonar poses relative to robot  private: int sonar_pose_count;  private: pf_vector_t sonar_poses[PLAYER_SONAR_MAX_SAMPLES];    // Laser device info  private: CDevice *laser;  private: int laser_index;  // Laser pose relative to robot  private: pf_vector_t laser_pose;  // Effective robot radius (used for c-space tests)  private: double robot_radius;  // Occupancy map  private: const char *map_file;  private: double map_scale;  private: int map_negate;  private: map_t *map;  // Odometry sensor/action model  private: odometry_t *odom_model;  // Sonar sensor model  private: sonar_t *sonar_model;  // Laser sensor model  private: laser_t *laser_model;  private: int laser_max_samples;  private: double laser_map_err;  // Odometric pose of last used sensor reading  private: pf_vector_t odom_pose;  // Sensor data queue  private: int q_size, q_start, q_len;  private: amcl_sensor_data_t *q_data;    // Particle filter  private: pf_t *pf;  private: int pf_min_samples, pf_max_samples;  private: double pf_err, pf_z;  // Last odometric pose estimates used by filter  private: pf_vector_t pf_odom_pose;  private: uint32_t pf_odom_time_sec, pf_odom_time_usec;  // Initial pose estimate  private: pf_vector_t pf_init_pose_mean;  private: pf_matrix_t pf_init_pose_cov;  // Current particle filter pose estimates  private: int hyp_count;  private: amcl_hyp_t hyps[PLAYER_LOCALIZE_MAX_HYPOTHS];#ifdef INCLUDE_RTKGUI  // RTK stuff; for testing only  private: int enable_gui;  private: rtk_app_t *app;  private: rtk_canvas_t *canvas;  private: rtk_fig_t *map_fig;  private: rtk_fig_t *pf_fig;  private: rtk_fig_t *robot_fig;  private: rtk_fig_t *sonar_fig;#endif};// Initialization functionCDevice* AdaptiveMCL_Init(char* interface, ConfigFile* cf, int section){  if (strcmp(interface, PLAYER_LOCALIZE_STRING) != 0)  {    PLAYER_ERROR1("driver \"amcl\" does not support interface \"%s\"\n", interface);    return (NULL);  }  return ((CDevice*) (new AdaptiveMCL(interface, cf, section)));}// a driver registration functionvoid AdaptiveMCL_Register(DriverTable* table){  table->AddDriver("amcl", PLAYER_ALL_MODE, AdaptiveMCL_Init);  return;}////////////////////////////////////////////////////////////////////////////////// ConstructorAdaptiveMCL::AdaptiveMCL(char* interface, ConfigFile* cf, int section)    : CDevice(sizeof(player_localize_data_t), 0, 100, 100){  //double size;  double u[3];    this->odom = NULL;  this->odom_index = cf->ReadInt(section, "position_index", 0);  this->sonar = NULL;  this->sonar_index = cf->ReadInt(section, "sonar_index", -1);  this->laser = NULL;  this->laser_index = cf->ReadInt(section, "laser_index", -1);  // C-space info  this->robot_radius = cf->ReadLength(section, "robot_radius", 0.20);    // Get the map settings  this->map_file = cf->ReadFilename(section, "map_file", NULL);  this->map_scale = cf->ReadLength(section, "map_scale", 0.05);  this->map_negate = cf->ReadInt(section, "map_negate", 0);  this->map = NULL;    // Odometry model settings  this->odom_model = NULL;  // Laser model settings  this->laser_model = NULL;  this->laser_max_samples = cf->ReadInt(section, "laser_max_samples", 5);  this->laser_map_err = cf->ReadLength(section, "laser_map_err", 0.05);  // Particle filter settings  this->pf = NULL;  this->pf_min_samples = cf->ReadInt(section, "pf_min_samples", 100);  this->pf_max_samples = cf->ReadInt(section, "pf_max_samples", 10000);  // Adaptive filter parameters  this->pf_err = cf->ReadFloat(section, "pf_err", 0.01);  this->pf_z = cf->ReadFloat(section, "pf_z", 3);    // Initial pose estimate  this->pf_init_pose_mean = pf_vector_zero();  this->pf_init_pose_mean.v[0] = cf->ReadTupleLength(section, "init_pose", 0, 0);  this->pf_init_pose_mean.v[1] = cf->ReadTupleLength(section, "init_pose", 1, 0);  this->pf_init_pose_mean.v[2] = cf->ReadTupleAngle(section, "init_pose", 2, 0);  // Initial pose covariance  u[0] = cf->ReadTupleLength(section, "init_pose_var", 0, 1e3);  u[1] = cf->ReadTupleLength(section, "init_pose_var", 1, 1e3);  u[2] = cf->ReadTupleAngle(section, "init_pose_var", 2, 1e2);  this->pf_init_pose_cov = pf_matrix_zero();  this->pf_init_pose_cov.m[0][0] = u[0] * u[0];  this->pf_init_pose_cov.m[1][1] = u[1] * u[1];  this->pf_init_pose_cov.m[2][2] = u[2] * u[2];  // Initial hypothesis list  this->hyp_count = 0;  // Create the sensor queue  this->q_len = 0;  this->q_size = 100;  this->q_data = new amcl_sensor_data_t[this->q_size];#ifdef INCLUDE_RTKGUI  // Enable debug gui  this->enable_gui = cf->ReadInt(section, "enable_gui", 0);#endif    return;}////////////////////////////////////////////////////////////////////////////////// DestructorAdaptiveMCL::~AdaptiveMCL(void){  delete[] this->q_data;  return;}////////////////////////////////////////////////////////////////////////////////// Set up the device (called by server thread).int AdaptiveMCL::Setup(void){  amcl_sensor_data_t sdata;      PLAYER_TRACE0("setup");  // Initialise the underlying position device  if (this->SetupOdom() != 0)    return -1;    // Initialise the sonar  if (this->SetupSonar() != 0)    return -1;  // Initialise the laser  if (this->SetupLaser() != 0)    return -1;  // Create the map  if (!this->map_file)  {    PLAYER_ERROR("map file not specified");    return -1;  }    // Create the map  assert(this->map == NULL);  this->map = map_alloc(this->map_scale);    // Load the map  PLAYER_MSG1("loading map file [%s]", this->map_file);  if (map_load_occ(this->map, this->map_file, this->map_negate) != 0)    return -1;  // Compute the c-space  PLAYER_MSG0("computing cspace");  map_update_cspace(this->map, 2 * this->robot_radius);    // Create the odometry model  this->odom_model = odometry_alloc(this->map, this->robot_radius);  if (odometry_init_cspace(this->odom_model))  {    PLAYER_ERROR("error generating free space map (this could be a bad map)");    return -1;  }  // Create the sonar model  this->sonar_model = sonar_alloc(this->map, this->sonar_pose_count, this->sonar_poses);    // Create the laser model  this->laser_model = laser_alloc(this->map, this->laser_pose);  this->laser_model->range_cov = this->laser_map_err * this->laser_map_err;  // Create the particle filter  assert(this->pf == NULL);  this->pf = pf_alloc(this->pf_min_samples, this->pf_max_samples);  this->pf->pop_err = this->pf_err;  this->pf->pop_z = this->pf_z;  // Set the initial odometric poses  this->GetOdomData(&sdata);  this->odom_pose = sdata.odom_pose;  this->pf_odom_pose = sdata.odom_pose;  this->pf_odom_time_sec = sdata.odom_time_sec;  this->pf_odom_time_usec = sdata.odom_time_usec;  // Initial hypothesis list  this->hyp_count = 0;  #ifdef INCLUDE_RTKGUI  // Start the GUI  if (this->enable_gui)    this->SetupGUI();#endif  // Start the driver thread.  PLAYER_MSG0("running");  this->StartThread();    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -