2017-01-30 11 views
1

私は200Hzで3つのメッセージを吐き出しているナビゲーションユニットを持っています。これらのメッセージを送信された順に取り込み、これらのメッセージから特定のデータを取り込み、バイト配列で直列に送出されます。InputStreamからcertianバイトデータを検索する

私はソケットと入力ストリームを使用してデータを取得しており、ソケットリーダーと呼ばれる実行可能クラスに渡されます。もう1つの実行可能クラスは、変数を受け取り、数式を実行し、それらをバイトに変換してシリアルに送り出します。

このプログラムは、一度に約8時間実行され、データストリームは、単一である場合にのみ送信される第3のメッセージ(GPSデータ)を除いて一定です。

  InputStream in = echoSocket.getInputStream(); 
      DataInputStream dis = new DataInputStream(in); 

      OutputStream out = serialPort.getOutputStream(); 

      (new Thread(new SocketReader(dis))).start(); 
      (new Thread(new SerialWriter(out))).start(); 

私が問題を抱えているのは、socketReaderクラスです。だから私はヘックスでヘッダーを知っているので、DataInputStreamからデータをバイトバッファーに読み込んで、データをより多くの部分文字列に入れて浮動小数点数に変換するstringBuilderに読み込んでいます。

これは機能しますが、あなたはaltHoldのlogHold latHold文字列を解析するのに問題があります(コメントアウトされています)。データの4バイト(単精度浮動小数点)ではなく、8バイト(倍精度浮動小数点)です。しかし、私はここに車輪を再発明しているように感じる。メッセージのデータは最下位ビットで、私は自分のプログラムを遅くしているように感じていますか?またそれは完璧ではありませんループから落ちることによって終了してからしばらくの間実行されます。

現在のところ、私は最初の2つのメッセージと同じ頻度で3番目のメッセージが送信されていないことを見ています。私はDataInputStream以外の何かを使うべきですか?

public static class SocketReader implements Runnable { 

    //Message headers 
    final String mes1 = new String("FF5A0600"); 
    final String mes2 = new String("FF5A0800"); 
    final String mes3 = new String("FF5A1300"); 

    //These are the size of each message 
    final int Stop1 = 82; 
    final int Stop2 = 162; 
    final int Stop3 = 150; 

    StringBuilder rolHold = new StringBuilder(); 
    StringBuilder pitHold = new StringBuilder(); 
    StringBuilder yawHold = new StringBuilder(); 

    StringBuilder altHold = new StringBuilder(); 
    StringBuilder latHold = new StringBuilder(); 
    StringBuilder logHold = new StringBuilder(); 
    StringBuilder velNHold = new StringBuilder(); 
    StringBuilder velEHold = new StringBuilder(); 

    DataInputStream dis; 

    public SocketReader(DataInputStream dis) { 
     this.dis = dis; 
    } 

    public void run() { 

     byte[] buffer; 

     //dis is a DataInputStream 
     while (dis != null){ 

      buffer = new byte[ 1024 ]; 

      try { 
       dis.readFully(buffer); 
      } catch (IOException e1) { 
       e1.printStackTrace(); 
      } 

      StringBuilder sb = new StringBuilder(); 

      for (byte b: buffer){     
       sb.append(String.format("%02X", b)); 
      } 

      //Finds the first occurrence of the three messages 
      //If the index is -1 there is no occurrence 
      int index1 = sb.indexOf(mes1); 
      int index2 = sb.indexOf(mes2); 
      int index3 = sb.indexOf(mes3); 


      while (index1 <= sb.lastIndexOf(mes1) && (index1 != -1) && (index2 != -1) && (index2 != 0)){ 


       //this if statement deals with the first message 
       //There are three sets of data pulled from message 1 {rolValue, pitValue, yawValue}   
       if (index1 < index2 && (index1 != -1)){ 

        //reseting the Stringbuilders 
        rolHold.setLength(0); 
        pitHold.setLength(0); 
        yawHold.setLength(0); 

        //the data is sent little-endian and is appended in reverse order 
        rolHold.append(sb.substring((index1 + 26),(index1 + 28))); 
        rolHold.append(sb.substring((index1 + 24),(index1 + 26))); 
        rolHold.append(sb.substring((index1 + 22),(index1 + 24))); 
        rolHold.append(sb.substring((index1 + 20),(index1 + 22))); 
        Long rol = Long.parseLong(rolHold.toString(), 16); 
        rolValue = Float.intBitsToFloat(rol.intValue());        

        pitHold.append(sb.substring((index1 + 34),(index1 + 36))); 
        pitHold.append(sb.substring((index1 + 32),(index1 + 34))); 
        pitHold.append(sb.substring((index1 + 30),(index1 + 32))); 
        pitHold.append(sb.substring((index1 + 28),(index1 + 30))); 
        Long pit = Long.parseLong(pitHold.toString(), 16); 
        pitValue = Float.intBitsToFloat(pit.intValue());   

        yawHold.append(sb.substring((index1 + 42),(index1 + 44))); 
        yawHold.append(sb.substring((index1 + 40),(index1 + 42))); 
        yawHold.append(sb.substring((index1 + 38),(index1 + 40))); 
        yawHold.append(sb.substring((index1 + 36),(index1 + 38))); 
        Long yaw = Long.parseLong(yawHold.toString(), 16); 
        yawValue = Float.intBitsToFloat(yaw.intValue()); 


        //increments the index1 to its next sequence of message 1 
        //-1 is returned if there is not another 
        index1 = sb.indexOf(mes1, (index1 + Stop1)); 
       } 


       //this if statement deals with the second message 
       //There are five sets of data pulled from message 2 {velNValue, velEValue, latValue, logValue, altValue}   
       if(index2 < index1 && (index2 != -1) && (index2 != 0)){ 


        altHold.setLength(0); 
        latHold.setLength(0); 
        logHold.setLength(0); 
        velNHold.setLength(0); 
        velEHold.setLength(0); 

          velNHold.append(sb.substring((navIndex + 26),(navIndex + 28))); 
          velNHold.append(sb.substring((navIndex + 24),(navIndex + 26))); 
          velNHold.append(sb.substring((navIndex + 22),(navIndex + 24))); 
          velNHold.append(sb.substring((navIndex + 20),(navIndex + 22))); 
          Long velN = Long.parseLong(velNHold.toString(), 16); 
          velNValue = Float.intBitsToFloat(velN.intValue()); 



          velEHold.append(sb.substring((navIndex + 34),(navIndex + 36))); 
          velEHold.append(sb.substring((navIndex + 32),(navIndex + 34))); 
          velEHold.append(sb.substring((navIndex + 30),(navIndex + 32))); 
          velEHold.append(sb.substring((navIndex + 28),(navIndex + 30))); 
          Long velE = Long.parseLong(velEHold.toString(), 16); 
          velEValue = Float.intBitsToFloat(velE.intValue()); 


    //      latHold.append(sb.substring((navIndex + 82),(navIndex + 84))); 
    //      latHold.append(sb.substring((navIndex + 80),(navIndex + 82))); 
    //      latHold.append(sb.substring((navIndex + 78),(navIndex + 80))); 
    //      latHold.append(sb.substring((navIndex + 76),(navIndex + 78))); 
    //      latHold.append(sb.substring((navIndex + 74),(navIndex + 76))); 
    //      latHold.append(sb.substring((navIndex + 72),(navIndex + 74))); 
    //      latHold.append(sb.substring((navIndex + 70),(navIndex + 72))); 
    //      latHold.append(sb.substring((navIndex + 68),(navIndex + 70))); 
    //      Long lat = Long.parseLong(logHold.toString(), 16); 
    //      Float latValue = Float.intBitsToFloat(lat.intValue());      
    // 
    //      logHold.append(sb.substring((navIndex + 98),(navIndex + 100))); 
    //      logHold.append(sb.substring((navIndex + 96),(navIndex + 98))); 
    //      logHold.append(sb.substring((navIndex + 94),(navIndex + 96))); 
    //      logHold.append(sb.substring((navIndex + 92),(navIndex + 94))); 
    //      logHold.append(sb.substring((navIndex + 90),(navIndex + 92))); 
    //      logHold.append(sb.substring((navIndex + 88),(navIndex + 90))); 
    //      logHold.append(sb.substring((navIndex + 86),(navIndex + 88))); 
    //      logHold.append(sb.substring((navIndex + 84),(navIndex + 86))); 
    //      Long log = Long.parseLong(logHold.toString(), 16); 
    //      Float logValue = Float.intBitsToFloat(log.intValue()); 
    // 
    // 
    //      altHold.append(sb.substring((navIndex + 114),(navIndex + 116))); 
    //      altHold.append(sb.substring((navIndex + 112),(navIndex + 114))); 
    //      altHold.append(sb.substring((navIndex + 110),(navIndex + 112))); 
    //      altHold.append(sb.substring((navIndex + 108),(navIndex + 110))); 
    //      altHold.append(sb.substring((navIndex + 106),(navIndex + 108))); 
    //      altHold.append(sb.substring((navIndex + 104),(navIndex + 106))); 
    //      altHold.append(sb.substring((navIndex + 102),(navIndex + 104))); 
    //      altHold.append(sb.substring((navIndex + 100),(navIndex + 102))); 
    //      Long alt = Long.parseLong(altHold.toString(), 16); 
    //      Float altValue = Float.intBitsToFloat(alt.intValue()); 



        //increments the index2 to its next sequence of message 2 
        //-1 is returned if there is not another 
        index2 = sb.indexOf(mes2, (index2 +Stop2)); 

       } 

      } 
     } 
    } 
} 

私はあなたに助けていただきありがとうございます。あなたが私からの情報をもっと必要とするなら、私はそれを与えることを嬉しく思うでしょう。

ありがとうございます!

答えて

1

DataInputStreamを使用してDataOutputStreamによって生成されたデータを読み取ることは推奨されません(IMHO)。彼らは、特定のデータ型(例えば、UTF String)の書き込み/読み取りに独自のプロトコルを使用します。

これはreadFully(1024)の読み取りバイトだけであるため、上記のコードの問題ではありません。しかし、この方法の使用はここで問題になる可能性があります。コネクションがクローズされない限り(通常は、またはExceptionによって)、フル・バッファーを読み込みます。つまり、メッセージの長さは1024バイトでなければなりません。

また、コードによって行われた変換を理解することは難しいです。それは私が行っていると思います:文字列(16進表記)、16進数の順序の文字列を変更し、longに変換し、floatに変換します。 文字列ですべての算術演算を行うのが最善の解決策であるとは思わない...

とにかく、バイト配列と(開始)インデックスを指定すると、計算されたfloat/doubleを返す

private static float readFloat(byte[] buffer, int index) { 
    // not done in a loop for demonstration 
    int bits = (buffer[index+0] & 255) 
      + ((buffer[index+1] & 255) << 8) 
      + ((buffer[index+2] & 255) << 16) 
      + ((buffer[index+3] & 255) << 24); 
    return Float.intBitsToFloat(bits); 
} 

とより良いソリューションの私見をラップするByteBufferを使用して、またはその代わりのbyte[]されています、のように、)理解しやすいとTESTです。 ByteBufferはリトルエンディアンに設定でき、floatとdouble(example)を取得するメソッドを持ち、ソケットから読み取るためのオプションもあります

関連する問題