Communication avec un laser en TCP/IP: décalage temporel de 10 sec !? (pb thread ?)
Bonjour,
Nous communiquons avec un LIDAR branché par ethernet à notre ordinateur. Nous utilisons un protocol TCP/IP. Apres avoir envoyé une instruction de début de mesures au laser, celui -ci nous donne ces mesures sous forme de string. Chaque string représente un plan (cad environ 500 points).
La classe LMS contient un thread qui est à l'écoute du laser. Chaque mesure (500 points sous forme de string) est stockée dans l'attribut answer de la classe LMS.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| public void Connect(){
try{
s=new Socket(host,port);
in=new BufferedReader(new InputStreamReader(s.getInputStream()));
out = new PrintStream( s.getOutputStream() );
}catch(IOException e){
System.out.println("Probleme de Socket");
System.exit(1);
}
//lance le thread d'�coute
start();
Send("commande d'id laser");//identification auprès du laser
}
public void SEstartMeas(){
Send("commande de début de mesure");
try{ sleep(50); }catch(InterruptedException e){System.out.println("erreur sleep");}
// message de configuration de base du telegramme par d�faut �a ne change pas donc inutile en premier lieu
Send("commande de config de base");
try{ sleep(50); }catch(InterruptedException e){System.out.println("erreur sleep");}
Send("commande START MESURES");
try{ sleep(1000); }catch(InterruptedException e){System.out.println("erreur sleep");}
//TabThread();
}
public void run(){ //lit le cot� serv et met � jour le tabPosition
String ligne=null;
int character;
try{
while( (character = in.read()) != -1){
if((char)character==stx){
//System.out.print((char)character+"\n");
ligne=ligne+(char)character;
answerSplit=ligne.split("\\s");
System.out.println("LMS:"+(char)character);
//34 est un nombre arbitraire
if(answerSplit.length>3)
IsPrompted=true;
ligne=null;
nbreMesures++;
}
else{
System.out.print((char)character);
ligne=ligne+(char)character;
}
}
}catch(Exception e){
System.out.println("connexion perdue");
}
} |
D'un autre coté, nous affichons ces données dans la classe Visual, avec un thread qui tourne en permanence pour lire la valeur de l'attribut answer. Nous avons pensé qu' en procédant de la sorte, le temps de traitement des données pour l'affichage (transformation de tous les points de coordonnées polaires en cartésiennes) n'aurait pas d'influence sur l'acquisition de données. De cette manière si on reçoit les points toutes les t millisecondes, et que notre traitement d'affichage dure 4t, nous n'aurons pas 4 valeurs en retard puisque entre temps, l'attribut answer a été mis à jour 4 fois ainsi nous pouvons lire la donnée la plus récente.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
| package pair2;
import java.util.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.BorderFactory;
import java.lang.Math;
import java.lang.*;
public class Visual {
public Visual() {
}
public static void main(String[] args) {
JFrame frame = new JFrame();
LMS111 lms = new LMS111("192.168.0.1",2111);
Graph g1 =new Graph(lms);
GraphThread g = new GraphThread(g1); //graph extends jpanel
JLabel titre = new JLabel("VISUAL GRAPH");
/* frame */
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Visual LMS");
frame.setSize(500,500);
frame.getContentPane().add(titre);
frame.getContentPane().add(g1);
frame.getContentPane().setLayout(null);
frame.setVisible(true);
/* frame */
/* titre */
//titre.setBounds(210,10,100,100);
/* titre */
/* cadre */
Border compound,raisedbevel,loweredbevel;
raisedbevel = BorderFactory.createRaisedBevelBorder();
loweredbevel = BorderFactory.createLoweredBevelBorder();
compound = BorderFactory.createCompoundBorder(raisedbevel, loweredbevel);
g1.setBorder(compound);
/* cadre */
g1.setBounds(50,50,400,400);//position du graphique
lms.Connect();
lms.SEstartMeas();
for(int i=0;i<1;)
i++;
lms.SEstopMeas();
}
}
class Graph extends JPanel{
int x,y;
LMS111 lms;
String []answersplit;
int[][] affichage;
public Graph(LMS111 lms) {
this.lms=lms;
affichage = new int[600][2];
}
public void trace(){
float x,y,teta;
int r;
float Xmin,Xmax,Ymin,Ymax;
Xmin=Ymin=999; Xmax=Ymax=0;
//int i=270+32;
//System.out.println(answersplit.length);
if(lms.IsPrompted){
answersplit = lms.getAnswerSplit();
System.out.println("VISUAL:"+answersplit[90+32]);
if(answersplit.length>3){
for(int i=0;i<540;i++){
r=Integer.parseInt(answersplit[i+31],16);
teta=((lms.startAngle/10000)+i*(lms.angleRes/10000))*(float)Math.PI/180;
x=r*(float)Math.cos(teta);
y=r*(float)Math.sin(teta);
x=(float)(x*(200/(310.6+1931.4))+200);
y=(float)(y*(200/(2659.4+66.6))+200);
affichage[i][0]=(int)x;
affichage[i][1]=(int)y;
}
}}
repaint();
}
public void paintComponent (Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
for(int i=0;i<540;i++) {
g.drawOval(affichage[i][0],affichage[i][1],2,2);
}
}
}
class GraphThread extends Thread{
Graph g;
public GraphThread(Graph g){
this.g=g;
start();
}
public void run() {
while(true){
g.trace();
try{
sleep(10);
}
catch(InterruptedException e){
System.err.println("Interrupted");
}
}
}
} |
Notre problème est que entre le moment où le laser transmet une valeur, et le moment ou nous l'affichons, 10 secondes sont perdues quelque part. Pour comprendre voici une info importante: lorsque nous envoyons l'instruction d'arrêt des mesures, nous pensons que le laser s'arrête instantanément, cependant il affiche encore des valeurs pendant 10 sec, ce fameux décalage!
Peut-être est-ce un problème de priorité de thread ? Le processeur ne passe pas assez de temps dans la boucle de mise à jour de données ?
Merci de votre aide/