RTDEClient.java 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. package at.acdp.urweb.rtde;
  2. import org.slf4j.LoggerFactory;
  3. import java.io.DataInputStream;
  4. import java.io.DataOutputStream;
  5. import java.io.IOException;
  6. import java.net.Socket;
  7. import java.nio.ByteBuffer;
  8. import java.nio.ByteOrder;
  9. import java.util.List;
  10. import static at.acdp.urweb.rtde.CommandType.RTDE_REQUEST_PROTOCOL_VERSION;
  11. public class RTDEClient implements Runnable {
  12. private final static org.slf4j.Logger logger = LoggerFactory.getLogger(RTDEClient.class);
  13. private final String ip;
  14. private final int port;
  15. private volatile boolean _running=true;
  16. private DataOutputStream dos;
  17. private DataInputStream dis;
  18. public static int RTDE_PROTOCOL_VERSION=2;
  19. public RTDEClient(String ip, int port) {
  20. this.ip=ip;
  21. this.port=port;
  22. }
  23. public void start() throws IOException {
  24. try (Socket rt = new Socket(ip, port);) {
  25. rt.setSoTimeout(0);
  26. if (rt.isConnected()) {
  27. System.out.println("Connected to UR Realtime Client");
  28. }
  29. dis = new DataInputStream(rt.getInputStream());
  30. dos = new DataOutputStream(rt.getOutputStream());
  31. Thread readThread = new Thread(this);
  32. //readThread.start();
  33. negotiate_protocol_version();
  34. send_output_setup(List.of(OutParams.timestamp), List.of(), 125);
  35. }
  36. }
  37. // Internal method that actually reads the data
  38. private void readSocket() throws IOException {
  39. while(true) {
  40. int length = dis.readInt();
  41. double[] rtm = new double[length];
  42. rtm[0] = length;
  43. // Calculate how much data is available from the length
  44. int data_available = (length - 4) / 8;
  45. for(int i=0; i<data_available; i++){
  46. rtm[i] = dis.readDouble();
  47. }
  48. }
  49. }
  50. private interface RtdeData<T> {
  51. public CommandType getType();
  52. public T read(DataInputStream di) throws IOException;
  53. }
  54. private class RtdeRequestProtocolVersion implements RtdeData{
  55. public int major;
  56. public int minor;
  57. public int bugfix;
  58. public int build;
  59. @Override
  60. public CommandType getType() {
  61. return RTDE_REQUEST_PROTOCOL_VERSION;
  62. }
  63. public RtdeRequestProtocolVersion read(DataInputStream d) throws IOException {
  64. major = d.readInt();
  65. minor = d.readInt();
  66. bugfix = d.readInt();
  67. build = d.readInt();
  68. return this;
  69. }
  70. }
  71. private void receive(RtdeData cmd) throws IOException {
  72. switch (cmd) {
  73. case RTDE_REQUEST_PROTOCOL_VERSION:
  74. logger.info("RTDE_REQUEST_PROTOCOL_VERSION");
  75. var pv=new ProtocolVersion();
  76. return pv.read(dis);
  77. break;
  78. case RTDE_GET_URCONTROL_VERSION:
  79. logger.info("RTDE_GET_URCONTROL_VERSION");
  80. break;
  81. case RTDE_TEXT_MESSAGE:
  82. logger.info("RTDE_TEXT_MESSAGE");
  83. break;
  84. case RTDE_CONTROL_PACKAGE_SETUP_OUTPUTS:
  85. logger.info("RTDE_CONTROL_PACKAGE_SETUP_OUTPUTS");
  86. break;
  87. case RTDE_CONTROL_PACKAGE_SETUP_INPUTS:
  88. logger.info("RTDE_CONTROL_PACKAGE_SETUP_INPUTS");
  89. break;
  90. case RTDE_CONTROL_PACKAGE_START:
  91. logger.info("RTDE_CONTROL_PACKAGE_START");
  92. break;
  93. case RTDE_CONTROL_PACKAGE_PAUSE:
  94. logger.info("RTDE_CONTROL_PACKAGE_PAUSE");
  95. break;
  96. case RTDE_DATA_PACKAGE:
  97. logger.info("RTDE_DATA_PACKAGE");
  98. break;
  99. }
  100. return null;
  101. }
  102. @Override
  103. public void run() {
  104. while(_running) {
  105. try {
  106. readSocket();
  107. } catch (IOException e) {
  108. e.printStackTrace();
  109. }
  110. }
  111. }
  112. public void send_input_setup(List<String> variables, List<String> types) {
  113. var cmd = CommandType.RTDE_CONTROL_PACKAGE_SETUP_INPUTS;
  114. var payload = String.join(",", variables);
  115. var rpv = new RtdeRequestProtocolVersion();
  116. sendAndReceive(rpv, payload.getBytes());
  117. }
  118. private void sendAndReceive(RtdeData cmd, byte[] payload) {
  119. sendall(cmd, payload);
  120. receive(cmd);
  121. }
  122. public void send_output_setup(List<String> variables, List<String> types, int frequency) {
  123. var cmd = CommandType.RTDE_CONTROL_PACKAGE_SETUP_OUTPUTS;
  124. var payload = String.join(",", variables);
  125. byte[] p= payload.getBytes();
  126. ByteBuffer bytes = ByteBuffer.allocate(8+p.length);
  127. bytes.putDouble(frequency);
  128. bytes.put(p);
  129. sendAndReceive(cmd, bytes.array());
  130. }
  131. public void negotiate_protocol_version() {
  132. var cmd = RTDE_REQUEST_PROTOCOL_VERSION;
  133. ByteBuffer bytes = ByteBuffer.allocate(2);
  134. bytes.putShort((short) RTDE_PROTOCOL_VERSION);
  135. sendAndReceive(cmd, bytes.array());
  136. }
  137. public void sendall(RtdeData cmd, byte[] payload) {
  138. try {
  139. int size = 3 + payload.length;
  140. ByteBuffer bytes = ByteBuffer.allocate(size);
  141. bytes.order(ByteOrder.BIG_ENDIAN);
  142. bytes.order( ByteOrder.BIG_ENDIAN);
  143. bytes.putShort((short) size);
  144. bytes.put((byte) cmd.getVal());
  145. bytes.put(payload);
  146. bytes.rewind();
  147. byte[] arr = new byte[bytes.remaining()];
  148. bytes.get(arr);
  149. dos.write(arr);
  150. dos.flush();
  151. } catch (IOException e) {
  152. e.printStackTrace();
  153. }
  154. }
  155. }