Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

VisualSensor.cpp

Go to the documentation of this file.
00001 #include "VisualSensor.h"
00002 #include "Circle.h"
00003 #include "CappedRectangle.h"
00004 #include "MathTools.h"
00005 
00006 
00007 VisualSensor::VisualSensor(PhysicalObject* parent, 
00008             real relativeX, real relativeY, real relativeAlpha, 
00009             real R, real viewAngle, unsigned int nSensors,
00010             std::string label):
00011    PhysicalObject(label, nSensors),
00012    viewAngle(viewAngle)
00013 {
00014    this->parent=parent;
00015    this->relativeR.setXY(relativeX, relativeY);
00016    this->relativeAlpha=relativeAlpha;
00017    assert(viewAngle>0 && viewAngle<=2*M_PI);
00018    delta=viewAngle/2;
00019    epsilon=viewAngle/nSensors;
00020    boxMin.setXY(-ThyrixParameters::infinity,-ThyrixParameters::infinity);
00021    boxMax.setXY(ThyrixParameters::infinity,ThyrixParameters::infinity);
00022 }
00023 
00024 VisualSensor::~VisualSensor(){
00025 }
00026 
00027 bool VisualSensor::detectContacts(Circle* circle, GlobalContactInfoVector* contacts){
00028    if(circle==parent) return false;
00029    
00030    real dx = circle->r.x - (parent->r.x+relativeR.x);
00031    real dy = circle->r.y - (parent->r.y+relativeR.y);
00032    real d = MathTools::modulus(dx,dy);
00033 
00034    //compute visual activation
00035    real gamma=computeGamma(dx,dy);
00036 
00037    assert(d > circle->R);
00038    real phi = asin(circle->R / d); //0..Pi/2
00039    
00040    real gammaM = gamma - phi; //-3Pi/2..Pi
00041    real gammaP = gamma + phi; //-Pi..3Pi/2
00042 
00043    activate(gammaM, gammaP);
00044    
00045    return false;
00046 }
00047 
00048 bool VisualSensor::detectContacts(CappedRectangle* capsule, GlobalContactInfoVector* contacts){
00049    if(capsule==parent) return false;
00050 
00051    real lx=capsule->cosAlpha*capsule->l;
00052    real ly=capsule->sinAlpha*capsule->l;
00053    
00054    real dx1 = capsule->r.x+lx - (parent->r.x+relativeR.x);
00055    real dy1 = capsule->r.y+ly - (parent->r.y+relativeR.y);
00056    real d1 = MathTools::modulus(dx1,dy1);
00057 
00058    real dx2 = capsule->r.x-lx - (parent->r.x+relativeR.x);
00059    real dy2 = capsule->r.y-ly - (parent->r.y+relativeR.y);
00060    real d2 = MathTools::modulus(dx2,dy2);
00061 
00062    //compute visual activation
00063    real gamma1=computeGamma(dx1,dy1);
00064    real gamma2=computeGamma(dx2,dy2);
00065 
00066    bool change=false;
00067    if(gamma1<=gamma2){
00068       if(gamma2-gamma1>=M_PI) {
00069          change=true;
00070          gamma2-=2*M_PI;
00071       }
00072    } else {
00073       change=true;
00074       if(gamma1-gamma2>=M_PI) {
00075          change=false;
00076          gamma1-=2*M_PI;
00077       }
00078    }
00079 
00080    if(change){
00081       real temp=gamma1;
00082       gamma1=gamma2;
00083       gamma2=temp;
00084       temp=d1;
00085       d1=d2;
00086       d2=temp;
00087    }
00088 
00089 
00090    //gammaP in (-Pi,Pi); gammaM in (-2Pi,Pi); but gammaP-gammaM in (0,Pi)
00091    //assert((d1 > capsule->R) && (d2 > capsule->R));
00092    assert((d1 > 1e-6) && (d2 > 1e-6));
00093    // asin returns a value 0..Pi/2
00094    real phi1=asin(capsule->R / d1);
00095    real phi2=asin(capsule->R / d2);
00096    real gammaM=gamma1-phi1;
00097    if(gamma2-phi2<gammaM) gammaM=gamma2-phi2;
00098    real gammaP=gamma2+phi2;
00099    if(gamma1+phi1>gammaP) gammaP=gamma1+phi1;
00100 
00101    activate(gammaM, gammaP);
00102    
00103    return false;
00104 }
00105 
00106 
00107 void VisualSensor::activate(real gammaM, real gammaP){
00108    //g1=gammaM; g2=gammaP; //for debugging
00109 
00110    int where;
00111    
00112    //check where the beginning of the first sensor is relative to the angle covered by the object
00113    if(gammaM < -delta){
00114       if(gammaP >= -delta){
00115          where=0; //inside
00116       } else {
00117          where=1; //after
00118       }
00119    } else {
00120       where=-1; //before
00121    }
00122    
00123    
00124    real u=-delta;
00125    for(int i=0; i<nSensors; i++, u+=epsilon){
00126       
00127       if(where==1){
00128          //we are after the covered angle
00129          //prepare for the case that -2Pi<gammaM<-Pi
00130          //since gammaP-gammaM<Pi (we assume that the viewed object does not cover the sensor),
00131          //in this case -Pi<gammaP<0
00132          gammaM+=2*M_PI;
00133          gammaP+=2*M_PI;
00134          where=-1;
00135          //we are now before the covered angle
00136          //gammaM in (0,Pi); gammaP in (Pi,2Pi)
00137       }
00138       
00139       if(where==-1){
00140          //we were before the beginning of the covered angle
00141          if(gammaM<u+epsilon){
00142             //the covered angle starts within the current pixel
00143             if(gammaP<=u+epsilon){
00144                //the covered angle also ends within the current pixel
00145                //set pixel to a fractional activation
00146                activations[i]+=(gammaP-gammaM)/epsilon;
00147                if(activations[i]>1) activations[i]=1;
00148                //the beginning of the next pixel will be after the covered angle
00149                where=1;
00150             } else {
00151                //the covered angle ends after the current pixel
00152                //set pixel to a fractional activation
00153                activations[i]+=(u+epsilon-gammaM)/epsilon;
00154                if(activations[i]>1) activations[i]=1;
00155                //the beginning of the next pixel will be within the covered angle
00156                where=0;
00157             }
00158          }
00159       } else{
00160          if(where==0){
00161             //we are inside the covered angle
00162             if(gammaP<=u+epsilon){
00163                //the covered angle also ends within the current pixel
00164                //set pixel to a fractional activation
00165                activations[i]+=(gammaP-u)/epsilon;
00166                if(activations[i]>1) activations[i]=1;
00167                where=1;
00168             } else {
00169                //current pixel is fully covered
00170                activations[i]=1;
00171             }
00172          }
00173       }
00174    }
00175 }
00176 
00177 
00178 void VisualSensor::draw(GUI *gui){
00179    real l=2, u;
00180    int i;
00181    //activations
00182    gui->setPenColor(Color("orange"));
00183    real x=parent->r.x+relativeR.x;
00184    real y=parent->r.y+relativeR.y;
00185    for(i=0; i<nSensors; i++){
00186       u=parent->alpha+relativeAlpha-delta+(i+0.5)*epsilon;
00187       gui->drawLine(x, y, x+l*cos(u)*activations[i], y+l*sin(u)*activations[i]);
00188 
00189    }
00190    gui->setPenColor(Color("papayaWhip"));
00191    for(i=0; i<=nSensors; i++){
00192       u=parent->alpha+relativeAlpha-delta+i*epsilon;
00193       gui->drawLine(x, y, x+l*cos(u), y+l*sin(u));
00194    }
00195    /*
00196    //for debugging: draw gammas
00197    gui->setPenColor(Color("red"));
00198    u=parent->alpha+relativeAlpha+g1;
00199    gui->drawLine(x, y, x+l*cos(u), y+l*sin(u));
00200    gui->setPenColor(Color("green"));
00201    u=parent->alpha+relativeAlpha+g2;
00202    gui->drawLine(x, y, x+l*cos(u), y+l*sin(u));
00203    */
00204 }

Thyrix homepageUsers' guide

(C) Arxia 2004-2005