![](/media/cache/profiles/68a15b5278e4f7c4c056df9d5f1d3b1f.jpg.50x50_q85.jpg)
save loops
blobConfig.cpp
- Committer:
- mbedalvaro
- Date:
- 2014-12-02
- Revision:
- 0:df6fdd9b99f0
- Child:
- 1:3be7b7d050f4
File content as of revision 0:df6fdd9b99f0:
#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) } }