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

📄 rbpf_1.c

📁 一个外国人网站上的资料
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  ratbot-slam (c) 2006 Kris Beevers  This file is part of ratbot-slam.  ratbot-slam 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.  ratbot-slam 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 ratbot-slam; if not, write to the Free Software  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA*/// your basic particle filter (except, with multiscans).  no improved// proposal.#include "ratbot-slam.h"#include <string.h>#include <stdlib.h>#ifdef _TESTING#include <stdio.h>#else#include "rprintf.h"#endif#ifndef _TESTINGvoid printfp(char *pre, fixed_t n){  rprintfStr(pre);  rprintf(" ");  rprintfNum(10, 12, 1, ' ', n);  rprintf("\r\n");}#endiftypedef struct{  // trajectory  pose_t trajectory[TRAJ_STORAGE_SIZE];  int traj_begin, traj_end; // end is 1+index of last valid pose  // map  extent_feature map[MAX_LANDMARKS];  int n; // num landmarks  fixed_t w; // particle weight} particle_t;#ifdef _TESTINGparticle_t *particles = 0;static pose_t multiscan_mu[M];static cov3_t multiscan_cov[M];static int16_t multiscan_ranges[5*M];static int multiscan_count;static pose_t trajectory[N][MAX_TRAJECTORY_LENGTH];static uint32_t traj_count = 0;#else//particle_t *particles = (particle_t *)0x1100; // start of extmem (4352)particle_t *particles = (particle_t *)0x4400; // after all the other fixed-loc storagepose_t *multiscan_mu = (pose_t *)0x1100; // start of extmemcov3_t *multiscan_cov = (cov3_t *)4517;int16_t *multiscan_ranges = (int16_t *)4847;int multiscan_count;#endif//// trajectory and map management//int inc_traj_counter(int count){  ++count;  if(count == TRAJ_STORAGE_SIZE)    count = 0;  return count;}pose_t * traj_current_pose(int particle){  particle_t *p = &particles[particle];  return &(p->trajectory[p->traj_begin]);}// implements a circular bufferpose_t * traj_add_new_pose(int particle){  particle_t *p = &particles[particle];  p->traj_begin = inc_traj_counter(p->traj_begin);  if(p->traj_begin == p->traj_end)    p->traj_end = inc_traj_counter(p->traj_end);  return traj_current_pose(particle);}//// particle filter//void filter_init(const pose_t *start){  int i = 0;  pose_t *p;#ifdef _TESTING  particles = (particle_t *)malloc(N*sizeof(particle_t));#endif  for(; i < N; ++i) {    particles[i].traj_begin = -1;    particles[i].traj_end = 0;    particles[i].n = 0;    particles[i].w = one_over_N;    p = traj_add_new_pose(i);    p->x = start->x;    p->y = start->y;    p->t = start->t;  }  multiscan_count = 0;  multiscan_mu[0].x = start->x;  multiscan_mu[0].y = start->y;  multiscan_mu[0].t = start->t;  multiscan_cov[0].xx = multiscan_cov[0].xy = multiscan_cov[0].xt =    multiscan_cov[0].yy = multiscan_cov[0].yt = multiscan_cov[0].tt = 0;}// gets points corresponding to the range readings from each of the// infrared sensors over the course of the multiscan.  the points are// in the frame of the last multiscan pose.  readings that are outside// the valid range of the sensor are discarded.// it is expensive to compute the real point covariances wrt to the// multiscan frame, including pose uncertainty, etc.  instead we will// compute weights for the points equal to the inverse of the trace of// the pose uncertainty.  these weights will be used in the feature// extraction.void get_multiscan_points  (fixed_t *x, fixed_t *y, fixed_t *u, int *n){  int16_t *scan = multiscan_ranges;  pose_t *pose = multiscan_mu;  cov3_t *cov = multiscan_cov;  *n = 0;  int i = 0, s = 0;  fixed_t range, trace;  pose_t xform;  //  static fixed_t lx[5], ly[5];  fixed_t lx[5], ly[5];  for(; i < M; ++i, s = 0) {    scan = &multiscan_ranges[5*i];    // right back    range = fp_mul(int2fp(scan[0]), CONVERT_IR_RB);    if(range >= IR_MIN && range <= IR_MAX) {      lx[s] = -IR_OFF_X_BACK;      ly[s] = -IR_OFF_Y - range;      ++s;    }    // right front    range = fp_mul(int2fp(scan[1]), CONVERT_IR_RF);    if(range >= IR_MIN && range <= IR_MAX) {      lx[s] = IR_OFF_X_CORNER;      ly[s] = -IR_OFF_Y - range;      ++s;    }    // front    range = fp_mul(int2fp(scan[2]), CONVERT_IR_F);    if(range >= IR_MIN && range <= IR_MAX) {      lx[s] = IR_OFF_X_FRONT + range;      ly[s] = 0;      ++s;    }    // left front    range = fp_mul(int2fp(scan[3]), CONVERT_IR_LF);    if(range >= IR_MIN && range <= IR_MAX) {      lx[s] = IR_OFF_X_CORNER;      ly[s] = IR_OFF_Y + range;      ++s;    }    // left back    range = fp_mul(int2fp(scan[4]), CONVERT_IR_LB);    if(range >= IR_MIN && range <= IR_MAX) {      lx[s] = -IR_OFF_X_BACK;      ly[s] = IR_OFF_Y + range;      ++s;    }    if(s > 0) {      pose = &multiscan_mu[i];      cov = &multiscan_cov[i];#if 0      // FIXME: i really don't want to have to do the work to handle      // orientation uncertainty properly so i'm just doing this for      // now, but i think it's not enough and i'll probably have to      // deal with it, or otherwise inflate the uncertainty      trace = fp_div(fp_1, cov->xx + cov->yy + cov->tt); // FIXME overflow?#endif      // compute the transformation between the current MS pose and      // the final MS pose, which is the origin for the MS      //      xform.x = pose->x - multiscan_mu[M-1].x;      //      xform.y = pose->y - multiscan_mu[M-1].y;      //      xform.t = angular_distance(pose->t, multiscan_mu[M-1].t);      /*      xform.x = multiscan_mu[M-1].x - pose->x;      xform.y = multiscan_mu[M-1].y - pose->y;      xform.t = angular_distance(multiscan_mu[M-1].t, pose->t);      */      xform = *pose;      // transform scan points to this frame      transform_points(lx, ly, s, &xform, x + *n, y + *n);      *n += s;#if 0      // compute "scalar uncertainties" for feature extraction equal      // to the trace of the current pose uncertainty (and increment      // *n)      for(; s > 0; --s, ++(*n))	u[*n] = trace;#endif    }  }#if 0  for(i=0;i<M;++i) {    printf("%g %g %g\r\n", fp2float(multiscan_mu[i].x), fp2float(multiscan_mu[i].y), fp2float(multiscan_mu[i].t));  }  printf("\n\n");#endif}void resample_random(void){  //  printf("resampling\n");  // first, select particle indices with replacement according to the  // weights of the corresponding particles  fixed_t r;  int i = 0, j;  //  static int resample_count[N];  int resample_count[N];  memset(resample_count, 0, N*sizeof(int));  for(; i < N; ++i) {    r = fp_rand_0_1();    for(j = 0; j < N; ++j) {      r -= particles[j].w;      if(r < 0) break;    }    ++resample_count[j];  }  // now, here's a tricky little method for doing the actual copying  // of particles: some particles may have been resampled more than  // once and others not at all.  copy the multiply-resampled ones  // into the not-resampled particles' locations.  particles resampled  // exactly once thus require no copying at all.  int next_zero = 0;  for(i = 0; i < N; ++i) {    while(resample_count[i] > 1) {      while(resample_count[next_zero] != 0)	++next_zero;      memcpy(&(particles[next_zero]), &(particles[i]), sizeof(particle_t));#ifdef _TESTING      memcpy(trajectory[next_zero], trajectory[i], traj_count*sizeof(pose_t));#endif      --resample_count[i];      ++next_zero;    }  }}uint32_t start_predict, tot_predict = 0, num_predict = 0,  start_update, tot_update = 0, num_update = 0;void filter_update(int16_t left, int16_t right, int16_t ir[5]){  //  // first, project the particles and multiscan mean trajectory  // forward according to the motion model  //  pose_t mu;  cov3_t cov;#ifndef _TESTING  TCNT1 = 0;  start_predict = TCNT1;#endif  //  printf("%d %d\n",left,right);  // project particles forward

⌨️ 快捷键说明

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