save loops

Dependencies:   mbed

Revision:
0:df6fdd9b99f0
Child:
1:3be7b7d050f4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/blobConfig.cpp	Tue Dec 02 04:39:15 2014 +0000
@@ -0,0 +1,537 @@
+
+#include "blobConfig.h"
+
+blobConfig::blobConfig(): numBlobs(0) {
+    //blobArray.clear();// there is no need to do this, the vector does not contains anything here.
+}
+
+blobConfig::~blobConfig() {
+    clearConfig();
+}
+
+// =========================================== STANDARD CONFIGURATIONS =============================================================================
+
+
+
+void blobConfig::clearConfig() {
+    for (int i=0; i<blobArray.size(); i++) delete blobArray[i]; // we must delete the pointer created with new, so the memory for the object is liberated (calls its destructor)
+    blobArray.clear();
+    numBlobs=0;// this is just equal to blobArray.size()
+}
+
+void blobConfig::initConfig(configType cfType,  int numblobs) {
+    myConfigType=cfType;
+    int i;
+    switch(myConfigType) {
+        case ONE_ELASTIC_FOLLOWING:
+            // computeBoundingBox();
+            clearConfig();
+            addOneElasticContourFollowing();
+        break;
+        case ONE_ELASTIC_MOUTH:
+            // computeBoundingBox();
+            clearConfig();
+            addOneElasticLoopContractCentral();
+        break;
+        case ONE_ELASTIC_MOUTH_SMALL:
+            // computeBoundingBox();
+            clearConfig();
+            addOneElasticLoopContractCentralFast();
+        break;
+        case BOUNCING_SPOTS:
+            // computeBoundingBox();
+           clearConfig();
+           for (i=0; i<numblobs ; i++) addOneRigidLoopBouncing();
+           randomizeAllColors();
+        break;
+        case LORENTZ_SPOTS:
+         // computeBoundingBox();
+            clearConfig();
+            for (i=0; i<numblobs ; i++) addOneRigidLoopLorentz();
+            randomizeAllColors();
+        break;
+        case FOLLOWING_SPOTS:
+         // computeBoundingBox();
+            clearConfig();
+            for (i=0; i<numblobs ; i++) {
+                addOneRigidLoopFollowing(vector2Df(CENTER_AD_MIRROR_X+i*200, CENTER_AD_MIRROR_Y+i*200), vector2Df(11,0));
+                }
+            // randomize colors:
+            randomizeAllColors();
+        break;
+        case ONE_TRACKING_SPOT:
+           clearConfig();
+           addOneRigidTrackingSpot();
+        break;
+         case ONE_TRACKING_SPOT_DOT:
+           clearConfig();
+           addOneRigidTrackingSpotDot();
+        break;
+        case AIR_HOCKEY_GAME: 
+            // computeBoundingBox();
+            clearConfig();
+            for (i=0; i<numblobs ; i++) addOneRigidLoopAirHockey();
+        break;
+        case CIRCULAR_PONG_GAME:
+            // computeBoundingBox();
+            clearConfig();
+            // (1) One SPOT_TRACK to track the background. It will be the number 0 in the config. 
+            addOneRigidTrackingSpotDot();
+            // (2) Add bouncing spots:
+            for (i=0; i<numblobs ; i++) {
+                float anglaux=1.0*i/numblobs*2*PI;
+                addOneRigidLoopBouncing(vector2Df(CENTER_AD_MIRROR_X+200*cos(anglaux), CENTER_AD_MIRROR_Y+200*sin(anglaux)), 
+                                        vector2Df(5*cos(anglaux),sin(anglaux))*10);
+            }
+        break;
+        case VERTICAL_PINBALL_GAME:
+         clearConfig();
+         // (1) one (or two) SPOT_TRACK or SPOT_TRACK_DOT to track the background - It will be the number 0 (and 1) in the config. 
+          addOneRigidTrackingSpotDot(vector2Df(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y+600), 
+                                     vector2Df(0,0));
+         // addOneRigidTrackingSpot(vector2Df(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y+600), 
+          //                           vector2Df(0,0));
+         // (2) one or more bouncing spots with gravity:
+         for (i=0; i<numblobs ; i++) {
+            addOneRigidLoopBouncingGravity(vector2Df(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y-600), 
+                                           vector2Df(i*10-5,0));   
+         }                   
+
+        break; 
+        case RAIN_MODE:
+        clearConfig();
+         // Add bouncing spot with gravity:
+          for (i=0; i<numblobs ; i++) {
+          addOneRigidLoopBouncingGravity(vector2Df(CENTER_AD_MIRROR_X, 10), vector2Df(0,0));   
+         }       
+          randomizeAllColors();
+        break;
+        case FISH_NET_GAME:
+        clearConfig();
+         // (1) one SPOT_TRACK_DOT to track the background - It will be the number 0  
+          addOneRigidTrackingSpotDot(vector2Df(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y),  // CENTERED
+                                     vector2Df(0,0));
+        // (2) Add bouncing spots without gravity:
+            for (i=0; i<numblobs ; i++) {
+                float anglaux=1.0*i/numblobs*2*PI;
+                addOneRigidLoopBouncing(vector2Df(CENTER_AD_MIRROR_X+400*cos(anglaux), CENTER_AD_MIRROR_Y+400*sin(anglaux)), 
+                                        vector2Df(cos(anglaux),sin(anglaux))*10);
+            }                      
+        break;
+        case PAC_MAN_GAME:
+            clearConfig();
+            //(1) add one very slowly slidind-bouncing spot, the PACMAN (number 0 in the config):
+           // addOneRigidLoopPacman(vector2Df(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y), vector2Df(20,0));
+           
+           // note: the pacman behaviour is not so good... for the time being, let's just use a following spot:
+            addOneRigidLoopFollowing(vector2Df(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y), vector2Df(10,0));
+            // set the color to red+green:
+            blobArray.back()->setColor(0x06);
+          
+          
+            // (2) Add some initial SPOT_FOLLOWING or SPOT_GHOST spots (the ghosts):
+            addOneRigidLoopGhost(vector2Df(CENTER_AD_MIRROR_X+500, CENTER_AD_MIRROR_Y-500), vector2Df(-5,0));
+            addOneRigidLoopGhost(vector2Df(CENTER_AD_MIRROR_X-500, CENTER_AD_MIRROR_Y-500), vector2Df(5,0));
+            
+        break;
+        default:
+        break;
+    }
+    
+    // make sure lockin red is ON (could be off if using blue for checking mirror delay...):
+    IO.setLaserLockinPower(1);
+}
+
+void blobConfig::printParameters() {
+    for (int i=0; i<blobArray.size(); i++) { 
+     pc.printf("Blob n.%d\n", i);
+     blobArray[i]->printParameters(); // a blob that is in stand-by mode may send data (good for testing with a fixed loop)
+    }
+    }
+
+ // ==================== Template spots from which to create multi-spot configurations: =====================
+
+void blobConfig::addOneElasticLoopRelax(vector2Df initpos, vector2Df initspeed) {
+    elasticLoop* pBlob= new elasticLoop();
+    pBlob->createBlob(blobArray.size(), RELAX, initpos, initspeed);
+    // add this relaxing loop to the present config:
+    blobArray.push_back(pBlob);
+
+    // update auxiliary variable numBlobs (just for easy reference):
+    numBlobs=blobArray.size();
+
+}
+
+
+void blobConfig::addOneElasticLoopContract(vector2Df initpos, vector2Df initspeed) {
+    elasticLoop* pBlob= new elasticLoop();
+    pBlob->createBlob(blobArray.size(), CONTRACT, initpos, initspeed);
+    // add this relaxing loop to the present config:
+    blobArray.push_back(pBlob);
+
+    // update auxiliary variable numBlobs (just for easy reference):
+    numBlobs=blobArray.size();
+}
+
+void blobConfig::addOneElasticLoopContractCentral(vector2Df initpos, vector2Df initspeed) {
+    elasticLoop* pBlob= new elasticLoop();
+    pBlob->createBlob(blobArray.size(), CONTRACT_CENTRAL, initpos, initspeed);
+    // add this relaxing loop to the present config:
+    blobArray.push_back(pBlob);
+
+    // update auxiliary variable numBlobs (just for easy reference):
+    numBlobs=blobArray.size();
+}
+
+void blobConfig::addOneElasticLoopContractCentralFast(vector2Df initpos, vector2Df initspeed) {
+    elasticLoop* pBlob= new elasticLoop();
+    pBlob->createBlob(blobArray.size(), CONTRACT_CENTRAL_FAST, initpos, initspeed);
+    // add this relaxing loop to the present config:
+    blobArray.push_back(pBlob);
+
+    // update auxiliary variable numBlobs (just for easy reference):
+    numBlobs=blobArray.size();
+}
+
+void blobConfig::addOneElasticContourFollowing(vector2Df initpos, vector2Df initspeed) {
+
+    elasticLoop* pBlob= new elasticLoop();
+    pBlob->createBlob(blobArray.size(), CONTOUR_FOLLOWING, initpos, initspeed);
+    // add this relaxing loop to the present config:
+    blobArray.push_back(pBlob);
+
+    // update auxiliary variable numBlobs (just for easy reference):
+    numBlobs=blobArray.size();
+}
+
+
+void blobConfig:: addOneElasticContourFollowingFAST(vector2Df initpos, vector2Df initspeed) {
+    elasticLoop* pBlob= new elasticLoop();
+    pBlob->createBlob(blobArray.size(), CONTOUR_FOLLOWING_FAST,  initpos, initspeed);
+    // add this relaxing loop to the present config:
+    blobArray.push_back(pBlob);
+
+    // update auxiliary variable numBlobs (just for easy reference):
+    numBlobs=blobArray.size();
+}
+
+void blobConfig::addOneElasticBouncing(vector2Df initpos, vector2Df initspeed) {
+    elasticLoop* pBlob= new elasticLoop();
+    pBlob->createBlob(blobArray.size(), BOUNCING,  initpos, initspeed);
+    // add this relaxing loop to the present config:
+    blobArray.push_back(pBlob);
+
+    // update auxiliary variable numBlobs (just for easy reference):
+    numBlobs=blobArray.size();
+}
+void blobConfig::addOneRigidLoopBouncingGravity(vector2Df initpos, vector2Df initspeed) {
+    rigidLoop* pBlob= new rigidLoop();
+    pBlob->createBlob(blobArray.size(), SPOT_BOUNCING_FACTOR,  initpos, initspeed);
+    // (We can use here methods of the child class, even if these are not declared virtual on the base class, because we are doing this BEFORE
+    // adding this to the blobArray as a pointer). This is good to set parameters...
+    pBlob->gravity.set(0,3.5);  
+    pBlob->centerMass.dampMotion = 0.002;
+    pBlob->factorBouncingForce=0;//0.003; // this is because we will use a force on the central mass (not used in SPOT_BOUNCING_FACTOR)
+    pBlob->factorAbsorptionShock=0.9; // coef elastic bouncing
+   
+    // add this relaxing loop to the present config:
+    blobArray.push_back(pBlob);
+
+    // update auxiliary variable numBlobs (just for easy reference):
+    numBlobs=blobArray.size();
+}
+void blobConfig::addOneRigidLoopBouncing(vector2Df initpos, vector2Df initspeed) {
+    rigidLoop* pBlob= new rigidLoop();
+    pBlob->createBlob(blobArray.size(), SPOT_BOUNCING_FACTOR, initpos, initspeed);
+    // add this relaxing loop to the present config:
+    blobArray.push_back(pBlob);
+ 
+    // update auxiliary variable numBlobs (just for easy reference):
+    numBlobs=blobArray.size();
+}
+
+void blobConfig::addOneRigidLoopPacman(vector2Df initpos, vector2Df initspeed) {
+    rigidLoop* pBlob= new rigidLoop();
+    pBlob->createBlob(blobArray.size(), SPOT_PACMAN, initpos, initspeed);
+    // add this relaxing loop to the present config:
+    blobArray.push_back(pBlob);
+
+    // update auxiliary variable numBlobs (just for easy reference):
+    numBlobs=blobArray.size();
+}
+void blobConfig::addOneRigidLoopGhost(vector2Df initpos, vector2Df initspeed) {
+    rigidLoop* pBlob= new rigidLoop();
+    pBlob->createBlob(blobArray.size(), SPOT_GHOST, initpos, initspeed);
+    // add this relaxing loop to the present config:
+    blobArray.push_back(pBlob);
+
+    // update auxiliary variable numBlobs (just for easy reference):
+    numBlobs=blobArray.size();
+}
+
+
+void blobConfig::addOneRigidLoopLorentz(vector2Df initpos, vector2Df initspeed) {
+    rigidLoop* pBlob= new rigidLoop();
+    pBlob->createBlob(blobArray.size(), SPOT_LORENTZ_FORCE, initpos, initspeed);
+    // add this loop to the present config:
+    blobArray.push_back(pBlob);
+
+    // update auxiliary variable numBlobs (just for easy reference):
+    numBlobs=blobArray.size();
+}
+
+void blobConfig::addOneRigidLoopAirHockey(vector2Df initpos, vector2Df initspeed) {
+    rigidLoop* pBlob= new rigidLoop();
+    pBlob->createBlob(blobArray.size(), SPOT_AIR_HOCKEY,  initpos, initspeed);
+    // add this loop to the present config:
+    blobArray.push_back(pBlob);
+
+    // update auxiliary variable numBlobs (just for easy reference):
+    numBlobs=blobArray.size();
+}
+
+void blobConfig::addOneRigidLoopFollowing(vector2Df initpos, vector2Df initspeed) {
+    rigidLoop* pBlob= new rigidLoop();
+    pBlob->createBlob(blobArray.size(), SPOT_FOLLOWING, initpos, initspeed);
+    // add this relaxing loop to the present config:
+    blobArray.push_back(pBlob);
+    
+    // random color for Tokyo Designer Week:
+    //randomizeAllColors();
+
+    // update auxiliary variable numBlobs (just for easy reference):
+    numBlobs=blobArray.size();
+}
+
+void blobConfig::addOneRigidLoopTest(vector2Df initpos, vector2Df initspeed) {
+    rigidLoop* pBlob= new rigidLoop();
+    pBlob->createBlob(blobArray.size(), SPOT_TEST, initpos, initspeed);
+    // add this relaxing loop to the present config:
+    blobArray.push_back(pBlob);
+
+    // update auxiliary variable numBlobs (just for easy reference):
+    numBlobs=blobArray.size();
+}
+
+void blobConfig::addOneRigidTrackingSpot(vector2Df initpos, vector2Df initspeed) {
+   rigidLoop* pBlob= new rigidLoop();
+    pBlob->createBlob(blobArray.size(), SPOT_TRACK, initpos, initspeed);
+    // add this relaxing loop to the present config:
+    blobArray.push_back(pBlob);
+
+    // update auxiliary variable numBlobs (just for easy reference):
+    numBlobs=blobArray.size();
+}
+
+void blobConfig::addOneRigidTrackingSpotDot(vector2Df initpos, vector2Df initspeed) {
+   rigidLoop* pBlob= new rigidLoop();
+    pBlob->createBlob(blobArray.size(), SPOT_TRACK_DOT, initpos, initspeed);
+    // add this relaxing loop to the present config:
+    blobArray.push_back(pBlob);
+
+    // update auxiliary variable numBlobs (just for easy reference):
+    numBlobs=blobArray.size();
+}
+// ==================================================================================================================================================
+void blobConfig::processSensedData() {
+     for (int i=0; i<blobArray.size(); i++) blobArray[i]->displaySensingBuffer.processSensedData(); // note: region with light is -1, and without is 2 (TO CHANGE!!! then we don't need to do "if" in the moment computation, but just a product)
+}
+
+void blobConfig::allKill() { // this put all the blobs in "dead" mode, meaning that neither rendering nor update is done (but they are not deleted).
+    for (int i=0; i<blobArray.size(); i++) {
+        blobArray[i]->render = false;
+        blobArray[i]->standByMode = false;
+    }
+}
+void blobConfig::allAlive() {
+    for (int i=0; i<blobArray.size(); i++) {
+        blobArray[i]->render = true;
+        blobArray[i]->standByMode = true;
+    }
+}
+
+void blobConfig::allStandBy() {
+    for (int i=0; i<blobArray.size(); i++) blobArray[i]->standByMode = true;
+}
+
+void blobConfig::allResume() {
+    for (int i=0; i<blobArray.size(); i++) blobArray[i]->standByMode = false;
+}
+
+void blobConfig::allVisible() {
+    for (int i=0; i<blobArray.size(); i++) blobArray[i]->render = true;
+}
+
+void blobConfig::allInvisible() { // note that they may continue to evolve
+    for (int i=0; i<blobArray.size(); i++) blobArray[i]->render = false;
+}
+
+void blobConfig::allSetColor(unsigned char c) {
+    for (int i=0; i<blobArray.size(); i++) blobArray[i]->setColor(c);
+ }
+ 
+ void blobConfig::allSetGreen(unsigned char c) {
+    for (int i=0; i<blobArray.size(); i++) blobArray[i]->setGreenColor(c);
+ }
+ 
+  void blobConfig::allSetBlue(unsigned char c) {
+    for (int i=0; i<blobArray.size(); i++) blobArray[i]->setBlueColor(c);
+ }
+ 
+  void blobConfig::randomizeAllColors() {   
+    int c;
+    for (int i=0; i<blobArray.size(); i++) {
+     c= rand() % 2;  
+     blobArray[i]->setBlueColor(c);
+     c= rand() % 2;  
+     blobArray[i]->setGreenColor(c);
+ }
+ }
+
+void blobConfig::update() { // update dynamics of the blob configuration:
+int i;
+float minDist=5000, dist;
+bool win;
+    // Depending on the config type, perform some special test and updates: 
+   switch(myConfigType) {
+        // simple behaviours:
+        case ONE_ELASTIC_FOLLOWING:
+        case ONE_ELASTIC_MOUTH:
+        case ONE_ELASTIC_MOUTH_SMALL:
+        case BOUNCING_SPOTS:
+        case LORENTZ_SPOTS:
+        case FOLLOWING_SPOTS:
+        case ONE_TRACKING_SPOT:
+        case AIR_HOCKEY_GAME:
+            // In all these simple cases, update dynamics of each blob independently:
+            for (i=0; i<blobArray.size(); i++) {
+                 if (blobArray[i]->standByMode==false) blobArray[i]->update();
+            }
+        break; 
+        // more game-like:
+        case CIRCULAR_PONG_GAME:
+          // spot index 0 is a tracking spot, the background "anchor":
+         if (blobArray[0]->standByMode==false) blobArray[0]->update();
+         // all the other spots are bouncing spots:
+        for (i=1; i<blobArray.size(); i++) {
+            if (blobArray[i]->standByMode==false) blobArray[i]->update();
+        }
+        // GAME CHECK: is some bouncing spot too far from the anchor? if so, make it "explode" (and then dissapear, but leave this for now):
+        for (i=1; i<blobArray.size(); i++) {
+            dist=(blobArray[0]->getCenter()).distance(blobArray[i]->getCenter());
+            if (dist>1000) {
+                blobArray[i]->explosion();
+                float anglaux=1.0*(i-1)/(blobArray.size()-1)*2*PI;
+                 blobArray[i]->setPositionSpeed(vector2Df(CENTER_AD_MIRROR_X+200*cos(anglaux), CENTER_AD_MIRROR_Y+200*sin(anglaux)), 
+                                                vector2Df(cos(anglaux),sin(anglaux))*10);
+            }
+        }
+        break;
+        case RAIN_MODE: // this is just spots with gravity that reapears in the top position when reaching the bottom:
+          // others are bouncing with gravity:
+        for (i=0; i<blobArray.size(); i++) {
+            if (blobArray[i]->standByMode==false) blobArray[i]->update();
+        }
+        // GAME CHECKS:
+         for (i=0; i<blobArray.size(); i++) {
+           if (blobArray[i]->getCenter().y>MAX_AD_MIRRORS-20) {
+           // Replace position of spot to the initial position:
+                blobArray[i]->explosion();
+                blobArray[i]->resetPositionSpeed();
+            }
+      }
+        break;
+        case VERTICAL_PINBALL_GAME:
+          // spot index 0 is a tracking spot, the background "anchor":
+         if (blobArray[0]->standByMode==false) blobArray[0]->update();
+         // others are bouncing with gravity:
+        for (i=1; i<blobArray.size(); i++) {
+            if (blobArray[i]->standByMode==false) blobArray[i]->update();
+        }
+        // GAME CHECKS:
+         for (i=1; i<blobArray.size(); i++) {
+            dist=(blobArray[0]->getCenter()).distance(blobArray[i]->getCenter());
+            //(1) win (meaning bouncing spot very close to anchor):
+            if (dist<60) {
+                blobArray[i]->explosion();
+                blobArray[i]->setPositionSpeed(vector2Df(blobArray[0]->getCenter().x-400+rand()%800, blobArray[0]->getCenter().y-1200), 
+                                                        vector2Df(0, 0));
+            }
+            //(2) loose (meaning spot went outside range):
+            if (blobArray[i]->getCenter().y>blobArray[0]->getCenter().y) {
+                blobArray[i]->setPositionSpeed(vector2Df(blobArray[0]->getCenter().x-400+rand()%800, blobArray[0]->getCenter().y-1200), 
+                                                        vector2Df(i*10-5, 0));
+                }
+            }
+        break; 
+        case FISH_NET_GAME:
+         // spot index 0 is a tracking spot, the background "anchor":
+         if (blobArray[0]->standByMode==false) blobArray[0]->update();
+         // all the other spots are bouncing spots:
+        for (i=1; i<blobArray.size(); i++) {
+            if (blobArray[i]->standByMode==false) blobArray[i]->update();
+        }
+        // GAME CHECKS: a win only, when all the spots are very close to the mother spot:
+         win=true;
+         for (i=1; i<blobArray.size(); i++) {
+            dist=(blobArray[0]->getCenter()).distance(blobArray[i]->getCenter());
+            win&=(dist<80);
+        }
+        if (win) {
+            for (i=1; i<blobArray.size(); i++) {
+            blobArray[i]->explosion();
+             float anglaux=1.0*(i-1)/(blobArray.size()-1)*2*PI;
+                 blobArray[i]->setPositionSpeed(vector2Df(CENTER_AD_MIRROR_X+400*cos(anglaux), CENTER_AD_MIRROR_Y+400*sin(anglaux)), 
+                                                vector2Df(cos(anglaux),sin(anglaux))*10);
+        }
+        }
+        break;
+        case PAC_MAN_GAME:
+        // spot index 0 is the pacman:
+        if (blobArray[0]->standByMode==false) blobArray[0]->update();
+        // spot 1 and 2 are ghosts:
+        if (blobArray[1]->standByMode==false) blobArray[1]->update(blobArray[0]->getCenter());
+        if (blobArray[2]->standByMode==false) blobArray[2]->update(blobArray[0]->getCenter()); // pass the position of the PACMAN!
+        
+        // GAME CHECK: are any ghost too close to the pacman?
+        for (i=1; i<blobArray.size(); i++) {
+            dist=(blobArray[0]->getCenter()).distance(blobArray[i]->getCenter());
+            if (minDist>dist) minDist=dist;
+        }
+        if (minDist<50) {
+             blobArray[0]->explosion();
+             // then restart the game: 
+            // initConfig(PAC_MAN_GAME);
+        }
+        
+        break;
+        default:
+        break;
+    }
+     
+    
+}
+
+void blobConfig::computeBoundingBox() {
+    for (int i=0; i<blobArray.size(); i++) {
+        blobArray[i]->computeBoundingBox();
+    }
+}
+
+void blobConfig::draw() { // draw uses the opengl like renderer (if any), and save projected trajectory in the LaserSensingTrajectory object of each blob
+    for (int i=0; i<blobArray.size(); i++) {
+        if (blobArray[i]->render==true) blobArray[i]->draw();
+    }
+}
+
+void blobConfig::sendConfData() {
+// For the time being, only "per blob" data sending:
+// (b) Per-spot sending of data (note: both are NOT exclusive; so if we want just packaged data, we need to make all the spot STOP sending data.
+    for (int i=0; i<blobArray.size(); i++) { 
+        if (blobArray[i]->render==true) blobArray[i]->sendData(); // a blob that is in stand-by mode may send data (good for testing with a fixed loop)
+    }
+}
+
+
+
+