save loops

Dependencies:   mbed

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

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbedalvaro 0:df6fdd9b99f0 1 #include "classLaserSensingTrajectory.h"
mbedalvaro 0:df6fdd9b99f0 2 using namespace std;
mbedalvaro 0:df6fdd9b99f0 3
mbedalvaro 0:df6fdd9b99f0 4 LaserSensingTrajectory::LaserSensingTrajectory():lightTouched(false), lightState(ALL_DARK),
mbedalvaro 0:df6fdd9b99f0 5 min_contrast_ratio(MIN_CONTRAST_RATIO), threshold_factor(THRESHOLD_FACTOR),
mbedalvaro 0:df6fdd9b99f0 6 min_acceptable_intensity(MIN_ACCEPTABLE_INTENSITY), fixedThreshold(FIXED_THRESHOLD), delayMirrorSamples(0)
mbedalvaro 0:df6fdd9b99f0 7 {
mbedalvaro 0:df6fdd9b99f0 8 lsdTrajectory.clear(); // no need in principle! the constructor of the vector will give an empty vector!
mbedalvaro 0:df6fdd9b99f0 9 // attention: properly set the state of the threshold switch in the IO.init (which by the way, in THIS hardware
mbedalvaro 0:df6fdd9b99f0 10 // implementation indicates the state for ALL the objects..)
mbedalvaro 0:df6fdd9b99f0 11 modeThreshold=AUTO;
mbedalvaro 0:df6fdd9b99f0 12 // IO.setSwitchOneState(true);
mbedalvaro 0:df6fdd9b99f0 13 }
mbedalvaro 0:df6fdd9b99f0 14
mbedalvaro 0:df6fdd9b99f0 15 LaserSensingTrajectory::~LaserSensingTrajectory() {
mbedalvaro 0:df6fdd9b99f0 16 // lsdTrajectory.clear(); // there is no need to clear the vector, the destructor of this vector is called by default (and it's NOT a vector of pointers)
mbedalvaro 0:df6fdd9b99f0 17 }
mbedalvaro 0:df6fdd9b99f0 18
mbedalvaro 0:df6fdd9b99f0 19
mbedalvaro 0:df6fdd9b99f0 20 void LaserSensingTrajectory::setDelayMirrors(int delay) {
mbedalvaro 0:df6fdd9b99f0 21 delayMirrorSamples=delay;
mbedalvaro 0:df6fdd9b99f0 22 }
mbedalvaro 0:df6fdd9b99f0 23
mbedalvaro 0:df6fdd9b99f0 24 void LaserSensingTrajectory::addDelayMirrors(int add_delay) {
mbedalvaro 0:df6fdd9b99f0 25 delayMirrorSamples+=add_delay;
mbedalvaro 0:df6fdd9b99f0 26 }
mbedalvaro 0:df6fdd9b99f0 27
mbedalvaro 0:df6fdd9b99f0 28 bool LaserSensingTrajectory::processSensedData() {
mbedalvaro 0:df6fdd9b99f0 29 // Compute max and min intensity on the loop
mbedalvaro 0:df6fdd9b99f0 30 maxI=0;
mbedalvaro 0:df6fdd9b99f0 31 minI=255; // ratio has been normalized between 0 and 255
mbedalvaro 0:df6fdd9b99f0 32 unsigned short auxSize=lsdTrajectory.size(); // could be an unsigned char in principle... no more than 255 points per object, but well, memory in future versions
mbedalvaro 0:df6fdd9b99f0 33 // of the microprocessor can be larger.
mbedalvaro 0:df6fdd9b99f0 34
mbedalvaro 0:df6fdd9b99f0 35 // Compute minimum and maximum intensities:
mbedalvaro 0:df6fdd9b99f0 36 for (unsigned short i = 0; i < auxSize; i++) {
mbedalvaro 0:df6fdd9b99f0 37 unsigned char mesI=lsdTrajectory[i].intensity;
mbedalvaro 0:df6fdd9b99f0 38 if (maxI<mesI) maxI=mesI;
mbedalvaro 0:df6fdd9b99f0 39 if (minI>mesI) minI=mesI;
mbedalvaro 0:df6fdd9b99f0 40 }
mbedalvaro 0:df6fdd9b99f0 41
mbedalvaro 0:df6fdd9b99f0 42 // Compute autoThreshold:
mbedalvaro 0:df6fdd9b99f0 43 switch(modeThreshold) {
mbedalvaro 0:df6fdd9b99f0 44 case AUTO:
mbedalvaro 0:df6fdd9b99f0 45 if (minI==0) minI=1;
mbedalvaro 0:df6fdd9b99f0 46 if (maxI<min_acceptable_intensity) autoThreshold=255;// (we consider that the saccade is FULL on something black - this is noise)
mbedalvaro 0:df6fdd9b99f0 47 else if (1.0*maxI/minI > min_contrast_ratio ) {
mbedalvaro 0:df6fdd9b99f0 48 autoThreshold = (unsigned char) (1.0 * (maxI-minI) * threshold_factor + minI); // threshold_factor = 2/3 or 1/2 is a good value.
mbedalvaro 0:df6fdd9b99f0 49 } else {// ... otherwise, we consider that the saccade is FULL on something WHITE (convention...)
mbedalvaro 0:df6fdd9b99f0 50 autoThreshold=0;
mbedalvaro 0:df6fdd9b99f0 51 }
mbedalvaro 0:df6fdd9b99f0 52 break;
mbedalvaro 0:df6fdd9b99f0 53 case FIXED:
mbedalvaro 0:df6fdd9b99f0 54 autoThreshold=fixedThreshold;
mbedalvaro 0:df6fdd9b99f0 55 break;
mbedalvaro 0:df6fdd9b99f0 56 }
mbedalvaro 0:df6fdd9b99f0 57
mbedalvaro 0:df6fdd9b99f0 58
mbedalvaro 0:df6fdd9b99f0 59 // Segment the trajectory (only two levels for the time being, but we can have more - meaning different forces, real or even complex values to have different angle forces...):
mbedalvaro 0:df6fdd9b99f0 60 // NOTE: if using 1 and -1 instead of 1 and 0, we can avoid having to add a "blob internal pressure"! -1 means a force towards the interior, and +1 outwards...
mbedalvaro 0:df6fdd9b99f0 61 // This means that the loop will naturally become inside-out depending on the color of the main surface! (but will mantain its normal size). Much better and elegant solution than the
mbedalvaro 0:df6fdd9b99f0 62 // idea of the blob "constant" internal pressure...
mbedalvaro 0:df6fdd9b99f0 63 bool isLightZone=false, isDarkZone=false;
mbedalvaro 0:df6fdd9b99f0 64 for (unsigned short i = 0; i < auxSize; i++) {
mbedalvaro 0:df6fdd9b99f0 65 unsigned short delayedpoint=(i+auxSize+delayMirrorSamples)%auxSize; // this way we can have negative delayMirrorSamples if required (would be absurd though)
mbedalvaro 0:df6fdd9b99f0 66 if (lsdTrajectory[delayedpoint].intensity>=autoThreshold) { // this means a WHITE zone:
mbedalvaro 0:df6fdd9b99f0 67 lsdTrajectory[i].lightZone= -1;
mbedalvaro 0:df6fdd9b99f0 68 isLightZone=true;
mbedalvaro 0:df6fdd9b99f0 69 } else { // this means DARK ZONE
mbedalvaro 0:df6fdd9b99f0 70 lsdTrajectory[i].lightZone= 2;
mbedalvaro 0:df6fdd9b99f0 71 isDarkZone=true;
mbedalvaro 0:df6fdd9b99f0 72 }
mbedalvaro 0:df6fdd9b99f0 73 }
mbedalvaro 0:df6fdd9b99f0 74
mbedalvaro 0:df6fdd9b99f0 75 // In the case of AUTO mode, we assume that something is touching the object when the trajectory has at least one light zone and one dark zone;
mbedalvaro 0:df6fdd9b99f0 76 // in the case of FIXED mode, we assume something is touching the object when there is at least one light zone (this is a convention, because it depends
mbedalvaro 0:df6fdd9b99f0 77 // on the background - but we can argue that "no background" corresponds to no reflection (then dark), and, say, a ping pong ball or finger is front
mbedalvaro 0:df6fdd9b99f0 78 // will be "light".
mbedalvaro 0:df6fdd9b99f0 79 // Mmm... not convinced by the arguments above. Let's rather do this: lightTouched will mean ALWAYS that the saccade is touched by something, meaning it's intensity
mbedalvaro 0:df6fdd9b99f0 80 // goes from dark to light, i.e. at least one light AND one dark zone. In fact we should have THREE states: touched, all light, all dark.
mbedalvaro 0:df6fdd9b99f0 81 if (modeThreshold==FIXED) {
mbedalvaro 0:df6fdd9b99f0 82 lightTouched=isLightZone;
mbedalvaro 0:df6fdd9b99f0 83 lightZone=isLightZone;
mbedalvaro 0:df6fdd9b99f0 84 darkZone=isDarkZone;
mbedalvaro 0:df6fdd9b99f0 85 if (lightTouched) lightState=TOUCHED;
mbedalvaro 0:df6fdd9b99f0 86 else if (isLightZone) lightState=ALL_LIGHT;
mbedalvaro 0:df6fdd9b99f0 87 else lightState=ALL_DARK;
mbedalvaro 0:df6fdd9b99f0 88 }
mbedalvaro 0:df6fdd9b99f0 89 else {
mbedalvaro 0:df6fdd9b99f0 90 lightTouched=(isLightZone&&isDarkZone); // assuming only two modes for modeThreshold
mbedalvaro 0:df6fdd9b99f0 91 lightZone=isLightZone;
mbedalvaro 0:df6fdd9b99f0 92 darkZone=isDarkZone;
mbedalvaro 0:df6fdd9b99f0 93 if (lightTouched) lightState=TOUCHED;
mbedalvaro 0:df6fdd9b99f0 94 else if (isLightZone) lightState=ALL_LIGHT;
mbedalvaro 0:df6fdd9b99f0 95 else lightState=ALL_DARK;
mbedalvaro 0:df6fdd9b99f0 96 }
mbedalvaro 0:df6fdd9b99f0 97 // Return lightTouched for commodity:
mbedalvaro 0:df6fdd9b99f0 98 //return(lightTouched);
mbedalvaro 0:df6fdd9b99f0 99 return(lightState);
mbedalvaro 0:df6fdd9b99f0 100 }