RTDEClient.java 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package at.acdp.urweb.rtde;
  2. import at.acdp.urweb.rtde.packets.*;
  3. import org.slf4j.LoggerFactory;
  4. import java.io.DataInputStream;
  5. import java.io.DataOutputStream;
  6. import java.io.IOException;
  7. import java.net.Socket;
  8. import java.util.HashMap;
  9. import java.util.concurrent.Semaphore;
  10. import static at.acdp.urweb.rtde.CommandType.*;
  11. public class RTDEClient implements Runnable {
  12. private final static org.slf4j.Logger logger = LoggerFactory.getLogger(RTDEClient.class);
  13. private final Semaphore waitingRequestSem = new Semaphore(0);
  14. private final Semaphore socketOpen = new Semaphore(0);
  15. private volatile IRtdeData waitingRequest=null;
  16. public static int RTDE_PROTOCOL_VERSION = 2;
  17. private final String ip;
  18. private final int port;
  19. private final boolean _running = true;
  20. private DataOutputStream dos;
  21. private DataInputStream dis;
  22. private Thread readThread;
  23. private RtdeSetupOutputs outputs;
  24. private HashMap<String, String> lastData;
  25. public RTDEClient(String ip, int port) {
  26. this.ip = ip;
  27. this.port = port;
  28. }
  29. public void start() throws IOException, InterruptedException {
  30. readThread = new Thread(this);
  31. readThread.start();
  32. socketOpen.acquire();
  33. init();
  34. }
  35. public HashMap<String, String> getLastData() {
  36. return lastData;
  37. }
  38. public void request(IRtdeData data) throws IOException, InterruptedException {
  39. if(readThread.getId()==Thread.currentThread().getId()) {
  40. logger.error("request() must not be called from readThread.");
  41. }
  42. if(data.hasReply()) {
  43. waitingRequest=data;
  44. }
  45. data.send(dos);
  46. if(data.hasReply()) {
  47. waitingRequestSem.acquire();
  48. waitingRequest=null;
  49. }
  50. return;
  51. }
  52. // Internal method that actually reads the data
  53. private void readSocket() throws IOException, InterruptedException {
  54. int length = dis.readShort();
  55. int type=dis.readByte() & 0xFF;
  56. var wreq=waitingRequest;
  57. if(wreq != null && type==wreq.getType()) {
  58. waitingRequest.read(dis, length-3);
  59. if(type== RTDE_CONTROL_PACKAGE_SETUP_OUTPUTS) {
  60. outputs= (RtdeSetupOutputs) waitingRequest;
  61. }
  62. waitingRequestSem.release();
  63. } else switch(type) {
  64. case RTDE_TEXT_MESSAGE:
  65. var rpv = new RtdeTextMessage();
  66. rpv.read(dis, length-3);
  67. logger.info(String.format("RTDE_TEXT_MESSAGE: %s", rpv.text));
  68. break;
  69. case RTDE_DATA_PACKAGE:
  70. var p = new RtdeOutDataPackage(outputs);
  71. p.read(dis, length-3);
  72. lastData=p.getPdata();
  73. lastData.entrySet().forEach(entry->{
  74. System.out.println(entry.getKey() + " " + entry.getValue());
  75. });
  76. break;
  77. default: {
  78. logger.warn(String.format("Unexpected package type: %d", type));
  79. byte[] buf=new byte[length];
  80. dis.readFully(buf);
  81. }
  82. }
  83. }
  84. @Override
  85. public void run() {
  86. try {
  87. Socket rt = new Socket(ip, port);
  88. rt.setSoTimeout(0);
  89. rt.setReuseAddress(true);
  90. rt.setTcpNoDelay(true);
  91. if (rt.isConnected()) {
  92. System.out.println("Connected to UR Realtime Client");
  93. }
  94. dos = new DataOutputStream(rt.getOutputStream());
  95. dis = new DataInputStream(rt.getInputStream());
  96. socketOpen.release();
  97. while (_running) {
  98. try {
  99. readSocket();
  100. } catch (IOException | InterruptedException e) {
  101. e.printStackTrace();
  102. }
  103. }
  104. } catch (IOException e) {
  105. logger.warn("run",e);
  106. }
  107. }
  108. public void init() throws IOException, InterruptedException {
  109. var rpv = new RtdeRequestProtocolVersion();
  110. request(rpv);
  111. logger.info("RtdeRequestProtocolVersion succes:" + rpv.success);
  112. var ruv = new RtdeRequestURVersion();
  113. request(ruv);
  114. logger.info(String.format("RtdeRequestURVersion: %d.%d.%d.%d",ruv.major, ruv.minor, ruv.build, ruv.bugfix));
  115. }
  116. }