just a test

Dependencies:   mbed

Fork of scoreLight_Advanced by Alvaro Cassinelli

Committer:
mbedalvaro
Date:
Sat Apr 28 13:42:14 2012 +0000
Revision:
19:228430f1350e
Parent:
18:d72935b13858
Child:
20:8e82b95180e7
relatively stable. Now need to make commands to control speed/stiffness/color and size of spot form the computer

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