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
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;
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(){
package nl.ru.des;
import java.util.LinkedList;
+import java.util.Random;
import lejos.hardware.ev3.EV3;
import lejos.hardware.ev3.LocalEV3;
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) {
BTController.startMaster(slave, sc);
LCDPrinter.print("Finished loading");
LinkedList<Mission> 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!");
}
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;
private static final float DANGER_DISTANCE_BACK = 0.035f;
private static final float DANGER_LIGHT = 0.45f;
+ private Set<Integer> collectedColors;
+
//Local sensors
private EV3GyroSensor gyroSensor;
private SampleProvider ultra, leftLight, rightLight, gyro;
leftLightTime = System.currentTimeMillis();
rightLightTime = System.currentTimeMillis();
gyroTime = System.currentTimeMillis();
+
+ collectedColors = new HashSet<Integer>();
}
//Local sensors
}
//Remote sensors
+ public void resetColors(){
+ collectedColors.clear();
+ }
+
public boolean collected(int[] colors){
- return false;
+ return collectedColors.containsAll(Arrays.asList(colors));
}
public int color(){
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;
StoppingExpression:
'(' op=Operator s+=StoppingExpression s+=StoppingExpression+ ')' |
- 'not ' negscond=StoppingCondition |
+ 'not ' negscond=StoppingExpression |
scond=StoppingCondition;
StoppingCondition:
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';
public static LinkedList<Mission> getMissions(final SensorCollector sensors, RegulatedMotor rightMotor,
RegulatedMotor leftMotor, RegulatedMotor measMotor){
LinkedList<Mission> missions = new LinkedList<Mission>();
- «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»
return «printExpression(m.se)»;
}
}}
- «ENDFOR»));
+ «ENDFOR»
return missions;
}
}
}
«IF b.tc != null»
@Override public boolean takeControl(){
- return getSuppressed() == SuppressedState.IN_ACTION || «printExpression(b.tc)»;
+ return «printExpression(b.tc)»;
}
«ENDIF»
«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»
«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»
# endfloat
*.ttt
*.fff
+
+*.xyc
\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}}
\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\\
\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.\\
- 1. Requirements
-done
2. Robot
-done Tools
+mart subsumption
adit DSL description
adit Code structure, what do we generate?