Benutzer-Werkzeuge

Webseiten-Werkzeuge


virtuelles_java-teleskop

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
virtuelles_java-teleskop [2019/06/24 10:43] torsten.roehlvirtuelles_java-teleskop [2020/11/22 16:19] (aktuell) – Externe Bearbeitung 127.0.0.1
Zeile 3: Zeile 3:
 ===== Übersicht ===== ===== Übersicht =====
  
 +Die grundsätzliche Arbeitsweise zwischen Linux und dem Teleskop (Steuerung) kann man auch ohne Elektronik (& Teleskop) studieren. Die drei großen Clients (KStart, Skychart und Stellarium) können mit der Indi-Schnittstelle kommunizieren und
 +virtuelle Teleskopmontierungen einbinden. Diese Teleskopsimulatoren sind technisch gesehen INDI-C++-Treiber. Ich erzeuge hier z.B. mit Java eine virtuelle serielle Schnittstelle und benutze "täusche" eine rudimentäre
 +LX200 Montierung vor, die mit Stellarium verwendet werden kann.
  
-   
  
 == Software == == Software ==
  
 +
 +<WRAP center round info 95%>
 +Um mit Java auf die serielle Schnittstelle zugreifen zu können, verwenden wir die jSSC (Java Simple Serial Connector) API. Sie besteht aus nur einer jar-Datei und wird auch von der Arduino-IDE selbst verwendet. In Eclipse wird sie über Eigenschaften (Java Build Path - Add External JAR's...) dem Projekt hinzugefügt.
 +
 +https://code.google.com/archive/p/java-simple-serial-connector/
 +oder {{ :serial.zip |}}
 +</WRAP>
 + 
 ===== Details ===== ===== Details =====
  
Zeile 14: Zeile 24:
  
 ==== Software ==== ==== Software ====
 +
 +<WRAP center round info 60%>
 +socat - universelles Linux Netwerk Tool
 +</WRAP>
  
 ==== Installation und Inbetriebnahme ==== ==== Installation und Inbetriebnahme ====
  
-Die grundsätzliche Arbeitsweise kann man auch ohne Elektronik (& Teleskop) studieren. Die drei großen Clients (KStart, Skychart und Stellarium) können mit der Indi-Schnittstelle kommunizieren und +  Eclipseprojekt erzeugen und die Datei (unten) **SimulatorTeleskop** einfügen 
-virtuelle Teleskopmontierungen einbinden. Diese Teleskopsimulatoren sind technisch gesehen INDI-C++-TreiberIch erzeuge hier z.B. mit Java eine virtuelle serielle Schnittstelle und benutze "täuscheeine +  jssc-2.0.0.jar als Externe Library dem Projekt hinzufügen 
-LX200 Montierung vor um dann mit Stellarium dieses virtuelle Teleskop zu verwenden.+  - Projekt mit Eclipse übersetzen (kann nicht fehlerfrei gestartet werden, da die Schnittstelle "/dev/ttyUSB60nicht vorhanden ist) 
 +  - Virtuelle serielle Schnittstelle erzeugen 
 +  - Rechte setzen 
 +  - Testen
  
-Die auf diese Weise angelegte  Schnittstelle muss häufig neu eingerichtet werden (Schritte 1 und 2) +== Details ==
-) und soll nur die grundlegende Kommunikation aufzeigen.+
  
 +Die folgenden beiden befehle erfordern Rootrechte. Außerdem müssen  auf diese Weise angelegte  Schnittstellen muss häufig neu eingerichtet werden. Nicht vergessen, dieses Projekt soll zum eigenen Experimentieren anregen und lediglich die grundlegende Kommunikation aufzeigen.
  
-1. Virtuelle serielle Schnittstelle erzeugen +Die virtuelle Schnittstelle wird mit dem folgenden Befehl  gesetzt
   socat -d -d PTY,link=/dev/ttyUSB60 PTY,link=/dev/ttyUSB61   socat -d -d PTY,link=/dev/ttyUSB60 PTY,link=/dev/ttyUSB61
- +   
-2.Rechte setzen +Anschließend werden zum Testen alle Rechte vergeben 
   # chmod 777 /dev/ttyUSB6*   # chmod 777 /dev/ttyUSB6*
  
-3. Testen+Überprüfen Sie (Konsole ls-Befehl) ob alles richtig gemacht wurde 8-)
  
- i) Konsole+== Test 1: Konsole ==
  
-  echo ":GD#" > /dev/ttyUSB60+Ein erste Test erfolgt mit einer User-Konsole, indem folgender Befehl an das Gerät gesendet wird, zuvor muss das Programm (z.B. über Eclipse gestartet werden). 
 + 
 +  echo ":GD#" > /dev/ttyUSB61
      
-Simulator.java sollte Nachricht anzeigen!+Auf der Konsole (Eclipse) sollten jetzt die Anzahl der gelesenen Bytes angezeigt werden. Damit funktioniert die Kommunikation über die virtuelle serielle Schnittstelle.
  
- iiStellarium+  - Schnittstelle einrichten (socat,chmod) 
 +  - Java //SimulatorTeleskop// starten 
 +  - In einer Userkonsole //echo ":GD#" > /dev/ttyUSB61// eingeben
  
-lx200 Teleskop einrichten mit /dev/ttyUSB60 als Device 
  
 +== Test 2: Stellarium ==
 + 
 +Der zweite Test ist spannender, da wir mit Stellarium kommunizieren.
 +  - LX200 Teleskop einrichten mit /dev/ttyUSB61 als Device (__noch nicht verbinden!__)
 +  - Schnittstelle einrichten (socat, chmod)
 +  - Java //SimulatorTeleskop// starten
 +  - LX200 Teleskop in Stellarium verbinden
  
  
 +===== Quellcode Projekt A =====
  
- <code java> +Das Protokoll kann hier eingesehen werden {{ :telescopeprotocol_lx200.pdf | LX200 Seriell-Protokoll}}
-package test;+
  
-import com.fazecast.jSerialComm.SerialPort;+Das Javaprogramm implementiert nur wenige Kommandos des ProtokollsNachdem Stellarium sich mit dem "Teleskop" (Javaprogramm) verbunden hat, sendet es permanent Anfragen um die Rektaszension //(#:GR#)// und die Deklination //(#:GE#)// des Telekops zu erhalten.
  
-public class Test01 {+Wenn mit Stellarium geschwenkt werden soll, d.h. ein bestimmtes Objekt angefahren werden soll, werden drei Kommandos geschickt. Die ersten beiden Kommandos übermitteln die Zielkoordinaten, während das dritte Kommando //(:MS#)// eine Bestätigung erwartet um das Teleskop zu schwenken. Diese Befehle sind im {{ :telescopeprotocol_lx200.pdf | LX200 Seriell-Protokoll}} aufgelistet. Damit wir bei Stellarium eine animierte Bewegung sehen, wurde die Methode //simulateMove()// hinzugefügt, die lediglich die RA-Achse in zehn Schritten von den aktuellen Koordinaten //currentRA// zu den Zielkoordinaten //targetRA// bewegt. 
 +<code java> 
 + 
 +/** LX200 Protocol  
 + * @author torsten.roehl@fsg-preetz.org 
 + * simple demo to communicate with a indi-client! 
 + */ 
 + 
 +import java.util.Timer; 
 +import java.util.TimerTask; 
 + 
 +import jssc.SerialPort; 
 +import jssc.SerialPortException; 
 + 
 +public class SimulatorTeleskop { 
 + 
 + static String currentRA = "02:31:50#"; 
 + static String currentDE = "+89*15#"; 
 + 
 + static String targetRA = currentRA; 
 + static String targetDE = currentDE; 
 + 
 + static String dev = "/dev/ttyUSB60"; 
 + 
 + public enum Protocol // some serial lx200 commands 
 +
 + CMD_GR, CMD_GD, CMD_QS, CMD_SD, CMD_MS, CMD_UNKNOWN 
 +
 + 
 + public static void main(String[] args) throws InterruptedException { 
 + 
 + SerialPort serialPort = new SerialPort(dev); 
 + try { 
 + serialPort.openPort(); 
 + serialPort.setParams(9600, 8, 1, 0); 
 + System.out.println("... initializing the serial port"); 
 + Thread.sleep(4000); // necessary, otherwise serial will fail!!! 
 + 
 + } catch (SerialPortException e1) { 
 + e1.printStackTrace(); 
 + }
  
- public static void main(String[] args) { 
- SerialPort comPort = SerialPort.getCommPorts()[2]; 
- comPort.openPort(); 
- comPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 100, 0); 
  try {  try {
  while (true) {  while (true) {
- byte[] readBuffer = new byte[1024]; 
- int numRead = comPort.readBytes(readBuffer, readBuffer.length); 
  
- if (numRead > 0{ + String msg = decode(serialPort); 
- plot(numRead, readBuffer);+ Protocol cmd = protocol(msg);
  
- if(getRADEC(numRead,readBuffer)){ + switch (cmd) { 
- System.out.println("received radec messgage"); + case CMD_GR: 
- writeRADEC(comPort); + writeMessage(serialPortcurrentRA)
- } + break; 
- if (isGetRA(numReadreadBuffer)) { + case CMD_GD: 
- System.out.println("received ra messgage"); + writeMessage(serialPort, currentDE); 
- writeRa(comPort); + break; 
- } + case CMD_QS: 
- if (isGetDec(numRead, readBuffer)) { + targetRA = msg.substring(msg.indexOf(' ')).trim(); 
- System.out.println("received dec messgage"); + writeMessage(serialPort, "1"); 
- writeDec(comPort); + break; 
-+ case CMD_SD: 
- //+ currentDE = msg.substring(msg.indexOf(' ')).trim(); 
 + targetDE = currentDE; 
 + writeMessage(serialPort"1"); 
 + break; 
 + case CMD_MS: 
 + writeMessage(serialPort, "0"); 
 + simulateMove(); 
 + break; 
 + case CMD_UNKNOWN: 
 + if (!msg.startsWith("zero")) 
 + System.out.println("...received unknown serial command: + msg); 
 + break;
  }  }
 +
  Thread.sleep(100);  Thread.sleep(100);
  
Zeile 87: Zeile 158:
  e.printStackTrace();  e.printStackTrace();
  }  }
- comPort.closePort(); 
  
- }+ try { 
 + serialPort.closePort(); 
 + } catch (SerialPortException e) { 
 + e.printStackTrace(); 
 + }
  
- static void plot(int numRead, byte[] readBuffer) { 
- System.out.println("Read " + numRead + " bytes."); 
- 
- for (int i = 0; i < numRead; i++) { 
- char c = (char) readBuffer[i]; 
- System.out.print(c); 
- } 
- System.out.println(""); 
  }  }
- static boolean getRADEC(int num, byte[] readBuffer) { 
- char c[] = new char[num]; 
- if (readBuffer.length < 1) 
- return false; 
  
- for (int i = 0; i < num; i++) { + private static Protocol protocol(String msg) {
- c[i] = (char) readBuffer[i];+
  
- }+ if (msg.startsWith("#:GR#")) 
 + return Protocol.CMD_GR; 
 + if (msg.startsWith("#:GD#")) 
 + return Protocol.CMD_GD; 
 + if (msg.startsWith("#:Q#:S")) 
 + return Protocol.CMD_QS; 
 + if (msg.startsWith(":Sd ")) 
 + return Protocol.CMD_SD; 
 + if (msg.startsWith(":MS#")) 
 + return Protocol.CMD_MS;
  
- if (c[0] == 'e' ) { + return Protocol.CMD_UNKNOWN;
- return true; +
-+
- +
- return false;+
  }  }
-  
- static void writeRADEC(SerialPort p) { 
  
- String str = "34AB0500,12CE0500#"; + static String decode(SerialPort serialPort) { 
- byte[] buffer = new byte[18]; + try { 
- byte[] byte_str = str.getBytes(); + // step 1: read bytes from port 
- for (int i 0; i < 18; i+++ byte[] buffer = serialPort.readBytes(); 
- buffer[i] = byte_str[i];+ // step 2: verify 
 + if (buffer == null
 + return "zero buffer";
  
-// buffer[9] 0x0D+ int numRead buffer.length
-// buffer[10] 0x0A;+ if (buffer.length <0) 
 + return "zero length";
  
- p.writeBytes(buffer, (long) buffer.length)+ // step 3: convert buffer to string 
- + String res = ""
-  + for (int i = 0; i < numRead; i++) { 
-  + byte b buffer[i];
-  +
-  +
-  +
-  +
-  +
-  +
- static boolean isGetRA(int num, byte[] readBuffer) { +
- char c[] new char[num]+
- if (readBuffer.length < 4) +
- return false;+
  
- for (int i = 0; i < num; i++) { + // fixme: problem with Star * 
- c[i] = (char) readBuffer[i];+ char c = (char) b; 
 + if (b == -33) 
 + c = '*'; 
 + res += c;
  
- }+ } 
 + return res;
  
- if (c[0] == '#' && c[1] == ':' && c[2] == 'G' && c[3] == 'R' && c[4] == '#') { + } catch (SerialPortException e) { 
- return true;+ e.printStackTrace();
  }  }
  
- return false;+ return "should not happen";
  }  }
  
- static boolean isGetDec(int numbyte[] readBuffer) { + static void writeMessage(SerialPort pString msg) { 
- char c[] = new char[num]+ try { 
- if (readBuffer.length < 4+ byte[] buffer msg.getBytes(); 
- return false;+ p.writeBytes(buffer)
 + } catch (SerialPortException e{ 
 + e.printStackTrace(); 
 +
 + }
  
- for (int = 0; i < num; i++{ + /** 
- c[i] = (charreadBuffer[i];+ * helper method convert a ra-string to a number (for arithmetic use) 
 + */ 
 + static int string2int(String str) { 
 + String tmp str.substring(0, str.length(- 1); 
 + String lsTmp[] = tmp.split(":")
 + int res = 3600 * Integer.valueOf(lsTmp[0]) + 60 * Integer.valueOf(lsTmp[1]) + Integer.valueOf(lsTmp[2]); 
 + return res; 
 + }
  
- }+ /** 
 + * helper method to convert a number into ra-string 
 + */ 
 + static String number2string(double number) {
  
- if (c[0] == '#' && c[1] == ':' && c[2] == 'G' && c[3] == 'D' && c[4] == '#'{ + int h = (int) (number - (number % 3600)) / 3600; 
- return true+ int rest (int) (number - h * 3600); 
- }+ int m (int(rest - (rest % 60)) / 60; 
 + rest = rest - m * 60
 + int s = rest;
  
- return false;+ String strH = String.format("%02d", h); 
 + String strM = String.format("%02d", m); 
 + String strS = String.format("%02d", s); 
 + return strH + ":" + strM + ":" + strS + "#";
  }  }
  
- static void writeRa(SerialPort p) {+ /** 
 + * dummy method to simulate kind of telescope motion - using ten steps only 
 + * in ra-axis 
 + */ 
 + static void simulateMove() { 
 + TimerTask repeatedTask = new TimerTask() {
  
- String str "14:15:00#"+ int run 0
- byte[] buffer new byte[9]+ double stepwidth 0
- byte[] byte_str = str.getBytes(); + int iTo = 0; 
- for (int = 0; i < 9; i++) + int iFrom 0;
- buffer[i] byte_str[i];+
  
-// buffer[9] = 0x0D; + public void run() { 
-// buffer[10] = 0x0A;+ System.out.println(run + " ...move simulation ");
  
- p.writeBytes(buffer, (longbuffer.length); + // step 0: calculate stepwidth once 
- }+ if (run == 0) { 
 + iFrom = string2int(currentRA)
 + iTo = string2int(targetRA); 
 + stepwidth = (iTo - iFrom) / 10.0; 
 +
 + // step 1: adjust currentRA with stepwidth 
 + if (run > 0) { 
 + currentRA = number2string(iFrom + run * stepwidth); 
 + }
  
- static void writeDec(SerialPort p) { + // step 2finish motion 
- String str = "+19*10#"; + run++
- //"%c%02d%c%02d:%02d#" + if (run > 10
- byte[] buffer = new byte[7]+ currentRA = targetRA
- byte[] byte_str = str.getBytes(); + cancel(); 
- for (int i = 0i < 7; i++) + } 
- buffer[i] = byte_str[i]; + } 
-// + }
-// buffer[7] = 0x0D+ Timer timer new Timer("Timer")
-// buffer[8] 0x0A; + timer.scheduleAtFixedRate(repeatedTask0, 250);
- +
- p.writeBytes(buffer(long) buffer.length);+
  }  }
  
 } }
 +
  
 </code> </code>
 +<WRAP center round info 90%>
 +Das dieses einfache Programm (die nur wenige Kommandos des Protokolls implementiert) funktioniert, verdanken wir den  saloppen Umgang von Stellarium (getestet mit 0.18.0) mit dem Protokoll. Eine verfünftige Initialisierung (Handschake) ist beispielsweise nicht erforderlich.
 +</WRAP>
 +
  
virtuelles_java-teleskop.1561373021.txt.gz · Zuletzt geändert: 2020/11/22 16:52 (Externe Bearbeitung)