package at.acdp.urweb.rtde; import at.acdp.urweb.rtde.packets.IRtdeData; import at.acdp.urweb.rtde.packets.RtdeRequestProtocolVersion; import at.acdp.urweb.rtde.packets.RtdeRequestURVersion; import at.acdp.urweb.rtde.packets.RtdeTextMessage; import org.slf4j.LoggerFactory; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.net.SocketException; import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.util.List; import java.util.concurrent.Semaphore; import static at.acdp.urweb.rtde.CommandType.*; public class RTDEClient implements Runnable { private final static org.slf4j.Logger logger = LoggerFactory.getLogger(RTDEClient.class); private final Semaphore waitingRequestSem = new Semaphore(0); private final Semaphore socketOpen = new Semaphore(0); private volatile IRtdeData waitingRequest=null; public static int RTDE_PROTOCOL_VERSION = 2; private final String ip; private final int port; private final boolean _running = true; private DataOutputStream dos; private DataInputStream dis; public RTDEClient(String ip, int port) { this.ip = ip; this.port = port; } public void start() throws IOException, InterruptedException { Thread readThread = new Thread(this); readThread.start(); socketOpen.acquire(); init(); } private void request(IRtdeData data) throws IOException, InterruptedException { waitingRequest=data; data.send(dos); waitingRequestSem.acquire(); return; } // Internal method that actually reads the data private void readSocket() throws IOException, InterruptedException { int length = dis.readShort(); int type=dis.readByte(); if(type==waitingRequest.getType()) { waitingRequest.read(dis); waitingRequestSem.release(); } else switch(type) { case RTDE_TEXT_MESSAGE: var rpv = new RtdeTextMessage(); request(rpv); logger.info("RTDE_TEXT_MESSAGE", rpv.text); break; default: { logger.warn(String.format("Unexpected package type: %d", type)); byte[] buf=new byte[length]; dis.readFully(buf); } } } @Override public void run() { try { Socket rt = new Socket(ip, port); rt.setSoTimeout(0); rt.setReuseAddress(true); rt.setTcpNoDelay(true); if (rt.isConnected()) { System.out.println("Connected to UR Realtime Client"); } dos = new DataOutputStream(rt.getOutputStream()); dis = new DataInputStream(rt.getInputStream()); socketOpen.release(); while (_running) { try { readSocket(); } catch (IOException | InterruptedException e) { e.printStackTrace(); } } } catch (IOException e) { logger.warn("run",e); } } public void send_output_setup(List variables, List types, int frequency) throws IOException { var payload = String.join(",", variables); byte[] p = payload.getBytes(); ByteBuffer bytes = ByteBuffer.allocate(8 + p.length); bytes.putDouble(frequency); bytes.put(p); } public void init() throws IOException, InterruptedException { var rpv = new RtdeRequestProtocolVersion(); request(rpv); logger.info("RtdeRequestProtocolVersion succes:" + rpv.success); var ruv = new RtdeRequestURVersion(); request(ruv); logger.info(String.format("RtdeRequestURVersion: %d.%d.%d.%d",ruv.major, ruv.minor, ruv.build, ruv.bugfix)); } }