just a test

Dependencies:   mbed

Fork of scoreLight_Advanced by Alvaro Cassinelli

Committer:
mbedalvaro
Date:
Wed Mar 28 14:40:01 2012 +0000
Revision:
0:345b3bc7a0ea
Child:
1:a4050fee11f7
This version (using rigid frame, base and child classes, etc) works, but the blob is strangely smaller. Need to check this.

Who changed what in which revision?

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