From 1b13ccb59263b66abc763fb8f298b14bdebc9582 Mon Sep 17 00:00:00 2001 From: Mart Lubbers Date: Tue, 5 Jan 2016 14:04:06 +0100 Subject: [PATCH] update code --- dsl/runtime/specs/wander.tdsl | 47 +++++++++++++--- dsl/runtime/src/nl/ru/des/BasicBehaviour.java | 53 ++++++++++--------- dsl/runtime/src/nl/ru/des/Marster.java | 5 +- .../nl/ru/des/sensors/SensorCollector.java | 15 +++++- dsl/xtend/src/robots/missions/TaskDSL.xtext | 9 +++- .../missions/generator/TaskDSLGenerator.xtend | 18 ++++--- marsrover/document/.gitignore | 2 + marsrover/document/preamble.tex | 4 +- marsrover/document/requirements.tex | 20 ++++--- marsrover/document/todo.txt | 4 +- 10 files changed, 123 insertions(+), 54 deletions(-) diff --git a/dsl/runtime/specs/wander.tdsl b/dsl/runtime/specs/wander.tdsl index 80cd169..be30d5a 100644 --- a/dsl/runtime/specs/wander.tdsl +++ b/dsl/runtime/specs/wander.tdsl @@ -1,25 +1,58 @@ Acceleration 1000 Speed 150 + Behaviour Wander take control: action: left motor forward right motor forward - wait forever + wait 2000 ms + turn randomly 0 to 45 degrees + left motor forward + right motor forward + wait 2000 ms + Behaviour StayInFieldL take control: Light on left action: - turn right 90 + turn right exactly 60 degrees + wait 500 ms + Behaviour StayInFieldR take control: Light on right action: - turn left 90 + turn left exactly 60 degrees + wait 500 ms + Behaviour StayInFieldB take control: Distance dangerous at back action: - wait 750 ms -Behaviour Measure - take control: Color is Green + left motor forward + right motor forward + wait 1000 ms + +Behaviour MeasureLake + take control: (|| Color is Green Color is Blue Color is Red) action: measure -Mission stayinfield using Wander Measure StayInFieldL StayInFieldR and stops when Color is Blue \ No newline at end of file + +Behaviour BumpL + take control: Touched on left + action: + left motor backward with speed 50 acceleration 1000 + right motor backward + wait 2000 ms + +Behaviour BumpR + take control: Touched on right + action: + right motor backward with speed 50 acceleration 1000 + left motor backward + wait 2000 ms + +Mission findBlueLakeWhileAvoidingRocks + using Wander BumpR BumpL StayInFieldB StayInFieldL StayInFieldR and stops when Color is Blue +Mission findAllLakesAndMeasureThem + using Wander MeasureLake StayInFieldB StayInFieldL StayInFieldR and stops when Collected at least Green Blue Red +Mission justWander + using Wander StayInFieldB StayInFieldL StayInFieldR and stops when Color is Cyan \ No newline at end of file diff --git a/dsl/runtime/src/nl/ru/des/BasicBehaviour.java b/dsl/runtime/src/nl/ru/des/BasicBehaviour.java index 8fd1fd3..2a6240e 100644 --- a/dsl/runtime/src/nl/ru/des/BasicBehaviour.java +++ b/dsl/runtime/src/nl/ru/des/BasicBehaviour.java @@ -5,10 +5,8 @@ import lejos.robotics.subsumption.Behavior; import nl.ru.des.sensors.SensorCollector; public abstract class BasicBehaviour implements Behavior{ - protected enum SuppressedState { - IDLE, IN_ACTION, SUPPRESSED; - } - private SuppressedState suppressed; + protected boolean suppressed; + protected boolean finished; protected RegulatedMotor leftMotor, rightMotor, measMotor; protected SensorCollector sensors; protected long time; @@ -19,75 +17,80 @@ public abstract class BasicBehaviour implements Behavior{ this.rightMotor = rightMotor; this.measMotor = measMotor; this.sensors = sensors; + suppressed = false; + finished = true; } protected void reset(){ + finished = true; rightMotor.setSpeed(Constants.speed); rightMotor.setAcceleration(Constants.acceleration); leftMotor.setSpeed(Constants.speed); leftMotor.setAcceleration(Constants.acceleration); rightMotor.stop(true); leftMotor.stop(true); - setSuppressed(SuppressedState.IDLE); - long time = System.currentTimeMillis(); - while(System.currentTimeMillis()-time > 250){ - Thread.yield(); - } } protected void measure(){ measMotor.backward(); - while(getSuppressed() == SuppressedState.IN_ACTION && !measMotor.isStalled()){ + while(!suppressed && !measMotor.isStalled()){ Thread.yield(); } measMotor.forward(); - while(getSuppressed() == SuppressedState.IN_ACTION && !measMotor.isStalled()){ + while(!suppressed && !measMotor.isStalled()){ Thread.yield(); } measMotor.stop(true); rightTurn(90); } + protected void turnRandom(int from, int to){ + int degrees = Marster.random.nextInt(to-from)+from; + if(Marster.random.nextBoolean()){ + rightTurn(degrees); + } else { + leftTurn(degrees); + } + } + protected void rightTurn(int angle){ - rightMotor.stop(); + rightMotor.stop(true); leftMotor.stop(); sensors.resetGyro(); rightMotor.backward(); leftMotor.forward(); - while(getSuppressed() == SuppressedState.IN_ACTION && Math.abs(sensors.gyro()) < angle){ + while(!suppressed && Math.abs(sensors.gyro()) < angle){ Thread.yield(); } + rightMotor.stop(true); + leftMotor.stop(true); LCDPrinter.print(Float.toString(sensors.gyro())); } protected void leftTurn(int angle){ - rightMotor.stop(); + rightMotor.stop(true); leftMotor.stop(); sensors.resetGyro(); leftMotor.backward(); rightMotor.forward(); - while(getSuppressed() == SuppressedState.IN_ACTION && Math.abs(sensors.gyro()) < angle){ + while(!suppressed && Math.abs(sensors.gyro()) < angle){ Thread.yield(); } + rightMotor.stop(true); + leftMotor.stop(true); LCDPrinter.print(Float.toString(sensors.gyro())); } - protected synchronized void setSuppressed(SuppressedState sup){ - suppressed = sup; - } - - protected SuppressedState getSuppressed(){ - return suppressed; - } - @Override public void action() { - setSuppressed(SuppressedState.IN_ACTION); + suppressed = false; + finished = false; } @Override public void suppress() { - setSuppressed(SuppressedState.SUPPRESSED); + suppressed = true; + finished = true; } @Override public boolean takeControl(){ diff --git a/dsl/runtime/src/nl/ru/des/Marster.java b/dsl/runtime/src/nl/ru/des/Marster.java index ee38341..81ee5f6 100644 --- a/dsl/runtime/src/nl/ru/des/Marster.java +++ b/dsl/runtime/src/nl/ru/des/Marster.java @@ -1,6 +1,7 @@ package nl.ru.des; import java.util.LinkedList; +import java.util.Random; import lejos.hardware.ev3.EV3; import lejos.hardware.ev3.LocalEV3; @@ -17,12 +18,12 @@ import lejos.hardware.sensor.NXTLightSensor; import lejos.robotics.RegulatedMotor; import lejos.robotics.SampleProvider; import nl.ru.des.sensors.BTController; -import nl.ru.des.Arbitrator; import nl.ru.des.sensors.RemoteSensors; import nl.ru.des.sensors.SensorCollector; public class Marster { public static Arbitrator arb; + public static Random random; @SuppressWarnings("resource") public static void main(String[] args) { @@ -80,9 +81,11 @@ public class Marster { BTController.startMaster(slave, sc); LCDPrinter.print("Finished loading"); LinkedList missions = Missions.getMissions(sc, rightMotor, leftMotor, measMotor); + random = new Random(); for(Mission m : missions){ LCDPrinter.print("Start " + m.name + " mission..."); arb = new Arbitrator(m.behaviours); + sc.resetColors(); arb.start(); LCDPrinter.print(m.name + " finished!!1one!"); } diff --git a/dsl/runtime/src/nl/ru/des/sensors/SensorCollector.java b/dsl/runtime/src/nl/ru/des/sensors/SensorCollector.java index dcf2d87..59fe6cd 100644 --- a/dsl/runtime/src/nl/ru/des/sensors/SensorCollector.java +++ b/dsl/runtime/src/nl/ru/des/sensors/SensorCollector.java @@ -1,5 +1,9 @@ package nl.ru.des.sensors; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + import lejos.hardware.sensor.EV3GyroSensor; import lejos.robotics.SampleProvider; @@ -10,6 +14,8 @@ public class SensorCollector implements MessageHandler{ private static final float DANGER_DISTANCE_BACK = 0.035f; private static final float DANGER_LIGHT = 0.45f; + private Set collectedColors; + //Local sensors private EV3GyroSensor gyroSensor; private SampleProvider ultra, leftLight, rightLight, gyro; @@ -38,6 +44,8 @@ public class SensorCollector implements MessageHandler{ leftLightTime = System.currentTimeMillis(); rightLightTime = System.currentTimeMillis(); gyroTime = System.currentTimeMillis(); + + collectedColors = new HashSet(); } //Local sensors @@ -78,8 +86,12 @@ public class SensorCollector implements MessageHandler{ } //Remote sensors + public void resetColors(){ + collectedColors.clear(); + } + public boolean collected(int[] colors){ - return false; + return collectedColors.containsAll(Arrays.asList(colors)); } public int color(){ @@ -104,6 +116,7 @@ public class SensorCollector implements MessageHandler{ switch(RemoteSensors.RemoteSensorEnum.values()[Integer.valueOf(Character.toString(m.charAt(0)))]){ case COLOR: color = Integer.valueOf(s); + collectedColors.add(color); break; case LEFT: leftTouch = Integer.valueOf(s)==1; diff --git a/dsl/xtend/src/robots/missions/TaskDSL.xtext b/dsl/xtend/src/robots/missions/TaskDSL.xtext index afefa5d..14a834f 100644 --- a/dsl/xtend/src/robots/missions/TaskDSL.xtext +++ b/dsl/xtend/src/robots/missions/TaskDSL.xtext @@ -13,7 +13,7 @@ Mission: StoppingExpression: '(' op=Operator s+=StoppingExpression s+=StoppingExpression+ ')' | - 'not ' negscond=StoppingCondition | + 'not ' negscond=StoppingExpression | scond=StoppingCondition; StoppingCondition: @@ -29,9 +29,14 @@ Behaviour: 'Behaviour' name=ID Action: whichMotor=LeftRight 'motor' moveDir=Direction ('with speed' spd=INT 'acceleration' acc=INT)? | - 'turn' turnDir=LeftRight degrees=INT ('with speed' spd=INT 'acceleration' acc=INT)? | + 'turn' turnType=Turn ('with speed' spd=INT 'acceleration' acc=INT)? | {Action} 'measure'| 'wait' time=Time; + +Turn: + turnDir=LeftRight 'exactly' degrees=INT 'degrees'| + 'randomly' start=INT 'to' end=INT 'degrees' +; Time: time=INT 'ms' | {Time} 'forever'; diff --git a/dsl/xtend/src/robots/missions/generator/TaskDSLGenerator.xtend b/dsl/xtend/src/robots/missions/generator/TaskDSLGenerator.xtend index ff72ba4..f413af6 100644 --- a/dsl/xtend/src/robots/missions/generator/TaskDSLGenerator.xtend +++ b/dsl/xtend/src/robots/missions/generator/TaskDSLGenerator.xtend @@ -45,7 +45,7 @@ public class Missions{ public static LinkedList getMissions(final SensorCollector sensors, RegulatedMotor rightMotor, RegulatedMotor leftMotor, RegulatedMotor measMotor){ LinkedList missions = new LinkedList(); - «FOR m : mission» + «FOR m : mission SEPARATOR "));" AFTER "));"» missions.add(new Mission("«m.name»", new Behavior[]{ «FOR b : m.behaviours SEPARATOR "," AFTER ","»new «b.name»Behaviour(sensors, rightMotor, leftMotor, measMotor) «ENDFOR» @@ -54,7 +54,7 @@ public class Missions{ return «printExpression(m.se)»; } }} - «ENDFOR»)); + «ENDFOR» return missions; } } @@ -73,7 +73,7 @@ public class «b.name»Behaviour extends BasicBehaviour { } «IF b.tc != null» @Override public boolean takeControl(){ - return getSuppressed() == SuppressedState.IN_ACTION || «printExpression(b.tc)»; + return «printExpression(b.tc)»; } «ENDIF» @@ -89,17 +89,21 @@ public class «b.name»Behaviour extends BasicBehaviour { «a.whichMotor.d.toString()»Motor.«a.moveDir.d.toString()»(); «ELSEIF a.time != null» time = System.currentTimeMillis(); - while(getSuppressed() != SuppressedState.SUPPRESSED«IF a.time.time > 0» && System.currentTimeMillis()-time>«a.time.time»«ENDIF»){ + while(!suppressed«IF a.time.time > 0» && System.currentTimeMillis()-time<«a.time.time»«ENDIF»){ Thread.yield(); } - «ELSEIF a.turnDir != null» + «ELSEIF a.turnType != null» «IF a.acc > 0» leftMotor.setAcceleration(«a.acc»); leftMotor.setSpeed(«a.spd»); rightMotor.setAcceleration(«a.acc»); rightMotor.setSpeed(«a.spd»); «ENDIF» - «a.turnDir.d.toString()»Turn(«a.degrees»); + «IF a.turnType.turnDir != null» + «a.turnType.turnDir.d.toString()»Turn(«a.turnType.degrees»); + «ELSE» + turnRandom(«a.turnType.start», «a.turnType.end»); + «ENDIF» «ELSE» measure(); «ENDIF» @@ -131,6 +135,8 @@ public class Constants{ «ELSEIF e.scond.color != null» sensors.color() == «e.scond.color.d.ordinal» «ENDIF» + «ELSEIF e.negscond != null» + !(«printExpression(e.negscond)») «ELSE» «IF e.op.d.equals(OperatorE.AND)» «FOR ex : e.s BEFORE "(" SEPARATOR "&&" AFTER ")"»«printExpression(ex)»«ENDFOR» diff --git a/marsrover/document/.gitignore b/marsrover/document/.gitignore index ac95be6..f82a0ab 100644 --- a/marsrover/document/.gitignore +++ b/marsrover/document/.gitignore @@ -145,3 +145,5 @@ pythontex-files-*/ # endfloat *.ttt *.fff + +*.xyc diff --git a/marsrover/document/preamble.tex b/marsrover/document/preamble.tex index f197fa0..ceafe0f 100644 --- a/marsrover/document/preamble.tex +++ b/marsrover/document/preamble.tex @@ -12,13 +12,15 @@ \usepackage[all]{xypic} % For nice diagrams \usepackage{listings} % For source code listings -\title{Autonomous sequentional mission execution on Mars with a multi-brick +\title{Autonomous sequential mission execution on Mars with a multi-brick \textsc{lego}$^{\small\textcopyright}$ robot.} \author{Natanael Adityasatria (s4417992)\and Mart Lubbers (s4109503)} \date{\today} \hypersetup{hidelinks} +\CompileMatrices + \pagestyle{fancy} \renewcommand{\headrulewidth}{0pt} \fancyhead[RF]{\small\textsc{DES2015: Mart \& Natanael. Page: \thepage}} diff --git a/marsrover/document/requirements.tex b/marsrover/document/requirements.tex index a47aac9..c8beedd 100644 --- a/marsrover/document/requirements.tex +++ b/marsrover/document/requirements.tex @@ -1,13 +1,16 @@ \section{Requirements} -The requirements are is ordered following the MoSCoW prioritization method. The -MoSCoW approach originated from the RAD methodology~\cite{clegg_case_1994}. -MoSCoW is used to sort the MarsRover features into priority order based on the -importance. In this way, the developers are able to understand what feature is -essential to be done. The term MoSCoW itself is an acronym derived from the -first letter of each of four prioritization categories (Must have, Should have, -Could have, and Would like but won't get). The first letters are used in the -first column of \autoref{tab:req} to describe the priority of the requirements. +\subsection{\emph{MoSCoW}} +The requirements are ordered following the \emph{MoSCoW} prioritization method. +The \emph{MoSCoW} approach originated from the RAD +methodology~\cite{clegg_case_1994}. \emph{MoSCoW} is used to sort the features +into priority order based on the importance. In this way, the developers are +able to understand what feature is essential to be done. The term \emph{MoSCoW} +itself is an acronym derived from the first letter of each of four +prioritization categories (Must have, Should have, Could have, and Would like +but will not get). The first letters are used in the first column of +\autoref{tab:req} to describe the priority of the requirements. +\subsection{Requirements} \begin{longtabu}to \linewidth{llX} \toprule \rowfont\bfseries Code & Priority & Description\\ @@ -40,6 +43,7 @@ first column of \autoref{tab:req} to describe the priority of the requirements. \midrule\midrule \multicolumn{3}{l}{Non-functional requirements}\\ + \midrule\midrule NR1 & \textsc{M} & The code should be generated by a DSL.\\ NR2 & \textsc{S} & Finish the entire mission set within the demonstration time.\\ diff --git a/marsrover/document/todo.txt b/marsrover/document/todo.txt index b6316c8..9a623dd 100644 --- a/marsrover/document/todo.txt +++ b/marsrover/document/todo.txt @@ -1,7 +1,5 @@ - 1. Requirements -done 2. Robot -done Tools +mart subsumption adit DSL description adit Code structure, what do we generate? -- 2.20.1