00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stdlib.h>
00017 #include <math.h>
00018 #include <robomath.h>
00019 #include <string.h>
00020 #include "mcl.h"
00021
00034 void mcl_move(struct mcl_model *mcl, double dx, double dy, double dangle)
00035 {
00036 struct mcl_particle *parts = (struct mcl_particle *)mcl->parts;
00037
00038 int i=0;
00039 double xdiff, ydiff;
00040
00041
00042 for (i=0; i<mcl->count; i++) {
00043 xdiff = dx*cos(parts[i].angle) + dy*sin(parts[i].angle);
00044 ydiff = dy*cos(parts[i].angle) + dx*sin(parts[i].angle);
00045
00046 parts[i].x += xdiff + mcl->mov_dnoise*xdiff*gaussrand();
00047 parts[i].y += ydiff + mcl->mov_dnoise*ydiff*gaussrand();
00048 parts[i].angle += dangle + mcl->mov_anoise*dangle*gaussrand();
00049
00050
00051
00052 }
00053 }
00054
00065 void mcl_update(struct mcl_model *mcl, double x, double y, double angle)
00066 {
00067 struct mcl_particle *parts = (struct mcl_particle *)mcl->parts;
00068 double xdiff, ydiff, dist, avdist=0;
00069 int i;
00070
00071
00072 for (i=0; i<mcl->count; i++) {
00073 xdiff = parts[i].x - x;
00074 ydiff = parts[i].y - y;
00075 dist = fabs(sqrt(xdiff*xdiff + ydiff*ydiff));
00076 avdist += dist;
00077
00078
00079 parts[i].weight *= evaluate_gaussian(dist, mcl->eval_sigma);
00080 }
00081
00082
00083 avdist /= mcl->count;
00084 if (avdist > mcl->maxavdist) {
00085 if (mcl->noisecycle > mcl->maxnoisecycle) {
00086 mcl->flag = MCL_RESET;
00087 return;
00088 } else
00089 mcl->noisecycle++;
00090 }
00091 }
00092
00098 void mcl_normalize(struct mcl_model *mcl)
00099 {
00100 struct mcl_particle *parts = (struct mcl_particle *)mcl->parts;
00101 double gain=0, w=0;
00102 int i;
00103
00104 for (i=0; i<mcl->count; i++)
00105 w += parts[i].weight;
00106 gain = mcl->count / w;
00107
00108 if (gain <= 0)
00109 return;
00110
00111 for (i=0; i<mcl->count; i++)
00112 parts[i].weight *= gain;
00113 }
00114
00115
00116
00117 int compare(const void *a, const void *b)
00118 {
00119 return ((double)(((struct mcl_particle *)a)->weight) >
00120 (double)(((struct mcl_particle *)b)->weight));
00121 }
00122
00128 void mcl_partsort(struct mcl_model *mcl)
00129 {
00130 struct mcl_particle *parts = (struct mcl_particle *)mcl->parts;
00131 qsort(parts, mcl->count, sizeof(struct mcl_particle), compare);
00132 }
00133
00140 void mcl_resample(struct mcl_model *mcl)
00141 {
00142 struct mcl_particle *parts = (struct mcl_particle *)mcl->parts;
00143 int i, j;
00144 int i_max=0, i_min=0;
00145 size_t num = 0;
00146 int count;
00147
00148
00149 for (i=0; i<mcl->count; i++)
00150 if (parts[i].weight > mcl->w_min)
00151 break;
00152 i_min = (i>0) ? i-1: i;
00153
00154
00155 for (i=0; i<mcl->count; i++)
00156 if (parts[i].weight > mcl->w_max)
00157 break;
00158 i_max = (i>0) ? i-1: i;
00159
00160 for (i=i_max; i<mcl->count; i++) {
00161 count = (int)parts[i].weight;
00162 count = (count > 0) ? count : 1;
00163 parts[i].weight /= count;
00164 for (j=num; j<num+count-1; j++)
00165 memcpy(&parts[j], &parts[i],
00166 sizeof(struct mcl_particle));
00167 num += count-1;
00168 }
00169
00170 for (i=num; i<i_min; i++) {
00171 i_max--;
00172 parts[i_max].weight /= 2;
00173 memcpy(&parts[i], &parts[i_max], sizeof(struct mcl_particle));
00174 }
00175 }
00176
00182 void mcl_init (struct mcl_model *mcl)
00183 {
00184 struct mcl_particle *parts = (struct mcl_particle *)mcl->parts;
00185 int i;
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 for (i=0; i<mcl->count; i++) {
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 parts[i].x = (rand()%mcl->width) * mcl->gen_dnoise;
00209 parts[i].y = (rand()%mcl->height) * mcl->gen_dnoise;
00210 parts[i].angle = rand() % (int)mcl->gen_anoise;
00211 parts[i].weight = 1;
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 }
00224 }
00225
00231 inline struct mcl_particle mcl_get_pos(struct mcl_model *mcl)
00232 {
00233 return (((struct mcl_particle *)mcl->parts)[mcl->count-1]);
00234 }
00235