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

Spherus.cpp

Go to the documentation of this file.
00001 #include "Spherus.h"
00002 #include "RandomController.h"
00003 #include "Circle.h"
00004 
00005 static const int nVisionSensors=7; //per circle
00006 static const int nTactileSensors=8;//per circle
00007 //1 proprioceptive extension sensor, 2*2 proprioceptive velocity sensors, 
00008 //total sensors: 2*(nVisionSensors+nTactileSensors)+1+4=35
00009 //2*2 rocket effectors, 1 extension effector
00010 //total effectors: 5
00011 static const real maxExtension=0.8;
00012 static const real maxExtensionForce=0.5;
00013 static const real maxRocketForce=0.5;
00014 static const real elasticK=maxExtensionForce/(maxExtension/5);
00015 
00016 const unsigned int Spherus::nSensors=2*(nVisionSensors+nTactileSensors)+1+4;
00017 const unsigned int Spherus::nEffectors=2*2+1;
00018 
00019 Spherus::Spherus(real x, real y, real alpha, real extension, real R, Controller* controller) : 
00020     PhysicalObject("Spherus"){
00021    this->r.setXY(x,y);
00022    this->alpha=alpha;
00023    this->computeSinCos();
00024    this->extension=extension;
00025    this->R=R;
00026    circles[0]=new Circle(R, 0,0, "left body", nTactileSensors, M_PI-M_PI/nTactileSensors, 0.1); //Pi-2Pi/8/2
00027    circles[1]=new Circle(R, 0,0, "right body", nTactileSensors, M_PI/nTactileSensors, 0.1); //2Pi/8/2
00028    for(int i=0;i<2;i++){
00029       eyes[i]=new VisualSensor(circles[i], 0,0, M_PI/2, R, 7*M_PI/12, nVisionSensors);
00030       rocketActivations[i]=0.0;
00031       rocketForceValues[i]=0.0;
00032    }
00033    extensionActivation=1.0;
00034    targetExtension=extensionActivation*maxExtension;
00035    computeMemberPositions();  
00036    if(controller==NULL){
00037       this->controller=new RandomController(35,5);
00038    } else {
00039       this->controller=controller;
00040    }
00041    //bounding box is infinite because of the visual sensors
00042    boxMin.setXY(-ThyrixParameters::infinity,-ThyrixParameters::infinity);
00043    boxMax.setXY(ThyrixParameters::infinity,ThyrixParameters::infinity);
00044 }
00045 
00046 Spherus::~Spherus(){
00047    for(int i=0;i<2;i++){
00048       delete(circles[i]);
00049       delete(eyes[i]);
00050    }
00051    delete controller;
00052 }
00053 
00054 void Spherus::computeState(){
00055    real dx=circles[1]->r.x-circles[0]->r.x;
00056    real dy=circles[1]->r.y-circles[0]->r.y;
00057    extension=sqrt(sqr(dx)+sqr(dy));
00058    alpha=atan2(dy,dx);//-Pi..Pi
00059    if(alpha<0) alpha+=2*M_PI; //0..2Pi
00060    computeSinCos();
00061    r=circles[0]->r;
00062    r+=circles[1]->r;
00063    r/=2;
00064 }
00065 
00066 void Spherus::computeSinCos(){
00067    sinAlpha=sin(alpha);
00068    cosAlpha=cos(alpha);
00069 }
00070 
00071 void Spherus::computeMemberPositions(){
00072    circles[0]->r.setXY(r.x-extension/2*cosAlpha,r.y-extension/2*sinAlpha);
00073    circles[1]->r.setXY(r.x+extension/2*cosAlpha,r.y+extension/2*sinAlpha);
00074 }
00075 
00076 void Spherus::controll(){
00077    int i, i0;
00078    /*
00079    Sensors:
00080    0..13 vision
00081    14..29 tactile
00082    30 length proprioception
00083    31..34 velocity proprioception
00084 
00085    Effectors:
00086    0..3 rockets
00087    4 extension
00088    */
00089 
00090    //set sensor activations
00091    //visual sensors
00092    for(i=0;i<nVisionSensors;i++)
00093       controller->setInput(i, eyes[1]->activations[i]);
00094    i0=i;
00095    for(;i<i0+nVisionSensors;i++)
00096       controller->setInput(i, eyes[0]->activations[i-i0]);
00097    i0=i;
00098    //tactile sensors
00099    for(;i<i0+nTactileSensors;i++)
00100       controller->setInput(i, circles[1]->activations[i-i0]);
00101    i0=i;
00102    for(;i<i0+nTactileSensors;i++)
00103       controller->setInput(i, circles[0]->activations[i-i0]);
00104    //extension proprioception
00105    controller->setInput(i, extension/maxExtension);
00106    i++;
00107    float p1,p2;
00108    //velocity proprioception
00109    computeCircleProprioception(circles[1],p1,p2);
00110    controller->setInput(i, p1); i++;
00111    controller->setInput(i, p2); i++;
00112    computeCircleProprioception(circles[0],p1,p2);
00113    controller->setInput(i, p1); i++;
00114    controller->setInput(i, p2); i++;
00115    
00116    controller->advanceTime();
00117 
00118 
00119    //srand( (unsigned)time( NULL ) );
00120    //each rocket is controlled by 2 neurons, one inhibitory and one excitatory
00121    //total activation: -1..1
00122    rocketActivations[1]=controller->getOutput(0)-controller->getOutput(1);
00123    rocketActivations[0]=controller->getOutput(2)-controller->getOutput(3);
00124    extensionActivation=controller->getOutput(4);
00125    
00126    for(i=0;i<2;i++){
00127       rocketForceValues[i]=rocketActivations[i]*maxRocketForce;
00128    }
00129 
00130    targetExtension=extensionActivation*maxExtension;
00131 }
00132 
00133 void Spherus::computeCircleProprioception(Circle* circle, float& forward, float& backward){
00134    real u=-(alpha+M_PI/2); //rotation angle
00135    u=circle->m*(circle->v.x*cos(u)-circle->v.y*sin(u))/maxRocketForce;
00136    if(u>0){
00137       if(u>1.0) u=1.0;
00138       forward=(float)u;
00139       backward=0.0;
00140    } else {
00141       if(u<-1.0) u=-1.0;
00142       forward=0.0;
00143       backward=(float)-u;
00144    }
00145 }
00146 
00147 void Spherus::computeDerivativesWithoutContacts(ContactSolver* contactSolver){
00148    real elasticForceValue;
00149    Vector2 force;
00150    Vector2 elasticForce;
00151 
00152    elasticForceValue=elasticK*(extension-targetExtension); 
00153    //elastic force applied towards body 0, oriented from body 0 to 1
00154    //elasticForceValue>0 => compression
00155    elasticForce.setXY(elasticForceValue*cosAlpha, elasticForceValue*sinAlpha);
00156 
00157    
00158 
00159    rocketForces[0].setXY(-rocketForceValues[0]*sinAlpha,rocketForceValues[0]*cosAlpha);
00160    force=rocketForces[0];
00161    force+=elasticForce;
00162    circles[0]->externalForce+=force;
00163    circles[0]->computeDerivativesWithoutContacts(contactSolver);
00164 
00165    rocketForces[1].setXY(-rocketForceValues[1]*sinAlpha,rocketForceValues[1]*cosAlpha);
00166    force=rocketForces[1];
00167    force-=elasticForce;
00168    circles[1]->externalForce+=force;
00169    circles[1]->computeDerivativesWithoutContacts(contactSolver);
00170 
00171 }
00172 
00173 bool Spherus::detectContacts(PhysicalObject* object, GlobalContactInfoVector* contacts){
00174    bool isContact=false;
00175    for(int i = 0; i < 2; ++i){
00176       isContact=circles[i]->detectContacts(object, contacts) || isContact;
00177       eyes[i]->detectContacts(object, contacts);
00178    }
00179    return isContact;
00180 }
00181 
00182 void Spherus::detectInternalContacts(GlobalContactInfoVector* contacts){
00183    circles[0]->detectContacts(circles[1], contacts);
00184 }
00185 
00186 void Spherus::deleteContacts(){
00187    for(int i=0;i<2;i++){
00188       circles[i]->deleteContacts();
00189       eyes[i]->deleteContacts();
00190    }
00191 }
00192 
00193 bool Spherus::detectMouseContact(const Vector2& rMouse, Vector2& p, PhysicalObject*& object){
00194    bool isContact=false;
00195    for(int i=0;i<2 && !isContact;i++){
00196       isContact = circles[i]->detectMouseContact(rMouse, p, object);
00197    }
00198    return isContact;
00199 }
00200 
00201 void Spherus::computeDerivatives(GlobalContactInfoVector* globalContacts){
00202    for(int i = 0; i < 2; ++i){
00203       circles[i]->computeDerivatives(globalContacts);
00204    }
00205 
00206 }
00207 
00208 void Spherus::integrate(const Integrator &integrator){
00209    int i;
00210    for(i=0;i<2;i++){
00211       circles[i]->integrate(integrator);
00212    }
00213    computeState();
00214    for(i=0;i<2;i++){
00215       circles[i]->alpha=alpha;
00216    }
00217 }
00218 
00219 void Spherus::draw(GUI *gui){
00220    gui->setBrushColor(Color("gray"));
00221    for(int i=0;i<2;i++){
00222       eyes[i]->draw(gui);
00223       circles[i]->draw(gui);
00224       gui->drawForce(circles[i]->r,rocketForces[i]);
00225       
00226    }
00227    gui->setBrushColor(GUI::colorTransparent);
00228    
00229    gui->setPenColor(Color("green"));
00230    gui->drawLine(circles[0]->r.x,circles[0]->r.y,circles[1]->r.x,circles[1]->r.y);
00231    gui->setPenColor(GUI::colorBlack);
00232 }

Thyrix homepageUsers' guide

(C) Arxia 2004-2005