Aller au contenu


Photo
- - - - -

Suivre un signal avec un décalage en temps et non en frame.

Processing

  • Veuillez vous connecter pour répondre
3 réponses à ce sujet

#1 bvking

bvking

    Membre occasionnel

  • Membres
  • Pip
  • 98 messages

Posté 12 septembre 2022 - 11:34

Bonjour,

 

Une balle [0] oscillant entre 0 et PI est suivie par 9 autres balles sans décalages temporels. Elles ont donc le meme signal.

J'aimerais, en appuyant une fois sur la flèche droite, que les balles de 1 à 9 autres suivent la balle 0 avec 1 à 9 * 500 ms seconde de retard.

J'ai un premier  programme qui fonctionne, les balles suivent bien le signal avec 10, 20 ... frame de retard.

Mais je veux qu'elles suivent le signal en fonction de l'incrementation d'un temps et non par l'incrementation par image ( par la fonction frameCount qui s'actualise dans la main loop).

Comment puis je faire?

J'ai fait une variable qui s'actualise avec la fonction millis() qui s'actualise bien avec l'horloge du processeurs et non par frameCount.

Ca fonctionne, mais mon incrementation temporelle n'est pas precise.

Aussi, je n'arrive pas à récupérer les positions des balles qui suivent la balle 0.

 

Merci pour vos signaux éclairés!

 

PS: Ici est le programme où frameCount est remplacé par frameCountBis qui s'actualise avec millis() 

String debug ="";
String dataToControlMotor;
boolean way;

// MANAGE PERSPECTIVE
import peasy.*;

// change these for screen size
float w = 1000;
float h = 800;

// don't change these
float w2 = w / 2;
float h2 = h / 2;

int nbBall = 9;
int nbMaxDelais = 2000;
float pendulairePhase;
float formerDecayTime, decayTime;
int frameCountBis = 0;
int lastSec, sec, countSec;

// Code pour option de follow
boolean firstFollowingLast = true;
float deltaFollow = PI/180;
boolean firstFollowingStarted = false;

float [][] phases = new float[nbBall][nbMaxDelais];
int[] phaseToMotor;
float [] phaseMapped;

float x, y;

float Phase;

int d, k; // to modulate parameter of phase and time offset

int frameRatio;

public void settings() {
  size(600, 600, P3D);  
}

void setup() {
  new PeasyCam(this, 2000);
  frameRatio=30;
  countSec=0;
  k=1;
  

  frameRate(frameRatio);
  for (int i = 0; i < nbBall; i++) {
    phaseToMotor= new int [nbBall];
    phaseMapped= new float [nbBall];

    for (int j = 0; j < nbMaxDelais; j++)
      phases[i][j] = PI;
  }
}

void draw() {
  background(0);
  if (lastSec>=sec){
  background (100);
  countSec++;
  };
  
  if (formerDecayTime>=decayTime){
      frameCountBis=frameCountBis+1;
  } 
   
   formerDecayTime = decayTime;
   decayTime = (millis()*1)%20;// counter actualise 20 times in on sec
   lastSec= sec; 
   sec=millis()%1000;
    
  println(frameCount + ": " + frameRatio + " : incrementTime " + frameCountBis + " Sec " + second() + " : sec " + countSec  + " decayT "  + decayTime + " : decay en ms " + d*50)   ;
 
  rotate(- TWO_PI  ); //TO change the beginning of the 0 (cercle trigo) and the cohesion point to - HALF_PI
  translate(width/2, -height/2, -1000);// To set the center of the perspective

  if (!firstFollowingStarted) {
    float signal = diffAngle(PI + (frameCountBis /4) * cos (1000 / 250.0), 0);

    print ("signal ");
    print ( signal );
    
    float deltaFollow = PI/180;
     
  if (signal > 0 )
      phases[0][frameCountBis/1 % nbMaxDelais]= diffAngle(signal, HALF_PI);//% 
  else
      phases[0][frameCountBis/1 % nbMaxDelais]= diffAngle(2* PI, signal + HALF_PI);//% TWO_PI
      drawBall(0, phases[0][frameCountBis  % nbMaxDelais]); // affiche le point 0. NE PAS AFFICHER SINON IL APPARAIT EN DOUBLE
  }

  for (int i = 1; i < nbBall; i++) {
    debug ="Normal follow ";
    //   follow( i-1, i, 20 * i, 0);  // Modifier les deux derniers paramètres : délais et phase
    follow( i-1, i, d, k*QUARTER_PI/8);  // ici, le temps que les points attendent pour se suivre est de d frames, et il faut un espace entre eux de QUARTER_PI/8

    //*****   drawBall(i, phaseMapped[i] );
    drawBall(i, phases[i][frameCountBis*1 % nbMaxDelais] );

  }   
      float balle0;
      float balle1;
      float balle2;
      
  balle0 = phases[0][frameCountBis  % nbMaxDelais];
  balle1 = phases[1][frameCountBis  % nbMaxDelais];
  balle2 = phases[2][frameCountBis  % nbMaxDelais];
  
    println(" balle0 " + balle0 + " balle1 " + balle1 + " balle2 " + balle2)  ;


}

void drawBall(int n, float phase) {
  pushMatrix();
  translate(-w2, -h2, -1000);
  noStroke();
  float side = height*0.15*1/nbBall;
  float rayon = width/2;
  
  x = rayon*cos(phase); //-300 à 300
  y = rayon*sin(phase);
  
  translate (x, y, 200+(50*5*n)); // 
  translate (100, 100, 200+(50*5*n));
  colorMode(RGB, 255, 255, 255);
  fill( 0, 255, 0 );
  sphere(side*3);
  popMatrix();
}

void follow( int target, int follower, int delais, float deltaphase) {
  int step = frameCountBis % nbMaxDelais;
  int followedStep = (step + nbMaxDelais - delais) % nbMaxDelais;
  phases[follower][step] = diffAngle(phases[target][followedStep] + deltaphase, 0);
}

float diffAngle(float angle1, float angle2) { // return the difference angle1 - angle2 between two angle between -PI PI
  float result = angle1 - angle2;
  while (result > PI) {
    result -= 2 * PI;
  }
  while (result < -PI) {
    result += 2 * PI;
  }
  return result;
}

void keyPressed () {
   
  if (keyCode == UP) {
    frameRatio=frameRatio+5;
    frameRatio=frameRatio%65;
 
      if (frameRatio <=0 ){
       frameRatio=5;
      }
       frameRate(frameRatio);  
  }
  if (keyCode == DOWN) {
   
  if (frameRatio <=5 ){
       frameRatio=5;
      }
       frameRatio=frameRatio-1;
  }
       frameRate(frameRatio); // pas dans le void draw
  
  if (keyCode == RIGHT) {
       println(" right INCREASE timeOffset ")  ; //
       d+= 10; // incremente de demi sec. I need to increment 1282 to have 60 sec. So one sec is 1282/60 => 21.5 incrementations/sec
       d=d%65;
       print ("d= timeOffsetRatio: ");
       println (d);
  }

  if (keyCode == LEFT) {
      println(" left INCREASE phase shifting"); //
      d-=10; // incremente de demi sec
     }
  }

programme avec FrameCount

String debug ="";
String dataToControlMotor;
boolean way;

// MANAGE PERSPECTIVE
import peasy.*;

// change these for screen size
float w = 1000;
float h = 800;

// don't change these
float w2 = w / 2;
float h2 = h / 2;

int nbBall = 9;
int nbMaxDelais = 2000;
float pendulairePhase;
float formerDecayTime, decayTime;
int frameCountBis = 0;
int lastSec, sec, countSec;

// Code pour option de follow
boolean firstFollowingLast = true;
float deltaFollow = PI/180;
boolean firstFollowingStarted = false;

float [][] phases = new float[nbBall][nbMaxDelais];
int[] phaseToMotor;
float [] phaseMapped;

float x, y;

float Phase;

int d, k; // to modulate parameter of phase and time offset

int frameRatio;

public void settings() {
  size(600, 600, P3D);  
}

void setup() {
  new PeasyCam(this, 2000);
  frameRatio=30;
  countSec=0;
  k=1;
  

  frameRate(frameRatio);
  for (int i = 0; i < nbBall; i++) {
    phaseToMotor= new int [nbBall];
    phaseMapped= new float [nbBall];

    for (int j = 0; j < nbMaxDelais; j++)
      phases[i][j] = PI;
  }
}

void draw() {
  background(0);
  if (lastSec>=sec){
  background (100);
  countSec++;
  };
  
  if (formerDecayTime>=decayTime){
      frameCountBis=frameCountBis+1;
  } 
   
   formerDecayTime = decayTime;
   decayTime = (millis()*1)%20;// counter actualise 20 times in on sec
   lastSec= sec; 
   sec=millis()%1000;
    
  println(frameCount + ": " + frameRatio + " : incrementTime " + frameCountBis + " Sec " + second() + " : sec " + countSec  + " decayT "  + decayTime + " : decay en ms " + d*50)   ;
 
  rotate(- TWO_PI  ); //TO change the beginning of the 0 (cercle trigo) and the cohesion point to - HALF_PI
  translate(width/2, -height/2, -1000);// To set the center of the perspective

  if (!firstFollowingStarted) {
    float signal = diffAngle(PI + (frameCount /4) * cos (1000 / 250.0), 0);

    print ("signal ");
    print ( signal );
    
    float deltaFollow = PI/180;
     
  if (signal > 0 )
      phases[0][frameCount/1 % nbMaxDelais]= diffAngle(signal, HALF_PI);//% 
  else
      phases[0][frameCount/1 % nbMaxDelais]= diffAngle(2* PI, signal + HALF_PI);//% TWO_PI
      drawBall(0, phases[0][frameCount  % nbMaxDelais]); // affiche le point 0. NE PAS AFFICHER SINON IL APPARAIT EN DOUBLE
  }

  for (int i = 1; i < nbBall; i++) {
    debug ="Normal follow ";
    //   follow( i-1, i, 20 * i, 0);  // Modifier les deux derniers paramètres : délais et phase
    follow( i-1, i, d, k*QUARTER_PI/8);  // ici, le temps que les points attendent pour se suivre est de d frames, et il faut un espace entre eux de QUARTER_PI/8

    //*****   drawBall(i, phaseMapped[i] );
    drawBall(i, phases[i][frameCount*1 % nbMaxDelais] );

  }   
      float balle0;
      float balle1;
      float balle2;
      
  balle0 = phases[0][frameCount  % nbMaxDelais];
  balle1 = phases[1][frameCount  % nbMaxDelais];
  balle2 = phases[2][frameCount  % nbMaxDelais];
  
    println(" balle0 " + balle0 + " balle1 " + balle1 + " balle2 " + balle2)  ;
}

void drawBall(int n, float phase) {
  pushMatrix();
  translate(-w2, -h2, -1000);
  noStroke();
  float side = height*0.15*1/nbBall;
  float rayon = width/2;
  
  x = rayon*cos(phase); //-300 à 300
  y = rayon*sin(phase);
  
  translate (x, y, 200+(50*5*n)); // 
  translate (100, 100, 200+(50*5*n));
  colorMode(RGB, 255, 255, 255);
  fill( 0, 255, 0 );
  sphere(side*3);
  popMatrix();
}

void follow( int target, int follower, int delais, float deltaphase) {
  int step = frameCount % nbMaxDelais;
  int followedStep = (step + nbMaxDelais - delais) % nbMaxDelais;
  phases[follower][step] = diffAngle(phases[target][followedStep] + deltaphase, 0);
}

float diffAngle(float angle1, float angle2) { // return the difference angle1 - angle2 between two angle between -PI PI
  float result = angle1 - angle2;
  while (result > PI) {
    result -= 2 * PI;
  }
  while (result < -PI) {
    result += 2 * PI;
  }
  return result;
}

void keyPressed () {
   
  if (keyCode == UP) {
    frameRatio=frameRatio+5;
    frameRatio=frameRatio%65;
 
      if (frameRatio <=0 ){
       frameRatio=5;
      }
       frameRate(frameRatio);  
  }
  if (keyCode == DOWN) {
   
  if (frameRatio <=5 ){
       frameRatio=5;
      }
       frameRatio=frameRatio-1;
  }
       frameRate(frameRatio); // pas dans le void draw
  
  if (keyCode == RIGHT) {
       println(" right INCREASE timeOffset ")  ; //
       d+= 10; // incremente de demi sec. I need to increment 1282 to have 60 sec. So one sec is 1282/60 => 21.5 incrementations/sec
       d=d%65;
       print ("d= timeOffsetRatio: ");
       println (d);
  }

  if (keyCode == LEFT) {
      println(" left INCREASE phase shifting"); //
      d-=10; // incremente de demi sec
     }
  }


#2 Ludovic Dille

Ludovic Dille

    Habitué

  • Membres
  • PipPip
  • 186 messages
  • Gender:Male
  • Location:Belgique

Posté 13 septembre 2022 - 08:17

Bonjour bvking,

Pour être certains de bien avoir compris tu veux implémenter:
y0 = f(t)
ton signal de base qui oscille entre 0 et pi

yi = f(t-i*0.5) avec i compris entre 1 et 9

Ludo



#3 bvking

bvking

    Membre occasionnel

  • Membres
  • Pip
  • 98 messages

Posté 18 octobre 2022 - 11:39

Hello Ludo.

Là on voit un signal circulaire sur 10 balles . Le signal depend de la vitesse d'incrementation de frameCount.

Le décalage entre chaque balle qui se suivent est de d*20 ms. En appuyant sur la flèche droite

String debug ="";
String dataToControlMotor;
boolean way;

// MANAGE PERSPECTIVE
import peasy.*;

// change these for screen size
float w = 1000;
float h = 800;

// don't change these
float w2 = w / 2;
float h2 = h / 2;

int nbBall = 9;
int nbMaxDelais = 2000;
float pendulairePhase;
float formerDecayTime, decayTime;
int frameCountBis = 0;
int lastSec, sec, countSec;

// Code pour option de follow
boolean firstFollowingLast = true;
float deltaFollow = PI/180;
boolean firstFollowingStarted = false;

float [][] phases = new float[nbBall][nbMaxDelais];
int[] phaseToMotor;
float [] phaseMapped;

float x, y;

float Phase;

int d, k; // to modulate parameter of phase and time offset

int frameRatio;

public void settings() {
  size(600, 600, P3D);  
}

void setup() {
  new PeasyCam(this, 2000);
  frameRatio=30;
  countSec=0;
  k=1;
  

  frameRate(frameRatio);
  for (int i = 0; i < nbBall; i++) {
    phaseToMotor= new int [nbBall];
    phaseMapped= new float [nbBall];

    for (int j = 0; j < nbMaxDelais; j++)
      phases[i][j] = PI;
  }
}

void draw() {
  background(0);
  if (lastSec>=sec){
  background (100);
  countSec++;
  };
  
  if (formerDecayTime>=decayTime){
      frameCountBis=frameCountBis+1;
  } 
   
   formerDecayTime = decayTime;
   decayTime = millis()%50;// counter actualise 20 times in on sec
 
    
  println( " decayT "  + decayTime + " : decay en ms " + d*50)   ;
 
  rotate(- TWO_PI  ); //TO change the beginning of the 0 (cercle trigo) and the cohesion point to - HALF_PI
  translate(width/2, -height/2, -1000);// To set the center of the perspective

  if (!firstFollowingStarted) {
 
       float signal = PI + (frameCount /4) * cos (1000 / 25.0);
 
    phases[0][frameCountBis/1 % nbMaxDelais]=signal;
 
  for (int i = 1; i < nbBall; i++) {
    debug ="Normal follow ";
    //   follow( i-1, i, 20 * i, 0);  // Modifier les deux derniers paramètres : délais et phase
    follow( i-1, i, d, k*QUARTER_PI/8);  // ici, le temps que les points attendent pour se suivre est de d frames (, et il faut un espace entre eux de QUARTER_PI/8

    //*****   drawBall(i, phaseMapped[i] );
    drawBall(i, phases[i][frameCountBis*1 % nbMaxDelais] );

  }   
  }  
}

void drawBall(int n, float phase) {
  pushMatrix();
  translate(-w2, -h2, -1000);
  noStroke();
  float side = height*0.15*1/nbBall;
  float rayon = width/2;
  
  x = rayon*cos(phase); //-300 à 300
  y = rayon*sin(phase);
  
  translate (x, y, 200+(50*5*n)); // 
  translate (100, 100, 200+(50*5*n));
  colorMode(RGB, 255, 255, 255);
  fill( 0, 255, 0 );
  sphere(side*3);
  popMatrix();
}

void follow( int target, int follower, int delais, float deltaphase) {
  int step = frameCountBis % nbMaxDelais;
  int followedStep = (step + nbMaxDelais - delais) % nbMaxDelais;
  phases[follower][step] = phases[target][followedStep] + deltaphase;
}

void keyPressed () {
   
  if (keyCode == RIGHT) {
       println(" right INCREASE timeOffset ")  ; //
       d+= 1; // incremente 50 ms. So if d=10 second ball follows first with a time offset of 500 ms
       d=d%51;
       print ("d= timeOffsetRatio: ");
       println (d);
  }

  if (keyCode == LEFT) {
      println(" left INCREASE phase shifting"); //
      d-=1; // incremente de demi sec
     }
  }


#4 Mike118

Mike118

    Staff Robot Maker

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

Posté 19 octobre 2022 - 11:09

bvking, tout le monde ne va pas forcément installer processing pour tester le programme pour pouvoir ensuite te répondre, je pense que si tu mets une vidéo de ce qui se passe / du problème ça insiterait plus les gens à essayer de comprendre ce que tu fais et à te proposer des choses pour résoudre ton problème. 

Après je ne suis pas sûr à 100% de ton problème : 

=> Ta base de temps en ms n'est pas précise 

Tu utilises un compteur " qui n'est pas système " et donc pas précis, qui compte les ms qui se sont écoulée le tout, sur un pc multi thread qui fait pas mal de chose en même temps.
Par exemple si  tu as un autre thread qui te mange 2ms de ton proc avant de retourner sur le thread de ton programme ton compteur va compter faire un saut de 2ms au lieu de réussir à conter chaque ms ... 

Je suppose que la notion de " fps " est plus précise car cela doit appeler une routine sub système qui doit faire en sorte de rappeler le processus de manière un peu plus précise afin d'avoir un nombre d'image / secondes qui fonctionne correctement... 

La question est : Pourquoi est ce que tu veux un temps et pas te baser sur le système visiblement plus précis qui est ton nombre d'image, sachant que tu peux ajuster ton nombre d'image pour compter un temps assez précis non ?  


Ensuite :  "je n'arrive pas à récupérer les positions des balles qui suivent la balle 0 " 

Comment est ce que tu fais pour afficher une position que tu n'arrives pas à récupérer ... 

tu as la phase de toutes tes balles "i" qui sont indiquées dans la ligne : 
 

drawBall(i, phases[i][frameCount*1 % nbMaxDelais] ); 

Si tu as la phase tu peux calculer le x y vu que c'est fait dans la fonction drawBall ... 

 

  x = rayon*cos(phase); //-300 à 300
  y = rayon*sin(phase);

...

 





 


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  

 

 

 






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

0 members, 0 guests, 0 anonymous users