just a test

Dependencies:   mbed

Fork of scoreLight_Advanced by Alvaro Cassinelli

Committer:
mbedalvaro
Date:
Fri Sep 21 10:02:35 2012 +0000
Revision:
30:d8af03f01cd4
Parent:
27:1ce994629ffc
Child:
31:5f039cbddee8
first commit. Not yet functional. Added ghost and pacman game modes, but the behaviour of these "rigid spots" is not implemented yet

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbedalvaro 30:d8af03f01cd4 1 /*
mbedalvaro 30:d8af03f01cd4 2 * elasticLoop.cpp
mbedalvaro 30:d8af03f01cd4 3 * laserBlobPure
mbedalvaro 30:d8af03f01cd4 4 *
mbedalvaro 30:d8af03f01cd4 5 * Created by CASSINELLI ALVARO on 5/20/11.
mbedalvaro 30:d8af03f01cd4 6 * Copyright 2011 TOKYO UNIVERSITY. All rights reserved.
mbedalvaro 30:d8af03f01cd4 7 *
mbedalvaro 30:d8af03f01cd4 8 */
mbedalvaro 30:d8af03f01cd4 9
mbedalvaro 30:d8af03f01cd4 10 #include "elasticLoop.h"
mbedalvaro 30:d8af03f01cd4 11
mbedalvaro 30:d8af03f01cd4 12 // SHOULD NOT BE HERE: (only because I am using AD_MIRRIOR... max and min in the set region function that should not be here)
mbedalvaro 30:d8af03f01cd4 13 #include "hardwareIO.h"
mbedalvaro 30:d8af03f01cd4 14
mbedalvaro 30:d8af03f01cd4 15 elasticLoop::elasticLoop() {
mbedalvaro 30:d8af03f01cd4 16 }
mbedalvaro 30:d8af03f01cd4 17
mbedalvaro 30:d8af03f01cd4 18 elasticLoop::~elasticLoop() {
mbedalvaro 30:d8af03f01cd4 19 // no need to do clear, this is done by default when clearing the vector container?
mbedalvaro 30:d8af03f01cd4 20 massesLoop.clear();
mbedalvaro 30:d8af03f01cd4 21 loopSpringArray.clear();
mbedalvaro 30:d8af03f01cd4 22 hairVector.clear();
mbedalvaro 30:d8af03f01cd4 23 lightForce.clear();
mbedalvaro 30:d8af03f01cd4 24 centralSpringArray.clear();
mbedalvaro 30:d8af03f01cd4 25 displaySensingBuffer.lsdTrajectory.clear();
mbedalvaro 30:d8af03f01cd4 26 }
mbedalvaro 30:d8af03f01cd4 27
mbedalvaro 30:d8af03f01cd4 28
mbedalvaro 30:d8af03f01cd4 29 void elasticLoop::createBlob(int _id, ElasticLoopMode _elasticBlobMode, vector2Df _initPos, vector2Df _initSpeed) {
mbedalvaro 30:d8af03f01cd4 30 // (1) set ID:
mbedalvaro 30:d8af03f01cd4 31 identifier=_id;
mbedalvaro 30:d8af03f01cd4 32
mbedalvaro 30:d8af03f01cd4 33 startCenter=_initPos;
mbedalvaro 30:d8af03f01cd4 34 startSpeed=_initSpeed;
mbedalvaro 30:d8af03f01cd4 35
mbedalvaro 30:d8af03f01cd4 36 // (2) Initialize common variables of all blobs (base class):
mbedalvaro 30:d8af03f01cd4 37 initCommonVariables();
mbedalvaro 30:d8af03f01cd4 38
mbedalvaro 30:d8af03f01cd4 39 // (3) initialize common variables for the elastic blob types:
mbedalvaro 30:d8af03f01cd4 40 slidingDirection=true; // (will change when touching wall)
mbedalvaro 30:d8af03f01cd4 41 // Sending data:
mbedalvaro 30:d8af03f01cd4 42 periodSendingData=15; // in ms
mbedalvaro 30:d8af03f01cd4 43 sendingLoopPositions=false;
mbedalvaro 30:d8af03f01cd4 44 sendingBlobArea=true;
mbedalvaro 30:d8af03f01cd4 45 sendingKineticEnergy=true;
mbedalvaro 30:d8af03f01cd4 46 sendingOnlyWhenTouch=false; // send ALWAYS, regardless of the fact the blob is being touched or not.
mbedalvaro 30:d8af03f01cd4 47
mbedalvaro 30:d8af03f01cd4 48 // (3) Initialize secondary variables depending on the blob type and mode:
mbedalvaro 30:d8af03f01cd4 49
mbedalvaro 30:d8af03f01cd4 50 // NOTE (!): the mode does not affect the update method; in fact, all these elastic loops have different behaviours because of different parameters (but the booleans modes could
mbedalvaro 30:d8af03f01cd4 51 // actually be "condensed" in a mode...)
mbedalvaro 30:d8af03f01cd4 52
mbedalvaro 30:d8af03f01cd4 53 switch (_elasticBlobMode) {
mbedalvaro 30:d8af03f01cd4 54 case RELAX:
mbedalvaro 30:d8af03f01cd4 55
mbedalvaro 30:d8af03f01cd4 56 // Name of this kind of spot:
mbedalvaro 30:d8af03f01cd4 57 sprintf(spotName,"loop_relax"); //this is an relaxing elastic loop
mbedalvaro 30:d8af03f01cd4 58
mbedalvaro 30:d8af03f01cd4 59 // Color: (use parameter in the future):
mbedalvaro 30:d8af03f01cd4 60 //setColor(0x07);//0x04+0x02>>i);
mbedalvaro 30:d8af03f01cd4 61 setColor(0x04);
mbedalvaro 30:d8af03f01cd4 62
mbedalvaro 30:d8af03f01cd4 63 // default (initial) shape (the scafold belongs to the base class):
mbedalvaro 30:d8af03f01cd4 64 startRadius=400;
mbedalvaro 30:d8af03f01cd4 65 bluePrint.buildCircularScafold(startRadius, vector2Dd(0,0), 40); //(float _radius, vector2Dd _pos, int _numScafoldPoints);
mbedalvaro 30:d8af03f01cd4 66
mbedalvaro 30:d8af03f01cd4 67 // Numeric parameters for the simulated mechanical system:
mbedalvaro 30:d8af03f01cd4 68 massLoopParticle=0.25;
mbedalvaro 30:d8af03f01cd4 69 dampMotionMassesLoop=0.025;//0.17;
mbedalvaro 30:d8af03f01cd4 70 massAnchor=2.0;
mbedalvaro 30:d8af03f01cd4 71 dampMotionAnchorMass=0.001;
mbedalvaro 30:d8af03f01cd4 72 // Springs:
mbedalvaro 30:d8af03f01cd4 73 centralSpringK=0.3;
mbedalvaro 30:d8af03f01cd4 74 centralSpringRelax=startRadius;// use the radius of the scafold
mbedalvaro 30:d8af03f01cd4 75 interSpringK=0.46;
mbedalvaro 30:d8af03f01cd4 76 interSpringRelax=20;
mbedalvaro 30:d8af03f01cd4 77 // for "zack-like" blob:
mbedalvaro 30:d8af03f01cd4 78 interParticleRange=100;
mbedalvaro 30:d8af03f01cd4 79 factorInterParticleForce=18.0;
mbedalvaro 30:d8af03f01cd4 80
mbedalvaro 30:d8af03f01cd4 81 searchActive=false;
mbedalvaro 30:d8af03f01cd4 82 pseudopodesMode=false; // this is for contour following.
mbedalvaro 30:d8af03f01cd4 83
mbedalvaro 30:d8af03f01cd4 84 // Active/inactive forces:
mbedalvaro 30:d8af03f01cd4 85 springForcesOnLoop=true;
mbedalvaro 30:d8af03f01cd4 86 lightForcesOnLoop=true;
mbedalvaro 30:d8af03f01cd4 87 forceBorderOnLoop=false;
mbedalvaro 30:d8af03f01cd4 88 nuclearForceOnLoop=false;//true;
mbedalvaro 30:d8af03f01cd4 89 interParticleForceOnLoop=false;
mbedalvaro 30:d8af03f01cd4 90 forceInternalPressureOnLoop=false; // (when true, either constant force or calculated area using Green function or approximation by bounding box)
mbedalvaro 30:d8af03f01cd4 91
mbedalvaro 30:d8af03f01cd4 92 // Recentering vector:
mbedalvaro 30:d8af03f01cd4 93 angleCorrectionForceLoop=0;// in deg
mbedalvaro 30:d8af03f01cd4 94 recenteringForceOnLoop=false;
mbedalvaro 30:d8af03f01cd4 95 angleCorrectionForceNucleus=0;// in deg
mbedalvaro 30:d8af03f01cd4 96 recenteringForceOnNucleus=false;//true;
mbedalvaro 30:d8af03f01cd4 97
mbedalvaro 30:d8af03f01cd4 98 factorLightForce=4.0;//3.0;//8.0;
mbedalvaro 30:d8af03f01cd4 99 factorRecenteringAnchorMass=20.0/bluePrint.scafold.size(); // use number of points in the scafold
mbedalvaro 30:d8af03f01cd4 100 factorRecenteringLoopMass=0.3;
mbedalvaro 30:d8af03f01cd4 101 factorPressureLoopMass=1.0;
mbedalvaro 30:d8af03f01cd4 102 factorForceBorder=4.5;
mbedalvaro 30:d8af03f01cd4 103
mbedalvaro 30:d8af03f01cd4 104 // per-blob mirror delay (if things were well adjusted - in particular mirror waiting times, then this could be 0.
mbedalvaro 30:d8af03f01cd4 105 //But in case of unique blobs, it may be interesting to accelerate display AND correct the delay by software):
mbedalvaro 30:d8af03f01cd4 106 displaySensingBuffer.setDelayMirrors(2);
mbedalvaro 30:d8af03f01cd4 107
mbedalvaro 30:d8af03f01cd4 108 break;
mbedalvaro 30:d8af03f01cd4 109
mbedalvaro 30:d8af03f01cd4 110 case CONTRACT:
mbedalvaro 30:d8af03f01cd4 111
mbedalvaro 30:d8af03f01cd4 112 sprintf(spotName,"loop_contract"); //this is an relaxing elastic loop
mbedalvaro 30:d8af03f01cd4 113
mbedalvaro 30:d8af03f01cd4 114 setColor(0x07);//0x04+0x02>>i);
mbedalvaro 30:d8af03f01cd4 115
mbedalvaro 30:d8af03f01cd4 116 // default (initial) shape:
mbedalvaro 30:d8af03f01cd4 117 startRadius =400;
mbedalvaro 30:d8af03f01cd4 118 bluePrint.buildCircularScafold(startRadius, vector2Dd(0,0), 40); //(float _radius, vector2Dd _pos,vector2D _vel, int _numScafoldPoints);
mbedalvaro 30:d8af03f01cd4 119
mbedalvaro 30:d8af03f01cd4 120 // Numeric parameters for the simulated mechanical system:
mbedalvaro 30:d8af03f01cd4 121 massLoopParticle=0.25;
mbedalvaro 30:d8af03f01cd4 122 dampMotionMassesLoop=0.024;//0.17;
mbedalvaro 30:d8af03f01cd4 123 massAnchor=2.0;
mbedalvaro 30:d8af03f01cd4 124 dampMotionAnchorMass=0.001;
mbedalvaro 30:d8af03f01cd4 125 // Springs:
mbedalvaro 30:d8af03f01cd4 126 centralSpringK=0.5;
mbedalvaro 30:d8af03f01cd4 127 centralSpringRelax=startRadius;
mbedalvaro 30:d8af03f01cd4 128 interSpringK=0.4;//46;
mbedalvaro 30:d8af03f01cd4 129 interSpringRelax=30;
mbedalvaro 30:d8af03f01cd4 130 // for "zack-like" blob:
mbedalvaro 30:d8af03f01cd4 131 interParticleRange=100;
mbedalvaro 30:d8af03f01cd4 132 factorInterParticleForce=18.0;
mbedalvaro 30:d8af03f01cd4 133
mbedalvaro 30:d8af03f01cd4 134 searchActive=false;
mbedalvaro 30:d8af03f01cd4 135 pseudopodesMode=false; // this is for contour following.
mbedalvaro 30:d8af03f01cd4 136
mbedalvaro 30:d8af03f01cd4 137 // Active/Inactive Forces:
mbedalvaro 30:d8af03f01cd4 138 springForcesOnLoop=true;
mbedalvaro 30:d8af03f01cd4 139 lightForcesOnLoop=true;
mbedalvaro 30:d8af03f01cd4 140 forceBorderOnLoop=false;
mbedalvaro 30:d8af03f01cd4 141 nuclearForceOnLoop=true;//true;
mbedalvaro 30:d8af03f01cd4 142 interParticleForceOnLoop=false;
mbedalvaro 30:d8af03f01cd4 143 forceInternalPressureOnLoop=false; // (when true, either constant force or calculated area using Green function or approximation by bounding box)
mbedalvaro 30:d8af03f01cd4 144 // Recentering vector:
mbedalvaro 30:d8af03f01cd4 145 angleCorrectionForceLoop=0;// in deg
mbedalvaro 30:d8af03f01cd4 146 recenteringForceOnLoop=false;
mbedalvaro 30:d8af03f01cd4 147 angleCorrectionForceNucleus=0;// in deg
mbedalvaro 30:d8af03f01cd4 148 recenteringForceOnNucleus=false;//true;
mbedalvaro 30:d8af03f01cd4 149
mbedalvaro 30:d8af03f01cd4 150 factorLightForce=6.0;//3.0;//8.0;
mbedalvaro 30:d8af03f01cd4 151 factorRecenteringAnchorMass=20.0/bluePrint.scafold.size();
mbedalvaro 30:d8af03f01cd4 152 factorRecenteringLoopMass=0.3;
mbedalvaro 30:d8af03f01cd4 153 factorPressureLoopMass=1.0;
mbedalvaro 30:d8af03f01cd4 154 factorForceBorder=4.5;
mbedalvaro 30:d8af03f01cd4 155
mbedalvaro 30:d8af03f01cd4 156 // per-blob mirror delay (if things were well adjusted - in particular mirror waiting times, then this could be 0.
mbedalvaro 30:d8af03f01cd4 157 //But in case of unique blobs, it may be interesting to accelerate display AND correct the delay by software):
mbedalvaro 30:d8af03f01cd4 158 displaySensingBuffer.setDelayMirrors(2); // per-blob mirror delay (if things were well adjusted - in particular mirror waiting times, then this could be 0.
mbedalvaro 30:d8af03f01cd4 159
mbedalvaro 30:d8af03f01cd4 160 break;
mbedalvaro 30:d8af03f01cd4 161 case CONTRACT_CENTRAL:
mbedalvaro 30:d8af03f01cd4 162
mbedalvaro 30:d8af03f01cd4 163 sprintf(spotName,"contract_central");
mbedalvaro 30:d8af03f01cd4 164
mbedalvaro 30:d8af03f01cd4 165 //setColor(0x07);//0x04+0x02>>i);
mbedalvaro 30:d8af03f01cd4 166 setColor(0x04);
mbedalvaro 30:d8af03f01cd4 167
mbedalvaro 30:d8af03f01cd4 168 // default (initial) shape:
mbedalvaro 30:d8af03f01cd4 169 startRadius=400;
mbedalvaro 30:d8af03f01cd4 170 bluePrint.buildCircularScafold(startRadius, vector2Dd(0,0), 45); //(float _radius, vector2Dd _pos,vector2D _vel, int _numScafoldPoints);
mbedalvaro 30:d8af03f01cd4 171
mbedalvaro 30:d8af03f01cd4 172 // Numeric parameters for the simulated mechanical system:
mbedalvaro 30:d8af03f01cd4 173 massLoopParticle=0.3;
mbedalvaro 30:d8af03f01cd4 174 dampMotionMassesLoop=0.023;//0.17;
mbedalvaro 30:d8af03f01cd4 175 massAnchor=0.5;
mbedalvaro 30:d8af03f01cd4 176 dampMotionAnchorMass=0.001;
mbedalvaro 30:d8af03f01cd4 177 // Springs:
mbedalvaro 30:d8af03f01cd4 178 centralSpringK=0.3;
mbedalvaro 30:d8af03f01cd4 179 centralSpringRelax=startRadius;
mbedalvaro 30:d8af03f01cd4 180 interSpringK=0.54;//46;
mbedalvaro 30:d8af03f01cd4 181 interSpringRelax=30;
mbedalvaro 30:d8af03f01cd4 182 // for "zack-like" blob:
mbedalvaro 30:d8af03f01cd4 183 interParticleRange=100;
mbedalvaro 30:d8af03f01cd4 184 factorInterParticleForce=18.0;
mbedalvaro 30:d8af03f01cd4 185
mbedalvaro 30:d8af03f01cd4 186 searchActive=false;
mbedalvaro 30:d8af03f01cd4 187 pseudopodesMode=false; // this is for contour following.
mbedalvaro 30:d8af03f01cd4 188
mbedalvaro 30:d8af03f01cd4 189 // Active/Inactive Forces:
mbedalvaro 30:d8af03f01cd4 190 springForcesOnLoop= true;
mbedalvaro 30:d8af03f01cd4 191 lightForcesOnLoop= true;
mbedalvaro 30:d8af03f01cd4 192 forceBorderOnLoop=false;
mbedalvaro 30:d8af03f01cd4 193 nuclearForceOnLoop=false;//true;
mbedalvaro 30:d8af03f01cd4 194 interParticleForceOnLoop=false;
mbedalvaro 30:d8af03f01cd4 195 forceInternalPressureOnLoop=false; // (when true, either constant force or calculated area using Green function or approximation by bounding box)
mbedalvaro 30:d8af03f01cd4 196 // Recentering vector:
mbedalvaro 30:d8af03f01cd4 197 angleCorrectionForceLoop=0;// in deg
mbedalvaro 30:d8af03f01cd4 198 recenteringForceOnLoop=false ; //true; !!!!!!!!!!!!!!!
mbedalvaro 30:d8af03f01cd4 199 angleCorrectionForceNucleus=0;// in deg
mbedalvaro 30:d8af03f01cd4 200 recenteringForceOnNucleus=false;//true;
mbedalvaro 30:d8af03f01cd4 201
mbedalvaro 30:d8af03f01cd4 202 factorLightForce=6.3;//4.3;
mbedalvaro 30:d8af03f01cd4 203 factorRecenteringAnchorMass= 20.0/bluePrint.scafold.size();
mbedalvaro 30:d8af03f01cd4 204 factorRecenteringLoopMass=0.045;
mbedalvaro 30:d8af03f01cd4 205 factorPressureLoopMass=1.5;
mbedalvaro 30:d8af03f01cd4 206 factorForceBorder=150;
mbedalvaro 30:d8af03f01cd4 207
mbedalvaro 30:d8af03f01cd4 208 // per-blob mirror delay (if things were well adjusted - in particular mirror waiting times, then this could be 0.
mbedalvaro 30:d8af03f01cd4 209 //But in case of unique blobs, it may be interesting to accelerate display AND correct the delay by software):
mbedalvaro 30:d8af03f01cd4 210 displaySensingBuffer.setDelayMirrors(4);
mbedalvaro 30:d8af03f01cd4 211
mbedalvaro 30:d8af03f01cd4 212 break;
mbedalvaro 30:d8af03f01cd4 213
mbedalvaro 30:d8af03f01cd4 214 case CONTRACT_CENTRAL_FAST:
mbedalvaro 30:d8af03f01cd4 215
mbedalvaro 30:d8af03f01cd4 216 //setColor(0x07);//0x04+0x02>>i);
mbedalvaro 30:d8af03f01cd4 217 setColor(0x04);
mbedalvaro 30:d8af03f01cd4 218
mbedalvaro 30:d8af03f01cd4 219 // default (initial) shape:
mbedalvaro 30:d8af03f01cd4 220 startRadius=150;
mbedalvaro 30:d8af03f01cd4 221 bluePrint.buildCircularScafold(startRadius, vector2Dd(0,0), 40); //(float _radius, vector2Dd _pos,vector2D _vel, int _numScafoldPoints);
mbedalvaro 30:d8af03f01cd4 222
mbedalvaro 30:d8af03f01cd4 223 // Numeric parameters for the simulated mechanical system:
mbedalvaro 30:d8af03f01cd4 224 massLoopParticle=0.06;
mbedalvaro 30:d8af03f01cd4 225 dampMotionMassesLoop=0.021;//0.17;
mbedalvaro 30:d8af03f01cd4 226 massAnchor=0.5;
mbedalvaro 30:d8af03f01cd4 227 dampMotionAnchorMass=0.01;
mbedalvaro 30:d8af03f01cd4 228 // Springs:
mbedalvaro 30:d8af03f01cd4 229 centralSpringK=0.3;
mbedalvaro 30:d8af03f01cd4 230 centralSpringRelax=startRadius;
mbedalvaro 30:d8af03f01cd4 231 interSpringK=0.54;//46;
mbedalvaro 30:d8af03f01cd4 232 interSpringRelax=40;
mbedalvaro 30:d8af03f01cd4 233 // for "zack-like" blob:
mbedalvaro 30:d8af03f01cd4 234 interParticleRange=150;
mbedalvaro 30:d8af03f01cd4 235 factorInterParticleForce=160.0;
mbedalvaro 30:d8af03f01cd4 236
mbedalvaro 30:d8af03f01cd4 237 searchActive=false;
mbedalvaro 30:d8af03f01cd4 238 pseudopodesMode=false; // this is for contour following.
mbedalvaro 30:d8af03f01cd4 239
mbedalvaro 30:d8af03f01cd4 240 // Active/Inactive Forces:
mbedalvaro 30:d8af03f01cd4 241 springForcesOnLoop= true;
mbedalvaro 30:d8af03f01cd4 242 lightForcesOnLoop= true;
mbedalvaro 30:d8af03f01cd4 243 forceBorderOnLoop=false;
mbedalvaro 30:d8af03f01cd4 244 nuclearForceOnLoop=false;
mbedalvaro 30:d8af03f01cd4 245 interParticleForceOnLoop=true; //!!!
mbedalvaro 30:d8af03f01cd4 246 forceInternalPressureOnLoop=false; // (when true, either constant force or calculated area using Green function or approximation by bounding box)
mbedalvaro 30:d8af03f01cd4 247 // Recentering vector:
mbedalvaro 30:d8af03f01cd4 248 angleCorrectionForceLoop=90;// in deg
mbedalvaro 30:d8af03f01cd4 249 recenteringForceOnLoop=true;
mbedalvaro 30:d8af03f01cd4 250 angleCorrectionForceNucleus=0;// in deg
mbedalvaro 30:d8af03f01cd4 251 recenteringForceOnNucleus=false;//true;
mbedalvaro 30:d8af03f01cd4 252
mbedalvaro 30:d8af03f01cd4 253 factorLightForce=-4;//3.0;//8.0;
mbedalvaro 30:d8af03f01cd4 254 factorRecenteringAnchorMass= 20.0/bluePrint.scafold.size();
mbedalvaro 30:d8af03f01cd4 255 factorRecenteringLoopMass=0.06;
mbedalvaro 30:d8af03f01cd4 256 factorPressureLoopMass=1.5;
mbedalvaro 30:d8af03f01cd4 257 factorForceBorder=150;
mbedalvaro 30:d8af03f01cd4 258
mbedalvaro 30:d8af03f01cd4 259 displaySensingBuffer.setDelayMirrors(70);
mbedalvaro 30:d8af03f01cd4 260 break;
mbedalvaro 30:d8af03f01cd4 261
mbedalvaro 30:d8af03f01cd4 262 case CONTOUR_FOLLOWING:
mbedalvaro 30:d8af03f01cd4 263 sprintf(spotName,"following"); //this is a contour-following loop
mbedalvaro 30:d8af03f01cd4 264
mbedalvaro 30:d8af03f01cd4 265 //setColor(0x07);//0x04+0x02>>i);
mbedalvaro 30:d8af03f01cd4 266 setColor(0x04);
mbedalvaro 30:d8af03f01cd4 267
mbedalvaro 30:d8af03f01cd4 268 // default (initial) shape:
mbedalvaro 30:d8af03f01cd4 269 startRadius=100;
mbedalvaro 30:d8af03f01cd4 270 bluePrint.buildCircularScafold(startRadius, vector2Dd(0,0), 20); //(float _radius, vector2Dd _pos,vector2D _vel, int _numScafoldPoints);
mbedalvaro 30:d8af03f01cd4 271
mbedalvaro 30:d8af03f01cd4 272 // Numeric parameters for the simulated mechanical system:
mbedalvaro 30:d8af03f01cd4 273 massLoopParticle=0.05;
mbedalvaro 30:d8af03f01cd4 274 dampMotionMassesLoop=0.27;//0.17;
mbedalvaro 30:d8af03f01cd4 275 massAnchor=3.0;
mbedalvaro 30:d8af03f01cd4 276 dampMotionAnchorMass=0.03;
mbedalvaro 30:d8af03f01cd4 277 // Springs:
mbedalvaro 30:d8af03f01cd4 278 centralSpringK=0.4;
mbedalvaro 30:d8af03f01cd4 279 centralSpringRelax=100;//bluePrint.radius;
mbedalvaro 30:d8af03f01cd4 280 interSpringK=0.4;//46;
mbedalvaro 30:d8af03f01cd4 281 interSpringRelax=0.7*startRadius*2*sin(1.0* PI/ bluePrint.scafold.size()); // if factor=1, this makes for a perfect polygon at relax for all springs...
mbedalvaro 30:d8af03f01cd4 282 // for "zack-like" blob:
mbedalvaro 30:d8af03f01cd4 283 interParticleRange=70;
mbedalvaro 30:d8af03f01cd4 284 factorInterParticleForce=4.0;
mbedalvaro 30:d8af03f01cd4 285
mbedalvaro 30:d8af03f01cd4 286 searchActive=true;
mbedalvaro 30:d8af03f01cd4 287 pseudopodesMode=true; // this is for contour following.
mbedalvaro 30:d8af03f01cd4 288
mbedalvaro 30:d8af03f01cd4 289 // Active/Inactive Forces:
mbedalvaro 30:d8af03f01cd4 290 springForcesOnLoop=true;
mbedalvaro 30:d8af03f01cd4 291 lightForcesOnLoop=true;
mbedalvaro 30:d8af03f01cd4 292 forceBorderOnLoop=false;
mbedalvaro 30:d8af03f01cd4 293 nuclearForceOnLoop=false;//true;
mbedalvaro 30:d8af03f01cd4 294 interParticleForceOnLoop=true;
mbedalvaro 30:d8af03f01cd4 295 forceInternalPressureOnLoop=false; // (when true, either constant force or calculated area using Green function or approximation by bounding box)
mbedalvaro 30:d8af03f01cd4 296 // Recentering vector:
mbedalvaro 30:d8af03f01cd4 297 angleCorrectionForceLoop=240;//239;// in deg
mbedalvaro 30:d8af03f01cd4 298 recenteringForceOnLoop=true;
mbedalvaro 30:d8af03f01cd4 299 angleCorrectionForceNucleus=180;// in deg
mbedalvaro 30:d8af03f01cd4 300 recenteringForceOnNucleus=false;//true;
mbedalvaro 30:d8af03f01cd4 301
mbedalvaro 30:d8af03f01cd4 302 factorLightForce=2.23;//3.0;//8.0;
mbedalvaro 30:d8af03f01cd4 303 factorRecenteringAnchorMass=1.0;//20.0/scafold.size();
mbedalvaro 30:d8af03f01cd4 304 factorRecenteringLoopMass=0.09;
mbedalvaro 30:d8af03f01cd4 305 factorPressureLoopMass=1.5;
mbedalvaro 30:d8af03f01cd4 306 factorForceBorder=150;
mbedalvaro 30:d8af03f01cd4 307 // per-blob mirror delay (if things were well adjusted - in particular mirror waiting times, then this could be 0.
mbedalvaro 30:d8af03f01cd4 308 //But in case of unique blobs, it may be interesting to accelerate display AND correct the delay by software):
mbedalvaro 30:d8af03f01cd4 309 displaySensingBuffer.setDelayMirrors(4);
mbedalvaro 30:d8af03f01cd4 310
mbedalvaro 30:d8af03f01cd4 311 break;
mbedalvaro 30:d8af03f01cd4 312 case CONTOUR_FOLLOWING_FAST:
mbedalvaro 30:d8af03f01cd4 313 sprintf(spotName,"following_fast");
mbedalvaro 30:d8af03f01cd4 314
mbedalvaro 30:d8af03f01cd4 315 setColor(0x07);//0x04+0x02>>i);
mbedalvaro 30:d8af03f01cd4 316
mbedalvaro 30:d8af03f01cd4 317 // default (initial) shape:
mbedalvaro 30:d8af03f01cd4 318 startRadius=100;
mbedalvaro 30:d8af03f01cd4 319 bluePrint.buildCircularScafold(startRadius, vector2Dd(0,0), 30); //(float _radius, vector2Dd _pos,vector2D _vel, int _numScafoldPoints);
mbedalvaro 30:d8af03f01cd4 320
mbedalvaro 30:d8af03f01cd4 321 // Numeric parameters for the simulated mechanical system:
mbedalvaro 30:d8af03f01cd4 322 massLoopParticle=0.05;
mbedalvaro 30:d8af03f01cd4 323 dampMotionMassesLoop=0.27;//0.17;
mbedalvaro 30:d8af03f01cd4 324 massAnchor=3.0;
mbedalvaro 30:d8af03f01cd4 325 dampMotionAnchorMass=0.03;
mbedalvaro 30:d8af03f01cd4 326 // Springs:
mbedalvaro 30:d8af03f01cd4 327 centralSpringK=-200;
mbedalvaro 30:d8af03f01cd4 328 centralSpringRelax=100;//bluePrint.radius;
mbedalvaro 30:d8af03f01cd4 329 interSpringK=0.5;//46;
mbedalvaro 30:d8af03f01cd4 330 interSpringRelax=0.7*startRadius*2*sin(1.0* PI/bluePrint.scafold.size()); // if factor=1, this makes for a perfect polygon at relax for all springs...
mbedalvaro 30:d8af03f01cd4 331 // for "zack-like" blob:
mbedalvaro 30:d8af03f01cd4 332 interParticleRange=80;
mbedalvaro 30:d8af03f01cd4 333 factorInterParticleForce=4.0;
mbedalvaro 30:d8af03f01cd4 334
mbedalvaro 30:d8af03f01cd4 335 searchActive=false;
mbedalvaro 30:d8af03f01cd4 336 pseudopodesMode=true; // this is for contour following.
mbedalvaro 30:d8af03f01cd4 337
mbedalvaro 30:d8af03f01cd4 338 // Active/Inactive Forces:
mbedalvaro 30:d8af03f01cd4 339 springForcesOnLoop=true;
mbedalvaro 30:d8af03f01cd4 340 lightForcesOnLoop=true;
mbedalvaro 30:d8af03f01cd4 341 forceBorderOnLoop=false;
mbedalvaro 30:d8af03f01cd4 342 nuclearForceOnLoop=false;//true;
mbedalvaro 30:d8af03f01cd4 343 interParticleForceOnLoop=false;
mbedalvaro 30:d8af03f01cd4 344 forceInternalPressureOnLoop=false; // (when true, either constant force or calculated area using Green function or approximation by bounding box)
mbedalvaro 30:d8af03f01cd4 345 // Recentering vector:
mbedalvaro 30:d8af03f01cd4 346 angleCorrectionForceLoop=243;// in deg
mbedalvaro 30:d8af03f01cd4 347 recenteringForceOnLoop=true;
mbedalvaro 30:d8af03f01cd4 348 angleCorrectionForceNucleus=180;// in deg
mbedalvaro 30:d8af03f01cd4 349 recenteringForceOnNucleus=false;//true;
mbedalvaro 30:d8af03f01cd4 350
mbedalvaro 30:d8af03f01cd4 351 factorLightForce=2.3;//3.0;//8.0;
mbedalvaro 30:d8af03f01cd4 352 factorRecenteringAnchorMass=1.0;//20.0/bluePrint.scafold.size();
mbedalvaro 30:d8af03f01cd4 353 factorRecenteringLoopMass=0.09;
mbedalvaro 30:d8af03f01cd4 354 factorPressureLoopMass=1.5;
mbedalvaro 30:d8af03f01cd4 355 factorForceBorder=150;
mbedalvaro 30:d8af03f01cd4 356
mbedalvaro 30:d8af03f01cd4 357 // per-blob mirror delay (if things were well adjusted - in particular mirror waiting times, then this could be 0.
mbedalvaro 30:d8af03f01cd4 358 //But in case of unique blobs, it may be interesting to accelerate display AND correct the delay by software):
mbedalvaro 30:d8af03f01cd4 359 displaySensingBuffer.setDelayMirrors(2);
mbedalvaro 30:d8af03f01cd4 360 break;
mbedalvaro 30:d8af03f01cd4 361 case BOUNCING:
mbedalvaro 30:d8af03f01cd4 362 sprintf(spotName,"bouncing");
mbedalvaro 30:d8af03f01cd4 363
mbedalvaro 30:d8af03f01cd4 364 setColor(0x07);//0x04+0x02>>i);
mbedalvaro 30:d8af03f01cd4 365
mbedalvaro 30:d8af03f01cd4 366 // default (initial) shape:
mbedalvaro 30:d8af03f01cd4 367 startRadius=70;
mbedalvaro 30:d8af03f01cd4 368 bluePrint.buildCircularScafold(startRadius, vector2Dd(0,0), 20); //(float _radius, vector2Dd _pos,vector2D _vel, int _numScafoldPoints);
mbedalvaro 30:d8af03f01cd4 369
mbedalvaro 30:d8af03f01cd4 370 // Numeric parameters for the simulated mechanical system:
mbedalvaro 30:d8af03f01cd4 371 massLoopParticle=5.0;
mbedalvaro 30:d8af03f01cd4 372 dampMotionMassesLoop=0.001;//0.17;
mbedalvaro 30:d8af03f01cd4 373 massAnchor=1.0;
mbedalvaro 30:d8af03f01cd4 374 dampMotionAnchorMass=0.002;
mbedalvaro 30:d8af03f01cd4 375 // Springs:
mbedalvaro 30:d8af03f01cd4 376 centralSpringK=1.0;
mbedalvaro 30:d8af03f01cd4 377 centralSpringRelax=70;//bluePrint.radius;
mbedalvaro 30:d8af03f01cd4 378 interSpringK=0.4;//46;
mbedalvaro 30:d8af03f01cd4 379 interSpringRelax==1.0*startRadius*2*sin(1.0* PI/bluePrint.scafold.size()); // if factor=1, this makes for a perfect polygon at relax for all springs...
mbedalvaro 30:d8af03f01cd4 380 // for "zack-like" blob:
mbedalvaro 30:d8af03f01cd4 381 interParticleRange=100;
mbedalvaro 30:d8af03f01cd4 382 factorInterParticleForce=3.0;
mbedalvaro 30:d8af03f01cd4 383
mbedalvaro 30:d8af03f01cd4 384 searchActive=false;
mbedalvaro 30:d8af03f01cd4 385 pseudopodesMode=false; // this is for contour following.
mbedalvaro 30:d8af03f01cd4 386
mbedalvaro 30:d8af03f01cd4 387 // Active/Inactive Forces:
mbedalvaro 30:d8af03f01cd4 388 springForcesOnLoop=true;
mbedalvaro 30:d8af03f01cd4 389 lightForcesOnLoop=true;
mbedalvaro 30:d8af03f01cd4 390 forceBorderOnLoop=true;
mbedalvaro 30:d8af03f01cd4 391 nuclearForceOnLoop=true;//true;
mbedalvaro 30:d8af03f01cd4 392 interParticleForceOnLoop=false;
mbedalvaro 30:d8af03f01cd4 393 forceInternalPressureOnLoop=false; // (when true, either constant force or calculated area using Green function or approximation by bounding box)
mbedalvaro 30:d8af03f01cd4 394 // Recentering vector:
mbedalvaro 30:d8af03f01cd4 395 angleCorrectionForceLoop=0;// in deg
mbedalvaro 30:d8af03f01cd4 396 recenteringForceOnLoop=false;
mbedalvaro 30:d8af03f01cd4 397 angleCorrectionForceNucleus=0;// in deg
mbedalvaro 30:d8af03f01cd4 398 recenteringForceOnNucleus=false;//true;
mbedalvaro 30:d8af03f01cd4 399
mbedalvaro 30:d8af03f01cd4 400 factorLightForce=0.6;//3.0;//8.0;
mbedalvaro 30:d8af03f01cd4 401 factorRecenteringAnchorMass=100.0/bluePrint.scafold.size();
mbedalvaro 30:d8af03f01cd4 402 factorRecenteringLoopMass=5.0;
mbedalvaro 30:d8af03f01cd4 403 factorPressureLoopMass=2.0;
mbedalvaro 30:d8af03f01cd4 404 factorForceBorder=4.5;
mbedalvaro 30:d8af03f01cd4 405
mbedalvaro 30:d8af03f01cd4 406 // per-blob mirror delay (if things were well adjusted - in particular mirror waiting times, then this could be 0.
mbedalvaro 30:d8af03f01cd4 407 //But in case of unique blobs, it may be interesting to accelerate display AND correct the delay by software):
mbedalvaro 30:d8af03f01cd4 408 displaySensingBuffer.setDelayMirrors(2);
mbedalvaro 30:d8af03f01cd4 409 break;
mbedalvaro 30:d8af03f01cd4 410 }
mbedalvaro 30:d8af03f01cd4 411
mbedalvaro 30:d8af03f01cd4 412 // Finally, we can create the loop using these parameters, and the positions given in the scafold:
mbedalvaro 30:d8af03f01cd4 413 createLoopFromScafold(); // this sets the number of masses
mbedalvaro 30:d8af03f01cd4 414
mbedalvaro 30:d8af03f01cd4 415 // Excursion limits (ATTN!!! this will set the limits for all the masses, so we need FIRT to call to createLoopFromScafold - NO NEEDED ANYMORE: now calling to static member method of pointMass...)
mbedalvaro 30:d8af03f01cd4 416 setRegionMotion(MIN_AD_MIRRORS, MIN_AD_MIRRORS, MAX_AD_MIRRORS, MAX_AD_MIRRORS);
mbedalvaro 30:d8af03f01cd4 417
mbedalvaro 30:d8af03f01cd4 418 // draw it once on the display buffer for good initialization:
mbedalvaro 30:d8af03f01cd4 419 draw();
mbedalvaro 30:d8af03f01cd4 420 }
mbedalvaro 30:d8af03f01cd4 421
mbedalvaro 30:d8af03f01cd4 422 void elasticLoop::speedFactor(float speedfactor) {
mbedalvaro 30:d8af03f01cd4 423 // This method is more appropiate for rigid loop, but we can "simulate" speed up in case of elastic loop by changing some parameters, even if the loop is not
mbedalvaro 30:d8af03f01cd4 424 // set in "contour following" mode.
mbedalvaro 30:d8af03f01cd4 425 factorRecenteringLoopMass*=speedfactor;
mbedalvaro 30:d8af03f01cd4 426 }
mbedalvaro 30:d8af03f01cd4 427
mbedalvaro 30:d8af03f01cd4 428 void elasticLoop::initSizeBlob(int _numMasses) {
mbedalvaro 30:d8af03f01cd4 429 // Iinitialize blob size (number of points for the loop, as well as other structures such as lsdTrajectory)
mbedalvaro 30:d8af03f01cd4 430 numMasses=_numMasses;
mbedalvaro 30:d8af03f01cd4 431 // Since this is an elastic loop object, let's create an elastic loop of masses:
mbedalvaro 30:d8af03f01cd4 432 massesLoop.resize(numMasses);
mbedalvaro 30:d8af03f01cd4 433 loopSpringArray.resize(numMasses); // springs connecting consecutive masses
mbedalvaro 30:d8af03f01cd4 434 // NOTE: to save memory, we can drop hairVector (use lightForce instead)
mbedalvaro 30:d8af03f01cd4 435 hairVector.resize(numMasses); // the perpendiculars to the loop
mbedalvaro 30:d8af03f01cd4 436 lightForce.resize(numMasses); // light force in each particle
mbedalvaro 30:d8af03f01cd4 437 //vector2D totalLightForce; // this belongs to the base class now
mbedalvaro 30:d8af03f01cd4 438 centralSpringArray.resize(numMasses); // springs connecting each mass to the anchorMass.
mbedalvaro 30:d8af03f01cd4 439
mbedalvaro 30:d8af03f01cd4 440 // Sensing and Display trajectory:
mbedalvaro 30:d8af03f01cd4 441 displaySensingBuffer.lsdTrajectory.resize(numMasses); // the lsdTrajectory and the elastic loop will have the same number of points (this could be different - decimation?).
mbedalvaro 30:d8af03f01cd4 442 }
mbedalvaro 30:d8af03f01cd4 443
mbedalvaro 30:d8af03f01cd4 444 // We will build the masses from the scafold shape (and maybe render it once on the lsdTrajectory to initialize this array?)
mbedalvaro 30:d8af03f01cd4 445 void elasticLoop::createLoopFromScafold(void) {
mbedalvaro 30:d8af03f01cd4 446 initSizeBlob(bluePrint.scafold.size()); // important: we will have here the same number of points in the scafold and the elastic loop (massLoop)
mbedalvaro 30:d8af03f01cd4 447
mbedalvaro 30:d8af03f01cd4 448 // Initial conditions for the loop masses:
mbedalvaro 30:d8af03f01cd4 449 for (int i = 0; i < numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 450 massesLoop[i].setIntegrationStep(0.23);//18); // VERY IMPORTANT! in the case of verlet integration, we need to set dt BEFORE setting the initial speed.
mbedalvaro 30:d8af03f01cd4 451 massesLoop[i].setInitialCondition(startCenter.x+bluePrint.scafold[i].x,startCenter.y+bluePrint.scafold[i].y, startSpeed.x, startSpeed.y);
mbedalvaro 30:d8af03f01cd4 452 massesLoop[i].mass=massLoopParticle;
mbedalvaro 30:d8af03f01cd4 453 massesLoop[i].dampMotion=dampMotionMassesLoop;
mbedalvaro 30:d8af03f01cd4 454 }
mbedalvaro 30:d8af03f01cd4 455
mbedalvaro 30:d8af03f01cd4 456 // Springs for the loop:
mbedalvaro 30:d8af03f01cd4 457 for (int i = 0; i<numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 458 loopSpringArray[i].distance =interSpringRelax;
mbedalvaro 30:d8af03f01cd4 459 // if we want an perfect polygon: =startRadius*2*sin(1.0* PI/ numMasses);
mbedalvaro 30:d8af03f01cd4 460 // loopSpringArray[i].distance = startRadius*2*sin(1.0* PI/ numMasses);
mbedalvaro 30:d8af03f01cd4 461 loopSpringArray[i].springiness = interSpringK;//*(i%5==0? .6 : 1);//0.4;//4f;
mbedalvaro 30:d8af03f01cd4 462 loopSpringArray[i].massA = & (massesLoop[i ]);
mbedalvaro 30:d8af03f01cd4 463 loopSpringArray[i].massB = & (massesLoop[(i+1) % numMasses]);
mbedalvaro 30:d8af03f01cd4 464 }
mbedalvaro 30:d8af03f01cd4 465
mbedalvaro 30:d8af03f01cd4 466 // Central (anchor mass):
mbedalvaro 30:d8af03f01cd4 467 anchorMass.setIntegrationStep(0.3); // VERY IMPORTANT! in the case of verlet integration, we need to set dt BEFORE setting the initial speed.
mbedalvaro 30:d8af03f01cd4 468 anchorMass.setInitialCondition(startCenter, startSpeed);
mbedalvaro 30:d8af03f01cd4 469 anchorMass.mass=massAnchor;
mbedalvaro 30:d8af03f01cd4 470 anchorMass.dampMotion = dampMotionAnchorMass;
mbedalvaro 30:d8af03f01cd4 471
mbedalvaro 30:d8af03f01cd4 472
mbedalvaro 30:d8af03f01cd4 473 // Initial conditions for central springs:
mbedalvaro 30:d8af03f01cd4 474 for (int i = 0; i<numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 475 centralSpringArray[i].distance =centralSpringRelax;// + 60* cos ( (1.0*i / numMasses) * 7* 2 * PI);
mbedalvaro 30:d8af03f01cd4 476 centralSpringArray[i].springiness =centralSpringK;// 0.4f;
mbedalvaro 30:d8af03f01cd4 477 centralSpringArray[i].massA = & (anchorMass);
mbedalvaro 30:d8af03f01cd4 478 centralSpringArray[i].massB = & (massesLoop[i]);
mbedalvaro 30:d8af03f01cd4 479 }
mbedalvaro 30:d8af03f01cd4 480 }
mbedalvaro 30:d8af03f01cd4 481
mbedalvaro 30:d8af03f01cd4 482
mbedalvaro 30:d8af03f01cd4 483 void elasticLoop::setRegionMotion(float mmix, float mmiy, float mmax, float mmay) { // Attention: the initial position should be INSIDE this...
mbedalvaro 30:d8af03f01cd4 484 /*
mbedalvaro 30:d8af03f01cd4 485 for (int i = 0; i<numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 486 massesLoop[i].setWallLimits(mmix, mmiy, mmax, mmay);
mbedalvaro 30:d8af03f01cd4 487 }
mbedalvaro 30:d8af03f01cd4 488 anchorMass.setWallLimits(mmix+10, mmiy+10, mmax-10, mmay-10);
mbedalvaro 30:d8af03f01cd4 489 */
mbedalvaro 30:d8af03f01cd4 490
mbedalvaro 30:d8af03f01cd4 491 // Use the static method of the class pointMass:
mbedalvaro 30:d8af03f01cd4 492 // pointMass::setWallLimits(mmix+10, mmiy+10, mmax-10, mmay-10);
mbedalvaro 30:d8af03f01cd4 493 pointMass::setWallLimits(mmix+10, mmiy+10, mmax-10, mmay-10);
mbedalvaro 30:d8af03f01cd4 494 }
mbedalvaro 30:d8af03f01cd4 495
mbedalvaro 30:d8af03f01cd4 496 void elasticLoop::update() {
mbedalvaro 30:d8af03f01cd4 497
mbedalvaro 30:d8af03f01cd4 498 // (I) Process loop geometry (compute "hair vectors", area and first order moment):
mbedalvaro 30:d8af03f01cd4 499 processLoopData();
mbedalvaro 30:d8af03f01cd4 500
mbedalvaro 30:d8af03f01cd4 501 // (II) Process sensing buffer and compute light forces
mbedalvaro 30:d8af03f01cd4 502 displaySensingBuffer.processSensedData();
mbedalvaro 30:d8af03f01cd4 503
mbedalvaro 30:d8af03f01cd4 504 // (III) Reset all forces:
mbedalvaro 30:d8af03f01cd4 505 for (int i = 0; i < numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 506 massesLoop[i].resetForce();
mbedalvaro 30:d8af03f01cd4 507 }
mbedalvaro 30:d8af03f01cd4 508 anchorMass.resetForce();
mbedalvaro 30:d8af03f01cd4 509
mbedalvaro 30:d8af03f01cd4 510 // (IV) COMPUTE FORCES (motion is not update yet):
mbedalvaro 30:d8af03f01cd4 511 //== (1) Compute each particle light force as well as total light force (this will be stored separatedly from the final total particle force to send to OSC):
mbedalvaro 30:d8af03f01cd4 512 totalLightForce.set(0,0);
mbedalvaro 30:d8af03f01cd4 513 for (int i = 0; i < numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 514 // NOTE: to save memory, we can drop hairVector...
mbedalvaro 30:d8af03f01cd4 515 lightForce[i]=hairVector[i]*factorLightForce*displaySensingBuffer.lsdTrajectory[i].lightZone;
mbedalvaro 30:d8af03f01cd4 516 // lightForce[i]=lightForce[i]*factorLightForce*displaySensingBuffer.lsdTrajectory[i].lightZone;
mbedalvaro 30:d8af03f01cd4 517 //compute total light force, not only on lighted zones, because it will mean AWAY from black zones:
mbedalvaro 30:d8af03f01cd4 518 totalLightForce+=lightForce[i]; // note: bad value choice (negative means TOUCH, and equal to -1), TO CHANGE this in future implementations
mbedalvaro 30:d8af03f01cd4 519 }
mbedalvaro 30:d8af03f01cd4 520 //== (2) Compute the "recentering vector" from the total light force, by rotating by the angleCorrection (this will give different behaviours):
mbedalvaro 30:d8af03f01cd4 521 recenteringVectorLoop= totalLightForce.getRotatedDeg(slidingDirection? angleCorrectionForceLoop : 140); // the hard coded value is a hack for the time being...
mbedalvaro 30:d8af03f01cd4 522 // Compute redundant quantities:
mbedalvaro 30:d8af03f01cd4 523 normRecenteringVector=recenteringVectorLoop.length();
mbedalvaro 30:d8af03f01cd4 524 angleRecenteringVector=recenteringVectorLoop.angleDegHoriz();
mbedalvaro 30:d8af03f01cd4 525 recenteringVectorNucleus=totalLightForce.getRotatedDeg(angleCorrectionForceNucleus);
mbedalvaro 30:d8af03f01cd4 526 //== (3) Compute forces on the loop:
mbedalvaro 30:d8af03f01cd4 527 //----(a) Nearest neighbour inter-particle springs on the loop (always? we can have still another mode, following the center mass only, etc...)
mbedalvaro 30:d8af03f01cd4 528 if (springForcesOnLoop) {
mbedalvaro 30:d8af03f01cd4 529 for (int i = 0; i < numMasses; i++) { // if putting -1, the loop is broken
mbedalvaro 30:d8af03f01cd4 530 loopSpringArray[i].update();// this add forces to the particles
mbedalvaro 30:d8af03f01cd4 531 }
mbedalvaro 30:d8af03f01cd4 532 }
mbedalvaro 30:d8af03f01cd4 533 //----(b) Direct forces from light pressure (COULD BE MERGED WITH FORCE RECENTERING!!)
mbedalvaro 30:d8af03f01cd4 534 if (pseudopodesMode) {
mbedalvaro 30:d8af03f01cd4 535 // special "patches" on blob membrane:
mbedalvaro 30:d8af03f01cd4 536 if (lightForcesOnLoop) {
mbedalvaro 30:d8af03f01cd4 537 int sign=1;
mbedalvaro 30:d8af03f01cd4 538 for (int i = 0; i < numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 539 if ((i%2)==0) sign*=-1;
mbedalvaro 30:d8af03f01cd4 540 if (displaySensingBuffer.lsdTrajectory[i].lightZone>0) // this means touching something black: make SOME points attracted by it (pseudopodes!!) - but not all!
mbedalvaro 30:d8af03f01cd4 541 massesLoop[i].addForce(lightForce[i]*(sign<0? -1.24 : 1.4)); // sign<0 means this is a pseudopode attracted by dark zones
mbedalvaro 30:d8af03f01cd4 542 else // this means something white: do nothing, all forces are towards the exterior
mbedalvaro 30:d8af03f01cd4 543 massesLoop[i].addForce(lightForce[i]*1.6); // this force tends to make the blob "inflate", but is not "directional"
mbedalvaro 30:d8af03f01cd4 544 }
mbedalvaro 30:d8af03f01cd4 545 }
mbedalvaro 30:d8af03f01cd4 546 //----(c) Forces from the recentering vector on each particle (WITH PATCHES on the loop?):
mbedalvaro 30:d8af03f01cd4 547 if (recenteringForceOnLoop) {
mbedalvaro 30:d8af03f01cd4 548
mbedalvaro 30:d8af03f01cd4 549 vector2Df auxForce= recenteringVectorLoop*factorRecenteringLoopMass*1.0;
mbedalvaro 30:d8af03f01cd4 550 vector2Df auxForce2= totalLightForce.getRotatedDeg(80)*factorRecenteringLoopMass*(slidingDirection? 0 : 1)*1.8;
mbedalvaro 30:d8af03f01cd4 551 int sign=1;
mbedalvaro 30:d8af03f01cd4 552 for (int i = 0; i < numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 553 if ((i%2)==0) sign*=-1;
mbedalvaro 30:d8af03f01cd4 554 if (displaySensingBuffer.lsdTrajectory[i].lightZone>0) {// this means touching something black: behaviour may depend on the pseudopode presence:
mbedalvaro 30:d8af03f01cd4 555 massesLoop[i].addForce((sign<0? auxForce2 : auxForce2)); // nothing, or sign, or corrected angle
mbedalvaro 30:d8af03f01cd4 556 } else
mbedalvaro 30:d8af03f01cd4 557 massesLoop[i].addForce(auxForce); // this force is responsible for the behaviour (contour following or not)
mbedalvaro 30:d8af03f01cd4 558 }
mbedalvaro 30:d8af03f01cd4 559 }
mbedalvaro 30:d8af03f01cd4 560 } else { // no special zones in the "cell membrane":
mbedalvaro 30:d8af03f01cd4 561 if (lightForcesOnLoop) {
mbedalvaro 30:d8af03f01cd4 562 for (int i = 0; i < numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 563 massesLoop[i].addForce(lightForce[i]);
mbedalvaro 30:d8af03f01cd4 564 }
mbedalvaro 30:d8af03f01cd4 565 }
mbedalvaro 30:d8af03f01cd4 566 //----(c') Forces from the recentering vector on each particle:
mbedalvaro 30:d8af03f01cd4 567 if (recenteringForceOnLoop) {
mbedalvaro 30:d8af03f01cd4 568 vector2Df auxForce= recenteringVectorLoop*factorRecenteringLoopMass;
mbedalvaro 30:d8af03f01cd4 569 for (int i = 0; i < numMasses; i++) massesLoop[i].addForce(auxForce);
mbedalvaro 30:d8af03f01cd4 570 }
mbedalvaro 30:d8af03f01cd4 571 }
mbedalvaro 30:d8af03f01cd4 572
mbedalvaro 30:d8af03f01cd4 573 //----(d) Forces from the anchorMass (depending on how we set the equilibrium position for each central spring, we can have a nice blob shape at equilibrium... like a gear for instance)
mbedalvaro 30:d8af03f01cd4 574 if (nuclearForceOnLoop) {
mbedalvaro 30:d8af03f01cd4 575 // Springs:
mbedalvaro 30:d8af03f01cd4 576 for (int i = 0; i < numMasses; i++) centralSpringArray[i].update();//assymetricUpdate();
mbedalvaro 30:d8af03f01cd4 577 // note: if using centralSpringArray[i].update(), we will add forces to the particles AND to the anchor mass...
mbedalvaro 30:d8af03f01cd4 578 // Inverse square (attractive):
mbedalvaro 30:d8af03f01cd4 579 //for (int i = 0; i < numMasses; i++) massesLoop[i].addInterInvSquareForce(anchorMass, 10, 300, centralSpringK);
mbedalvaro 30:d8af03f01cd4 580 }
mbedalvaro 30:d8af03f01cd4 581 //----(d) Inter loop-particles forces (Zach-Liebermann-like blob):
mbedalvaro 30:d8af03f01cd4 582 if (interParticleForceOnLoop) {
mbedalvaro 30:d8af03f01cd4 583 for (int i = 0; i < numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 584 for (int j = 0; j < i-1; j++) massesLoop[i].addInterSpringForce(massesLoop[j], interParticleRange, factorInterParticleForce);
mbedalvaro 30:d8af03f01cd4 585 }
mbedalvaro 30:d8af03f01cd4 586 }
mbedalvaro 30:d8af03f01cd4 587 //----(e) Internal blob pressure force (my faster method to have a blob-like behaviour):
mbedalvaro 30:d8af03f01cd4 588 if (forceInternalPressureOnLoop) {
mbedalvaro 30:d8af03f01cd4 589 // NOTE on the Physics of the thing: the force on the membrane of a ballon is proportional to the DIFFERENCE of pressures (outside and inside):
mbedalvaro 30:d8af03f01cd4 590 // so: f= factor/area - cte, with cte=factor/area0, with area0 being the area at equilibrium.
mbedalvaro 30:d8af03f01cd4 591 // (And of course, to make it even more exact, we should do pressure*surface, but this will be considered constant)
mbedalvaro 30:d8af03f01cd4 592 // float area0=30000; // area in pixels when at equilibrium
mbedalvaro 30:d8af03f01cd4 593 //float factorPressureLoopMass=-0.1*(1.0/area-1.0/area0);
mbedalvaro 30:d8af03f01cd4 594 //float factorPressureLoopMass=500000.0*(1.0/(area*area)-1.0/(area0*area0));
mbedalvaro 30:d8af03f01cd4 595 //float factorPressureLoopMass=20000.0*(1.0/sqrt(area)-1.0/sqrt(area0));
mbedalvaro 30:d8af03f01cd4 596 // Constant force seems to work well too... but produces an annoying blob reversal (probably solved by using negative light forces instead of internal blob pressure):
mbedalvaro 30:d8af03f01cd4 597 //float factorPressureLoopMass=2.5;//4.8;
mbedalvaro 30:d8af03f01cd4 598 // Now, add the pressure force proportional to the inverse of the area to all particles, or just a signed constant:
mbedalvaro 30:d8af03f01cd4 599 int auxsign=(area>=0? -1: 1);
mbedalvaro 30:d8af03f01cd4 600 auxsign=-1;
mbedalvaro 30:d8af03f01cd4 601 for (int i = 0; i < numMasses; i++) massesLoop[i].addForce( hairVector[i] * factorPressureLoopMass* auxsign);
mbedalvaro 30:d8af03f01cd4 602 }
mbedalvaro 30:d8af03f01cd4 603 //----(f) force from border:
mbedalvaro 30:d8af03f01cd4 604 if (forceBorderOnLoop) {
mbedalvaro 30:d8af03f01cd4 605 for (int i = 0; i < numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 606 if (massesLoop[i].bWallCollision) massesLoop[i].addForce(massesLoop[i].innerCollitionDirection*factorForceBorder);
mbedalvaro 30:d8af03f01cd4 607 }
mbedalvaro 30:d8af03f01cd4 608 }
mbedalvaro 30:d8af03f01cd4 609
mbedalvaro 30:d8af03f01cd4 610 //== (4) Compute forces on the anchor mass:
mbedalvaro 30:d8af03f01cd4 611 //----(a) Force from data send by OSC? (ex: from mouse?)
mbedalvaro 30:d8af03f01cd4 612 // anchorMass.addSpringForce(mx, my, 500, -10.2f);
mbedalvaro 30:d8af03f01cd4 613 // or direct control:
mbedalvaro 30:d8af03f01cd4 614 // anchorMass.pos.x=mx;anchorMass.pos.y=my;
mbedalvaro 30:d8af03f01cd4 615 //----(b) Force from the total light force (aka, the "recentering vector"!):
mbedalvaro 30:d8af03f01cd4 616 if (recenteringForceOnNucleus) {
mbedalvaro 30:d8af03f01cd4 617 anchorMass.addForce(recenteringVectorNucleus*factorRecenteringAnchorMass);
mbedalvaro 30:d8af03f01cd4 618 }
mbedalvaro 30:d8af03f01cd4 619
mbedalvaro 30:d8af03f01cd4 620 // when nothing is touching it for a while:
mbedalvaro 30:d8af03f01cd4 621 if (searchActive) {
mbedalvaro 30:d8af03f01cd4 622 if (!displaySensingBuffer.lightTouched) {
mbedalvaro 30:d8af03f01cd4 623 if (firstTimeNoTouch) {
mbedalvaro 30:d8af03f01cd4 624 firstTimeNoTouch=false;
mbedalvaro 30:d8af03f01cd4 625 computeBoundingBox();
mbedalvaro 30:d8af03f01cd4 626 randomForce.set(2000-cx,2000-cy);
mbedalvaro 30:d8af03f01cd4 627 randomForce.normalize();
mbedalvaro 30:d8af03f01cd4 628 randomForce= randomForce.getRotatedDeg(rand()%50-25);
mbedalvaro 30:d8af03f01cd4 629 }
mbedalvaro 30:d8af03f01cd4 630 if (noTouchedCounter>0) {
mbedalvaro 30:d8af03f01cd4 631 // add random force, modulated:
mbedalvaro 30:d8af03f01cd4 632 float aux=1.0*noTouchedCounter/1150;
mbedalvaro 30:d8af03f01cd4 633 vector2Df randf=randomForce.getRotatedDeg(40.0*sin(aux*2*PI*2))*20.0;//*(1.0-aux)*0.3;
mbedalvaro 30:d8af03f01cd4 634 for (int i = 0; i < 1; i=i+1) { // only on some of the particles, and better if these are in the "black attractive" patch!
mbedalvaro 30:d8af03f01cd4 635 massesLoop[i].addForce(randf);
mbedalvaro 30:d8af03f01cd4 636 }
mbedalvaro 30:d8af03f01cd4 637 // and a special point?
mbedalvaro 30:d8af03f01cd4 638 //massesLoop[numMasses/2].addForce(randf);
mbedalvaro 30:d8af03f01cd4 639 // plus amoeba effect ?
mbedalvaro 30:d8af03f01cd4 640 // for (int i = 0; i < numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 641 // massesLoop[i].addForce(hairVector[i]*18*cos( (0.0*noTouchedCounter/1000 + 1.0*i/(numMasses-1)*2*PI*3)));
mbedalvaro 30:d8af03f01cd4 642 //}
mbedalvaro 30:d8af03f01cd4 643
mbedalvaro 30:d8af03f01cd4 644 if ((noTouchedCounter>1150)||(blobWallCollision)) {
mbedalvaro 30:d8af03f01cd4 645 noTouchedCounter=0;
mbedalvaro 30:d8af03f01cd4 646 // compute force towards the center, slightly rotated to make the blob wander about:
mbedalvaro 30:d8af03f01cd4 647 computeBoundingBox();
mbedalvaro 30:d8af03f01cd4 648 randomForce.set(2000-cx,2000-cy);
mbedalvaro 30:d8af03f01cd4 649 randomForce.normalize();
mbedalvaro 30:d8af03f01cd4 650 randomForce= randomForce.getRotatedDeg(rand()%50-25);
mbedalvaro 30:d8af03f01cd4 651 }
mbedalvaro 30:d8af03f01cd4 652 }
mbedalvaro 30:d8af03f01cd4 653 } else {
mbedalvaro 30:d8af03f01cd4 654 firstTimeNoTouch=true;
mbedalvaro 30:d8af03f01cd4 655 noTouchedCounter=0;
mbedalvaro 30:d8af03f01cd4 656 }
mbedalvaro 30:d8af03f01cd4 657 noTouchedCounter++;
mbedalvaro 30:d8af03f01cd4 658 }
mbedalvaro 30:d8af03f01cd4 659
mbedalvaro 30:d8af03f01cd4 660 // (V) UPDATE DYNAMICS
mbedalvaro 30:d8af03f01cd4 661 //== (1) particules on the loop:
mbedalvaro 30:d8af03f01cd4 662 for (int i = 0; i < numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 663 #ifndef VERLET_METHOD
mbedalvaro 30:d8af03f01cd4 664 massesLoop[i].addDampingForce(); // only in case of EULER method (damping in VERLET mode is done automatically when updating)
mbedalvaro 30:d8af03f01cd4 665 #endif
mbedalvaro 30:d8af03f01cd4 666 massesLoop[i].update(); // unconstrained
mbedalvaro 30:d8af03f01cd4 667 massesLoop[i].bounceOffWalls(); // constrain position (and compute wall "hit")
mbedalvaro 30:d8af03f01cd4 668 }
mbedalvaro 30:d8af03f01cd4 669 //== (2) For the anchorMass:
mbedalvaro 30:d8af03f01cd4 670 #ifndef VERLET_METHOD
mbedalvaro 30:d8af03f01cd4 671 anchorMass.addDampingForce(); // // only in case of EULER method (damping in VERLET mode is done automatically when updating)
mbedalvaro 30:d8af03f01cd4 672 #endif
mbedalvaro 30:d8af03f01cd4 673 anchorMass.update(); // unconstrained
mbedalvaro 30:d8af03f01cd4 674 anchorMass.bounceOffWalls(); // constrain position (and compute wall "hit")
mbedalvaro 30:d8af03f01cd4 675
mbedalvaro 30:d8af03f01cd4 676 // OTHER PARTICULAR THINGS:
mbedalvaro 30:d8af03f01cd4 677 // (1) current color: change with touch? NO
mbedalvaro 30:d8af03f01cd4 678 // if (displaySensingBuffer.lightTouched)
mbedalvaro 30:d8af03f01cd4 679 // transientBlobColor=blobColor|0x02; // set green ON on the trajectory, regardless of the initial color
mbedalvaro 30:d8af03f01cd4 680 // else
mbedalvaro 30:d8af03f01cd4 681 transientBlobColor=blobColor; // just the original blob color
mbedalvaro 30:d8af03f01cd4 682
mbedalvaro 30:d8af03f01cd4 683 // change sliding direction (for countour following):
mbedalvaro 30:d8af03f01cd4 684 if (blobWallCollision) {
mbedalvaro 30:d8af03f01cd4 685 if (wallCounter>10) {
mbedalvaro 30:d8af03f01cd4 686 slidingDirection=!slidingDirection;
mbedalvaro 30:d8af03f01cd4 687 wallCounter=0;
mbedalvaro 30:d8af03f01cd4 688 }
mbedalvaro 30:d8af03f01cd4 689 }
mbedalvaro 30:d8af03f01cd4 690 wallCounter++;
mbedalvaro 30:d8af03f01cd4 691 }
mbedalvaro 30:d8af03f01cd4 692
mbedalvaro 30:d8af03f01cd4 693 // Drawing the graphics - this will in fact use the graphic renderer - if any - and produce the trajectory to be displayed by the laser
mbedalvaro 30:d8af03f01cd4 694 void elasticLoop::draw() {
mbedalvaro 30:d8af03f01cd4 695 // for the time being, there is no "opengl" like renderer, so we just copy the coordinates of the mass into the lsdTrajectory:
mbedalvaro 30:d8af03f01cd4 696 for (int i = 0; i < numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 697 displaySensingBuffer.lsdTrajectory[i].x= (unsigned short)( massesLoop[i].pos.x ); // note: it should be an unsigned short
mbedalvaro 30:d8af03f01cd4 698 displaySensingBuffer.lsdTrajectory[i].y= (unsigned short)( massesLoop[i].pos.y );
mbedalvaro 30:d8af03f01cd4 699
mbedalvaro 30:d8af03f01cd4 700 //displaySensingBuffer.lsdTrajectory[i]= massesLoop[i].pos.y; // NOTE: doing this means converting from unsigned short to float (vector2Dd to vector2Df)
mbedalvaro 30:d8af03f01cd4 701
mbedalvaro 30:d8af03f01cd4 702 //displaySensingBuffer.lsdTrajectory[i].color=blobColor; // perhaps per point color is not a good idea for the time being...
mbedalvaro 30:d8af03f01cd4 703 }
mbedalvaro 30:d8af03f01cd4 704
mbedalvaro 30:d8af03f01cd4 705 // Global color for the whole loop:
mbedalvaro 30:d8af03f01cd4 706 displaySensingBuffer.displayColor=transientBlobColor;
mbedalvaro 30:d8af03f01cd4 707 }
mbedalvaro 30:d8af03f01cd4 708
mbedalvaro 30:d8af03f01cd4 709
mbedalvaro 30:d8af03f01cd4 710 void elasticLoop::processLoopData() {
mbedalvaro 30:d8af03f01cd4 711
mbedalvaro 30:d8af03f01cd4 712 // (0) Check if the blob touched the borders:
mbedalvaro 30:d8af03f01cd4 713 blobWallCollision=false;
mbedalvaro 30:d8af03f01cd4 714 for (int i = 0; i < numMasses; i++) blobWallCollision= (blobWallCollision || massesLoop[i].bWallCollision);
mbedalvaro 30:d8af03f01cd4 715
mbedalvaro 30:d8af03f01cd4 716 // (1) Compute all the "hairvectors" for the loop (this is, the normals to the particles, pointing outwards).
mbedalvaro 30:d8af03f01cd4 717 // This will be approximated by taking the 90 deg rotated difference between contiguous particles positions.
mbedalvaro 30:d8af03f01cd4 718 for (int i = 0; i < numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 719 vector2Df diff;
mbedalvaro 30:d8af03f01cd4 720 diff.set(massesLoop[(i+1)%numMasses].pos-massesLoop[i].pos);
mbedalvaro 30:d8af03f01cd4 721 // normalize and rotate 90 deg:
mbedalvaro 30:d8af03f01cd4 722 // NOTE: to save memory, we can drop hairVector...
mbedalvaro 30:d8af03f01cd4 723 hairVector[i]=diff.getPerpendicularNormed(CW);
mbedalvaro 30:d8af03f01cd4 724 //lightForce[i]=diff.getPerpendicularNormed(CW);
mbedalvaro 30:d8af03f01cd4 725 }
mbedalvaro 30:d8af03f01cd4 726
mbedalvaro 30:d8af03f01cd4 727 // (2) Compute area:
mbedalvaro 30:d8af03f01cd4 728 // (a) using Green method:
mbedalvaro 30:d8af03f01cd4 729 area=0;
mbedalvaro 30:d8af03f01cd4 730 float dx;
mbedalvaro 30:d8af03f01cd4 731 for (int i = 0; i < numMasses-1; i++){
mbedalvaro 30:d8af03f01cd4 732 dx=massesLoop[i].pos.x-massesLoop[i+1].pos.x;
mbedalvaro 30:d8af03f01cd4 733 area+=dx*massesLoop[i].pos.y;
mbedalvaro 30:d8af03f01cd4 734 }
mbedalvaro 30:d8af03f01cd4 735 // to avoid computation problems:
mbedalvaro 30:d8af03f01cd4 736 // if (area<=0) area=1; // or just norm: area CAN be negative! (a loop that is larger than the original blob...)
mbedalvaro 30:d8af03f01cd4 737
mbedalvaro 30:d8af03f01cd4 738 // (b) Compute approximate area from enclosing rectangle:
mbedalvaro 30:d8af03f01cd4 739 computeBoundingBox();
mbedalvaro 30:d8af03f01cd4 740
mbedalvaro 30:d8af03f01cd4 741 // (c) Compute kinetic energy:
mbedalvaro 30:d8af03f01cd4 742 totalKineticEnergy=0;
mbedalvaro 30:d8af03f01cd4 743 for (int i = 0; i < numMasses; i++){
mbedalvaro 30:d8af03f01cd4 744 totalKineticEnergy+=massesLoop[i].getSpeed().squareLength();
mbedalvaro 30:d8af03f01cd4 745 }
mbedalvaro 30:d8af03f01cd4 746 }
mbedalvaro 30:d8af03f01cd4 747
mbedalvaro 30:d8af03f01cd4 748
mbedalvaro 30:d8af03f01cd4 749 void elasticLoop::computeBoundingBox() {
mbedalvaro 30:d8af03f01cd4 750 float minx=4096, maxx=-1, miny=4096, maxy=-1;
mbedalvaro 30:d8af03f01cd4 751 for (int i = 0; i < numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 752 if (i == 0) {
mbedalvaro 30:d8af03f01cd4 753 minx = massesLoop[i].pos.x;
mbedalvaro 30:d8af03f01cd4 754 maxx = massesLoop[i].pos.x;
mbedalvaro 30:d8af03f01cd4 755 miny = massesLoop[i].pos.y;
mbedalvaro 30:d8af03f01cd4 756 maxy = massesLoop[i].pos.y;
mbedalvaro 30:d8af03f01cd4 757 } else {
mbedalvaro 30:d8af03f01cd4 758
mbedalvaro 30:d8af03f01cd4 759 minx = min(minx, massesLoop[i].pos.x);
mbedalvaro 30:d8af03f01cd4 760 maxx = max(maxx, massesLoop[i].pos.x);
mbedalvaro 30:d8af03f01cd4 761 miny = min(miny, massesLoop[i].pos.y);
mbedalvaro 30:d8af03f01cd4 762 maxy = max(maxy, massesLoop[i].pos.y);
mbedalvaro 30:d8af03f01cd4 763 }
mbedalvaro 30:d8af03f01cd4 764 }
mbedalvaro 30:d8af03f01cd4 765
mbedalvaro 30:d8af03f01cd4 766 // final results:
mbedalvaro 30:d8af03f01cd4 767 w = maxx - minx;
mbedalvaro 30:d8af03f01cd4 768 h = maxy - miny;
mbedalvaro 30:d8af03f01cd4 769 cx = minx+0.5*w; // note: center will be initialized with posX and posY when calling setInitialPos() of blobConfig
mbedalvaro 30:d8af03f01cd4 770 cy = miny+0.5*h;
mbedalvaro 30:d8af03f01cd4 771
mbedalvaro 30:d8af03f01cd4 772 // approx area:
mbedalvaro 30:d8af03f01cd4 773 approxArea=w*h;
mbedalvaro 30:d8af03f01cd4 774 }
mbedalvaro 30:d8af03f01cd4 775
mbedalvaro 30:d8af03f01cd4 776 void elasticLoop::sendDataSpecific() {
mbedalvaro 30:d8af03f01cd4 777 char auxstring[10];
mbedalvaro 30:d8af03f01cd4 778 myled2=1; // for tests...
mbedalvaro 30:d8af03f01cd4 779
mbedalvaro 30:d8af03f01cd4 780 // First, set the top address of the message to the ID of the blob (not the name):
mbedalvaro 30:d8af03f01cd4 781 // sprintf(auxstring, "%d", identifier);
mbedalvaro 30:d8af03f01cd4 782 // sendMes.setTopAddress("0");//auxstring);
mbedalvaro 30:d8af03f01cd4 783
mbedalvaro 30:d8af03f01cd4 784 // ===================== OSC ======================
mbedalvaro 30:d8af03f01cd4 785 if (sendOSC) {
mbedalvaro 30:d8af03f01cd4 786
mbedalvaro 30:d8af03f01cd4 787 // (new) Total kinetic energy:
mbedalvaro 30:d8af03f01cd4 788 if (sendingKineticEnergy) {
mbedalvaro 30:d8af03f01cd4 789 sprintf(auxstring, "/k %d",identifier);
mbedalvaro 30:d8af03f01cd4 790 sendMes.setSubAddress(auxstring);
mbedalvaro 30:d8af03f01cd4 791 long x; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 30:d8af03f01cd4 792 x=(long)(totalKineticEnergy);
mbedalvaro 30:d8af03f01cd4 793 sendMes.setArgs( "i", &x);
mbedalvaro 30:d8af03f01cd4 794 osc.sendOsc( &sendMes );
mbedalvaro 30:d8af03f01cd4 795 }
mbedalvaro 30:d8af03f01cd4 796 // (a) Anchor mass:
mbedalvaro 30:d8af03f01cd4 797 if (sendingAnchorPosition) {
mbedalvaro 30:d8af03f01cd4 798 sprintf(auxstring, "/p %d",identifier);
mbedalvaro 30:d8af03f01cd4 799 sendMes.setSubAddress(auxstring);
mbedalvaro 30:d8af03f01cd4 800 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 30:d8af03f01cd4 801 x=(long)(anchorMass.pos.x);
mbedalvaro 30:d8af03f01cd4 802 y=(long)(anchorMass.pos.y);
mbedalvaro 30:d8af03f01cd4 803 sendMes.setArgs( "ii", &x, &y);
mbedalvaro 30:d8af03f01cd4 804 osc.sendOsc( &sendMes );
mbedalvaro 30:d8af03f01cd4 805 }
mbedalvaro 30:d8af03f01cd4 806 if (sendingAnchorForce) {
mbedalvaro 30:d8af03f01cd4 807 sendMes.setSubAddress("/aforce");
mbedalvaro 30:d8af03f01cd4 808 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 30:d8af03f01cd4 809 x=(long)(anchorMass.totalForce.x);
mbedalvaro 30:d8af03f01cd4 810 y=(long)(anchorMass.totalForce.y);
mbedalvaro 30:d8af03f01cd4 811 sendMes.setArgs( "ii", &x, &y);
mbedalvaro 30:d8af03f01cd4 812 osc.sendOsc( &sendMes );
mbedalvaro 30:d8af03f01cd4 813 }
mbedalvaro 30:d8af03f01cd4 814 if (sendingAnchorTouchWall) {// note: not an else (we can send different data simultaneously)
mbedalvaro 30:d8af03f01cd4 815 sendMes.setSubAddress("/awall");
mbedalvaro 30:d8af03f01cd4 816 long wall=(long)(anchorMass.bWallCollision? 1 : 0);
mbedalvaro 30:d8af03f01cd4 817 sendMes.setArgs( "i", &wall);
mbedalvaro 30:d8af03f01cd4 818 osc.sendOsc( &sendMes );
mbedalvaro 30:d8af03f01cd4 819 }
mbedalvaro 30:d8af03f01cd4 820 // (b) data from blob points:
mbedalvaro 30:d8af03f01cd4 821 if (sendingLoopPositions) {
mbedalvaro 30:d8af03f01cd4 822 #ifdef SEND_AS_POINTS
mbedalvaro 30:d8af03f01cd4 823 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 30:d8af03f01cd4 824 for (int i = 0; i < numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 825 sprintf(auxstring, "/p %d", i); // auxstring read as "/p1", "/p2", ...
mbedalvaro 30:d8af03f01cd4 826 sendMes.setSubAddress(auxstring); // ATTENTION: the host computer needs to know in advance how many points are in the loop (I did not implement "bundle" messages yet...)
mbedalvaro 30:d8af03f01cd4 827 x=(long)(massesLoop[i].pos.x);
mbedalvaro 30:d8af03f01cd4 828 y=(long)(massesLoop[i].pos.y);
mbedalvaro 30:d8af03f01cd4 829 sendMes.setArgs( "ii", &x, &y);
mbedalvaro 30:d8af03f01cd4 830 osc.sendOsc( &sendMes );
mbedalvaro 30:d8af03f01cd4 831 }
mbedalvaro 30:d8af03f01cd4 832 #endif
mbedalvaro 30:d8af03f01cd4 833 #ifdef SEND_AS_BLOB
mbedalvaro 30:d8af03f01cd4 834 sendMes.clearArgs(); // no need, we won't use osc.sendOsc()...
mbedalvaro 30:d8af03f01cd4 835 uint8_t blobdata[4*numMasses]; // 2 bytes per coordinate, and 2 coordinates
mbedalvaro 30:d8af03f01cd4 836 for (int i = 0; i < numMasses; i++ ) {
mbedalvaro 30:d8af03f01cd4 837 // note: massesLoop[i].pos.x is a "float"
mbedalvaro 30:d8af03f01cd4 838 uint16_t x=(uint16_t)(massesLoop[i].pos.x);
mbedalvaro 30:d8af03f01cd4 839 blobdata[4*i]=(uint8_t)x>>8; // BIG ENDIAN (send FIRST the MOST SIGNIFICANT BYTE)
mbedalvaro 30:d8af03f01cd4 840 blobdata[4*i+1]=(uint8_t)x;
mbedalvaro 30:d8af03f01cd4 841
mbedalvaro 30:d8af03f01cd4 842 uint16_t y=(uint16_t)(massesLoop[i].pos.y);
mbedalvaro 30:d8af03f01cd4 843 blobdata[4*i+2]=(uint8_t)y>>8; // BIG ENDIAN (send FIRST the MOST SIGNIFICANT BYTE)
mbedalvaro 30:d8af03f01cd4 844 blobdata[4*i+3]=(uint8_t)y;
mbedalvaro 30:d8af03f01cd4 845 }
mbedalvaro 30:d8af03f01cd4 846 osc.sendOscBlob(&(blobdata[0]), 4*numMasses, &sendMes ); // second parameter is osc blob size in bytes
mbedalvaro 30:d8af03f01cd4 847 #endif
mbedalvaro 30:d8af03f01cd4 848 #ifdef SEND_AS_STRING
mbedalvaro 30:d8af03f01cd4 849 sendMes.clearArgs(); // no need, we won't use osc.sendOsc()...
mbedalvaro 30:d8af03f01cd4 850 uint8_t blobdata[4*numMasses]; // 2 bytes per coordinate, and 2 coordinates
mbedalvaro 30:d8af03f01cd4 851 for (int i = 0; i < numMasses; i++ ) {
mbedalvaro 30:d8af03f01cd4 852 // note: massesLoop[i].pos.x is a "float"
mbedalvaro 30:d8af03f01cd4 853 uint16_t x=(uint16_t)(massesLoop[i].pos.x);
mbedalvaro 30:d8af03f01cd4 854 blobdata[4*i]=(uint8_t)x>>8; // BIG ENDIAN (send FIRST the MOST SIGNIFICANT BYTE)
mbedalvaro 30:d8af03f01cd4 855 blobdata[4*i+1]=(uint8_t)x;
mbedalvaro 30:d8af03f01cd4 856
mbedalvaro 30:d8af03f01cd4 857 uint16_t y=(uint16_t)(massesLoop[i].pos.y);
mbedalvaro 30:d8af03f01cd4 858 blobdata[4*i+2]=(uint8_t)y>>8; // BIG ENDIAN (send FIRST the MOST SIGNIFICANT BYTE)
mbedalvaro 30:d8af03f01cd4 859 blobdata[4*i+3]=(uint8_t)y;
mbedalvaro 30:d8af03f01cd4 860 }
mbedalvaro 30:d8af03f01cd4 861 osc.sendOscString(blobdata, 4*numMasses, &sendMes ); // second parameter is osc blob size in bytes
mbedalvaro 30:d8af03f01cd4 862 #endif
mbedalvaro 30:d8af03f01cd4 863 }
mbedalvaro 30:d8af03f01cd4 864 if (sendingLoopForces) { // ATTN: the force is the TOTAL force on the point (interesting perhaps for making sound...)
mbedalvaro 30:d8af03f01cd4 865 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 30:d8af03f01cd4 866 for (int i = 0; i < numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 867 sprintf(auxstring, "/f%d", i); // auxstring read as "/f1", "/f2", ...
mbedalvaro 30:d8af03f01cd4 868 sendMes.setSubAddress(auxstring); // ATTENTION: the host computer needs to know in advance how many points are in the loop (I did not implement "bundle" messages yet...)
mbedalvaro 30:d8af03f01cd4 869 x=(long)(massesLoop[i].totalForce.x);
mbedalvaro 30:d8af03f01cd4 870 y=(long)(massesLoop[i].totalForce.y);
mbedalvaro 30:d8af03f01cd4 871 sendMes.setArgs( "ii", &x, &y);
mbedalvaro 30:d8af03f01cd4 872 osc.sendOsc( &sendMes );
mbedalvaro 30:d8af03f01cd4 873 }
mbedalvaro 30:d8af03f01cd4 874 }
mbedalvaro 30:d8af03f01cd4 875 if (sendingLoopForcesLight) { // ATTN: the force is the TOTAL force on the point (interesting perhaps for making sound...)
mbedalvaro 30:d8af03f01cd4 876 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 30:d8af03f01cd4 877 for (int i = 0; i < numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 878 sprintf(auxstring, "/g%d", i); // auxstring read as "/f1", "/f2", ...
mbedalvaro 30:d8af03f01cd4 879 sendMes.setSubAddress(auxstring); // ATTENTION: the host computer needs to know in advance how many points are in the loop (I did not implement "bundle" messages yet...)
mbedalvaro 30:d8af03f01cd4 880 x=(long)(1000*lightForce[i].x);
mbedalvaro 30:d8af03f01cd4 881 y=(long)(1000*lightForce[i].y);
mbedalvaro 30:d8af03f01cd4 882 sendMes.setArgs( "ii", &x, &y);
mbedalvaro 30:d8af03f01cd4 883 osc.sendOsc( &sendMes );
mbedalvaro 30:d8af03f01cd4 884 }
mbedalvaro 30:d8af03f01cd4 885 }
mbedalvaro 30:d8af03f01cd4 886
mbedalvaro 30:d8af03f01cd4 887 if (sendingLoopRegions) {
mbedalvaro 30:d8af03f01cd4 888 long x; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 30:d8af03f01cd4 889 for (int i = 0; i < numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 890 sprintf(auxstring, "/r%d", i); // auxstring read as "/f1", "/f2", ...
mbedalvaro 30:d8af03f01cd4 891 sendMes.setSubAddress(auxstring); // ATTENTION: the host computer needs to know in advance how many points are in the loop (I did not implement "bundle" messages yet...)
mbedalvaro 30:d8af03f01cd4 892 x=(long)(displaySensingBuffer.lsdTrajectory[i].lightZone>0? 1 : 0);
mbedalvaro 30:d8af03f01cd4 893 sendMes.setArgs( "i", &x);
mbedalvaro 30:d8af03f01cd4 894 osc.sendOsc( &sendMes );
mbedalvaro 30:d8af03f01cd4 895 }
mbedalvaro 30:d8af03f01cd4 896 }
mbedalvaro 30:d8af03f01cd4 897 if (sendingLoopTouchWall) { // global touch wall for the loop (not per point)
mbedalvaro 30:d8af03f01cd4 898 long wall; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 30:d8af03f01cd4 899 sprintf(auxstring, "/bWall");
mbedalvaro 30:d8af03f01cd4 900 sendMes.setSubAddress(auxstring);
mbedalvaro 30:d8af03f01cd4 901 wall=(long)(blobWallCollision? 1 : 0);
mbedalvaro 30:d8af03f01cd4 902 sendMes.setArgs( "i", &wall);
mbedalvaro 30:d8af03f01cd4 903 osc.sendOsc( &sendMes );
mbedalvaro 30:d8af03f01cd4 904 }
mbedalvaro 30:d8af03f01cd4 905 // (c) Blob geometry:
mbedalvaro 30:d8af03f01cd4 906 if (sendingBlobArea) {
mbedalvaro 30:d8af03f01cd4 907 /* sendMes.setSubAddress("/a");
mbedalvaro 30:d8af03f01cd4 908 long x; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 30:d8af03f01cd4 909 // x=(long)(area);//approxArea); // area or approxArea
mbedalvaro 30:d8af03f01cd4 910 x=(long)(area>0? approxArea : -approxArea);
mbedalvaro 30:d8af03f01cd4 911 sendMes.setArgs( "i", &x); // ATTENTION: AREA CAN BE NEGATIVE!!! (does MAX handles this well? test this!)
mbedalvaro 30:d8af03f01cd4 912 */
mbedalvaro 30:d8af03f01cd4 913 // HACK for the time being (for Daito):
mbedalvaro 30:d8af03f01cd4 914 sendMes.setSubAddress("/a");
mbedalvaro 30:d8af03f01cd4 915 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 30:d8af03f01cd4 916 // x=(long)(area);//approxArea); // area or approxArea
mbedalvaro 30:d8af03f01cd4 917 x=(long)(w); y=(long)(h);
mbedalvaro 30:d8af03f01cd4 918 sendMes.setArgs( "ii", &x, &y); // ATTENTION: AREA CAN BE NEGATIVE!!! (does MAX handles this well? test this!)
mbedalvaro 30:d8af03f01cd4 919
mbedalvaro 30:d8af03f01cd4 920 osc.sendOsc( &sendMes );
mbedalvaro 30:d8af03f01cd4 921 }
mbedalvaro 30:d8af03f01cd4 922 if (sendingBlobNormals) {
mbedalvaro 30:d8af03f01cd4 923 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 30:d8af03f01cd4 924 for (int i = 0; i < numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 925 sprintf(auxstring, "nf%d", i); // auxstring read as "/f1", "/f2", ...
mbedalvaro 30:d8af03f01cd4 926 sendMes.setSubAddress(auxstring); // ATTENTION: the host computer needs to know in advance how many points are in the loop (I did not implement "bundle" messages yet...)
mbedalvaro 30:d8af03f01cd4 927 x=(long)(hairVector[i].x);
mbedalvaro 30:d8af03f01cd4 928 y=(long)(hairVector[i].y);
mbedalvaro 30:d8af03f01cd4 929 sendMes.setArgs( "ii", &x, &y);
mbedalvaro 30:d8af03f01cd4 930 osc.sendOsc( &sendMes );
mbedalvaro 30:d8af03f01cd4 931 }
mbedalvaro 30:d8af03f01cd4 932 }
mbedalvaro 30:d8af03f01cd4 933 if (sendingBlobAngles) {
mbedalvaro 30:d8af03f01cd4 934 long x; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 30:d8af03f01cd4 935 for (int i = 0; i < numMasses; i++) {
mbedalvaro 30:d8af03f01cd4 936 sprintf(auxstring, "/a%d", i); // auxstring read as "/f1", "/f2", ...
mbedalvaro 30:d8af03f01cd4 937 sendMes.setSubAddress(auxstring); // ATTENTION: the host computer needs to know in advance how many points are in the loop (I did not implement "bundle" messages yet...)
mbedalvaro 30:d8af03f01cd4 938 x=(long)(hairVector[i].angleDegHoriz());
mbedalvaro 30:d8af03f01cd4 939 sendMes.setArgs( "i", &x);
mbedalvaro 30:d8af03f01cd4 940 osc.sendOsc( &sendMes );
mbedalvaro 30:d8af03f01cd4 941 }
mbedalvaro 30:d8af03f01cd4 942 }
mbedalvaro 30:d8af03f01cd4 943 // (d) Light sensing statistics:
mbedalvaro 30:d8af03f01cd4 944 if (sendingBlobMaxMin) {
mbedalvaro 30:d8af03f01cd4 945 sendMes.setSubAddress("/maxmin");
mbedalvaro 30:d8af03f01cd4 946 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 30:d8af03f01cd4 947 x=(long)(displaySensingBuffer.maxI);
mbedalvaro 30:d8af03f01cd4 948 y=(long)(displaySensingBuffer.minI);
mbedalvaro 30:d8af03f01cd4 949 sendMes.setArgs( "ii", &x, &y);
mbedalvaro 30:d8af03f01cd4 950 osc.sendOsc( &sendMes );
mbedalvaro 30:d8af03f01cd4 951 }
mbedalvaro 30:d8af03f01cd4 952 if (sendingLightForce) {
mbedalvaro 30:d8af03f01cd4 953 sendMes.setSubAddress("/lforce");
mbedalvaro 30:d8af03f01cd4 954 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 30:d8af03f01cd4 955 x=(long)(totalLightForce.x);
mbedalvaro 30:d8af03f01cd4 956 y=(long)(totalLightForce.y);
mbedalvaro 30:d8af03f01cd4 957 sendMes.setArgs( "ii", &x, &y);
mbedalvaro 30:d8af03f01cd4 958 osc.sendOsc( &sendMes );
mbedalvaro 30:d8af03f01cd4 959 }
mbedalvaro 30:d8af03f01cd4 960 // (e) Recentering vector: (note: redundant with sendingLightForce, IF the correction angle is known).
mbedalvaro 30:d8af03f01cd4 961 if (sendingRecenteringVector) {
mbedalvaro 30:d8af03f01cd4 962 sendMes.setSubAddress("/rvector");
mbedalvaro 30:d8af03f01cd4 963 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 30:d8af03f01cd4 964 x=(long)(recenteringVectorLoop.x);
mbedalvaro 30:d8af03f01cd4 965 y=(long)(recenteringVectorLoop.y);
mbedalvaro 30:d8af03f01cd4 966 sendMes.setArgs( "ii", &x, &y);
mbedalvaro 30:d8af03f01cd4 967 osc.sendOsc( &sendMes );
mbedalvaro 30:d8af03f01cd4 968 }
mbedalvaro 30:d8af03f01cd4 969 if (sendingRecenteringAngle) {
mbedalvaro 30:d8af03f01cd4 970 sendMes.setSubAddress("/rangle");
mbedalvaro 30:d8af03f01cd4 971 long x; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 30:d8af03f01cd4 972 x=(long)(angleRecenteringVector);
mbedalvaro 30:d8af03f01cd4 973 sendMes.setArgs( "i", &x);
mbedalvaro 30:d8af03f01cd4 974 osc.sendOsc( &sendMes );
mbedalvaro 30:d8af03f01cd4 975 }
mbedalvaro 30:d8af03f01cd4 976 if (sendingRecenteringNorm) {
mbedalvaro 30:d8af03f01cd4 977 sendMes.setSubAddress("/rnorm");
mbedalvaro 30:d8af03f01cd4 978 long x; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 30:d8af03f01cd4 979 x=(long)(normRecenteringVector);
mbedalvaro 30:d8af03f01cd4 980 sendMes.setArgs( "i", &x);
mbedalvaro 30:d8af03f01cd4 981 osc.sendOsc( &sendMes );
mbedalvaro 30:d8af03f01cd4 982 }
mbedalvaro 30:d8af03f01cd4 983
mbedalvaro 30:d8af03f01cd4 984 if (sendingTouched) {
mbedalvaro 30:d8af03f01cd4 985 if (displaySensingBuffer.lightTouched) {
mbedalvaro 30:d8af03f01cd4 986 sendMes.clearArgs(); // there are no arguments to send
mbedalvaro 30:d8af03f01cd4 987 sendMes.setSubAddress("/touched");
mbedalvaro 30:d8af03f01cd4 988 osc.sendOsc( &sendMes );
mbedalvaro 30:d8af03f01cd4 989 }
mbedalvaro 30:d8af03f01cd4 990 }
mbedalvaro 30:d8af03f01cd4 991
mbedalvaro 30:d8af03f01cd4 992 } // end of OSC sending per-spot
mbedalvaro 30:d8af03f01cd4 993
mbedalvaro 30:d8af03f01cd4 994 // ===================== SERIAL ======================
mbedalvaro 30:d8af03f01cd4 995 if (sendSerial) {
mbedalvaro 30:d8af03f01cd4 996 //.. to do
mbedalvaro 30:d8af03f01cd4 997 }
mbedalvaro 30:d8af03f01cd4 998
mbedalvaro 30:d8af03f01cd4 999 myled2=0; // for tests...
mbedalvaro 30:d8af03f01cd4 1000 }
mbedalvaro 30:d8af03f01cd4 1001