La vérité c'est que je suis un gros fainéant et que j'essaye de me mettre un peu de pression mais un peu de retour ne serait pas désagréble
Définitivement l'utilisation d'un uint16_t avec l'instruction analog_valueA.read_u16() est beaucoup plus rapide et surtout beaucoup plus stable. reste que je trouve bizarre de trouver des valeurs de 16 bis issues d'un convertisseur analogique digital de 12 bits mais bof pourquoi pas ! Il semble qu'il faille utiliser un timing à peu près identique entre les mesures avec celle qui ont servis pour l'étalonnage . Code : Sélectionner tout - Visualiser dans une fenêtre à part 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 /*probelasernoprint ** very beginning **9/13/2018 in Athens Greece **rokag3 ** this software should detect an intrusion of an object in rotation (or not) ** check the position of the tooth the most eccentric (mostEccentricTooth) ** calculate the time it wil be in the center of the lazer and send a probe flag ** **public domain /* #include "mbed.h" AnalogIn analog_valueA(A0);//blue wire attach the 1st channel of your oscilloscope AnalogIn analog_valueB(A1);//orange in the window the most susceptible to be shadowed AnalogIn analog_valueC(A2);//vert AnalogIn analog_valueD(A3);//jaune DigitalOut ledGreen (PA_9); //The 2nd channel oscilloscope must be attached here it is True if any delta with unshaded diode DigitalOut ledRed (PC_7);//probe signal Serial pc(USBTX,USBRX,115200); // baud rate uint16_t abcd[4]; uint16_t Oldmina,Oldmaxa,Oldminb,Oldmaxb,Oldminc,Oldmaxc,Oldmind,Oldmaxd; uint16_t iduty,windowduty; uint16_t intrusion; uint16_t valdeA; uint16_t valdeB; uint16_t valdeC; uint16_t valdeD; uint16_t stabilizeTime=1; void CheckIntrusion() { intrusion=0; windowduty=0; if (valdeA<Oldmina){intrusion++;windowduty=1;}// windowduty to know which diode is shadowed if (valdeB<Oldminb){intrusion++;windowduty+=2;}// if (valdeC<Oldminc){intrusion++;windowduty+=4;} if (valdeD<Oldmind){intrusion++;windowduty+=8;} switch (intrusion) { case 1: ledRed=0 ; ledGreen=1;//one window has been hit here the timing routines to validate or void the intrusion must be called break; case 2: ledRed=0 ; ledGreen=1; break; case 3: ledRed=1 ; ledGreen=1; break; case 4: ledRed=1 ; ledGreen=1; break; default: ledRed=0 ; ledGreen=0; break; } } int main() { //initialisation des minimax Oldmaxa=0;// val maxi du window A après initialisation Oldmina =65535; //val mini du window A après initialisation Oldmaxb=0;// val maxi du window B après initialisation etc... Oldminb =65535; Oldmaxc=0; Oldminc =65535; Oldmaxd=0; Oldmind =65535; ledRed= 1 ;// to check if the calibration is over ledGreen = 1; for (iduty=0 ; iduty<10000; iduty++) { //determination des variations maximums 10000 tests uint16_t maxa=analog_valueA.read_u16(); if(maxa < Oldmina) {Oldmina =maxa;} if(maxa > Oldmaxa) {Oldmaxa =maxa;} wait_us(1); uint16_t maxb=analog_valueB.read_u16(); if(maxb < Oldminb) {Oldminb =maxb;} if(maxb > Oldmaxb) {Oldmaxb =maxb;} wait_us(1); uint16_t maxc=analog_valueC.read_u16(); if(maxc < Oldminc) {Oldminc =maxc;} if(maxc > Oldmaxc) {Oldmaxc =maxc;} wait_us(1); uint16_t maxd=analog_valueD.read_u16(); if(maxd < Oldmind) {Oldmind =maxd;} if(maxd > Oldmaxd) {Oldmaxd =maxd;} wait_us(1); } ledRed= 0 ; ledGreen = 0; while(1) { //spool valdeA = analog_valueA.read_u16();// wait_us(stabilizeTime); valdeB = analog_valueB.read_u16(); wait_us(stabilizeTime); valdeC = analog_valueC.read_u16(); wait_us(stabilizeTime); valdeD = analog_valueD.read_u16(); wait_us(stabilizeTime); CheckIntrusion(); // display values if((iduty++>1000)||(intrusion>0)){ printf(" %d %d %d %d %d\n", intrusion, Oldmina, Oldminb, Oldminc, Oldmind); printf("I=%dA=%dB=%dC=%dD=%dW=%d\n", intrusion , valdeA, valdeB, valdeC, valdeD,windowduty); iduty=0; } } }
/*probelasernoprint ** very beginning **9/13/2018 in Athens Greece **rokag3 ** this software should detect an intrusion of an object in rotation (or not) ** check the position of the tooth the most eccentric (mostEccentricTooth) ** calculate the time it wil be in the center of the lazer and send a probe flag ** **public domain /* #include "mbed.h" AnalogIn analog_valueA(A0);//blue wire attach the 1st channel of your oscilloscope AnalogIn analog_valueB(A1);//orange in the window the most susceptible to be shadowed AnalogIn analog_valueC(A2);//vert AnalogIn analog_valueD(A3);//jaune DigitalOut ledGreen (PA_9); //The 2nd channel oscilloscope must be attached here it is True if any delta with unshaded diode DigitalOut ledRed (PC_7);//probe signal Serial pc(USBTX,USBRX,115200); // baud rate uint16_t abcd[4]; uint16_t Oldmina,Oldmaxa,Oldminb,Oldmaxb,Oldminc,Oldmaxc,Oldmind,Oldmaxd; uint16_t iduty,windowduty; uint16_t intrusion; uint16_t valdeA; uint16_t valdeB; uint16_t valdeC; uint16_t valdeD; uint16_t stabilizeTime=1; void CheckIntrusion() { intrusion=0; windowduty=0; if (valdeA<Oldmina){intrusion++;windowduty=1;}// windowduty to know which diode is shadowed if (valdeB<Oldminb){intrusion++;windowduty+=2;}// if (valdeC<Oldminc){intrusion++;windowduty+=4;} if (valdeD<Oldmind){intrusion++;windowduty+=8;} switch (intrusion) { case 1: ledRed=0 ; ledGreen=1;//one window has been hit here the timing routines to validate or void the intrusion must be called break; case 2: ledRed=0 ; ledGreen=1; break; case 3: ledRed=1 ; ledGreen=1; break; case 4: ledRed=1 ; ledGreen=1; break; default: ledRed=0 ; ledGreen=0; break; } } int main() { //initialisation des minimax Oldmaxa=0;// val maxi du window A après initialisation Oldmina =65535; //val mini du window A après initialisation Oldmaxb=0;// val maxi du window B après initialisation etc... Oldminb =65535; Oldmaxc=0; Oldminc =65535; Oldmaxd=0; Oldmind =65535; ledRed= 1 ;// to check if the calibration is over ledGreen = 1; for (iduty=0 ; iduty<10000; iduty++) { //determination des variations maximums 10000 tests uint16_t maxa=analog_valueA.read_u16(); if(maxa < Oldmina) {Oldmina =maxa;} if(maxa > Oldmaxa) {Oldmaxa =maxa;} wait_us(1); uint16_t maxb=analog_valueB.read_u16(); if(maxb < Oldminb) {Oldminb =maxb;} if(maxb > Oldmaxb) {Oldmaxb =maxb;} wait_us(1); uint16_t maxc=analog_valueC.read_u16(); if(maxc < Oldminc) {Oldminc =maxc;} if(maxc > Oldmaxc) {Oldmaxc =maxc;} wait_us(1); uint16_t maxd=analog_valueD.read_u16(); if(maxd < Oldmind) {Oldmind =maxd;} if(maxd > Oldmaxd) {Oldmaxd =maxd;} wait_us(1); } ledRed= 0 ; ledGreen = 0; while(1) { //spool valdeA = analog_valueA.read_u16();// wait_us(stabilizeTime); valdeB = analog_valueB.read_u16(); wait_us(stabilizeTime); valdeC = analog_valueC.read_u16(); wait_us(stabilizeTime); valdeD = analog_valueD.read_u16(); wait_us(stabilizeTime); CheckIntrusion(); // display values if((iduty++>1000)||(intrusion>0)){ printf(" %d %d %d %d %d\n", intrusion, Oldmina, Oldminb, Oldminc, Oldmind); printf("I=%dA=%dB=%dC=%dD=%dW=%d\n", intrusion , valdeA, valdeB, valdeC, valdeD,windowduty); iduty=0; } } }
Doit on utiliser l'integer ou le float pour la fonction .read() lorsque l'on utilise le convertisseur analogique/digital si l'on souhaite aller plus vite ?
Cette image est une image de cible le code est écris pour processing 3.3.5 et ne présente aucune difficultée particulière Code : Sélectionner tout - Visualiser dans une fenêtre à part 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 /** * prog name lirelaser * vizualize laser * work with adatestquadrants * processing 3.3.5 * */ PImage img; PFont f; float mx; float my; float easing = 0.05; int radius = 50; int edge = 100; int inner = edge + radius; import processing.serial.*; int testi; Serial myPort; // Create object from Serial class float valX,valY,valA,valB,valC,valD; // Data received from the serial port int c; void setup() { // I know that the first port in the serial list on my mac // is always my FTDI adaptor, so I open Serial.list()[0]. // On Windows machines, this generally opens COM1. // Open whatever port is the one you're using. String portName = Serial.list()[2]; myPort = new Serial(this, portName, 19200); size(800, 800); noStroke(); ellipseMode(RADIUS); rectMode(CORNERS); //printArray(PFont.list()); f = createFont("DialogInput.bolditalic", 24); textFont(f); textAlign(CENTER, CENTER); img = loadImage("5323_Steiner-5x25-56mm-reticle.jpg"); //https://www.outdoorsbay.com/gallery-1/originals/5323_Steiner-5x25-56mm-reticle.jpg } void draw() { background(51); if ( myPort.available() > 0 && ( testi++>=2)) { testi=2; String inBuffer = myPort.readStringUntil('\n'); //print(inBuffer); if (inBuffer != null) { //String myString = new String(inBuffer); //println(myString); float[] val = float(inBuffer.split(",", 12)); //val = new float[6]; // float val[] = float(split(inBuffer,',')); valX=val[0]; valY=val[1]; valA=int(val[2]); valB=int(val[3]); valC=int(val[4]); valD=int(val[5]); //String texta="A"; // read it and store it in val } if (abs(valX - mx) > 0.1) { mx = mx + (valX - mx) * easing; } if (abs(valY - my) > 0.1) { my = my + (valY- my) * easing; } mx = constrain(mx, inner, width - inner); my = constrain(my, inner, height - inner); fill(76); rect(edge, edge, width-edge, height-edge); image(img, 0, 0); //rect(edge, edge, width-edge, height-edge); //fill(128); fill(255, 0, 0); text(valA,50, 25); text("QUAD A",50, 125); text(valB,675, 25); text("QUAD B",700, 125); text(valC,50, 730); text("QUAD C",50, 610); text(valD,680, 730); text("QUAD D",700, 610); text(valY,500, 60); text(valX,150, 280); fill(255,0,0); stroke(255,0,0); noFill(); ellipse((width/2)-valX-(radius/2),height/2- valY-(radius/2) , 90, 90); fill(255,0,0); ellipse((width/2)-valX-(radius/2),height/2- valY-(radius/2), radius, radius); fill(0,255,0); rect(0,height/2-5,valA/8,height/2-45); rect((width/2)-50,0,width/2,valB/8); rect(width/2,height-51,width/2-50,height-51-valC/8); rect(width-(50+valD/8),height/2-45,width-50,height/2-5); ///upper left x,upper left y,width,height }} Le programme arduino Code : Sélectionner tout - Visualiser dans une fenêtre à part 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 /** * prog name adatestquadrants * vizualize laser * work with lirelaser processing 3.3.5 * this program for arduino transmit the position of the lazer spot on a target * */ String quadrant[4] ; String touslesquadrant,xystring ; int abcd[4]; int Oldmina,Oldmaxa,Oldminb,Oldmaxb,Oldminc,Oldmaxc,Oldmind,Oldmaxd; float x,y; int intrusion; int ledRed=9;//intrusion detected int ledGreen=8 ;//probe signal void setup() { // initialize the serial communication: Serial.begin(9600); Oldmaxa=analogRead(0);//lecture du quadrant A Oldmina =Oldmaxa; //initialisation des minimax Oldmaxb=analogRead(1);//lecture du quadrant B Oldminb =Oldmaxb; Oldmaxc=analogRead(2);//lecture du quadrant C Oldminc =Oldmaxc; Oldmaxd=analogRead(3);//lecture du quadrant D Oldmind =Oldmaxd; pinMode(ledGreen, OUTPUT); // pinMode(ledRed, OUTPUT); digitalWrite(ledRed, HIGH) ; digitalWrite(ledGreen,HIGH); for (int i=0 ;i<3000;i++){ //determination des variations maximums int maxa=analogRead(0); if(maxa < Oldmina){ Oldmina =maxa;} if(maxa > Oldmaxa){ Oldmaxa =maxa;} delay(3); // je doit déterminer si l'utilisation d'une matrice ne serait pas plus économe int maxb=analogRead(1); if(maxb < Oldminb){ Oldminb =maxb;} if(maxb > Oldmaxb){ Oldmaxb =maxb;} delay(3); int maxc=analogRead(2); if(maxc < Oldminc){ Oldminc =maxc;} if(maxc > Oldmaxc){ Oldmaxc =maxc;} delay(3); int maxd=analogRead(3); if(maxd < Oldmind){ Oldmind =maxd;} if(maxd > Oldmaxd){ Oldmaxd =maxd;} delay(3); } delay(5000);//time to vizualize the control leds Serial.print(" A-="); Serial.print(Oldmina); Serial.print(" A+="); Serial.println(Oldmaxa); Serial.print(" B-="); Serial.print(Oldminb); Serial.print(" B+="); Serial.println(Oldmaxb); Serial.print(" C-="); Serial.print(Oldminc); Serial.print(" C+="); Serial.println(Oldmaxc); Serial.println(touslesquadrant); Serial.println(touslesquadrant); Serial.print(" D-="); Serial.print(Oldmind); Serial.print(" D+="); Serial.println(Oldmaxd); pinMode(ledGreen, OUTPUT); // pinMode(ledRed, OUTPUT); digitalWrite(ledRed, LOW) ; digitalWrite(ledGreen, LOW); delay(5000); } void loop() { // send the value of analog input 0: for (int i = 0; i < 4; i++){ abcd[i]=analogRead(i); (touslesquadrant+quadrant[i]); Serial.print(" quadrant " ); Serial.print(i); Serial.print("=" ); Serial.print(abcd[i]); }; Serial.print(" maxa=" ); Serial.print(Oldmaxa); Serial.print(" maxb=" ); Serial.print(Oldmaxb); Serial.print(" maxc=" ); Serial.print(Oldmaxc); Serial.print(" maxd=" ); Serial.print(Oldmaxd); Serial.print(" intrusion=" ); Serial.print(intrusion); Serial.println(" fin"); x=(abcd[0]+abcd[1]); x=x-(abcd[2]+abcd[3]); x=x/(abcd[0]+abcd[1]+abcd[2]+abcd[3]+.001);// prevenir la division par zero int xx=int(x*1000); y=(abcd[1]+abcd[3]); y=y-(abcd[1]+abcd[2]); y=y/(abcd[0]+abcd[1]+abcd[2]+abcd[3]+.001); int yy=int(y*1000); intrusion=0; if (abcd[0]<Oldmina)intrusion++;// routine de détection d'intrusion, ne sert à rien dans ce programme if (abcd[1]<Oldminb)intrusion++;// mais permet de vérifier sans charger le programme définitif if (abcd[2]<Oldminc)intrusion++;// permet aussi de comprendre le principe des 3 fenêtres if (abcd[3]<Oldmind)intrusion++; switch (intrusion) { case 1: digitalWrite(ledRed, HIGH) ; digitalWrite(ledGreen, LOW); break; case 2: digitalWrite(ledRed, HIGH) ; digitalWrite(ledGreen, LOW); break; case 3: digitalWrite(ledRed, HIGH) ; digitalWrite(ledGreen, HIGH); break; case 4: digitalWrite(ledRed, HIGH) ; digitalWrite(ledGreen, HIGH); break; default: digitalWrite(ledRed, LOW) ; digitalWrite(ledGreen, LOW); break; } Serial.print(" xx=" ); Serial.print(xx); Serial.print(" yy=" ); Serial.println(yy); }
/** * prog name lirelaser * vizualize laser * work with adatestquadrants * processing 3.3.5 * */ PImage img; PFont f; float mx; float my; float easing = 0.05; int radius = 50; int edge = 100; int inner = edge + radius; import processing.serial.*; int testi; Serial myPort; // Create object from Serial class float valX,valY,valA,valB,valC,valD; // Data received from the serial port int c; void setup() { // I know that the first port in the serial list on my mac // is always my FTDI adaptor, so I open Serial.list()[0]. // On Windows machines, this generally opens COM1. // Open whatever port is the one you're using. String portName = Serial.list()[2]; myPort = new Serial(this, portName, 19200); size(800, 800); noStroke(); ellipseMode(RADIUS); rectMode(CORNERS); //printArray(PFont.list()); f = createFont("DialogInput.bolditalic", 24); textFont(f); textAlign(CENTER, CENTER); img = loadImage("5323_Steiner-5x25-56mm-reticle.jpg"); //https://www.outdoorsbay.com/gallery-1/originals/5323_Steiner-5x25-56mm-reticle.jpg } void draw() { background(51); if ( myPort.available() > 0 && ( testi++>=2)) { testi=2; String inBuffer = myPort.readStringUntil('\n'); //print(inBuffer); if (inBuffer != null) { //String myString = new String(inBuffer); //println(myString); float[] val = float(inBuffer.split(",", 12)); //val = new float[6]; // float val[] = float(split(inBuffer,',')); valX=val[0]; valY=val[1]; valA=int(val[2]); valB=int(val[3]); valC=int(val[4]); valD=int(val[5]); //String texta="A"; // read it and store it in val } if (abs(valX - mx) > 0.1) { mx = mx + (valX - mx) * easing; } if (abs(valY - my) > 0.1) { my = my + (valY- my) * easing; } mx = constrain(mx, inner, width - inner); my = constrain(my, inner, height - inner); fill(76); rect(edge, edge, width-edge, height-edge); image(img, 0, 0); //rect(edge, edge, width-edge, height-edge); //fill(128); fill(255, 0, 0); text(valA,50, 25); text("QUAD A",50, 125); text(valB,675, 25); text("QUAD B",700, 125); text(valC,50, 730); text("QUAD C",50, 610); text(valD,680, 730); text("QUAD D",700, 610); text(valY,500, 60); text(valX,150, 280); fill(255,0,0); stroke(255,0,0); noFill(); ellipse((width/2)-valX-(radius/2),height/2- valY-(radius/2) , 90, 90); fill(255,0,0); ellipse((width/2)-valX-(radius/2),height/2- valY-(radius/2), radius, radius); fill(0,255,0); rect(0,height/2-5,valA/8,height/2-45); rect((width/2)-50,0,width/2,valB/8); rect(width/2,height-51,width/2-50,height-51-valC/8); rect(width-(50+valD/8),height/2-45,width-50,height/2-5); ///upper left x,upper left y,width,height }}
/** * prog name adatestquadrants * vizualize laser * work with lirelaser processing 3.3.5 * this program for arduino transmit the position of the lazer spot on a target * */ String quadrant[4] ; String touslesquadrant,xystring ; int abcd[4]; int Oldmina,Oldmaxa,Oldminb,Oldmaxb,Oldminc,Oldmaxc,Oldmind,Oldmaxd; float x,y; int intrusion; int ledRed=9;//intrusion detected int ledGreen=8 ;//probe signal void setup() { // initialize the serial communication: Serial.begin(9600); Oldmaxa=analogRead(0);//lecture du quadrant A Oldmina =Oldmaxa; //initialisation des minimax Oldmaxb=analogRead(1);//lecture du quadrant B Oldminb =Oldmaxb; Oldmaxc=analogRead(2);//lecture du quadrant C Oldminc =Oldmaxc; Oldmaxd=analogRead(3);//lecture du quadrant D Oldmind =Oldmaxd; pinMode(ledGreen, OUTPUT); // pinMode(ledRed, OUTPUT); digitalWrite(ledRed, HIGH) ; digitalWrite(ledGreen,HIGH); for (int i=0 ;i<3000;i++){ //determination des variations maximums int maxa=analogRead(0); if(maxa < Oldmina){ Oldmina =maxa;} if(maxa > Oldmaxa){ Oldmaxa =maxa;} delay(3); // je doit déterminer si l'utilisation d'une matrice ne serait pas plus économe int maxb=analogRead(1); if(maxb < Oldminb){ Oldminb =maxb;} if(maxb > Oldmaxb){ Oldmaxb =maxb;} delay(3); int maxc=analogRead(2); if(maxc < Oldminc){ Oldminc =maxc;} if(maxc > Oldmaxc){ Oldmaxc =maxc;} delay(3); int maxd=analogRead(3); if(maxd < Oldmind){ Oldmind =maxd;} if(maxd > Oldmaxd){ Oldmaxd =maxd;} delay(3); } delay(5000);//time to vizualize the control leds Serial.print(" A-="); Serial.print(Oldmina); Serial.print(" A+="); Serial.println(Oldmaxa); Serial.print(" B-="); Serial.print(Oldminb); Serial.print(" B+="); Serial.println(Oldmaxb); Serial.print(" C-="); Serial.print(Oldminc); Serial.print(" C+="); Serial.println(Oldmaxc); Serial.println(touslesquadrant); Serial.println(touslesquadrant); Serial.print(" D-="); Serial.print(Oldmind); Serial.print(" D+="); Serial.println(Oldmaxd); pinMode(ledGreen, OUTPUT); // pinMode(ledRed, OUTPUT); digitalWrite(ledRed, LOW) ; digitalWrite(ledGreen, LOW); delay(5000); } void loop() { // send the value of analog input 0: for (int i = 0; i < 4; i++){ abcd[i]=analogRead(i); (touslesquadrant+quadrant[i]); Serial.print(" quadrant " ); Serial.print(i); Serial.print("=" ); Serial.print(abcd[i]); }; Serial.print(" maxa=" ); Serial.print(Oldmaxa); Serial.print(" maxb=" ); Serial.print(Oldmaxb); Serial.print(" maxc=" ); Serial.print(Oldmaxc); Serial.print(" maxd=" ); Serial.print(Oldmaxd); Serial.print(" intrusion=" ); Serial.print(intrusion); Serial.println(" fin"); x=(abcd[0]+abcd[1]); x=x-(abcd[2]+abcd[3]); x=x/(abcd[0]+abcd[1]+abcd[2]+abcd[3]+.001);// prevenir la division par zero int xx=int(x*1000); y=(abcd[1]+abcd[3]); y=y-(abcd[1]+abcd[2]); y=y/(abcd[0]+abcd[1]+abcd[2]+abcd[3]+.001); int yy=int(y*1000); intrusion=0; if (abcd[0]<Oldmina)intrusion++;// routine de détection d'intrusion, ne sert à rien dans ce programme if (abcd[1]<Oldminb)intrusion++;// mais permet de vérifier sans charger le programme définitif if (abcd[2]<Oldminc)intrusion++;// permet aussi de comprendre le principe des 3 fenêtres if (abcd[3]<Oldmind)intrusion++; switch (intrusion) { case 1: digitalWrite(ledRed, HIGH) ; digitalWrite(ledGreen, LOW); break; case 2: digitalWrite(ledRed, HIGH) ; digitalWrite(ledGreen, LOW); break; case 3: digitalWrite(ledRed, HIGH) ; digitalWrite(ledGreen, HIGH); break; case 4: digitalWrite(ledRed, HIGH) ; digitalWrite(ledGreen, HIGH); break; default: digitalWrite(ledRed, LOW) ; digitalWrite(ledGreen, LOW); break; } Serial.print(" xx=" ); Serial.print(xx); Serial.print(" yy=" ); Serial.println(yy); }
A cet adresse vous pouvez trouver une thèse sur le sujet de la mesure (gratuit ) Fang, Zixi (2015) Research and Application of the Cutter Geometry On-Machine Measurement Using Laser Tool Setters. Masters thesis, Concordia University. https://spectrum.library.concordia.ca/979713/