RTDEClient.java 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  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.util.List;
  9. import static at.acdp.urweb.rtde.CommandType.RTDE_GET_URCONTROL_VERSION;
  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. public static int RTDE_PROTOCOL_VERSION = 2;
  14. private final String ip;
  15. private final int port;
  16. private final boolean _running = true;
  17. private DataOutputStream dos;
  18. private DataInputStream dis;
  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. rt.setReuseAddress(true);
  27. rt.setTcpNoDelay(true);
  28. if (rt.isConnected()) {
  29. System.out.println("Connected to UR Realtime Client");
  30. }
  31. dos = new DataOutputStream(rt.getOutputStream());
  32. dis = new DataInputStream(rt.getInputStream());
  33. negotiate_protocol_version();
  34. //Thread readThread = new Thread(this);
  35. //readThread.start();
  36. // send_output_setup(List.of(OutParams.timestamp), List.of(), 125);
  37. }
  38. }
  39. // Internal method that actually reads the data
  40. private void readSocket() throws IOException {
  41. while (true) {
  42. int length = dis.readInt();
  43. double[] rtm = new double[length];
  44. rtm[0] = length;
  45. // Calculate how much data is available from the length
  46. int data_available = (length - 4) / 8;
  47. for (int i = 0; i < data_available; i++) {
  48. rtm[i] = dis.readDouble();
  49. }
  50. }
  51. }
  52. private void receive(RtdeData cmd) throws IOException {
  53. logger.info(cmd.getType().toString());
  54. cmd.read(dis);
  55. }
  56. @Override
  57. public void run() {
  58. try {
  59. negotiate_protocol_version();
  60. } catch (IOException e) {
  61. e.printStackTrace();
  62. }
  63. while (_running) {
  64. try {
  65. readSocket();
  66. } catch (IOException e) {
  67. e.printStackTrace();
  68. }
  69. }
  70. }
  71. public void send_input_setup(List<String> variables, List<String> types) throws IOException {
  72. var cmd = CommandType.RTDE_CONTROL_PACKAGE_SETUP_INPUTS;
  73. var payload = String.join(",", variables);
  74. var rpv = new RtdeRequestProtocolVersion();
  75. }
  76. private void sendAndReceive(RtdeData cmd) throws IOException {
  77. cmd.send(dos);
  78. cmd.read(dis);
  79. }
  80. public void send_output_setup(List<String> variables, List<String> types, int frequency) throws IOException {
  81. var payload = String.join(",", variables);
  82. byte[] p = payload.getBytes();
  83. ByteBuffer bytes = ByteBuffer.allocate(8 + p.length);
  84. bytes.putDouble(frequency);
  85. bytes.put(p);
  86. // sendAndReceive(rpv, bytes.array());
  87. }
  88. public void negotiate_protocol_version() throws IOException {
  89. var rpv = new RtdeRequestProtocolVersion();
  90. sendAndReceive(rpv);
  91. }
  92. private interface RtdeData<T> {
  93. CommandType getType();
  94. int getSize();
  95. void setSize(int i);
  96. T read(DataInputStream di) throws IOException;
  97. T send(DataOutputStream dos) throws IOException;
  98. default void sendHeader(DataOutputStream dos) throws IOException {
  99. dos.writeShort(getSize());
  100. dos.writeByte(getType().getVal());
  101. }
  102. default void readHeader(DataInputStream dis) throws IOException {
  103. setSize(dis.readShort());
  104. int cmd = dis.readByte();
  105. if (cmd != getType().getVal())
  106. throw new IOException(String.format("Expected %d, got %d", getType().getVal(), cmd));
  107. }
  108. }
  109. private class RtdeRequestURVersion implements RtdeData {
  110. private int size;
  111. @Override
  112. public CommandType getType() {
  113. return RTDE_GET_URCONTROL_VERSION;
  114. }
  115. @Override
  116. public int getSize() {
  117. return 5;
  118. }
  119. @Override
  120. public void setSize(int s) {
  121. size = s;
  122. }
  123. @Override
  124. public RtdeRequestURVersion read(DataInputStream di) throws IOException {
  125. readHeader(di);
  126. return this;
  127. }
  128. @Override
  129. public RtdeRequestURVersion send(DataOutputStream dos) throws IOException {
  130. sendHeader(dos);
  131. return this;
  132. }
  133. }
  134. private class RtdeRequestProtocolVersion implements RtdeData {
  135. public boolean success;
  136. private int size;
  137. @Override
  138. public CommandType getType() {
  139. return RTDE_REQUEST_PROTOCOL_VERSION;
  140. }
  141. @Override
  142. public int getSize() {
  143. return size;
  144. }
  145. @Override
  146. public void setSize(int size) {
  147. this.size = size;
  148. }
  149. @Override
  150. public RtdeRequestProtocolVersion read(DataInputStream d) throws IOException {
  151. readHeader(dis);
  152. success = dis.readBoolean();
  153. return this;
  154. }
  155. @Override
  156. public RtdeRequestProtocolVersion send(DataOutputStream dos) throws IOException {
  157. sendHeader(dos);
  158. dos.writeShort(RTDE_PROTOCOL_VERSION);
  159. dos.flush();
  160. return this;
  161. }
  162. }
  163. }