Homepage Demos Overview Downloads Tutorials Reference
Credits

Lookout.cc

Go to the documentation of this file.
00001 //-*-c++-*-
00002 
00003 #include "Events/EventRouter.h"
00004 #include "Events/LocomotionEvent.h"
00005 #include "Events/LookoutEvents.h"
00006 #include "Events/VisionObjectEvent.h"
00007 #include "Motion/HeadPointerMC.h"
00008 #include "Motion/PostureMC.h"
00009 #include "Motion/MMAccessor.h"
00010 #include "Motion/MotionSequenceMC.h"
00011 #include "Motion/MotionManager.h"
00012 #include "Shared/ProjectInterface.h"
00013 #include "Shared/WorldState.h"
00014 #include "Vision/RegionGenerator.h"
00015 
00016 #include "VRmixin.h"
00017 #include "LookoutRequests.h"
00018 #include "Lookout.h"
00019 
00020 namespace DualCoding {
00021 
00022 // some stuff for convenience  
00023 typedef SegmentedColorGenerator::color_class_state color_class_state;
00024 
00025 inline float getIR() {
00026 #ifdef TGT_ERS7 
00027   return state->sensors[NearIRDistOffset];
00028 #else 
00029   return state->sensors[IRDistOffset];
00030 #endif
00031 }
00032 
00033 
00034 Lookout::Lookout()
00035   : BehaviorBase("Lookout"),
00036     pointer_id(MotionManager::invalid_MC_ID), 
00037     sequence_id(MotionManager::invalid_MC_ID), 
00038     requests(), curReq(NULL), landmarkInView(true),
00039     idCounter(0)
00040 {}
00041 
00042 void Lookout::DoStart() {
00043   BehaviorBase::DoStart();
00044 }
00045 
00046 void Lookout::DoStop() {
00047   curReq = NULL;
00048   while (!requests.empty()) {
00049     if (requests.front() != NULL)
00050       delete requests.front();
00051     requests.pop();
00052   }
00053   motman->removeMotion(pointer_id);
00054   pointer_id = MotionManager::invalid_MC_ID;
00055   motman->removeMotion(sequence_id);
00056   sequence_id = MotionManager::invalid_MC_ID;
00057   BehaviorBase::DoStop();
00058 }
00059   /*
00060 
00061 vector<Point> Lookout::getVisionObjectData() {
00062 
00063 }
00064 
00065 vector<Point> Lookout::getIRData() {
00066 
00067 }
00068   */
00069 
00070 void Lookout::processScan(const EventBase& event) {
00071   //  cout << "Lookout::processScan: " << event.getName() << endl;
00072   static bool listeningObjEGID = false;
00073   static ScanRequest* curScanReq = dynamic_cast<ScanRequest*>(curReq);
00074   if (curScanReq != curReq) curScanReq = dynamic_cast<ScanRequest*>(curReq);
00075   switch (event.getGeneratorID()) {
00076   case EventBase::motmanEGID:
00077     if (event.getTypeID() != EventBase::deactivateETID) return;
00078     // head arrived at the start of motion sequence, add listeners and start scan sequence
00079     if (event.getSourceID() == pointer_id) {
00080       pointer_id = MotionManager::invalid_MC_ID;
00081       motman->setPriority(sequence_id,MotionManager::kStdPriority);
00082       MMAccessor<SmallMotionSequenceMC>(sequence_id)->play();
00083       for (unsigned int i = 0; i < curScanReq->tasks.size(); i++) {
00084   const ScanRequest::Task* task = curScanReq->tasks[i];
00085   if (task->getTaskType() == ScanRequest::Task::visObj) {
00086     const ScanRequest::VisionTask& vTask = *dynamic_cast<const ScanRequest::VisionTask*>(task);
00087     for(set<int>::const_iterator color_it = vTask.index.begin();
00088         color_it != vTask.index.end(); color_it++)
00089       erouter->addListener(this,EventBase::visObjEGID, *color_it);
00090   }
00091   erouter->addTimer(this,scan_timer+i,0,false); // for initial measurements
00092   erouter->addTimer(this,scan_timer+i,
00093         (int) ((float) task->interval/(float)curScanReq->scanSpeed),true);
00094       }
00095     }
00096     else if (event.getSourceID() == sequence_id) {
00097       sequence_id = MotionManager::invalid_MC_ID;
00098       requestComplete();
00099     }
00100     break;
00101   case EventBase::timerEGID: // time to take some measurements
00102     if (event.getSourceID()-scan_timer < curScanReq->tasks.size()) {
00103       ScanRequest::Task* task = curScanReq->tasks[event.getSourceID()-scan_timer];
00104       if (task->getTaskType() == ScanRequest::Task::visReg) {
00105   ScanRequest::VisionRegionTask* vrt = dynamic_cast<ScanRequest::VisionRegionTask*>(task);
00106   storeVisionRegionDataTo(vrt->data,vrt->index,vrt->minArea);
00107       }
00108       else if (task->getTaskType() == ScanRequest::Task::visObj) {
00109   erouter->addListener(this, EventBase::visSegmentEGID,
00110            ProjectInterface::visSegmentSID,EventBase::statusETID);
00111   listeningObjEGID = true;
00112       }
00113       else if (task->getTaskType() == ScanRequest::Task::ir) 
00114   storeIRDataTo(task->data);
00115     }
00116     break;
00117   case EventBase::visSegmentEGID:
00118     if (listeningObjEGID)
00119       listeningObjEGID = false;
00120     else
00121       erouter->removeListener(this, EventBase::visSegmentEGID);
00122     break;
00123   case EventBase::visObjEGID:
00124     if (listeningObjEGID) {
00125       const VisionObjectEvent voe = *static_cast<const VisionObjectEvent*>(&event);    
00126       for (vector<ScanRequest::Task*>::iterator it = curScanReq->tasks.begin();
00127      it != curScanReq->tasks.end(); it++)
00128   if ((*it)->getTaskType() == ScanRequest::Task::visObj) {
00129     ScanRequest::VisionTask& vTask = *dynamic_cast<ScanRequest::VisionTask*>(*it);
00130     if (vTask.index.find(event.getSourceID()) != vTask.index.end()) {
00131       vTask.data.push_back(findLocationFor(&voe));
00132       cout << "VisionObject at " << vTask.data.back() << endl;
00133       break;
00134     }
00135   }
00136     }
00137     break;
00138   default:
00139     cout << "Lookout::processScan: unknown event " << event.getName() << endl;
00140     break;
00141   };
00142 }
00143 
00144 void Lookout::storeVisionRegionDataTo(vector<Point>& data, const set<int>& colors, int minArea) {
00145   const unsigned char *img = 
00146     ProjectInterface::defRegionGenerator->getImage(ProjectInterface::fullLayer,0);
00147   const color_class_state *regions = reinterpret_cast<const color_class_state*> (img);
00148   for (set<int>::const_iterator it = colors.begin();
00149        it != colors.end(); it++)
00150     for (int i = 0; i < regions[*it].num; i++)
00151       if ((regions[*it].list+i)->area > minArea) {
00152   data.push_back(findLocationFor(regions[*it].list));
00153   cout << regions[*it].name  << " at " << data.back() << endl;
00154       }
00155       else break;
00156 }
00157   
00158 void Lookout::storeIRDataTo(vector<Point>& data) {
00159   NEWMAT::ColumnVector ray = Kinematics::pack(0,0,getIR());
00160   cout << "dist= " << ray(3) << ", in base frame= ";
00161 #ifdef TGT_ERS7
00162   NEWMAT::ColumnVector baseCoords = kine->jointToBase(NearIRFrameOffset)*ray;
00163 #else //not ERS7
00164   NEWMAT::ColumnVector baseCoords = kine->jointToBase(IRFrameOffset)*ray;
00165 #endif
00166   data.push_back(Point(baseCoords(1),baseCoords(2),baseCoords(3)));
00167   cout << data.back() << endl;
00168 }
00169 
00170 bool Lookout::findPixelModes(StoreModeImageRequest& modeRequest) {
00171   static size_t npixels = modeRequest.image->getNumPixels();
00172   static vector<map<uchar, unsigned int> > colorCount(npixels);
00173   if (modeRequest.numImages-- == 0) { // finished collecting samples, find modes
00174     for (size_t i = 0; i<npixels; i++) {
00175       unsigned int maxCount = 0; uchar maxChar = 0;
00176       for (map<uchar, unsigned int>::const_iterator it = colorCount[i].begin();
00177      it != colorCount[i].end(); it++)
00178   if (it->second > maxCount) {
00179     maxCount = it->second;
00180     maxChar = it->first;
00181   }
00182       modeRequest.image[i] = maxChar;
00183       colorCount[i].clear();
00184     }
00185     return true;
00186   }
00187   else {
00188     for (size_t i = 0; i<npixels; i++)
00189       colorCount[i][modeRequest.image[i]]++;
00190     return false;
00191   }
00192 }
00193   
00194 void Lookout::processPointAt(const EventBase& event) {
00195   //  cout << "Lookout::processPointAt: " << event.getName() << endl;
00196   switch (event.getGeneratorID()) {
00197   case EventBase::motmanEGID: // head motion complete, wait for duration
00198     if (event.getSourceID() == pointer_id && event.getTypeID() == EventBase::deactivateETID) {
00199       pointer_id = MotionManager::invalid_MC_ID;
00200       erouter->addTimer(this, dur_timer, dynamic_cast<const PointAtBase*>(curReq)->duration, false);
00201     }
00202     break;
00203   case EventBase::timerEGID:
00204     if (event.getSourceID() == dur_timer) { 
00205       PointAtBase* baseReq = dynamic_cast<PointAtBase*>(curReq);
00206       switch (baseReq->getPointAtType()) {
00207       case PointAtBase::storeImage:
00208   erouter->addListener(this, EventBase::visSegmentEGID,
00209            ProjectInterface::visSegmentSID,EventBase::statusETID);
00210   break;
00211       case PointAtBase::measureDist:
00212   erouter->addListener(this, EventBase::sensorEGID, SensorSourceID::UpdatedSID);
00213   break;
00214       default:
00215   requestComplete();
00216   break;
00217       };
00218       break;
00219     }
00220   case EventBase::visSegmentEGID: {
00221     erouter->removeListener(this, EventBase::visSegmentEGID);
00222     PointAtBase* baseReq = dynamic_cast<PointAtBase*>(curReq);
00223     baseReq->toBaseMatrix = kine->jointToBase(baseReq->joint);
00224     VRmixin::camSkS.clear();
00225     StoreImageRequest& storeImageReq = *dynamic_cast<StoreImageRequest*>(curReq);
00226     storeImageReq.image = (*storeImageReq.sketchFunc)();
00227     if (StoreModeImageRequest* modeReq = dynamic_cast<StoreModeImageRequest*>(curReq))
00228       if ( ! findPixelModes(*modeReq) ) {
00229   erouter->addTimer(this, dur_timer, modeReq->interval, false);
00230   return;
00231       }
00232     requestComplete();
00233   }
00234     break;
00235   case EventBase::sensorEGID: {
00236     MeasureDistanceRequest* measureDistReq = dynamic_cast<MeasureDistanceRequest*>(curReq);
00237     measureDistReq->toBaseMatrix = kine->jointToBase(measureDistReq->joint);
00238     measureDistReq->val = getIR();
00239     requestComplete();
00240   }
00241     break;
00242   default:
00243     cout << "Lookout::processPointAt: unknown event " << event.getName() << endl;
00244     break;
00245   };
00246 }
00247   /*
00248 void Lookout::processTrackVision(float normX, float normY, bool isCurrentlyVisible) {
00249   if (!isCurrentlyVisible && landmarkInView) { // landmark just lost
00250     cout << "landmark just lost" << endl;
00251     erouter->addTimer(this,start_pan,500,false); // wait 0.5 sec before starting to look for landmark
00252     erouter->removeTimer(this,reset_pan);
00253   }
00254   else if (!landmarkInView && isCurrentlyVisible) { // landmark just found
00255     cout << "found landmark" << endl;
00256     erouter->removeTimer(this,start_pan);
00257     erouter->addTimer(this,reset_pan,1000,false);
00258   }
00259   else if (isCurrentlyVisible) { // continue tracking landmark
00260     trackObjectAt(normX,normY);
00261   }
00262   landmarkInView = isCurrentlyVisible;
00263   lm_location = findLocationFor(normX,normY);
00264   erouter->postEvent(EventBase::lookoutEGID, curReq->getRequestID(), EventBase::statusETID,0);
00265 }
00266 
00267 void Lookout::processTrack(const EventBase& event) {
00268   switch (event.getGeneratorID()) {
00269   case EventBase::visObjEGID:
00270     if (event.getTypeID()==EventBase::statusETID) {
00271       const VisionObjectEvent *voe = (static_cast<const VisionObjectEvent*>(&event));
00272       const float area = voe->getBoundaryArea();
00273       processTrackVision(voe->getCenterX(), voe->getCenterY(), area > 0.03);
00274     }
00275     break;
00276   case EventBase::visSegmentEGID:
00277     if (event.getTypeID() == EventBase::statusETID) {
00278       vector<Point> pts = getRegionData();
00279       if (pts.empty()) processTrackVision(0,0,false);
00280       else processTrackVision(pts.front().coordX(),pts.front().coordY(),true);
00281     }
00282     break;
00283   case EventBase::timerEGID:
00284     switch (event.getSourceID()) {
00285     case start_pan: //! enough time passed after landmark lost
00286       cout << "landmark not seen for 0.5 sec\n";
00287       if (curReq->isSticky())
00288   lookForLandmark();
00289       else
00290   requestComplete();
00291       break;
00292     case reset_pan:
00293       cout << "reset pan motion" << endl;
00294       { MMAccessor<SmallMotionSequenceMC> (sequence_id)->setTime(0); }
00295       break;
00296     default:
00297       cout << "unknown source timer evenet" << endl;
00298       break;
00299     }
00300   case EventBase::motmanEGID:
00301     if (event.getSourceID() == sequence_id && curReq->isSticky()) { // lookForLandmark() failed
00302       cout << "Lookout::processTrack: track failed\n";
00303       requestComplete();
00304     }
00305     break;
00306   default:
00307     cout << "Lookout::processTrack: unknown event" << endl;
00308     break;
00309   };
00310 }
00311   */
00312 unsigned int Lookout::executeRequest(const LookoutRequest& req) { 
00313   switch (req.getHeadMotionType()) {
00314   case LookoutRequest::none:
00315     switch (dynamic_cast<const PointAtBase*>(&req)->getPointAtType()) {
00316     case PointAtBase::storeImage:
00317       if (dynamic_cast<const StoreModeImageRequest*>(&req))
00318   pushRequest<StoreModeImageRequest>(req);
00319       else
00320   pushRequest<StoreImageRequest>(req);
00321       break;
00322     case PointAtBase::measureDist:
00323       pushRequest<MeasureDistanceRequest>(req); break;
00324     default: 
00325       cout << "Lookout::executeRequest: unknown PointAtRequest type\n"; 
00326       break;
00327     };
00328     break;
00329   case LookoutRequest::pointAt:
00330     switch (dynamic_cast<const PointAtRequest*>(&req)->getPointAtType()) {
00331     case PointAtBase::none:
00332       pushRequest<PointAtRequest>(req); break;
00333     case PointAtBase::storeImage:
00334       if (dynamic_cast<const StoreModeImageAtRequest*>(&req))
00335   pushRequest<StoreModeImageAtRequest>(req);
00336       else
00337   pushRequest<StoreImageAtRequest>(req);
00338       break;
00339     case PointAtBase::measureDist:
00340       pushRequest<MeasureDistanceAtRequest>(req); break;
00341     default: cout << "Lookout::executeRequest: unknown PointAtRequest type\n"; break;
00342     };
00343     break;
00344   case LookoutRequest::scan:
00345     if (dynamic_cast<const ScanRequest*>(&req)->getScanType() == ScanRequest::line)
00346       pushRequest<ScanAlongLineRequest>(req);
00347     else
00348       pushRequest<ScanAreaRequest>(req); 
00349     break;
00350   case LookoutRequest::track:
00351     pushRequest<TrackRequest>(req); break;
00352   default:
00353     cout << "Lookout::executeRequest: unknown request type " << req.getHeadMotionType() << endl;
00354   };
00355   requests.back()->requestID = idCounter++;
00356   //  cout << " request " << requests.back()->requestID << " added to request queue\n";
00357   if (requests.size() == 1)
00358     executeRequest();
00359   return requests.back()->requestID;
00360 }
00361 
00362 // triggers action to start completing each type of front of request queue
00363 void Lookout::executeRequest() {
00364   curReq = requests.front();
00365   //  cout << "Executing Lookout Request #" << curReq->requestID << endl;
00366   switch (curReq->getHeadMotionType()) {
00367   case LookoutRequest::none:
00368     erouter->addTimer(this,dur_timer,dynamic_cast<const PointAtBase*>(curReq)->duration,false);
00369     break;
00370   case LookoutRequest::pointAt: {
00371     const Point& pt = dynamic_cast<const PointAtRequest*>(curReq)->gazePt;
00372     if (dynamic_cast<const PointAtBase*>(curReq)->getPointAtType() == PointAtBase::measureDist) {
00373       SharedObject<PostureMC> pstmc;
00374 #ifdef TGT_ERS7
00375       pstmc->solveLinkVector(pt.coords,NearIRFrameOffset,Kinematics::pack(0,0,1));
00376 #else
00377       pstmc->solveLinkVector(pt.coords,IRFrameOffset,Kinematics::pack(0,0,1));
00378 #endif
00379       pointer_id = motman->addPrunableMotion(pstmc);
00380     }
00381     else {
00382       SharedObject<HeadPointerMC> hpmc;
00383       hpmc->lookAtPoint(pt.coordX(),pt.coordY(),pt.coordZ());
00384       pointer_id = motman->addPrunableMotion(hpmc);
00385     }
00386     erouter->addListener(this,EventBase::motmanEGID,pointer_id);
00387   }
00388     break;
00389   case LookoutRequest::scan:
00390     erouter->addListener(this,EventBase::motmanEGID);
00391     scan();
00392     break;
00393   default:
00394     cout << "Lookout::executeRequest(): unknown request " << curReq->getHeadMotionType() << endl;
00395     break;
00396   };
00397 }
00398 
00399 void Lookout::requestComplete() {
00400   // remove all timer and listeners for now
00401   erouter->removeListener(this);
00402   erouter->removeTimer(this);
00403   if (curReq->getHeadMotionType() == LookoutRequest::scan) {
00404     erouter->postEvent(LookoutScanEvent
00405            (dynamic_cast<ScanRequest*>(curReq)->tasks,
00406       EventBase::lookoutEGID,curReq->requestID, EventBase::deactivateETID));
00407   }
00408   else if (curReq->getHeadMotionType() == LookoutRequest::pointAt
00409      || curReq->getHeadMotionType() == LookoutRequest::none) {
00410     const NEWMAT::Matrix& toBase = dynamic_cast<const PointAtBase*>(curReq)->toBaseMatrix;
00411     switch (dynamic_cast<const PointAtBase*>(curReq)->getPointAtType()) {
00412     case PointAtRequest::none:
00413       erouter->postEvent(LookoutPointAtEvent(toBase,EventBase::lookoutEGID,
00414             curReq->requestID, EventBase::deactivateETID));
00415       break;
00416     case PointAtRequest::storeImage:
00417       erouter->postEvent(LookoutSketchEvent
00418        (dynamic_cast<StoreImageRequest*>(curReq)->image,
00419         toBase,EventBase::lookoutEGID,
00420         curReq->requestID, EventBase::deactivateETID));
00421       break;
00422     case PointAtRequest::measureDist:
00423       erouter->postEvent(LookoutIREvent
00424        (dynamic_cast<const MeasureDistanceRequest*>(curReq)->val,
00425         toBase,EventBase::lookoutEGID,
00426         curReq->requestID, EventBase::deactivateETID));
00427       break;
00428     default:
00429       cout << "Lookout::requestComplete(): Unknown type returned by getPointAtType()\n";
00430     };
00431   }
00432   requests.pop();
00433   //  delete curReq;
00434   curReq = NULL;
00435   if (!requests.empty())
00436     executeRequest();
00437 }
00438 
00439 
00440 void Lookout::processEvent(const EventBase& event) {
00441   cout << "Lookout::processEvent got " << event.getDescription() << endl;
00442   if (NULL==curReq) {
00443     cout << "Should not get any event when executing no request\n";
00444     return;
00445   }
00446 
00447   switch (curReq->getHeadMotionType()) {
00448   case LookoutRequest::scan:
00449     processScan(event);
00450     break;
00451     /*
00452   case LookoutRequest::track:
00453     processTrack(event);
00454     break;
00455   case LookoutRequest::localize:
00456     // ??????
00457     break;
00458     */
00459   case LookoutRequest::pointAt:
00460   case LookoutRequest::none:
00461     processPointAt(event); break;
00462   default:
00463     cout << "Lookout::processEvent: unknown request type: " << event.getName() << endl;
00464     break;
00465   };
00466 }
00467   /*
00468 void Lookout::trackObjectAt(float horiz, float vert) {
00469   setPanPrior(false);
00470 //  findLandmarkLocation(voe);
00471 //  erouter->postEvent(EventBase::lookoutEGID, curReq->getRequestID(), EventBase::statusETID,0);
00472   double tilt=state->outputs[HeadOffset+TiltOffset]-vert*M_PI/7.5;
00473   double pan=state->outputs[HeadOffset+PanOffset]-horiz*M_PI/6;
00474   if(tilt<mathutils::deg2rad(-20.0))
00475     tilt=mathutils::deg2rad(-20.0);
00476   if(tilt>mathutils::deg2rad(40.0))
00477     tilt=mathutils::deg2rad(40.0);
00478   if(pan>mathutils::deg2rad(80.0))
00479     pan=mathutils::deg2rad(80.0);
00480   if(pan<mathutils::deg2rad(-80.0))
00481     pan=mathutils::deg2rad(-80.0);
00482 
00483 #ifdef TGT_ERS7
00484   //  cout << "tilt: " << state->outputs[HeadOffset+TiltOffset] << ", nod: " << state->outputs[HeadOffset+NodOffset] << endl;
00485   if (tilt < -0.5)
00486     MMAccessor<HeadPointerMC> (pointer_id)->setJoints(tilt,pan,outputRanges[HeadOffset+NodOffset][MinRange]);
00487   else {
00488     const float act_tilt = state->outputs[HeadOffset+TiltOffset];
00489     const float nod_fact = act_tilt*act_tilt*4.0;
00490     MMAccessor<HeadPointerMC> (pointer_id)->setJoints(tilt,pan,outputRanges[HeadOffset+NodOffset][MinRange]*nod_fact);
00491   }
00492 #else
00493   MMAccessor<HeadPointerMC> (pointer_id)->setJoints(tilt,pan,0);
00494 #endif
00495 }
00496   */
00497 
00498 Point Lookout::findLocationFor(float normX, float normY) {
00499   NEWMAT::ColumnVector ground_plane = kine->calculateGroundPlane();
00500   NEWMAT::ColumnVector cameraPt(4), groundPt(4);
00501   config->vision.computeRay(normX, normY, cameraPt(1),cameraPt(2),cameraPt(3));
00502   cameraPt(4) = 1;
00503   groundPt = kine->projectToPlane(CameraFrameOffset, cameraPt, 
00504           BaseFrameOffset, ground_plane, BaseFrameOffset);
00505   return Point(groundPt(1),groundPt(2),groundPt(3),egocentric);
00506 }
00507 
00508 void Lookout::scan() {
00509   cout << "scan speed: " << dynamic_cast<const ScanRequest*>(curReq)->scanSpeed 
00510        << "  (rad / millisec)\n";
00511   if (dynamic_cast<const ScanRequest*>(curReq)->getScanType()==ScanRequest::line) {
00512     const ScanAlongLineRequest& scanLineReq = *dynamic_cast<const ScanAlongLineRequest*>(curReq);
00513     scanAlongLine(scanLineReq.beginPt, scanLineReq.endPt);
00514   }
00515   else {
00516     const ScanAreaRequest& scanLineReq = *dynamic_cast<const ScanAreaRequest*>(curReq);
00517     scanArea(scanLineReq.left, scanLineReq.right, scanLineReq.far, scanLineReq.near);
00518   }
00519 }
00520 
00521 void Lookout::scanAlongLine(const Point& startPt, const Point& endPt) {
00522   SharedObject<HeadPointerMC> hpmc;
00523 
00524   hpmc->lookAtPoint(endPt.coordX(),endPt.coordY(),endPt.coordZ());
00525   const float pan1 = hpmc->getJointValue(PanOffset);
00526   const float tilt1 = hpmc->getJointValue(TiltOffset);
00527   const float roll1 = hpmc->getJointValue(RollOffset);
00528   
00529   hpmc->lookAtPoint(startPt.coordX(),startPt.coordY(),startPt.coordZ());
00530   const float pan0 = hpmc->getJointValue(PanOffset);
00531   const float tilt0 = hpmc->getJointValue(TiltOffset);
00532   const float roll0 = hpmc->getJointValue(RollOffset);
00533   
00534   const unsigned int time = (unsigned int) 
00535     (sqrt((pan1-pan0)*(pan1-pan0)+(tilt1-tilt0)*(tilt1-tilt0)+(roll1-roll0)*(roll1-roll0))
00536      / dynamic_cast<const ScanRequest*>(curReq)->scanSpeed);
00537   
00538   SharedObject<SmallMotionSequenceMC> scanmc;
00539   scanmc->pause();
00540   scanmc->setOutputCmd(HeadOffset+TiltOffset,tilt0);
00541   scanmc->setOutputCmd(HeadOffset+RollOffset,roll0);
00542   scanmc->setOutputCmd(HeadOffset+PanOffset,pan0);
00543   scanmc->advanceTime(time);
00544   scanmc->setOutputCmd(HeadOffset+TiltOffset,tilt1);
00545   scanmc->setOutputCmd(HeadOffset+RollOffset,roll1);
00546   scanmc->setOutputCmd(HeadOffset+PanOffset,pan1);
00547 
00548   pointer_id = motman->addPrunableMotion(hpmc); // moves head to where scan begins;
00549   // actual scan motion sequence (paused), played when pointer_id above is completed
00550   sequence_id = motman->addPrunableMotion(scanmc,MotionManager::kIgnoredPriority); 
00551 }
00552 
00553 void Lookout::scanArea(coordinate_t left, coordinate_t right,
00554         coordinate_t far, coordinate_t near) {
00555   const float& scanSpeed = dynamic_cast<const ScanRequest*>(curReq)->scanSpeed;
00556   static const float tiltJointValDelta = mathutils::deg2rad(15.0); //
00557   const int tiltTime = (int) (tiltJointValDelta / scanSpeed);
00558   const float z_coord = -150;//1/wmap.ground_plane(3);
00559   unsigned short counter = 1; // or 3 if start from left
00560   
00561   SharedObject<HeadPointerMC> hpmc; //! < virtual headpointer, never gets added to motman
00562   near = (near > 100) ? near : 100;
00563   const Point firstPt(near, (counter < 2) ? right : left, z_coord); // start of motion sequence
00564   hpmc->lookAtPoint(firstPt.coordX(),firstPt.coordY(),firstPt.coordZ());
00565   float tiltJointVal = hpmc->getJointValue(TiltOffset);
00566 
00567   // define scan waypoints in terms of joint angles instead of base frame coordinates (x,y,z)
00568   // this way you can make sure to cover entire region  but not scanning the same region twice
00569   // would be harder to achieve this if I did this in terms of base frame coords
00570 
00571   hpmc->lookAtPoint(far,left,z_coord);
00572   const float tiltJointValFar = hpmc->getJointValue(TiltOffset);
00573   const float panJointValLeftFar = hpmc->getJointValue(PanOffset);
00574   hpmc->lookAtPoint(far,right,z_coord);
00575   const float panJointValRiteFar = hpmc->getJointValue(PanOffset);
00576   hpmc->lookAtPoint(near,left,z_coord);
00577   float panJointValLeft = hpmc->getJointValue(PanOffset);
00578   hpmc->lookAtPoint(near,right,z_coord);
00579   float panJointValRite = hpmc->getJointValue(PanOffset);
00580   const int panTime = (int) (fabs(panJointValLeft-panJointValRite)/scanSpeed);
00581 
00582   const float panJointLeftDelta = (tiltJointValFar-tiltJointVal < 0.01) ? 0 : 
00583     (panJointValLeftFar-panJointValLeft)/(tiltJointValFar-tiltJointVal)*tiltJointValDelta;
00584   const float panJointRiteDelta = (tiltJointValFar-tiltJointVal < 0.01) ? 0 : 
00585     (panJointValRiteFar-panJointValRite)/(tiltJointValFar-tiltJointVal)*tiltJointValDelta;
00586 
00587   SharedObject<SmallMotionSequenceMC> scanmc;
00588   scanmc->pause();
00589   while (true) {
00590     counter++;
00591     counter = counter % 4;
00592     if (counter%2 == 1) {
00593       tiltJointVal += tiltJointValDelta;
00594       if (tiltJointVal > tiltJointValFar) break;
00595       if (counter == 1) panJointValRite += panJointRiteDelta;
00596       else panJointValLeft += panJointLeftDelta;
00597     }
00598     scanmc->advanceTime((counter%2==1) ? tiltTime : panTime);
00599     scanmc->setOutputCmd(HeadOffset+TiltOffset, tiltJointVal);
00600     scanmc->setOutputCmd(HeadOffset+RollOffset,0);
00601     scanmc->setOutputCmd(HeadOffset+PanOffset, (counter < 2) ? panJointValRite : panJointValLeft);
00602   }
00603   hpmc->lookAtPoint(firstPt.coordX(),firstPt.coordY(),firstPt.coordZ());
00604   pointer_id = motman->addPrunableMotion(hpmc); // moves head to where scan begins
00605   // actual scan motion sequence (paused), played when pointer_id above is completed
00606   sequence_id = motman->addPrunableMotion(scanmc,MotionManager::kIgnoredPriority);
00607 }
00608 
00609 } // namespace

DualCoding 3.0beta
Generated Wed Oct 4 00:01:53 2006 by Doxygen 1.4.7