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
00037
00038 #include "Robots/Beobot2/Navigation/Gist_Navigation/Gist_Navigation.H"
00039 #include "Ice/BeobotEvents.ice.H"
00040
00041 #include "Raster/Raster.H"
00042 #include "Util/sformat.H"
00043 #include "Image/Image.H"
00044 #include "Image/DrawOps.H"
00045 #include "Image/ColorOps.H"
00046 #include "Image/MathOps.H"
00047 #include "Image/MatrixOps.H"
00048 #include "Image/CutPaste.H"
00049
00050
00051 #include "SIFT/Keypoint.H"
00052 #include "SIFT/VisualObject.H"
00053 #include "SIFT/VisualObjectMatch.H"
00054 #include "Transport/FrameInfo.H"
00055
00056 #include "Ice/IceImageUtils.H"
00057
00058 #include "Gist/trainUtils.H"
00059
00060 #define GIST_DATA_FOLDER "../data/train/gistFeat/"
00061 #define TRAIN_DATA_FOLDER "../data/train/"
00062 #define LEARN_RATE 0.025
00063 #define NUM_DIRECTIONS 13
00064
00065
00066 Gist_Navigation::Gist_Navigation(OptionManager& mgr,
00067 const std::string& descrName, const std::string& tagName) :
00068 RobotBrainComponent(mgr, descrName, tagName),
00069 itsFftComputer(new GistEstimatorFFT(mgr)),
00070 itsOfs(new OutputFrameSeries(mgr)),
00071 itsFfn(new FeedForwardNetwork()),
00072 itsTimer(1000000),
00073 itsCurrImgID(-1),
00074 itsPrevProcImgID(-1)
00075 {
00076
00077 addSubComponent(itsOfs);
00078
00079
00080 initFFN();
00081
00082
00083 itsPcaIcaVector =
00084 setupPcaIcaMatrix("../data/train/E_FastICA.evec", 640, 40);
00085 }
00086
00087
00088 void Gist_Navigation::initFFN()
00089 {
00090
00091
00092
00093
00094
00095
00096
00097 itsFfn->init3L
00098 (sformat("%sh1.nnwt",TRAIN_DATA_FOLDER),
00099 sformat("%sh2.nnwt",TRAIN_DATA_FOLDER),
00100 sformat("%so.nnwt", TRAIN_DATA_FOLDER),
00101 40, 100, 50, NUM_DIRECTIONS, LEARN_RATE, 0.0);
00102 }
00103
00104
00105 Gist_Navigation::~Gist_Navigation()
00106 { }
00107
00108
00109 void Gist_Navigation::start1()
00110 {
00111 }
00112
00113
00114 void Gist_Navigation::registerTopics()
00115 {
00116
00117 this->registerSubscription("CameraMessageTopic");
00118 this->registerSubscription("MotorMessageTopic");
00119 this->registerPublisher("MotorRequestTopic");
00120 }
00121
00122
00123 void Gist_Navigation::evolve()
00124 {
00125
00126 its_Curr_Img_mutex.lock();
00127 bool newImageFlag = (itsPrevProcImgID < itsCurrImgID);
00128 its_Curr_Img_mutex.unlock();
00129
00130
00131 if(newImageFlag)
00132 {
00133 itsTimer.reset();
00134
00135 its_Curr_Img_mutex.lock();
00136 itsProcImg = itsCurrImg;
00137 itsPrevProcImgID = itsCurrImgID;
00138 its_Curr_Img_mutex.unlock();
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 itsNormalizedProcImg = normalize(Image<float>(luminance(itsProcImg)));
00151
00152
00153 itsFftComputer->computeGistFeatureVector(itsNormalizedProcImg);
00154 itsFftFeatures = itsFftComputer->getGist();
00155
00156
00157 Image<double> in = matrixMult(itsPcaIcaVector, itsFftFeatures);
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 itsFfn->run3L(in);
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 itsNNrotCommand.resize(1, NUM_DIRECTIONS, ZEROS);
00207 itsRCrotCommand.resize(1, NUM_DIRECTIONS, ZEROS);
00208 double sum = 0.0;
00209
00210 uint dir = 0; double max = 0.0;
00211 for(uint i = 0; i < NUM_DIRECTIONS; i++)
00212 {
00213 itsNNrotCommand.setVal
00214 (0, i,
00215 .90 * itsFfn->getOutput().getVal(0,i) +
00216 .10 * (double)rand()/(double)RAND_MAX );
00217 if(itsNNrotCommand.getVal(0, i) > max)
00218 { dir = i; max = itsNNrotCommand.getVal(0, i); }
00219 sum += itsNNrotCommand.getVal(0,i);
00220 }
00221
00222 for(uint i = 0; i < NUM_DIRECTIONS; i++)
00223 {
00224 itsNNrotCommand.setVal(0,i,itsNNrotCommand.getVal(0,i)/sum);
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 int half_ND = NUM_DIRECTIONS/2;
00240 double rot = double(half_ND - int(dir))/double(half_ND);
00241 double trans = 1.0;
00242
00243 LINFO("[R:%f T:%f]", rot, trans);
00244
00245
00246 int rcMode;
00247 double rcTrans, rcRot;
00248 its_Curr_Mtr_mutex.lock();
00249 rcMode = itsRemoteMode;
00250 rcRot = itsRcRotSpeed;
00251 rcTrans = itsRcTransSpeed;
00252 its_Curr_Mtr_mutex.unlock();
00253 LINFO("RC[M:%d R:%f T:%f]", rcMode, rcRot, rcTrans);
00254
00255 for(uint i = 0; i < NUM_DIRECTIONS; i++)
00256 {
00257 itsRCrotCommand.setVal(0,i,0);
00258 }
00259
00260 itsTrainMode = (rcMode == 3 && (rcRot > .1 || rcRot < -.1));
00261 if(itsTrainMode)
00262 {
00263 LINFO("\nTRAINING\n");
00264
00265 uint bDir = uint((half_ND)*(1.0 - rcRot));
00266 if(bDir >=0 && bDir < NUM_DIRECTIONS)
00267 {
00268 itsRCrotCommand.setVal(0, bDir, 1.0);
00269
00270
00271 if (bDir > 0)
00272 itsRCrotCommand.setVal(0, bDir-1, 0.5);
00273 if (bDir > 1)
00274 itsRCrotCommand.setVal(0, bDir-2, 0.25);
00275 if (bDir < NUM_DIRECTIONS - 1)
00276 itsRCrotCommand.setVal(0, bDir+1, 0.5);
00277 if (bDir < NUM_DIRECTIONS - 2)
00278 itsRCrotCommand.setVal(0, bDir+2, 0.25);
00279 }
00280 else LFATAL("CORRUPTED rcRot: %f", rcRot);
00281
00282
00283
00284
00285
00286
00287
00288 itsFfn->backprop3L(itsRCrotCommand);
00289
00290
00291 itsFfn->write3L
00292 (sformat("%sh1.nnwt",TRAIN_DATA_FOLDER),
00293 sformat("%sh2.nnwt",TRAIN_DATA_FOLDER),
00294 sformat("%so.nnwt", TRAIN_DATA_FOLDER));
00295
00296
00297 rot = rcRot;
00298 }
00299
00300
00301
00302
00303
00304 LINFO("Final[T:%f R:%f]", trans, rot);
00305 updateMotor(trans, rot);
00306
00307
00308
00309 }
00310 }
00311
00312
00313
00314 Image<float> Gist_Navigation::normalize(Image<float> img)
00315 {
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 Image<float> tImg = img;
00347 double tMean = float(mean(img));
00348 double tStdev = float(stdev(img));
00349 tImg -= tMean;
00350 tImg /= tStdev;
00351
00352 return tImg;
00353 }
00354
00355
00356 void Gist_Navigation::drawState()
00357 {
00358 uint w = itsProcImg.getWidth();
00359 uint h = itsProcImg.getHeight();
00360
00361 itsDispImg.resize(w*2, 2*h, NO_INIT);
00362
00363
00364 inplacePaste(itsDispImg, itsProcImg, Point2D<int>(0, 0));
00365
00366
00367 Image<float> dispNorm = itsNormalizedProcImg;
00368 inplaceNormalize(dispNorm, 0.0f, 255.0f);
00369 Image<PixRGB<byte> > dn = Image<PixRGB<byte> >(toRGB(dispNorm));
00370 inplacePaste(itsDispImg, dn, Point2D<int>(w, 0));
00371
00372
00373 Image<float> fftImg = itsFftComputer->getFftImage();
00374 inplaceNormalize(fftImg, 0.0f, 255.0f);
00375 Image<PixRGB<byte> > fft = Image<PixRGB<byte> >(toRGB(fftImg));
00376 inplacePaste(itsDispImg, fft, Point2D<int>(0, h));
00377
00378 std::vector<SimpleMeter> NNrotCommandMeters(13,SimpleMeter(20,60,0,100));
00379 std::vector<SimpleMeter> RCrotCommandMeters(13,SimpleMeter(20,60,0,100));
00380
00381 char buffer[128];
00382 for(uint i = 0; i < NUM_DIRECTIONS; i++)
00383 {
00384
00385 sprintf(buffer, "%3d",int(itsNNrotCommand.getVal(i)*100));
00386
00387 Point2D<int> pastePoint = Point2D<int>(
00388 10+NNrotCommandMeters[i].getWidth()*i*1.05+w,
00389 2*h -15
00390 );
00391
00392 writeText(itsDispImg, pastePoint, buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6));
00393
00394 pastePoint = Point2D<int>(
00395 10+NNrotCommandMeters[i].getWidth()*i*1.05+w,
00396 2*h - NNrotCommandMeters[i].getHeight() - 30
00397 );
00398 inplacePaste(itsDispImg, NNrotCommandMeters[i].render(itsNNrotCommand.getVal(i)*100), pastePoint );
00399
00400 sprintf(buffer, "%3d",int(itsRCrotCommand.getVal(i)*100));
00401
00402 pastePoint = Point2D<int>(
00403 10+NNrotCommandMeters[i].getWidth()*i*1.05+w,
00404 2*h - RCrotCommandMeters[i].getHeight() - 45
00405 );
00406
00407 writeText(itsDispImg, pastePoint, buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6));
00408
00409 pastePoint = Point2D<int>(
00410 10+RCrotCommandMeters[i].getWidth()*i*1.05+w,
00411 2*h - 2*RCrotCommandMeters[i].getHeight() - 60
00412 );
00413 inplacePaste(itsDispImg, NNrotCommandMeters[i].render(itsRCrotCommand.getVal(i)*100), pastePoint );
00414 }
00415
00416 }
00417
00418
00419 void Gist_Navigation::updateMessage
00420 (const RobotSimEvents::EventMessagePtr& eMsg, const Ice::Current&)
00421 {
00422
00423 if(eMsg->ice_isA("::BeobotEvents::CameraMessage"))
00424 {
00425
00426 BeobotEvents::CameraMessagePtr cameraMsg =
00427 BeobotEvents::CameraMessagePtr::dynamicCast(eMsg);
00428
00429 int currRequestID = cameraMsg->RequestID;
00430 Image<PixRGB<byte> > img = Ice2Image<PixRGB<byte> >(cameraMsg->image);
00431
00432 LDEBUG("Got a CameraMessage with Request ID = %d", currRequestID);
00433
00434 its_Curr_Img_mutex.lock();
00435 itsCurrImg = img;
00436 itsCurrImgID = cameraMsg->RequestID;
00437 its_Curr_Img_mutex.unlock();
00438 }
00439
00440 else if(eMsg->ice_isA("::BeobotEvents::MotorMessage"))
00441 {
00442 BeobotEvents::MotorMessagePtr mtrMsg =
00443 BeobotEvents::MotorMessagePtr::dynamicCast(eMsg);
00444 LDEBUG("Got a MotorMessage with Request ID = %d: RC Trans %f ,Rc Rot %f",
00445 mtrMsg->RequestID, itsRcTransSpeed, itsRcRotSpeed);
00446 its_Curr_Mtr_mutex.lock();
00447 itsRemoteMode = mtrMsg->rcMode;
00448 itsRcTransSpeed = mtrMsg->rcTransVel;
00449 itsRcRotSpeed = mtrMsg->rcRotVel;
00450 its_Curr_Mtr_mutex.unlock();
00451 }
00452 }
00453
00454
00455 void Gist_Navigation::updateMotor(double tran, double rot)
00456 {
00457 BeobotEvents::MotorRequestPtr msg = new BeobotEvents::MotorRequest;
00458 msg->transVel = tran;
00459 msg->rotVel = rot;
00460 this->publish("MotorRequestTopic", msg);
00461
00462 }
00463
00464
00465
00466
00467
00468