just a test

Dependencies:   mbed

Fork of scoreLight_Advanced by Alvaro Cassinelli

Committer:
mbedalvaro
Date:
Thu Apr 05 13:06:24 2012 +0000
Revision:
6:444859c27e78
Parent:
5:73cd58b58f95
Child:
7:0df17f3078bc
solved one problem related to the initialization of the positions, so now the "relax contract central blob" works as before.; - strange first point; - still did not try the strange problem with the variable on the class laser sensing trajectory (required...

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