just a test

Dependencies:   mbed

Fork of scoreLight_Advanced by Alvaro Cassinelli

Committer:
mbedalvaro
Date:
Mon Jun 18 12:39:28 2012 +0000
Revision:
26:c9329c4fc20a
Parent:
25:74cb85b85fd2
Child:
27:1ce994629ffc
still some color problems - cannot change the green from command

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