fsmloc.c

00001 /*
00002  *  @(#)locfsm.c                07/04/19
00003  *
00004  * Finite state machine of the localization part.
00005  *
00006  * Copyright    : (c) 2007 DCE Eurobot Dragon Team
00007  *                CTU FEE - Department of Control Engineering
00008  * Contacts     : Tran Duy Khanh <trandk1@fel.cvut.cz>
00009  * License      : GNU GPL v.2
00010  */
00011 
00012 #define FSM_LOC
00013 #include <math.h>
00014 #include <robomath.h>
00015 #include <laser-nav.h>
00016 #include <mcl.h>
00017 #include "robot.h"
00018 #include <fsm.h>
00019 #include "fsmmain.h"
00020 
00021 void loc_pln_update();
00022 int loc_mcl_update(struct mcl_model *mcl, double dx, double dy, double dangle);
00023 void dbg_print_parts();
00024 
00025 FSM_STATE_DECL(loc_init);
00026 FSM_STATE_DECL(loc_run);
00027 FSM_STATE_DECL(loc_mcl_init);
00028 FSM_STATE_DECL(loc_update);
00029 
00033 FSM_STATE(loc_init)
00034 {
00035         /* set reference points. Used to calculate position of the robot
00036          * using laser */
00037         pln_set_points();
00038         FSM_TIMEOUT(1000);
00039         FSM_TRANSITION(loc_mcl_init);
00040 }
00041 
00045 FSM_STATE(loc_mcl_init)
00046 {
00047         struct mcl_model *mcl = (struct mcl_model *)&robot.mcl;
00048 
00049         /* playground size */
00050         mcl->width = PLAYGROUND_WIDTH_MM;
00051         mcl->height = PLAYGROUND_HEIGHT_MM;
00052 
00053         /* the noises */
00054         mcl->gen_dnoise = 0.99;         /* distance noise */
00055         mcl->gen_anoise = DEGREES(10);  /* angle noise */
00056         mcl->mov_dnoise = 1.1;
00057         mcl->mov_anoise = 2.0;
00058         mcl->w_min = 0.25;
00059         mcl->w_max = 2.0;
00060         mcl->eval_sigma = 0.5;
00061         mcl->maxavdist = 50;
00062         mcl->maxnoisecycle = 10;        /* bad cycles before reseting */
00063 
00064         /* amount of particles */
00065         mcl->count = 5000;
00066         mcl->parts = (struct mcl_particle *)
00067                         malloc(sizeof(struct mcl_particle)*mcl->count);
00068 
00069         /* phases of the MCL */
00070         mcl->init = mcl_init;
00071         mcl->move = mcl_move;
00072         mcl->update = mcl_update;
00073         mcl->normalize = mcl_normalize;
00074         mcl->sort = mcl_partsort;
00075         mcl->resample = mcl_resample;
00076 
00077         /* cycles of enumeration */
00078         mcl->cycle = 0;
00079         mcl->noisecycle = 0;
00080 
00081         /* generate particles with noises */
00082         mcl->init(mcl);
00083         printf("loc_mcl_init: done\n");
00084 
00085         /* change flag */
00086         mcl->flag = MCL_RUN;
00087 
00088         /* print generated particles */
00089         /*dbg_print_parts();*/
00090 
00091         FSM_TRANSITION(loc_run);
00092 }
00093 
00097 FSM_STATE(loc_run)
00098 {
00099         DBG_PRINT_EVENT("loc_run event:");
00100 
00101         FSM_TIMEOUT(1000);
00102         switch (FSM_EVENT) {
00103                 case EV_LOC_INIT:
00104                         /*DBG_PRINT_EVENT("mcl_init event:");*/
00105                         FSM_TRANSITION(loc_mcl_init);
00106                         break;
00107                 case EV_TIMEOUT:
00108 //                      FIXME: dont forget to uncomment the break expression bellow
00109 //                      when the laser works.
00110 //                      DBG_PRINT_EVENT("timeout event:");
00111 //                      break;
00112                 case EV_LOC_LOCATE:
00113                 case EV_LASER_RECEIVED:
00114                         SUBFSM_TRANSITION(loc_update);
00115                         break;
00116                 default:
00117                         /*DBG_PRINT_EVENT("loc_run:unhandled event:");*/
00118                         ;
00119         }
00120 }
00121 
00126 FSM_STATE(loc_update)
00127 {
00128         int dx, dy, dangle;
00129         int rv;
00130 
00131         DBG_PRINT_EVENT("loc_update:");
00132 
00133         /* FIXME: here should be data from the odometry */
00134         ROBOT_LOCK(act_pos);
00135         dx = 1.0;
00136         dy = 1.0;
00137         dangle = 0.0;
00138         ROBOT_UNLOCK(act_pos);
00139 
00140         /* calculate measured position */
00141         loc_pln_update();
00142 
00143         /* update mcl with measured position */
00144         rv = loc_mcl_update(&robot.mcl, (double)dx, (double)dy, (double)dangle);
00145 
00146         /* send update signal if mcl update has finished successful */
00147         if (!rv)
00148                 FSM_SIGNAL(MOTION, EV_LOC_UPDATED);
00149         else {
00150                 printf("MCL_RESET: LOST!\n");
00151                 FSM_SIGNAL(MOTION, EV_LOC_LOST);
00152         }
00153 
00154         SUBFSM_RET();
00155 }
00156 
00160 void loc_pln_update()
00161 {
00162         struct pln_pos_state _act_pos;
00163         struct pln_pos_state _cal_pos;
00164         unsigned int times[LAS_CNT], cnt;
00165         int i;
00166 
00167         /* measured times from laser beacon */
00168         ROBOT_LOCK(laser_recv);
00169         /* FIXME: just a hack, until the laser will 
00170          * work correctly */
00171         robot.laser_recv.cnt = 5;
00172         robot.laser_recv.period = 54619;
00173         robot.laser_recv.measures[0] = 1714;
00174         robot.laser_recv.measures[1] = 12312;
00175         robot.laser_recv.measures[2] = 34549;
00176         robot.laser_recv.measures[3] = 41231;
00177         robot.laser_recv.measures[4] = 49670;
00178 
00179         cnt = robot.laser_recv.cnt + 1;
00180         times[0] = robot.laser_recv.period;
00181         for (i=0; i<robot.laser_recv.cnt; i++)
00182                 times[i+1] = robot.laser_recv.measures[i];
00183         ROBOT_UNLOCK(laser_recv);
00184 
00185 //      printf("cnt=%d period=%d measures: ", 
00186 //              robot.laser_recv.cnt, robot.laser_recv.period);
00187 //      for (i=0; i<robot.laser_recv.cnt; i++) {
00188 //              printf("%d ", robot.laser_recv.measures[i]);
00189 //      }
00190 //      printf("\n");
00191         printf("times:");
00192         for (i=0; i<cnt; i++)
00193                 printf("%d ", times[i]);
00194         printf("\n");
00195 
00196         /* actual position */
00197         /*ROBOT_LOCK(act_pos);
00198         _act_pos.x = robot.act_pos.x;
00199         _act_pos.y = robot.act_pos.y;
00200         _act_pos.head = robot.act_pos.phi;
00201         ROBOT_UNLOCK(act_pos);*/
00202         /* FIXME: this stays here just until the odometry will be done */
00203         _act_pos.x = 500;
00204         _act_pos.y = 1600;
00205         _act_pos.head = 0;
00206         printf("act: x=%f y=%f h=%f\n", _act_pos.x, _act_pos.y, _act_pos.head);
00207 
00208         /* calculated measured position */
00209         pln_cal_position(times, cnt, _act_pos, &_cal_pos);
00210         printf("calculated posititon: [x=%f,y=%f]\n", _cal_pos.x, _cal_pos.y);
00211 
00212         /* set currently calculated position */
00213         ROBOT_LOCK(est_pos);
00214         robot.est_pos.x = _cal_pos.x;
00215         robot.est_pos.y = _cal_pos.y;
00216         robot.est_pos.phi = _cal_pos.head;
00217         ROBOT_UNLOCK(est_pos);
00218 }
00219 
00228 int loc_mcl_update(struct mcl_model *mcl, double dx, double dy, double dangle)
00229 {
00230         struct mcl_particle est_pos;
00231         struct mcl_particle cal_pos;
00232 
00233         /* get calculated position by laser */
00234         ROBOT_LOCK(est_pos);
00235         cal_pos.x = robot.est_pos.x;
00236         cal_pos.y = robot.est_pos.y;
00237         cal_pos.angle = robot.est_pos.phi;
00238         ROBOT_UNLOCK(est_pos);
00239 
00240         mcl->cycle++;
00241         printf("loc_mcl_update: cycle = %d\n", mcl->cycle);
00242 
00243         /* move particles */
00244         mcl->move(mcl, dx, dy, dangle);
00245 
00246         /* update particles with calculated position from measured times */
00247         mcl->update(mcl, cal_pos.x, cal_pos.y, cal_pos.angle);
00248 
00249         /* we got lost, reset mcl */
00250         if (mcl->flag == MCL_RESET)
00251                 return 1;
00252 
00253         mcl->normalize(mcl);
00254         mcl->sort(mcl);
00255         mcl->resample(mcl);
00256         est_pos = mcl_get_pos(mcl);
00257 
00258         ROBOT_LOCK(est_pos);
00259         robot.est_pos.x = est_pos.x;
00260         robot.est_pos.y = est_pos.y;
00261         robot.est_pos.phi = est_pos.angle;
00262         ROBOT_UNLOCK(est_pos);
00263 
00264         printf("estimated position: %f %f %f %f\n", 
00265                 est_pos.x, est_pos.y, est_pos.angle, est_pos.weight);
00266 
00267         return 0;
00268 }
00269 
00270 /* Debug prints */
00271 void dbg_print_parts()
00272 {
00273         int i;
00274 
00275         for (i=0; i<robot.mcl.count; i++)
00276                 printf("%d) x=%f y=%f a=%f w=%f\n", 
00277                         i,
00278                         ((struct mcl_particle *)(robot.mcl.parts))[i].x,
00279                         ((struct mcl_particle *)(robot.mcl.parts))[i].y,
00280                         ((struct mcl_particle *)(robot.mcl.parts))[i].angle,
00281                         ((struct mcl_particle *)(robot.mcl.parts))[i].weight);
00282         printf("robot: x=%f y=%f angle=%f\n",
00283                 ((struct mcl_particle *)(robot.mcl.system))->x,
00284                 ((struct mcl_particle *)(robot.mcl.system))->y,
00285                 ((struct mcl_particle *)(robot.mcl.system))->angle);
00286 
00287 }

Generated on Thu Sep 13 11:28:28 2007 for DCE-Eurobot by  doxygen 1.5.3