save loops

Dependencies:   mbed

Committer:
mbedalvaro
Date:
Tue Dec 02 08:29:59 2014 +0000
Revision:
1:3be7b7d050f4
Parent:
0:df6fdd9b99f0
updated

Who changed what in which revision?

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