/**
* @file .java
* @author Anderson Antunes <anderson.utf@gmail.com>
* *seu nome* <*seu email*>
* @version 1.0
*
* @section LICENSE
*
* Copyright (C) 2013 by Anderson Antunes <anderson.utf@gmail.com>
* *seu nome* <*seu email*>
*
* RobotInterface is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* RobotInterface is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* RobotInterface. If not, see <http://www.gnu.org/licenses/>.
*
*/
package robotinterface.interpreter;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import robotinterface.algorithm.Command;
import robotinterface.algorithm.procedure.Function;
import robotinterface.algorithm.procedure.If;
import robotinterface.algorithm.procedure.While;
import robotinterface.algorithm.procedure.Procedure;
import org.nfunk.jep.JEP;
import org.nfunk.jep.SymbolTable;
import robotinterface.algorithm.parser.Parser;
import robotinterface.drawable.util.QuickFrame;
import robotinterface.gui.GUI;
import robotinterface.gui.panels.SimulationPanel;
import robotinterface.plugin.cmdpack.begginer.Move;
import robotinterface.plugin.cmdpack.begginer.ReadDevice;
import robotinterface.plugin.cmdpack.begginer.Wait;
import robotinterface.plugin.cmdpack.util.PrintString;
import robotinterface.robot.Robot;
import robotinterface.robot.device.Compass;
import robotinterface.robot.device.HBridge;
import robotinterface.robot.connection.Serial;
import robotinterface.robot.device.Device;
import robotinterface.util.trafficsimulator.Clock;
/**
* Classe responsável por interpretar os algoritmos e executar os comandos.
*/
public class Interpreter extends Thread {
public static final int STOP = 0;
public static final int PLAY = 1;
public static final int WAITING = 2;
private Clock clock;
private JEP parser;
private Robot robot;
private ResourceManager resourceManager;
private Function mainFunction;
private Command currentCmd = null;
private Command errorCmd = null;
private int state;
private int timestep = 0;
private boolean running = false;
public Interpreter() {
super("Interpreter");
parser = new JEP();
parser.addFunction("get", new Get());
clock = new Clock();
resourceManager = new ResourceManager();
resourceManager.setResource(clock);
resourceManager.setResource(parser);
resourceManager.setResource(this);
state = STOP;
}
public Robot getRobot() {
return robot;
}
public void setRobot(Robot robot) {
this.robot = robot;
resourceManager.setResource(robot);
}
public void reset() {
if (mainFunction != null) {
currentCmd = mainFunction;
} else {
currentCmd = null;
}
state = STOP;
running = false;
parser.initFunTab(); // clear the contents of the function table
parser.addStandardFunctions();
// parser.setTraverse(true); //exibe debug
parser.setImplicitMul(false);//multiplicação implicita: 2x+4
parser.initSymTab(); // clear the contents of the symbol table
try {
parser.addStandardConstants();
} catch (Throwable t) {
}
parser.setAllowAssignment(true);
parser.addFunction("get", new Get());
if (robot != null && robot.getMainConnection() != null) {
robot.stopAll();
robot.stop();
}
}
public Function getMainFunction() {
return mainFunction;
}
public void setMainFunction(Function f) {
mainFunction = f;
reset();
}
public void setInterpreterState(int state) {
this.state = state;
final int tmpState = state;
new Thread() {
@Override
public void run() {
if (tmpState != PLAY) {
if (robot != null) {
robot.stop();
while (running) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
}
robot.stopAll();
}
}
if (tmpState == STOP) {
reset();
if (robot != null) {
robot.reset();
}
}
GUI.getInstance().updateControlBar(Interpreter.this);
}
}.start();
}
public int getInterpreterState() {
return state;
}
public Command getCurrentCommand() {
return currentCmd;
}
public Command getErrorCommand() {
return errorCmd;
}
public void setTimestep(int timestep) {
this.timestep = timestep;
}
public int getTimestep() {
return timestep;
}
public boolean step() {
if (currentCmd == null) {
GUI.print(" > FIM < ");
return false;
}
clock.setPaused(false);
//System.out.println(currentCmd); //exibe o comando atual
try {
currentCmd.begin(resourceManager);
while (!currentCmd.perform(resourceManager)) {
clock.increase();
try {
Thread.sleep(5);
} catch (InterruptedException ex) {
}
if (state == STOP) {
return false;
}
}
currentCmd = currentCmd.step(resourceManager);
} catch (ForceInterruptionException e) {
return false;
} catch (ExecutionException e) {
//GUI.print("Erro: " + e.getMessage());
errorCmd = currentCmd;
String msg = "Houve um problema ao executar o código atual.\nO bloco que originou o erro foi destacado.\nFavor corrigir e tentar novamente.";
String ObjButtons[] = {"Continuar", "Mais detalhes"};
int PromptResult = JOptionPane.showOptionDialog(null, msg, "Erro", JOptionPane.NO_OPTION, JOptionPane.ERROR_MESSAGE, null, ObjButtons, ObjButtons[1]);
if (PromptResult == JOptionPane.NO_OPTION) {
JOptionPane.showMessageDialog(null, e.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
}
System.err.println(e.getMessage());
return false;
}
return true;
}
@Override
public void run() {
try {
while (true) {
if (state == PLAY) {
errorCmd = null;
if (!step()) {
state = STOP;
reset();
GUI.getInstance().updateControlBar(this);
}
if (currentCmd != null && currentCmd.getDrawableResource() != null) {
robot.disableMove(true);
if (timestep > 50 && Robot.UPDATE_ALL_DEVICES.getTimeout() <= 50) {
for (int i = 0; i < timestep; i += 50) {
robot.updatePerception();
Thread.sleep(50 - Robot.UPDATE_ALL_DEVICES.getTimeout());
}
} else {
Thread.sleep(timestep);
}
robot.disableMove(false);
}
running = true;
} else {
running = false;
Thread.sleep(100);
}
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
Robot r = new Robot();
r.add(new HBridge());
r.add(new Compass());
r.add(new Serial(57600));
Interpreter i = new Interpreter();
i.setRobot(r);
// f.add(new Cmd("a"));
// f.add(new Cmd("b"));
// If fi = new If();
// fi.addTrue(new Cmd("c"));
// fi.addFalse(new Cmd("d"));
// f.add(fi);
//
// Loop l1 = new Loop("l1");
//
// l1.add(new Cmd("e"));
// Loop l2 = new Loop("l2");
// l2.add(new Cmd("f"));
// l2.add(new Cmd("g"));
// l2.add(new Cmd("h"));
// l1.add(l2);
// l1.add(new Cmd("i"));
//
// f.add(l1);
// f.add(new Cmd("j"));
// i.setMainFunction(f);
//
//
// l1.addAfter(new Cmd("j0"));
// l1.addBefore(new Cmd("e0"));
// f.add(new Start());
//
// Loop l = new Loop();
// l.add(new Move(80, 80));
// l.add(new Move(0, 0));
// l.add(new Move(50, -50));
// l.add(new Move(0, 0));
// l.add(new Move(-80, -80));
// l.add(new Move(0, 0));
// f.add(l);
// f.add(new Stop());
// i.setMainFunction(f);
// Function func = new Function("main", null);
// func.add(new PrintString("inicio"));
// func.add(new Declaration("i", 3));
// While l = new While("i > 0");
// l.add(new Declaration("j", 512));
// If ii = new If("i == 2");
// ii.addTrue(new PrintString("true"));
// ii.addFalse(new PrintString("false"));
// l.add(ii);
// l.add(new PrintString("valor de i = %v","i"));
// l.add(new Wait(501));
// l.add(new Procedure("i=i-1"));
// l.add(new PrintString("%v","j"));
// func.add(l);
// func.add(new PrintString("v = %v","j"));
// func.add(new PrintString("fim"));
// i.setMainFunction(func);
ArrayList<Class<? extends Device>> aw = new ArrayList<>();
aw.add(HBridge.class);
aw.add(Compass.class);
Function func = new Function("main", null);
// func.add(new Wait(1000));
// func.add(new PrintString("inicio"));
// func.add(new Start());
// func.add(new Declaration("i", 10));
// func.add(new PrintString("Girando %v vezes...", "i"));
// While loop = new While("i > 0");
// loop.add(new Move(70, 70)); //move
// loop.add(new Wait(500));
// loop.add(new Move(-70, 70)); //gira
// loop.add(new Wait(500));
// loop.add(new Move(0, 0)); //para
// loop.add(new Wait(500));
// loop.add(new PrintString("Falta mais %v passo(s)...", "i"));
// loop.add(new Procedure("i = i - 1"));
// func.add(loop);
// func.add(new PrintString("Procurando angulo 100"));
// func.add(new Wait(500));
// func.add(new Declaration("alpha", 10));
// While loopCompass = new While("alpha != 100");// vai até 100
// If ifCompass = new If("alpha > 100");
// ifCompass.addTrue(new Move(55, -55));
// ifCompass.addTrue(new PrintString("Girando para a esquerda"));
// ifCompass.addFalse(new Move(-55, 55));
// ifCompass.addFalse(new PrintString("Girando para a direita"));
// loopCompass.add(ifCompass);
// loopCompass.add(new ReadDevice(Compass.class, "alpha"));
// loopCompass.add(new PrintString("Angulo atual: %v", "alpha"));
// func.add(loopCompass);
// func.add(new Move(0, 0));
// func.add(new ReadDevice(aw));
// func.add(new BlockRoboF(aw));
// //func.add(new ReadDevice(Compass.class, "alpha"));
// func.add(new PrintString("Angulo final: %v", "alpha"));
// func.add(new PrintString("fim"));
// func.add(new Declaration("i", new Vector<Object>(Arrays.asList(new Double[]{1.2,3.4}))));
// func.add(new PrintString("inicio"));
// func.add(new FunctionBlock(bubbleSort(10, false)));
// func.add(new PrintString("fim"));
func = newTestFunction();
i.setMainFunction(func);
// DrawingPanel p = new DrawingPanel();
// p.add((Drawable) func);
// boolean singleIdent = true;
// func.ident(0, 0, 40, 100, 0, 1, singleIdent);
// func.wire(40, 100, 0, 1, singleIdent);
// QuickFrame.create(p, "Teste do painel de desenho").addComponentListener(p);
// func.appendDCommandsOn(p);
// System.out.println(Function.getBounds(ifCompass, null, 10, 100, 1, 1, true));
// System.out.println(Function.getBounds(new Wait(1), null, 10,10,0));
SimulationPanel p = new SimulationPanel();
p.addRobot(r);
r.setEnvironment(p.getEnv());
QuickFrame.create(p, "Teste Simulação").addComponentListener(p);
//executa
while (i.step()) {
// try {
// Thread.sleep(100);
// } catch (InterruptedException ex) {
// }
}
// i.reset();
//
// while (i.step()) {
//// try {
//// Thread.sleep(100);
//// } catch (InterruptedException ex) {
//// }
// }
System.out.println(Parser.encode(func));
// System.exit(0);
}
public static Function bubbleSort(int size, boolean rand) {
rand = false;
Function func = new Function("bbSort", null);
StringBuilder sb = new StringBuilder();
sb.append("V = [");
if (rand) {
for (int i = size - 1; i > 1; i--) {
sb.append((int) (Math.random() * 100)).append(",");
}
sb.append((int) (Math.random() * 100)).append("]");
} else {
for (int i = size - 1; i > 1; i--) {
sb.append(i).append(",");
}
sb.append("1]");
}
func.add(new Procedure("var V"));
func.add(new Procedure(sb.toString()));
func.add(new Procedure("var size = " + size));
func.add(new Procedure("var i =1,j = 0;var k = 0, aux ,v = 1"));
// func.add(new Declaration("i", 1));
// func.add(new Declaration("j", 0));
// func.add(new Declaration("k", 0));
// func.add(new Declaration("aux", 0));
// func.add(new Declaration("v", 1));
// func.add(new DummyBlock());
func.add(new PrintString("Antes:"));
While loopP0 = new While("i < size");
loopP0.add(new Procedure("v = V[i]"));
loopP0.add(new PrintString("V[%v]: %v", "i", "v"));
loopP0.add(new Procedure("i = i + 1"));
func.add(loopP0);
func.add(new Procedure("k = size-1"));
func.add(new Procedure("i = 1"));
While loopI = new While("i < size");
loopI.add(new Procedure("j = 1"));
While loopJ = new While("j <= k");
If cond = new If("V[j] > V[j+1]");
// cond.addTrue(new Procedure("aux = V[j]"));
// cond.addTrue(new Procedure("V[j] = V[j+1]"));
// cond.addTrue(new Procedure("V[j+1] = aux"));
cond.addTrue(new Procedure("aux = V[j];V[j] = V[j+1];V[j+1] = aux;"));
loopJ.add(cond);
loopJ.add(new Procedure("j = j + 1"));
loopI.add(loopJ);
loopI.add(new Procedure("k = k - 1"));
loopI.add(new Procedure("i = i + 1"));
func.add(loopI);
func.add(new PrintString("\nDepois:"));
func.add(new Procedure("i = 1"));
While loopP1 = new While("i < size");
loopP1.add(new Procedure("v = V[i]"));
loopP1.add(new PrintString("V[%v]: %v", "i", "v"));
loopP1.add(new Procedure("i = i + 1"));
func.add(loopP1);
return func;
}
public static Function newTestFunction() {
ArrayList<Class<? extends Device>> aw = new ArrayList<>();
aw.add(HBridge.class);
aw.add(Compass.class);
Function func = new Function("main", null);
func.add(new Wait(1000));
func.add(new PrintString("inicio"));
func.add(new Procedure("var i = 10"));
func.add(new PrintString("Girando %v vezes...", "i"));
While loop = new While("i > 10");
loop.add(new Move(70, 70)); //move
loop.add(new Wait(500));
loop.add(new Move(-70, 70)); //gira
loop.add(new Wait(500));
loop.add(new Move(0, 0)); //para
loop.add(new Wait(500));
loop.add(new PrintString("Falta mais %v passo(s)...", "i"));
loop.add(new Procedure("i = i - 1"));
func.add(loop);
func.add(new PrintString("Procurando angulo 100"));
func.add(new Wait(500));
func.add(new Procedure("var alpha = 10"));
While loopCompass = new While("alpha != 100");// vai até 100
If ifCompass = new If("alpha > 100");
ifCompass.addTrue(new Move(55, -55));
ifCompass.addTrue(new PrintString("Girando para a esquerda"));
ifCompass.addFalse(new Move(-55, 55));
ifCompass.addFalse(new PrintString("Girando para a direita"));
//
// If ifCompass2 = new If("alpha > 100");
// ifCompass2.addTrue(new Move(55, -55));
// ifCompass2.addTrue(new PrintString("Girando para a esquerda"));
// ifCompass2.addFalse(new Move(-55, 55));
// ifCompass2.addFalse(new PrintString("Girando para a direita"));
// ifCompass.addFalse(ifCompass2);
//
// If ifCompass3 = new If("alpha > 100");
// ifCompass3.addTrue(new Move(55, -55));
// ifCompass3.addTrue(new PrintString("Girando para a esquerda"));
// ifCompass3.addFalse(new Move(-55, 55));
// ifCompass3.addFalse(new PrintString("Girando para a direita"));
// ifCompass2.addTrue(ifCompass3);
loopCompass.add(ifCompass);
// loopCompass.add(new ReadDevice(Compass.class, "alpha"));
loopCompass.add(new PrintString("Angulo atual: %v", "alpha"));
func.add(loopCompass);
func.add(new Move(0, 0));
// func.add(new ReadDevice(aw));
// func.add(new BlockRoboF(aw));
func.add(new Wait(500));
// func.add(new ReadDevice(Compass.class, "alpha"));
func.add(new PrintString("Angulo final: %v", "alpha"));
func.add(new PrintString("fim"));
return func;
}
}