|
@@ -1,54 +1,123 @@
|
|
package at.acdp.urweb;
|
|
package at.acdp.urweb;
|
|
|
|
|
|
import at.acdp.urweb.sclient.data.MasterBoardData;
|
|
import at.acdp.urweb.sclient.data.MasterBoardData;
|
|
|
|
+import at.acdp.urweb.sclient.data.RobotProgramLabel;
|
|
import at.acdp.urweb.sclient.data.ScReadThread;
|
|
import at.acdp.urweb.sclient.data.ScReadThread;
|
|
|
|
+import okhttp3.*;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
+import java.util.concurrent.BlockingQueue;
|
|
|
|
+import java.util.concurrent.LinkedBlockingQueue;
|
|
|
|
+import java.util.concurrent.Semaphore;
|
|
|
|
+import java.util.concurrent.atomic.AtomicInteger;
|
|
|
|
+
|
|
public class URBot {
|
|
public class URBot {
|
|
- private ScReadThread sc;
|
|
|
|
private static final Logger log = LoggerFactory.getLogger(URBot.class);
|
|
private static final Logger log = LoggerFactory.getLogger(URBot.class);
|
|
|
|
+ private static final MediaType MEDIA_TYPE_JSON
|
|
|
|
+ = MediaType.get("application/json; charset=utf-8");
|
|
|
|
+ private ScReadThread sc;
|
|
|
|
+ private BlockingQueue<RobotCommand> cmdq = new LinkedBlockingQueue<>();
|
|
|
|
+ private AtomicInteger nextID = new AtomicInteger(1);
|
|
|
|
+ private Semaphore cmdDoneSem = new Semaphore(0);
|
|
|
|
+ private RobotProgramLabel currentAck;
|
|
|
|
|
|
public URBot(String ip) {
|
|
public URBot(String ip) {
|
|
- sc=new ScReadThread(ip);
|
|
|
|
- Thread t=new Thread(sc);
|
|
|
|
- t.start();
|
|
|
|
|
|
+ sc = new ScReadThread(ip, this);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public synchronized void ackNumber(RobotProgramLabel rpl) {
|
|
|
|
+ this.currentAck = rpl;
|
|
|
|
+ cmdDoneSem.release();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void start() {
|
|
|
|
+ Thread readThread = new Thread(sc);
|
|
|
|
+ readThread.start();
|
|
|
|
+ Thread queueThread = new Thread(() -> {
|
|
|
|
+ try {
|
|
|
|
+ while (true) {
|
|
|
|
+ var c = cmdq.take();
|
|
|
|
+ write(c.cmd);
|
|
|
|
+ while (true) {
|
|
|
|
+ cmdDoneSem.acquire();
|
|
|
|
+ if (currentAck.id == c.id && currentAck.message.equals("URWEB_END"))
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ if (c.cpeeCallback != null) {
|
|
|
|
+ ackCPEE(c);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (InterruptedException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
|
|
- public void sendProgram(String program) {
|
|
|
|
- String[] lines=program.split("[\\r\\n]+");
|
|
|
|
- String res="";
|
|
|
|
- for(String line:lines) {
|
|
|
|
- line=line.trim();
|
|
|
|
- if(line.startsWith("//"))
|
|
|
|
|
|
+
|
|
|
|
+ private void write(String program) {
|
|
|
|
+ String[] lines = program.split("[\\r\\n]+");
|
|
|
|
+ String res = "";
|
|
|
|
+ for (String line : lines) {
|
|
|
|
+ line = line.trim();
|
|
|
|
+ if (line.startsWith("//"))
|
|
continue;
|
|
continue;
|
|
- if(line.startsWith("#"))
|
|
|
|
|
|
+ if (line.startsWith("#"))
|
|
continue;
|
|
continue;
|
|
- if(!line.endsWith("\n"))
|
|
|
|
- line+="\n";
|
|
|
|
|
|
+ if (!line.endsWith("\n"))
|
|
|
|
+ line += "\n";
|
|
|
|
+ res += line;
|
|
|
|
+ }
|
|
|
|
+ if (!program.endsWith("\n"))
|
|
|
|
+ program += "\n";
|
|
|
|
+ try {
|
|
|
|
+ this.cmdq.put(new RobotCommand(nextID.getAndIncrement(), program));
|
|
|
|
+ } catch (InterruptedException e) {
|
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- res+=line;
|
|
|
|
|
|
+ private void ackCPEE(RobotCommand r) {
|
|
|
|
+ try {
|
|
|
|
+ OkHttpClient client = new OkHttpClient();
|
|
|
|
+ Request request = new Request.Builder()
|
|
|
|
+ .url(r.cpeeCallback + "/")
|
|
|
|
+ .put(RequestBody.create(MEDIA_TYPE_JSON, "[{}]"))
|
|
|
|
+ .build();
|
|
|
|
+ log.info("putting to {}", r.cpeeCallback);
|
|
|
|
+ Response res = client.newCall(request).execute();
|
|
|
|
+ log.info("result {}", res.toString());
|
|
|
|
+ r.cpeeCallbackResult = res.body().string();
|
|
|
|
+ r.cpeeCallbackCode = res.code();
|
|
|
|
+ r.cpeeCallbackMessage = res.message();
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.warn("cpee callback failed", e);
|
|
|
|
+ r.cpeeCallbackError = e.getMessage();
|
|
}
|
|
}
|
|
- if(!program.endsWith("\n"))
|
|
|
|
- program+="\n";
|
|
|
|
- sc.writeCmd(program);
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void sendStringCmd(String cmd) {
|
|
|
|
+ sc.writeCmd(new RobotCommand(nextID.getAndIncrement(), cmd));
|
|
}
|
|
}
|
|
|
|
|
|
public void sendFreedrive(int timeout) {
|
|
public void sendFreedrive(int timeout) {
|
|
- sc.writeCmd(String.format("def myProg():\n\tfreedrive_mode()\n\tsleep(%d)\nend", timeout));
|
|
|
|
|
|
+ sendStringCmd(String.format("def myProg():\n\tfreedrive_mode()\n\tsleep(%d)\nend", timeout));
|
|
}
|
|
}
|
|
|
|
|
|
public void sendMessage(String message) {
|
|
public void sendMessage(String message) {
|
|
- sc.writeCmd(String.format("textmsg(%s)", message));
|
|
|
|
|
|
+ sendStringCmd(String.format("textmsg(%s)", message));
|
|
}
|
|
}
|
|
|
|
|
|
public void setDigital(int which, boolean val) {
|
|
public void setDigital(int which, boolean val) {
|
|
- String c=String.format("digital_out[%d]=%s", which, val?"True":"False");
|
|
|
|
- sc.writeCmd(c);
|
|
|
|
|
|
+ sendStringCmd(String.format("digital_out[%d]=%s", which, val ? "True" : "False"));
|
|
}
|
|
}
|
|
|
|
|
|
public boolean getDigital(int which) {
|
|
public boolean getDigital(int which) {
|
|
MasterBoardData mb = sc.getRde().getLastMB();
|
|
MasterBoardData mb = sc.getRde().getLastMB();
|
|
- return ((mb.digitalOutputBits&(1<<which)) >0) ;
|
|
|
|
|
|
+ return ((mb.digitalOutputBits & (1 << which)) > 0);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void sendCmd(String cmd) {
|
|
|
|
+ write(String.format("def urweb():\n{}\nend\n", cmd));
|
|
}
|
|
}
|
|
}
|
|
}
|