Aller au contenu


Photo
- - - - -

Interpolation à partir d'un pseudo cercle.

Processing. échantillonnage

9 réponses à ce sujet

#1 bvking

bvking

    Membre occasionnel

  • Membres
  • Pip
  • 98 messages

Posté 14 mars 2023 - 08:33

Bonjour à toutes et tous!

 

Pour un projet artistique, j'echantillonne (sampling) pendant deux secondes un pseudo cercle (pas entièrement fini) tracé à la souris.

Puis cette forme se répète toute seule.

 

J'aimerai ajouter entre le dernier et le premier point tracés, un point d'interpolation qui soit à la moyenne

de la droite affine crée par le premier et le dernier.

 

Il faut essayer de tracer un cercle sur deux secondes. L'enregistrement se fait à chaque changement de seconde.

(mais on est pas censé le savoir).

 

Merci pour votre aide ;) et ce n'est que le début!

int actualSec,lastSec,measure,measureToStartRecording;;
boolean bRecording = false;
boolean mouseRecorded =  true;

class Sample {
  int t, x, y;
  Sample( int t, int x, int y ) {
    this.t = t;  this.x = x;  this.y = y;
  }
}

class Sampler {
  
  ArrayList<Sample> samples;
  int startTime;
  int playbackFrame;
  
  Sampler() {
    samples = new ArrayList<Sample>();
    startTime = 0;
  }
  void beginRecording() {   
    samples = new ArrayList<Sample>();
    playbackFrame = 0;
  }
  void addSample( int x, int y ) {  // add sample when bRecording
    int now = millis();
    if( samples.size() == 0 ) startTime = now;
    samples.add( new Sample( now - startTime, x, y ) );
  }
  int fullTime() {
    return ( samples.size() > 1 ) ? 
    samples.get( samples.size()-1 ).t : 0;
  }
  void beginPlaying() {
    startTime = millis();
    playbackFrame = 0;
    println( samples.size(), "samples over", fullTime(), "milliseconds" );
  }
  
 
  void draw() {
    stroke( 255 );
    
    //**RECORD
    beginShape(LINES);
    for( int i=1; i<samples.size(); i++) {
      vertex( samples.get(i-1).x, samples.get(i-1).y ); // replace vertex with Pvector
      vertex( samples.get(i).x, samples.get(i).y );
    }
    endShape();
    //**ENDRECORD
    
    //**REPEAT
    int now = (millis() - startTime) % fullTime();
    if( now < samples.get( playbackFrame ).t ) playbackFrame = 0;
    while( samples.get( playbackFrame+1).t < now )
      playbackFrame = (playbackFrame+1) % (samples.size()-1);
    Sample s0 = samples.get( playbackFrame );
    Sample s1 = samples.get( playbackFrame+1 );
    float t0 = s0.t;
    float t1 = s1.t;
    float dt = (now - t0) / (t1 - t0);
    float x = lerp( s0.x, s1.x, dt );
    float y = lerp( s0.y, s1.y, dt );
    circle( x, y, 10 );
  }
  
}

Sampler sampler;

void setup() {  
  size( 800, 800, P3D );
  frameRate( 30 );  
  sampler = new Sampler();
}

void draw() {
  background( 0 );
  activeSampling();
  stopSampling();
  
  if  (actualSec!=lastSec){
       lastSec=actualSec;
       measure++;
       textSize (100);
       text (measure, 100, 100 );
     }
       actualSec =(int) (millis()*0.001);  // 
 
  if( bRecording) { // draw circle
    circle( mouseX, mouseY, 10 );
    sampler.addSample( mouseX, mouseY );
  }
  
  else {    
  if( sampler.fullTime() > 0 )
        sampler.draw();
  }
}

void mousePressed() {
  bRecording = true;   // draw circle
  mouseRecorded = true;
  measure=0;
}
  
void activeSampling() { 
   if (measure<=1 && measure>=1 &&actualSec!=lastSec && mouseRecorded == true) {
  sampler.beginRecording();
  }
}

void stopSampling() { 
   if (measure<=3 && measure>=3  && actualSec!=lastSec) {  
  mouseRecorded = false;
     //**REPEAT
  bRecording = false;
  sampler.beginPlaying();
  }
}

Image(s) jointe(s)

  • Capture d’écran 2023-03-14 à 20.28.39.png


#2 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 969 messages
  • Gender:Male
  • Location:Anglet

Posté 17 mars 2023 - 01:59

Si on traite uniquement les cas comme ce que tu as représenté, il y a une différence entre " la moyenne " et une interpolation ...


Petite image ci dessous qui compare " la moyenne " avec un algo "assez simple" d'interpolation qui part des tengentes ...

extrapol.png


Avec un cas particulier quand il n'y a pas d'intersection des tangentes ...  dans ce cas là on peut faire le calcul de tengence à partir du point 1 et de l'avant dernier point... 


 
 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#3 bvking

bvking

    Membre occasionnel

  • Membres
  • Pip
  • 98 messages

Posté 17 mars 2023 - 02:48

Yep,

Dans l'ideal la deniere interpolation est la plus lisse et donc m'intéresse le plus.

Mais comme je suis pressé d'avoir un resultat, la solution la plus simple m'ira.

 

Le but est quand je répète le cercle, celui ci passe par un point intermédiaire pour ne pas à avoir faire une saccade trop brutale pour revenir au point d'origine.

Surtout dans un cercle de 6400 points, il faut arriver à programmer:

Que si le point part de 0 et fini à 6234 point, alors il passe par le point intermédiaire, disons 6350, et continue à aller dans le meme sens,

c'est à dire à 0, sans revenir en arrière. Alors il faudrait que le point 0 devienne 6401.

Voiloù, c'est tout pour le moment ;)

Apres faudra penser à une solution quand le cercle tracé dépasse un tour, au quel cas il faudra considerer le point le plus proche et précédent le premier point, comme dernier point. 

Puis de meme, faire en sorte que le programme continue à faire tourner le cercle toujours dans le meme sens.

Merci Mike  :yahoo:



#4 bvking

bvking

    Membre occasionnel

  • Membres
  • Pip
  • 98 messages

Posté 18 mars 2023 - 04:21

Yep!

 

Voilà le code qui reçoit les positions des 6 encodeurs.

J'ajouterai la fonction qui contrôle les 6 moteurs si tu veux.

Merci encore. 

import processing.serial.*;
Serial encoderReceiveUSBport101; // serial port receiving datas of positions of 6 motors
Serial teensyport; // serial port sending positions to 6 motors

int actualSec,lastSec,measure,measureToStartRecording;;
boolean bRecording = false;
boolean mouseRecorded =  true;

class Sample {
  int t, x, y;
  Sample( int t, int x, int y ) {
    this.t = t;  this.x = x;  this.y = y;
  }
}

class Sampler {
  
  ArrayList<Sample> samples;
  int startTime;
  int playbackFrame;
  
  Sampler() {
    samples = new ArrayList<Sample>();
    startTime = 0;
  }
  void beginRecording() {   
    samples = new ArrayList<Sample>();
    playbackFrame = 0;
  }
  void addSample( int x, int y ) {  // add sample when bRecording
    int now = millis();
    if( samples.size() == 0 ) startTime = now;
    samples.add( new Sample( now - startTime, x, y ) );
  }
  int fullTime() {
    return ( samples.size() > 1 ) ? 
    samples.get( samples.size()-1 ).t : 0;
  }
  void beginPlaying() {
    startTime = millis();
    playbackFrame = 0;
    println( samples.size(), "samples over", fullTime(), "milliseconds" );
  }
  
 
  void draw() {
    stroke( 255 );
    
    //**RECORD
    beginShape(LINES);
    for( int i=1; i<samples.size(); i++) {
      vertex( samples.get(i-1).x, samples.get(i-1).y ); // replace vertex with Pvector
      vertex( samples.get(i).x, samples.get(i).y );
    }
    endShape();
    //**ENDRECORD
    
    //**REPEAT
    int now = (millis() - startTime) % fullTime();
    if( now < samples.get( playbackFrame ).t ) playbackFrame = 0;
    while( samples.get( playbackFrame+1).t < now )
      playbackFrame = (playbackFrame+1) % (samples.size()-1);
    Sample s0 = samples.get( playbackFrame );
    Sample s1 = samples.get( playbackFrame+1 );
    float t0 = s0.t;
    float t1 = s1.t;
    float dt = (now - t0) / (t1 - t0);
    float x = lerp( s0.x, s1.x, dt );
    float y = lerp( s0.y, s1.y, dt );
    circle( x, y, 10 );
  }
  
}

Sampler sampler;

void setup() {  
  size( 800, 800, P3D );
  frameRate(30); // when size is set as P3D (3 dimension) we have 27 or 28 frame (loop) per seconde
  sampler = new Sampler();
  
  //********Sending and Receiving data with two different serialport
  String[] ports = Serial.list();
  printArray(Serial.list()); // display port in terminal
  //*************** TEENSY connected
   teensyport = new Serial(this, ports[0], 115200);// choose port matching to send data
  //*************** ENCODERD connected // comment below if port not connected
  //  encoderReceiveUSBport101 = new Serial(this, Serial.list()[1], 1000000);choose port matching to receive data
  //  Read bytes into a buffer until you get a linefeed (ASCII 10):
  //  encoderReceiveUSBport101.bufferUntil('\n');
}

void draw() {
  background( 0 );
  activeSampling();
  stopSampling();
  
  if  (actualSec!=lastSec){
       lastSec=actualSec;
       measure++;
       textSize (100);
       text (measure, 100, 100 );
     }
       actualSec =(int) (millis()*0.001);  // 
 
  if( bRecording) { // draw circle
    circle( mouseX, mouseY, 10 );
    sampler.addSample( mouseX, mouseY );
  }
  
  else {    
  if( sampler.fullTime() > 0 )
        sampler.draw();
  }
}

void mousePressed() {
  bRecording = true;   // draw circle
  mouseRecorded = true;
  measure=0;
}
  
void activeSampling() { 
   if (measure<=1 && measure>=1 &&actualSec!=lastSec && mouseRecorded == true) {
  sampler.beginRecording();
  }
}

void stopSampling() { 
   if (measure<=3 && measure>=3  && actualSec!=lastSec) {  
  mouseRecorded = false;
     //**REPEAT
  bRecording = false;
  sampler.beginPlaying();
  }
}

void serialEvent(Serial encoderReceiveUSBport101) { // receive 6 datas from serialport splited with , and a last is send with println

  // read the serial buffer:
  String myString = encoderReceiveUSBport101.readStringUntil('\n');

  // if you got any bytes other than the linefeed:
  myString = trim(myString);

  // split the string at the commas
  // and convert the sections into integers:
  int values[] = int(split(myString, ','));

  if (values.length > 0) {// v0 is value of the encodeur from 0 to 4000
  int v0; int v1; int v2; int v3; int v4; int v5;

    v0 = (int) map (values[0], 0, 4000, 0, 400);
    v1 = (int) map (values[0], 0, 4000, 0, 400);
    v2 = (int) map (values[0], 0, 4000, 0, 400);
    v3 = (int) map (values[0], 0, 4000, 0, 400);
    v4 = (int) map (values[0], 0, 4000, 0, 400);
    v5 = (int) map (values[0], 0, 4000, 0, 400);
           
    println (" v0 " + v0 ); println (" v1 " + v1 ); println (" v2 " + v2 ); println (" v3 " + v3 );
    println (" v4 " + v4 ); println (" v5 " + v5 );
}
}


#5 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 969 messages
  • Gender:Male
  • Location:Anglet

Posté 18 mars 2023 - 05:59

Après si ton but n'est pas d'ajouter des points mais de " déformer la trajectoire " de sorte à garder le même nombre de points mais refermer le début avec la fin tu peux faire ça : 

Ci dessous tu trouveras l'implémentation d'un algo basique basé sur la répartition "uniforme " de l'erreur entre le point d'arrivé et le point de départ.
 

class Sampler {
  
  ArrayList<Sample> samples;
    ArrayList<Sample> samplesModified;
  int startTime;
  int playbackFrame;
  
  Sampler() {
    samples = new ArrayList<Sample>();
        samplesModified = new ArrayList<Sample>();
    startTime = 0;
  }
  void beginRecording() {   
    samples = new ArrayList<Sample>();
    samplesModified = new ArrayList<Sample>();
    playbackFrame = 0;
  }
  void addSample( int x, int y ) {  // add sample when bRecording
    int now = millis();
    if( samples.size() == 0 ) startTime = now;
    samples.add( new Sample( now - startTime, x, y ) );
  }
  int fullTime() {
    return ( samples.size() > 1 ) ? 
    samples.get( samples.size()-1 ).t : 0;
  }
  void beginPlaying() {
    startTime = millis();
    playbackFrame = 0;
    println( samples.size(), "samples over", fullTime(), "milliseconds" );
    if(samples.size() > 0){
     int deltax = samples.get(0).x - samples.get(samples.size()-1).x;
     int deltay = samples.get(0).y - samples.get(samples.size()-1).y;
     
      for(int i = 0; i < samples.size(); i++) {
        samplesModified.add( new Sample(samples.get(i).t, samples.get(i).x + i * deltax /samples.size(), samples.get(i).y + i * deltay / samples.size()) );
        print(samples.get(i).x);
        print(",");
        print(samples.get(i).y);
        print(",");
        print(samplesModified.get(i).x);
        print(",");
        print(samplesModified.get(i).y);
        println("");      
      }
    }
  }
  
 
  void draw() {
    stroke( 255 );
    
    //**RECORD
    beginShape(LINES);
    for( int i=1; i<samples.size(); i++) {
      vertex( samplesModified.get(i-1).x, samplesModified.get(i-1).y ); // replace vertex with Pvector
      vertex( samplesModified.get(i).x, samplesModified.get(i).y );
    }
    endShape();
    //**ENDRECORD
    
    //**REPEAT
    int now = (millis() - startTime) % fullTime();
    if( now < samplesModified.get( playbackFrame ).t ) playbackFrame = 0;
    while( samplesModified.get( playbackFrame+1).t < now )
      playbackFrame = (playbackFrame+1) % (samples.size()-1);
    Sample s0 = samplesModified.get( playbackFrame );
    Sample s1 = samplesModified.get( playbackFrame+1 );
    float t0 = s0.t;
    float t1 = s1.t;
    float dt = (now - t0) / (t1 - t0);
    float x = lerp( s0.x, s1.x, dt );
    float y = lerp( s0.y, s1.y, dt );
    circle( x, y, 10 );
  }
  
}

Teste et dis moi ce que tu en penses ... 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#6 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 969 messages
  • Gender:Male
  • Location:Anglet

Posté 18 mars 2023 - 07:39

Après réflexion plutôt qu'une répartition homogène répartie équitablement entre tous les points il vaudrait mieux répartir l'erreur proportionnellement en fonction de la distance entre deux points ... 

En effet avec la méthode précédente, si tu restais " sans bouger à un moment donné " après "transformation" les points qui étaient censé être immobiles se retrouvaient déplacés les uns des autres à cause de la transformation ... 

Avec la méthode basée sur la distance entre deux points, les points qui sont censés être immobiles restent inchangés après transformation.
 

class Sampler {
  
  ArrayList<Sample> samples;
    ArrayList<Sample> samplesModified;
  int startTime;
  int playbackFrame;
  
  Sampler() {
    samples = new ArrayList<Sample>();
        samplesModified = new ArrayList<Sample>();
    startTime = 0;
  }
  void beginRecording() {   
    samples = new ArrayList<Sample>();
    samplesModified = new ArrayList<Sample>();
    playbackFrame = 0;
  }
  void addSample( int x, int y ) {  // add sample when bRecording
    int now = millis();
    if( samples.size() == 0 ) startTime = now;
    samples.add( new Sample( now - startTime, x, y ) );
  }
  int fullTime() {
    return ( samples.size() > 1 ) ? 
    samples.get( samples.size()-1 ).t : 0;
  }
  void beginPlaying() {
    startTime = millis();
    playbackFrame = 0;
    println( samples.size(), "samples over", fullTime(), "milliseconds" );
    if(samples.size() > 0){
      int deltax = samples.get(0).x - samples.get(samples.size()-1).x;
      int deltay = samples.get(0).y - samples.get(samples.size()-1).y;
      float sumdist = 0;
      
      for(int i = 0; i < samples.size() - 1; i++) {
        sumdist += sqrt((samples.get(i).x - samples.get(i +1 ).x)*(samples.get(i).x - samples.get(i +1 ).x) + (samples.get(i).y - samples.get(i +1 ).y)*(samples.get(i).y - samples.get(i +1 ).y));
      }
      
      samplesModified.add( new Sample(samples.get(0).t, samples.get(0).x , samples.get(0).y ) );
      float dist = 0;
      for(int i = 0; i < samples.size() - 1; i++) {
        dist += sqrt((samples.get(i).x - samples.get(i +1 ).x)*(samples.get(i).x - samples.get(i +1 ).x) + (samples.get(i).y - samples.get(i +1 ).y)*(samples.get(i).y - samples.get(i +1 ).y));
        samplesModified.add( new Sample(samples.get(i+1).t, (int) (samples.get(i +1).x + (dist * deltax) / sumdist), (int) (samples.get(i+1).y +( dist * deltay )/ sumdist)) );
        print(samples.get(i).x);
        print(",");
        print(samples.get(i).y);
        print(",");
        print(samplesModified.get(i).x);
        print(",");
        print(samplesModified.get(i).y);
        println("");      
      }
    }
  }

 void draw() {
    stroke( 255 );
    
    //**RECORD
    beginShape(LINES);
    for( int i=1; i<samples.size(); i++) {
      vertex( samplesModified.get(i-1).x, samplesModified.get(i-1).y ); // replace vertex with Pvector
      vertex( samplesModified.get(i).x, samplesModified.get(i).y );
    }
    endShape();
    //**ENDRECORD
    
    //**REPEAT
    int now = (millis() - startTime) % fullTime();
    if( now < samplesModified.get( playbackFrame ).t ) playbackFrame = 0;
    while( samplesModified.get( playbackFrame+1).t < now )
      playbackFrame = (playbackFrame+1) % (samples.size()-1);
    Sample s0 = samplesModified.get( playbackFrame );
    Sample s1 = samplesModified.get( playbackFrame+1 );
    float t0 = s0.t;
    float t1 = s1.t;
    float dt = (now - t0) / (t1 - t0);
    float x = lerp( s0.x, s1.x, dt );
    float y = lerp( s0.y, s1.y, dt );
    circle( x, y, 10 );
  }
  
}

 

Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#7 bvking

bvking

    Membre occasionnel

  • Membres
  • Pip
  • 98 messages

Posté 18 mars 2023 - 08:48

Yep!

 

La v2 a l'air carrément mieux. Je dis à l'air, car il faut que je regarde dans la pratique. 

Je te dis çà demain.

Tres bonne soirée, et grrRRAAAAANNNNNNDDDDDDD merci!



#8 bvking

bvking

    Membre occasionnel

  • Membres
  • Pip
  • 98 messages

Posté 22 mars 2023 - 01:39

Hello!

 

J'ai amélioré la methode pour enregistrer un mouvement circulaire

 

Mais le mouvement reproduit me fait ce genre de forme

 

 

class Sample {
int t;
float x, y;
Sample( int t, float x, float y ) {
this.t = t; this.x = x; this.y = y;
}
}

class Sampler {
 
ArrayList<Sample> samples;
ArrayList<Sample> samplesModified;
int startTime;
int playbackFrame;
 
Sampler() {
samples = new ArrayList<Sample>();
samplesModified = new ArrayList<Sample>();
startTime = 0;
}
void beginRecording() {
samples = new ArrayList<Sample>();
samplesModified = new ArrayList<Sample>();
playbackFrame = 0;
}
void addSample( float x, float y ) { // add sample when bRecording
int now = millis();
if( samples.size() == 0 ) startTime = now;
samples.add( new Sample( now - startTime, x, y ) );
}
int fullTime() {
return ( samples.size() > 1 ) ?
samples.get( samples.size()-1 ).t : 0;
}
void beginPlaying() {
startTime = millis();
playbackFrame = 0;
println( samples.size(), "samples over", fullTime(), "milliseconds" );
if(samples.size() > 0){
float deltax = samples.get(0).x - samples.get(samples.size()-1).x;
float deltay = samples.get(0).y - samples.get(samples.size()-1).y;
float sumdist = 0;
 
for(int i = 0; i < samples.size() - 1; i++) {
sumdist += sqrt((samples.get(i).x - samples.get(i +1 ).x)*(samples.get(i).x - samples.get(i +1 ).x) + (samples.get(i).y - samples.get(i +1 ).y)*(samples.get(i).y - samples.get(i +1 ).y));
}
 
samplesModified.add( new Sample(samples.get(0).t, samples.get(0).x , samples.get(0).y ) );
float dist = 0;
for(int i = 0; i < samples.size() - 1; i++) {
dist += sqrt((samples.get(i).x - samples.get(i +1 ).x)*(samples.get(i).x - samples.get(i +1 ).x) + (samples.get(i).y - samples.get(i +1 ).y)*(samples.get(i).y - samples.get(i +1 ).y));
samplesModified.add( new Sample(samples.get(i+1).t, (int) (samples.get(i +1).x + (dist * deltax) / sumdist), (int) (samples.get(i+1).y +( dist * deltay )/ sumdist)) );
print(samples.get(i).x);
print(",");
print(samples.get(i).y);
print(",");
print( " good data x " + samplesModified.get(i).x);
print(",");
print( " good data y " + samplesModified.get(i).y);
println("");
}
}
}
 
 
void draw() {
stroke( 255 );
 
//**RECORD
beginShape(LINES);
for( int i=1; i<samples.size(); i++) {
vertex( samplesModified.get(i-1).x, samplesModified.get(i-1).y ); // replace vertex with Pvector
vertex( samplesModified.get(i).x, samplesModified.get(i).y );
}
endShape();
//**ENDRECORD
 
//**REPEAT
int now = (millis() - startTime) % fullTime();
if( now < samplesModified.get( playbackFrame ).t ) playbackFrame = 0;
while( samplesModified.get( playbackFrame+1).t < now )
playbackFrame = (playbackFrame+1) % (samples.size()-1);
Sample s0 = samplesModified.get( playbackFrame );
Sample s1 = samplesModified.get( playbackFrame+1 );
float t0 = s0.t;
float t1 = s1.t;
float dt = (now - t0) / (t1 - t0);

float x =constrain (lerp( s0.x, s1.x, dt ),-300, 300);
float y =constrain (lerp( s0.y, s1.y, dt ),-300, 300);


circle( x, y, 20 );
 
textSize (50);
 
movementInterpolated = y ;
text (" x " + x + " y " + y + " mov " + movementInterpolated , 100, 300);

}
}

Sampler sampler;


 

Image(s) jointe(s)

  • Capture d’écran 2023-03-22 à 16.11.30.png


#9 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 969 messages
  • Gender:Male
  • Location:Anglet

Posté 24 mars 2023 - 12:13

Le code fournit ne compile pas ... 

" movementInterpolated not defined"


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#10 bvking

bvking

    Membre occasionnel

  • Membres
  • Pip
  • 98 messages

Posté 24 mars 2023 - 01:02

Hello! resultat parfait bientôt! 

Cool on peut faire un pseudo cercle, s'arrêter avant ou aller un peu plus loin que le point de départ et le mouvement se répète parfaitement!
Mais ceci est vrai si on commence le mouvement sur la partie gauche du cercle trigo! Pas depuis la partie droite.
J'ai mis des lignes pour repérer le point de départ de l'enregistrement, qui d'ailleurs commence des qu'on clique sur la sourie et s'arrête au bout de deux secondes.

 

Capture d’écran 2023-05-14 à 20.10.28.png
 
Si tu commences à faire le mouvement depuis la premiere ligne jusqu’a la deuxième et un peu plus, ton programme fonctionne , le mouvement tourne en boucle.
Mais si je pars  de la deuxième ligne, comme sur le screen shot  et que je m’arrête à la troisième et un peu plus ça ne fonctionne pas .
Peux tu corriger ce problème , stp ? :thank_you: 
 

int actualSec,lastSec,measure,measureToStartRecording;
boolean bRecording = false;
boolean mouseRecorded =  true;
float movementInterpolated, angleToInterpolate;
int numberOfSample;

//--------------------        method of interpolation to return the position of (rotation) by adding modulo
float mlerp(float x0, float x1, float t, float M ){
   float dx = (x1 - x0 + 1.5*M) % M - 0.5*M;
   return (x0 + t * dx + M) % M;
}

class Sample {
int t;
float x, y;
Sample( int t, float x, float y ) {
this.t = t; this.x = x; this.y = y;
}
}

class Sampler {

ArrayList<Sample> samples;
ArrayList<Sample> samplesModified;
int startTime;
int playbackFrame;

Sampler() {
samples = new ArrayList<Sample>();
samplesModified = new ArrayList<Sample>();
startTime = 0;
}
void beginRecording() {
samples = new ArrayList<Sample>();
samplesModified = new ArrayList<Sample>();
playbackFrame = 0;
}
void addSample( float x, float y ) { // add sample when bRecording
int now = millis();
if( samples.size() == 0 ) startTime = now;
samples.add( new Sample( now - startTime, x, y ) );
}
int fullTime() {
return ( samples.size() > 1 ) ?
samples.get( samples.size()-1 ).t : 0;

}
void beginPlaying() {
startTime = millis();
playbackFrame = 0;
println( samples.size(), "samples over", fullTime(), "milliseconds" );
if(samples.size() > 0){
  numberOfSample=samples.size();
  
float deltax = samples.get(0).x - samples.get(samples.size()-1).x;
float deltay = samples.get(0).y - samples.get(samples.size()-1).y;
float sumdist = 0;

for(int i = 0; i < samples.size() - 1; i++) {
sumdist += sqrt((samples.get(i).x - samples.get(i +1 ).x)*(samples.get(i).x - samples.get(i +1 ).x) + (samples.get(i).y - samples.get(i +1 ).y)*(samples.get(i).y - samples.get(i +1 ).y));
}
samplesModified.add( new Sample(samples.get(0).t, samples.get(0).x , samples.get(0).y ) );
float dist = 0;
for(int i = 0; i < samples.size() - 1; i++) {
dist += sqrt((samples.get(i).x - samples.get(i +1 ).x)*(samples.get(i).x - samples.get(i +1 ).x) + (samples.get(i).y - samples.get(i +1 ).y)*(samples.get(i).y - samples.get(i +1 ).y));
samplesModified.add( new Sample(samples.get(i+1).t, (float) (samples.get(i +1).x + (dist * deltax) / sumdist), (float) (samples.get(i+1).y +( dist * deltay )/ sumdist)) );
print(samples.get(i).x);
print(",");
print(samples.get(i).y);
print(",");
print( " good data x " + samplesModified.get(i).x);
print(",");
print( " good data y " + samplesModified.get(i).y);
println("");
}
}
}

 void draw() {
stroke( 255 );
//**RECORD
beginShape(LINES);
for( int i=1; i<samples.size(); i++) {
vertex( samplesModified.get(i-1).x, samplesModified.get(i-1).y ); // replace vertex with Pvector
vertex( samplesModified.get(i).x, samplesModified.get(i).y );
}
endShape();
//**ENDRECORD

//**REPEAT
int now = (millis() - startTime) % fullTime();
if( now < samplesModified.get( playbackFrame ).t ) playbackFrame = 0;
while( samplesModified.get( playbackFrame+1).t < now )
playbackFrame = (playbackFrame+1) % (samples.size()-1);
Sample s0 = samplesModified.get( playbackFrame );
Sample s1 = samplesModified.get( playbackFrame+1 );
float t0 = s0.t;
float t1 = s1.t;
float dt = (now - t0) / (t1 - t0);

//float x =lerp( s0.x, s1.x, dt );  // interpolation without modulo
//float y =lerp( s0.y, s1.y, dt ); // 

float x =mlerp( s0.x, s1.x, dt, TWO_PI ); // interpolation with modulo, it's better
float y =mlerp( s0.x, s1.x, dt, TWO_PI );

movementInterpolated = y ;
text (" mov " +  (movementInterpolated) , 100, 500);
fill (255,255,255);
circle ( 100* cos (movementInterpolated)+200, 100*sin (movementInterpolated)+200, 20);
stroke(255);
 }
}

Sampler sampler;

void setup() {  
  size( 800, 800, P3D );
  frameRate(30); // when size is set as P3D (3 dimension) we have 27 or 28 frame (loop) per seconde
  sampler = new Sampler(); 
  mouseY= height/2;
}

void draw() {
  background(50);
   for (int i=0; i<=8; i++ ){ 
    stroke(2);
  line (0, height/8*i, width, height/8*i); // horizon
  line (width/8*i, 0, width/8*i, height); // vertical

  }
  textSize (20);
   //----------------------------------------
  angleToInterpolate = (float) map (mouseY, 0, 200, 0, TWO_PI)%TWO_PI; 
  fill( 100, 0, 0);
  circle ( 100* cos (angleToInterpolate)+200, 100*sin (angleToInterpolate)+200, 20); 
  //----------------------------------------
  pushMatrix();
  translate(width/2, height/2);
  rotate(angleToInterpolate);
  translate(28, 0);
  rect(-30, -5, 60, 10);
  popMatrix();
  //----------------------------------------
  ellipse(width/2, height/2, 5, 5);
  text( " repeted  " +nf (movementInterpolated, 0, 2)  + " original " +nf (angleToInterpolate,0,2 ),width/2, height/4);
//  text( " repeted  " +nf (movementInterpolated, 0, 2) , 10, 0);
  textSize (20);
    /*
      for(int i = 0; i < samples.size() - 1; i++) {
       text (" angleModif " +    sampledModifiedChecking[i], 0, 100+ 20*i);
       text (" angleModif " + samplesModified.get(i).x, 100+ 20*i);
      }
    */

 if  (actualSec!=lastSec){
       lastSec=actualSec;
       measure++;
   }
   
  text (measure, 100, 100 );
  actualSec =(int) (millis()*0.001);  // 

  activeSampling();
  stopSampling();
  
  if( bRecording) { // draw circle
 //   circle( mouseX, mouseY, 10 );
 //   sampler.addSample( mouseX, mouseY );
     textSize(100);
     fill (0, 255, 0);
     text (measure, 200, 100 );
  sampler.addSample( angleToInterpolate, angleToInterpolate );
  }
  
  else {    
  if( sampler.fullTime() > 0 )
        sampler.draw();
  }

  if(numberOfSample > 0){
  
  println (frameCount%numberOfSample+1 + " " + movementInterpolated);
  }
}

void mousePressed() {
  bRecording = true;   // draw circle
  mouseRecorded = true;
  measure=0;
}
  
void activeSampling() { 
  if (measure==0 && actualSec!=lastSec && mouseRecorded == true) {
     textSize(100);
    
     fill (0, 255, 0);
     text (measure, 200, 100 );
  sampler.beginRecording();
  }
}

void stopSampling() { 
  if (measure==2 && actualSec!=lastSec) {  
     textSize(100);
   
     fill (255, 0, 0); 
       text (measure, 200, 100 );
  mouseRecorded = false;
     //**REPEAT
  bRecording = false;
  sampler.beginPlaying();
  }
}




Répondre à ce sujet



  


0 utilisateur(s) li(sen)t ce sujet

0 members, 0 guests, 0 anonymous users