URBot.java 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package at.acdp.urweb;
  2. import at.acdp.urweb.sclient.data.MasterBoardData;
  3. import at.acdp.urweb.sclient.data.RobotProgramLabel;
  4. import at.acdp.urweb.sclient.data.ScReadThread;
  5. import okhttp3.*;
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8. import java.util.concurrent.BlockingQueue;
  9. import java.util.concurrent.LinkedBlockingQueue;
  10. import java.util.concurrent.Semaphore;
  11. import java.util.concurrent.atomic.AtomicInteger;
  12. public class URBot {
  13. private static final Logger log = LoggerFactory.getLogger(URBot.class);
  14. private static final MediaType MEDIA_TYPE_JSON
  15. = MediaType.get("application/json; charset=utf-8");
  16. private ScReadThread sc;
  17. private BlockingQueue<RobotCommand> cmdq = new LinkedBlockingQueue<>();
  18. private AtomicInteger nextID = new AtomicInteger(1);
  19. private Semaphore cmdDoneSem = new Semaphore(0);
  20. private RobotProgramLabel currentAck;
  21. public URBot(String ip, int port) {
  22. sc = new ScReadThread(ip, port, this);
  23. }
  24. public synchronized void ackNumber(RobotProgramLabel rpl) {
  25. this.currentAck = rpl;
  26. cmdDoneSem.release();
  27. }
  28. public void start() {
  29. Thread readThread = new Thread(sc);
  30. readThread.start();
  31. Thread queueThread = new Thread(() -> {
  32. try {
  33. while (true) {
  34. cmdDoneSem.acquire();
  35. var c = cmdq.take();
  36. sc.writeCmd(c);
  37. while (true) {
  38. if (currentAck.id == c.id && currentAck.message.equals("URWEB_END")) {
  39. if (c.cpeeCallback != null) {
  40. ackCPEE(c);
  41. }
  42. break;
  43. }
  44. }
  45. }
  46. } catch (InterruptedException e) {
  47. e.printStackTrace();
  48. }
  49. });
  50. queueThread.start();
  51. }
  52. private void write(RobotCommand rc) {
  53. String[] lines = rc.cmd.split("[\\r\\n]+");
  54. String res = "";
  55. for (String line : lines) {
  56. line = line.trim();
  57. if (line.startsWith("//"))
  58. continue;
  59. if (line.startsWith("#"))
  60. continue;
  61. if (!line.endsWith("\n"))
  62. line += "\n";
  63. res += line;
  64. }
  65. if (!res.endsWith("\n"))
  66. res += "\n";
  67. res=res.trim();
  68. int id = nextID.getAndIncrement();
  69. if(res.endsWith("end")) {
  70. res=res.substring(0, res.length()-3);
  71. res+=String.format("$ %s \"URWEB_END\"\nend\n", id);
  72. }
  73. try {
  74. rc.id=id;
  75. // rc.cmd = String.format("def urweb():\n%s\n$ %s \"URWEB_END\"\nend\n", res, id);
  76. rc.cmd = res;
  77. this.cmdq.put(rc);
  78. } catch (InterruptedException e) {
  79. Thread.currentThread().interrupt();
  80. }
  81. }
  82. private void ackCPEE(RobotCommand r) {
  83. try {
  84. OkHttpClient client = new OkHttpClient();
  85. Request request = new Request.Builder()
  86. .url(r.cpeeCallback + "/")
  87. .put(RequestBody.create(MEDIA_TYPE_JSON, "[{}]"))
  88. .build();
  89. log.info("putting to {}", r.cpeeCallback);
  90. Response res = client.newCall(request).execute();
  91. log.info("result {}", res.toString());
  92. r.cpeeCallbackResult = res.body().string();
  93. r.cpeeCallbackCode = res.code();
  94. r.cpeeCallbackMessage = res.message();
  95. } catch (Exception e) {
  96. log.warn("cpee callback failed", e);
  97. r.cpeeCallbackError = e.getMessage();
  98. }
  99. }
  100. private void sendStringCmd(String cmd) {
  101. sc.writeCmd(new RobotCommand(nextID.getAndIncrement(), cmd));
  102. }
  103. public void sendFreedrive(int timeout) {
  104. sendStringCmd(String.format("def myProg():\n\tfreedrive_mode()\n\tsleep(%d)\nend", timeout));
  105. }
  106. public void sendMessage(String message) {
  107. sendStringCmd(String.format("textmsg(%s)", message));
  108. }
  109. public void setDigital(int which, boolean val) {
  110. sendStringCmd(String.format("digital_out[%d]=%s", which, val ? "True" : "False"));
  111. }
  112. public boolean getDigital(int which) {
  113. MasterBoardData mb = sc.getRde().getLastMB();
  114. return ((mb.digitalOutputBits & (1 << which)) > 0);
  115. }
  116. public void sendCmd(RobotCommand cmd) {
  117. write(cmd);
  118. }
  119. public BlockingQueue<RobotCommand> getCmdq() {
  120. return cmdq;
  121. }
  122. }