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

📄 amcl.cc

📁 机器人仿真平台,和stage配合运行
💻 CC
📖 第 1 页 / 共 3 页
字号:
////////////////////////////////////////////////////////////////////////////////// Shutdown the device (called by server thread).int AdaptiveMCL::Shutdown(void){  // Stop the driver thread.  this->StopThread();    #ifdef INCLUDE_RTKGUI  // Stop the GUI  if (this->enable_gui)    this->ShutdownGUI();#endif  // Delete the particle filter  pf_free(this->pf);  this->pf = NULL;  // Delete the odometry model  odometry_free(this->odom_model);  this->odom_model = NULL;  // Delete the sonar model  sonar_free(this->sonar_model);  this->sonar_model = NULL;  // Delete the laser model  laser_free(this->laser_model);  this->laser_model = NULL;    // Delete the map  map_free(this->map);  this->map = NULL;    // Stop the laser  this->ShutdownLaser();  // Stop the sonar  this->ShutdownSonar();  // Stop the odom device  this->ShutdownOdom();  PLAYER_TRACE0("shutdown");  return 0;}#ifdef INCLUDE_RTKGUI////////////////////////////////////////////////////////////////////////////////// Set up the GUIint AdaptiveMCL::SetupGUI(void){  // Initialize RTK  rtk_init(NULL, NULL);  this->app = rtk_app_create();  this->canvas = rtk_canvas_create(this->app);  rtk_canvas_title(this->canvas, "AdaptiveMCL");  rtk_canvas_size(this->canvas, this->map->size_x, this->map->size_y);  rtk_canvas_scale(this->canvas, this->map->scale, this->map->scale);  this->map_fig = rtk_fig_create(this->canvas, NULL, -1);  this->pf_fig = rtk_fig_create(this->canvas, this->map_fig, 5);  // Draw the map  map_draw_occ(this->map, this->map_fig);  //map_draw_cspace(this->map, this->map_fig);  this->robot_fig = rtk_fig_create(this->canvas, NULL, 9);  this->sonar_fig = rtk_fig_create(this->canvas, this->robot_fig, 10);  // Draw the robot  rtk_fig_color(this->robot_fig, 0.7, 0, 0);  rtk_fig_rectangle(this->robot_fig, 0, 0, 0, 0.40, 0.20, 0);  rtk_app_main_init(this->app);  return 0;}////////////////////////////////////////////////////////////////////////////////// Shut down the GUIint AdaptiveMCL::ShutdownGUI(void){  rtk_fig_destroy(this->sonar_fig);  rtk_fig_destroy(this->robot_fig);  rtk_fig_destroy(this->map_fig);  rtk_fig_destroy(this->pf_fig);  rtk_canvas_destroy(this->canvas);  rtk_app_main_term(this->app);  rtk_app_destroy(this->app);    return 0;}  #endif////////////////////////////////////////////////////////////////////////////////// Set up the underlying odom device.int AdaptiveMCL::SetupOdom(void){  player_device_id_t id;      id.code = PLAYER_POSITION_CODE;  id.index = this->odom_index;  this->odom = deviceTable->GetDevice(id);  if (!this->odom)  {    PLAYER_ERROR("unable to locate suitable position device");    return -1;  }    if (this->odom->Subscribe(this) != 0)  {    PLAYER_ERROR("unable to subscribe to position device");    return -1;  }  return 0;}////////////////////////////////////////////////////////////////////////////////// Shutdown the underlying odom device.int AdaptiveMCL::ShutdownOdom(void){  this->odom->Unsubscribe(this);  return 0;}////////////////////////////////////////////////////////////////////////////////// Get the current odometry readingvoid AdaptiveMCL::GetOdomData(amcl_sensor_data_t *data){  size_t size;  player_position_data_t ndata;  // Get the odom device data.  size = this->odom->GetData(this, (uint8_t*) &ndata, sizeof(ndata),                             &data->odom_time_sec, &data->odom_time_usec);  // Byte swap  ndata.xpos = ntohl(ndata.xpos);  ndata.ypos = ntohl(ndata.ypos);  ndata.yaw = ntohl(ndata.yaw);  data->odom_pose.v[0] = (double) ((int32_t) ndata.xpos) / 1000.0;  data->odom_pose.v[1] = (double) ((int32_t) ndata.ypos) / 1000.0;  data->odom_pose.v[2] = (double) ((int32_t) ndata.yaw) * M_PI / 180;  return;}////////////////////////////////////////////////////////////////////////////////// Set up the sonarint AdaptiveMCL::SetupSonar(void){  int i;  uint8_t req;  uint16_t reptype;  player_device_id_t id;  player_sonar_geom_t geom;  struct timeval tv;  // If there is no sonar device...  if (this->sonar_index < 0)    return 0;    id.code = PLAYER_SONAR_CODE;  id.index = this->sonar_index;  this->sonar = deviceTable->GetDevice(id);  if (!this->sonar)  {    PLAYER_ERROR("unable to locate suitable sonar device");    return -1;  }  if (this->sonar->Subscribe(this) != 0)  {    PLAYER_ERROR("unable to subscribe to sonar device");    return -1;  }  // Get the sonar geometry  req = PLAYER_SONAR_GET_GEOM_REQ;  if (this->sonar->Request(&id, this, &req, 1, &reptype, &tv, &geom, sizeof(geom)) < 0)  {    PLAYER_ERROR("unable to get sonar geometry");    return -1;  }  this->sonar_pose_count = (int16_t) ntohs(geom.pose_count);  assert(this->sonar_pose_count < sizeof(this->sonar_poses) / sizeof(this->sonar_poses[0]));    for (i = 0; i < this->sonar_pose_count; i++)  {    this->sonar_poses[i].v[0] = ((int16_t) ntohs(geom.poses[i][0])) / 1000.0;    this->sonar_poses[i].v[1] = ((int16_t) ntohs(geom.poses[i][1])) / 1000.0;    this->sonar_poses[i].v[2] = ((int16_t) ntohs(geom.poses[i][2])) * M_PI / 180.0;  }  return 0;}////////////////////////////////////////////////////////////////////////////////// Shut down the sonarint AdaptiveMCL::ShutdownSonar(void){  // If there is no sonar device...  if (this->sonar_index < 0)    return 0;  this->sonar->Unsubscribe(this);  this->sonar = NULL;    return 0;}////////////////////////////////////////////////////////////////////////////////// Check for new sonar datavoid AdaptiveMCL::GetSonarData(amcl_sensor_data_t *data){  int i;  size_t size;  player_sonar_data_t ndata;  double r; //b, db;  // If there is no sonar device...  if (this->sonar_index < 0)  {    data->srange_count = 0;    return;  }    // Get the sonar device data.  size = this->sonar->GetData(this, (uint8_t*) &ndata, sizeof(ndata), NULL, NULL);  data->srange_count = ntohs(ndata.range_count);  assert(data->srange_count < sizeof(data->sranges) / sizeof(data->sranges[0]));  // Read and byteswap the range data  for (i = 0; i < data->srange_count; i++)  {    r = ((int16_t) ntohs(ndata.ranges[i])) / 1000.0;    data->sranges[i] = r;  }  return;}////////////////////////////////////////////////////////////////////////////////// Set up the laserint AdaptiveMCL::SetupLaser(void){  uint8_t req;  uint16_t reptype;  player_device_id_t id;  player_laser_geom_t geom;  struct timeval tv;  // If there is no laser device...  if (this->laser_index < 0)    return 0;  id.code = PLAYER_LASER_CODE;  id.index = this->laser_index;  this->laser = deviceTable->GetDevice(id);  if (!this->laser)  {    PLAYER_ERROR("unable to locate suitable laser device");    return -1;  }  if (this->laser->Subscribe(this) != 0)  {    PLAYER_ERROR("unable to subscribe to laser device");    return -1;  }  // Get the laser geometry  req = PLAYER_LASER_GET_GEOM;  if (this->laser->Request(&id, this, &req, 1, &reptype, &tv, &geom, sizeof(geom)) < 0)  {    PLAYER_ERROR("unable to get laser geometry");    return -1;  }  this->laser_pose.v[0] = ((int16_t) ntohl(geom.pose[0])) / 1000.0;  this->laser_pose.v[1] = ((int16_t) ntohl(geom.pose[1])) / 1000.0;  this->laser_pose.v[2] = ((int16_t) ntohl(geom.pose[2])) * M_PI / 180.0;  return 0;}////////////////////////////////////////////////////////////////////////////////// Shut down the laserint AdaptiveMCL::ShutdownLaser(void){  // If there is no laser device...  if (this->laser_index < 0)    return 0;    this->laser->Unsubscribe(this);  this->laser = NULL;    return 0;}////////////////////////////////////////////////////////////////////////////////// Check for new laser datavoid AdaptiveMCL::GetLaserData(amcl_sensor_data_t *data){  int i;  size_t size;  player_laser_data_t ndata;  double r, b, db;    // If there is no laser device...  if (this->laser_index < 0)  {    data->range_count = 0;    return;  }  // Get the laser device data.  size = this->laser->GetData(this, (uint8_t*) &ndata, sizeof(ndata), NULL, NULL);  b = ((int16_t) ntohs(ndata.min_angle)) / 100.0 * M_PI / 180.0;  db = ((int16_t) ntohs(ndata.resolution)) / 100.0 * M_PI / 180.0;  data->range_count = ntohs(ndata.range_count);  assert(data->range_count < sizeof(data->ranges) / sizeof(data->ranges[0]));  // Read and byteswap the range data  for (i = 0; i < data->range_count; i++)  {    r = ((int16_t) ntohs(ndata.ranges[i])) / 1000.0;    data->ranges[i][0] = r;    data->ranges[i][1] = b;    b += db;  }    return;}////////////////////////////////////////////////////////////////////////////////// Get the current pose.  This function is called by the server thread.size_t AdaptiveMCL::GetData(void* client, unsigned char* dest, size_t len,                            uint32_t* time_sec, uint32_t* time_usec){  int i, j, k;  int datalen;  player_localize_data_t data;  pf_vector_t odom_pose, odom_diff;  pf_vector_t pose;  pf_matrix_t pose_cov;  amcl_sensor_data_t sdata;  amcl_hyp_t *hyp;  double scale[3];    this->Lock();  // See if there is new odometry data.  If there is, push it and all  // the rest of the sensor data onto the sensor queue.  this->GetOdomData(&sdata);  // See how far the robot has moved  odom_pose = sdata.odom_pose;  odom_diff = pf_vector_coord_sub(odom_pose, this->odom_pose);  // Make sure we have moved a reasonable distance  if (fabs(odom_diff.v[0]) > 0.20 ||      fabs(odom_diff.v[1]) > 0.20 ||      fabs(odom_diff.v[2]) > M_PI / 6)  {    this->odom_pose = sdata.odom_pose;    // Get the current sonar data; we assume it is new data    this->GetSonarData(&sdata);    // Get the current laser data; we assume it is new data    this->GetLaserData(&sdata);    // Push the data    this->Push(&sdata);  }    // Compute the change in odometric pose  odom_diff = pf_vector_coord_sub(odom_pose, this->pf_odom_pose);  // Record the number of pending observations  data.pending_count = this->q_len;  data.pending_time_sec = this->pf_odom_time_sec;  data.pending_time_usec = this->pf_odom_time_usec;    // Encode the hypotheses  data.hypoth_count = this->hyp_count;  for (i = 0; i < this->hyp_count; i++)  {    hyp = this->hyps + i;    // Get the current estimate    pose = hyp->pf_pose_mean;    pose_cov = hyp->pf_pose_cov;    // Translate/rotate the hypotheses to take account of latency in filter    pose = pf_vector_coord_add(odom_diff, pose);    // Check for bad values    if (!pf_vector_finite(pose))    {      pf_vector_fprintf(pose, stderr, "%e");      assert(0);    }    if (!pf_matrix_finite(pose_cov))    {      pf_matrix_fprintf(pose_cov, stderr, "%e");      assert(0);    }    scale[0] = 1000;    scale[1] = 1000;    scale[2] = 3600 * 180 / M_PI;        data.hypoths[i].alpha = (uint32_t) (hyp->weight * 1e6);            data.hypoths[i].mean[0] = (int32_t) (pose.v[0] * scale[0]);    data.hypoths[i].mean[1] = (int32_t) (pose.v[1] * scale[1]);    data.hypoths[i].mean[2] = (int32_t) (pose.v[2] * scale[2]);      data.hypoths[i].cov[0][0] = (int64_t) (pose_cov.m[0][0] * scale[0] * scale[0]);    data.hypoths[i].cov[0][1] = (int64_t) (pose_cov.m[0][1] * scale[1] * scale[1]);    data.hypoths[i].cov[0][2] = 0;      data.hypoths[i].cov[1][0] = (int64_t) (pose_cov.m[1][0] * scale[0] * scale[0]);    data.hypoths[i].cov[1][1] = (int64_t) (pose_cov.m[1][1] * scale[1] * scale[1]);    data.hypoths[i].cov[1][2] = 0;    data.hypoths[i].cov[2][0] = 0;    data.hypoths[i].cov[2][1] = 0;    data.hypoths[i].cov[2][2] = (int64_t) (pose_cov.m[2][2] * scale[2] * scale[2]);  }  this->Unlock();    // Compute the length of the data packet  datalen = sizeof(data) - sizeof(data.hypoths) + data.hypoth_count * sizeof(data.hypoths[0]);  // Byte-swap  data.pending_count = htons(data.pending_count);

⌨️ 快捷键说明

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