00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "BayesFilters/ParticleFilter.H"
00037 #include "Component/ModelManager.H"
00038 #include "Raster/GenericFrame.H"
00039 #include "Image/Layout.H"
00040 #include "Image/MatrixOps.H"
00041 #include "Image/DrawOps.H"
00042 #include "GUI/DebugWin.H"
00043 #include "Util/MathFunctions.H"
00044 #include "Media/FrameSeries.H"
00045 #include "Transport/FrameInfo.H"
00046 #include "Image/Point3D.H"
00047
00048
00049
00050
00051
00052 class ParticleTracker : public ParticleFilter
00053 {
00054 public:
00055 ParticleTracker(int numStates, int numObservations, int numParticles) :
00056 ParticleFilter(numStates, numObservations, numParticles)
00057 {
00058
00059 }
00060
00061 ~ParticleTracker() {};
00062
00063 Image<double> getNextState(const Image<double>& X)
00064 {
00065
00066 double processMean = -0.1;
00067 double processSigma = 0.075;
00068 double processScale = 0.4;
00069
00070 double posX = X.getVal(0,0);
00071
00072 processMean = processMean + ((posX - processMean)*processScale) +
00073 processSigma * gaussianRand();
00074
00075 Image<double> Xnew(1,itsNumStates, ZEROS);
00076 Xnew[0] = processMean;
00077
00078 return Xnew;
00079 }
00080
00081 Image<double> getObservation(const Image<double>& X)
00082 {
00083 double posX = X.getVal(0,0);
00084
00085 Image<double> zNew(1,itsNumObservations, ZEROS);
00086 zNew[0] = posX;
00087 return zNew;
00088 }
00089
00090 };
00091
00092 std::vector<int> getIntervals(int n, int polyDegree)
00093 {
00094 std::vector<int> intervals(n+polyDegree+1);
00095
00096 for (int j=0; j<=n+polyDegree; j++)
00097 {
00098 if (j<polyDegree)
00099 intervals[j]=0;
00100 else
00101 if ((polyDegree<=j) && (j<=n))
00102 intervals[j]=j-polyDegree+1;
00103 else
00104 if (j>n)
00105 intervals[j]=n-polyDegree+2;
00106 }
00107
00108 return intervals;
00109
00110 }
00111
00112
00113 double blend(int k, int t, std::vector<int>& intervals, double v)
00114 {
00115 double value;
00116
00117 if (t==1)
00118 {
00119 if ((intervals[k]<=v) && (v<intervals[k+1]))
00120 value=1;
00121 else
00122 value=0;
00123 } else {
00124 if ((intervals[k+t-1]==intervals[k]) && (intervals[k+t]==intervals[k+1]))
00125 value = 0;
00126 else
00127 if (intervals[k+t-1]==intervals[k])
00128 value = (intervals[k+t] - v) / (intervals[k+t] - intervals[k+1]) * blend(k+1, t-1, intervals, v);
00129 else
00130 if (intervals[k+t]==intervals[k+1])
00131 value = (v - intervals[k]) / (intervals[k+t-1] - intervals[k]) * blend(k, t-1, intervals, v);
00132 else
00133 value = (v - intervals[k]) / (intervals[k+t-1] - intervals[k]) * blend(k, t-1, intervals, v) +
00134 (intervals[k+t] - v) / (intervals[k+t] - intervals[k+1]) * blend(k+1, t-1, intervals, v);
00135 }
00136
00137 return value;
00138
00139
00140
00141 }
00142
00143
00144 double getWeight(int k, double s)
00145 {
00146
00147 double weight = 0;
00148
00149 if (0 <= s && s < 1)
00150 weight = (s*s)/2;
00151 else if (1 <= s && s < 2)
00152 weight = (3/4)-((s-(3/2))*(s-(3/2)));
00153 else if (2 <= s && s < 3)
00154 weight = ((s-3)*(s-3))/2;
00155
00156 return weight;
00157 }
00158
00159 void drawBSpline(std::vector<Point3D<float> >& controlPoints)
00160 {
00161
00162 int numOutput = 100;
00163 int polyDegree = 3;
00164
00165 std::vector<int> intervals = getIntervals(controlPoints.size()-1, polyDegree);
00166 double incr = 1.0/double(controlPoints.size()-1);
00167 LINFO("Inc %f", incr);
00168
00169 std::vector<Point3D<float> > points;
00170 double interval = 0;
00171 for(int outputIndex=0; outputIndex<numOutput; outputIndex++)
00172 {
00173
00174 Point3D<float> point(0,0,0);
00175 for(uint k=0; k<controlPoints.size(); k++)
00176 {
00177 double blendVal = blend(k,polyDegree, intervals, interval);
00178
00179 point.x += blendVal*controlPoints[k].x;
00180 point.y += blendVal*controlPoints[k].y;
00181 point.z += blendVal*controlPoints[k].z;
00182 }
00183
00184 LINFO("Point %f %f", point.x, point.y);
00185 points.push_back(point);
00186 interval += incr;
00187 }
00188
00189
00190
00191 LINFO("Draw");
00192 Image<PixRGB<byte> > tmp(640,480,ZEROS);
00193 for(uint i=0; i<controlPoints.size(); i++)
00194 {
00195 Point2D<int> cLoc = Point2D<int>(controlPoints[i].x,controlPoints[i].y);
00196 drawCircle(tmp, cLoc, 3, PixRGB<byte>(0,255,0));
00197 }
00198
00199 for(uint i=0; i<points.size()-10; i++)
00200 {
00201 Point2D<int> loc = Point2D<int>(points[i].x,points[i].y);
00202 Point2D<int> loc2 = Point2D<int>(points[(i+1)%points.size()].x,points[(i+1)%points.size()].y);
00203 drawLine(tmp, loc, loc2, PixRGB<byte>(255,0,0));
00204
00205
00206 }
00207 SHOWIMG(tmp);
00208
00209
00210 }
00211
00212
00213 int main(int argc, char *argv[]){
00214
00215 ModelManager manager("Test UKF");
00216
00217 nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager));
00218 manager.addSubComponent(ofs);
00219
00220
00221 if (manager.parseCommandLine(argc, argv, "", 0, 0) == false) return(1);
00222
00223 manager.start();
00224
00225 std::vector<Point3D<float> > controlPoints;
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 controlPoints.push_back(Point3D<float>(50*2.75,50*5.25,0));
00236 controlPoints.push_back(Point3D<float>(50*3.28,50*7.07,0));
00237 controlPoints.push_back(Point3D<float>(50*6.61,50*7.08,0));
00238 controlPoints.push_back(Point3D<float>(50*6.85,50*5.19,0));
00239 controlPoints.push_back(Point3D<float>(50*5.29,50*4.00,0));
00240 controlPoints.push_back(Point3D<float>(50*5.67,50*1.28,0));
00241 controlPoints.push_back(Point3D<float>(50*4.12,50*1.28,0));
00242 controlPoints.push_back(Point3D<float>(50*4.33,50*4.04,0));
00243
00244
00245 drawBSpline(controlPoints);
00246
00247
00248 ParticleTracker pt(4,2, 1000);
00249
00250
00251 Image<PixRGB<byte> > worldImg(640,480,ZEROS);
00252
00253 double processMean = -0.1;
00254 double processSigma = 0.4;
00255 double scaling = 0.075;
00256
00257
00258
00259 for(uint t=0; t<100; t++)
00260 {
00261 double truePosition = processMean;
00262
00263 processMean = processMean + ((truePosition - processMean)*scaling) +
00264 processSigma * pt.gaussianRand();
00265
00266 pt.predictState();
00267
00268
00269 Image<double> z(1,1,ZEROS);
00270 z[0] = processMean + processSigma*pt.gaussianRand();
00271 pt.update(z);
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 getchar();
00284 }
00285
00286 exit(0);
00287
00288 }
00289
00290