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/UKF.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 "Psycho/EyeSFile.H"
00047
00048
00049 class EyeFilter : public UKF
00050 {
00051 public:
00052 EyeFilter() :
00053 UKF(6, 2)
00054 {
00055
00056
00057 itsState.setVal(0,0, 640/2);
00058 itsState.setVal(0,1, 480/2);
00059 itsState.setVal(0,2, 0);
00060 itsState.setVal(0,3, 0);
00061 itsState.setVal(0,4, 0);
00062 itsState.setVal(0,5, 0);
00063
00064
00065 itsSigma.setVal(0,0,100.0*100.0);
00066 itsSigma.setVal(1,1,100.0*100.0);
00067 itsSigma.setVal(2,2,0.01*0.01);
00068 itsSigma.setVal(3,3,0.01*0.01);
00069 itsSigma.setVal(4,4,0.01*0.01);
00070 itsSigma.setVal(5,5,0.01*0.01);
00071
00072 double posVar=4;
00073 double velVar=0.1;
00074 double accVar=0.1;
00075
00076 itsR.setVal(0,0,posVar);
00077 itsR.setVal(1,1,posVar);
00078 itsR.setVal(2,2,velVar);
00079 itsR.setVal(3,3,velVar);
00080 itsR.setVal(4,4,accVar);
00081 itsR.setVal(5,5,accVar);
00082 }
00083
00084 ~EyeFilter() {};
00085
00086 Image<double> getNextState(const Image<double>& X, int k)
00087 {
00088 double posX = X.getVal(k,0);
00089 double posY = X.getVal(k,1);
00090 double velX = X.getVal(k,2);
00091 double velY = X.getVal(k,3);
00092 double accX = X.getVal(k,4);
00093 double accY = X.getVal(k,5);
00094
00095 Image<double> Xnew(1,itsNumStates, ZEROS);
00096 Xnew[0] = posX + velX;
00097 Xnew[1] = posY + velY;
00098 Xnew[2] = velX + accX;
00099 Xnew[3] = velY + accY;
00100 Xnew[4] = accX;
00101 Xnew[5] = accY;
00102
00103 return Xnew;
00104 }
00105
00106 Image<double> getObservation(const Image<double>& X, int k)
00107 {
00108 double posX = X.getVal(k,0);
00109 double posY = X.getVal(k,1);
00110
00111
00112 Image<double> zNew(1,itsNumObservations, ZEROS);
00113 zNew[0] = posX;
00114 zNew[1] = posY;
00115 return zNew;
00116 }
00117
00118 Point2D<double> getPos() { return Point2D<double>(itsState[0], itsState[1]); }
00119 Point2D<double> getVel() { return Point2D<double>(itsState[2], itsState[3]); }
00120 Point2D<double> getAcc() { return Point2D<double>(itsState[4], itsState[5]); }
00121
00122 void getPosEllipse(Point2D<float>& mu, Point2D<float>& sigma)
00123 {
00124
00125 mu.i = itsState[0];
00126 mu.j = itsState[1];
00127
00128
00129
00130 sigma = Point2D<float>(2*sqrt(itsSigma.getVal(0,0)),
00131 2*sqrt(itsSigma.getVal(1,1)));
00132 }
00133
00134
00135 };
00136
00137
00138 int main(int argc, char *argv[]){
00139
00140 ModelManager manager("ShowEyePos");
00141
00142 nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager));
00143 manager.addSubComponent(ofs);
00144
00145 nub::ref<EyeSFile> eyeS(new EyeSFile(manager));
00146 manager.addSubComponent(eyeS);
00147
00148
00149 if (manager.parseCommandLine(argc, argv, "<velocity threshold> <delay>", 2, 2) == false) return(1);
00150
00151 manager.start();
00152
00153 double velThresh = atof(manager.getExtraArg(0).c_str());
00154 int delay = atoi(manager.getExtraArg(1).c_str());
00155
00156
00157
00158 EyeFilter eyeFilter;
00159
00160
00161 double pVar=3.0;
00162 Image<double> zNoise(2,2,ZEROS);
00163 zNoise.setVal(0,0,pVar*pVar);
00164 zNoise.setVal(1,1,pVar*pVar);
00165
00166
00167 Point2D<float> lastSaccLoc;
00168
00169 Point2D<float> eyeLoc = eyeS->getPos();
00170 while(eyeLoc.isValid())
00171 {
00172
00173 eyeFilter.predictState();
00174 eyeFilter.predictObservation(zNoise);
00175
00176
00177
00178 Image<double> z(1,2,ZEROS);
00179 z[0] = eyeLoc.i; z[1] = eyeLoc.j;
00180 eyeFilter.update(z, zNoise);
00181
00182
00183
00184 Point2D<double> pos = eyeFilter.getPos();
00185 Point2D<double> vel = eyeFilter.getVel();
00186 Point2D<double> acc = eyeFilter.getAcc();
00187
00188
00189
00190 Image<PixRGB<byte> > display(eyeS->getRawInputDims(),ZEROS);
00191
00192
00193 drawCircle(display, (Point2D<int>)eyeLoc, 2, PixRGB<byte>(0,255,0), 2);
00194
00195
00196 Point2D<float> mu, sigma;
00197 eyeFilter.getPosEllipse(mu,sigma);
00198
00199 if (vel.magnitude() > velThresh)
00200 {
00201 drawCircle(display, (Point2D<int>)mu, 3, PixRGB<byte>(0,0,255), 3);
00202 drawLine(display, (Point2D<int>)lastSaccLoc, (Point2D<int>)mu, PixRGB<byte>(255,255,255), 3);
00203 } else {
00204 drawCircle(display, (Point2D<int>)mu, 1, PixRGB<byte>(255,0,0), 1);
00205 lastSaccLoc = mu;
00206 }
00207
00208
00209 if (sigma.i < 500 && sigma.j < 500)
00210 drawEllipse(display, (Point2D<int>)mu, sigma.i,sigma.j, PixRGB<byte>(255,0,0));
00211
00212
00213
00214 char msg[255];
00215 sprintf(msg, "Pos: %0.1fx%0.1f", pos.i, pos.j);
00216 writeText(display, Point2D<int>(0,0), msg,
00217 PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0));
00218 sprintf(msg, "Vel: %0.2f", vel.magnitude());
00219 writeText(display, Point2D<int>(0,20), msg,
00220 PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0));
00221 sprintf(msg, "Acc: %0.2f", acc.magnitude());
00222 writeText(display, Point2D<int>(0,40), msg,
00223 PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0));
00224
00225
00226 ofs->writeRGB(display, "EyeMovement", FrameInfo("EyeMovement", SRC_POS));
00227
00228 eyeLoc = eyeS->getPos();
00229
00230 usleep(delay);
00231 }
00232
00233
00234
00235 manager.stop();
00236 exit(0);
00237
00238 }
00239
00240