@@ -17,6 +17,7 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||||
public static final int defaultTrackLength = 100; | public static final int defaultTrackLength = 100; | ||||
public static final float defaultBrakeProb = 0.3f; | public static final float defaultBrakeProb = 0.3f; | ||||
public static final float defaultMaxVelocity = 5.0f; | public static final float defaultMaxVelocity = 5.0f; | ||||
public static final int defaultDelay = 0; | |||||
protected Track track; | protected Track track; | ||||
protected TimeRecordView trackView; | protected TimeRecordView trackView; | ||||
protected Worker worker; | protected Worker worker; | ||||
@@ -26,7 +27,8 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||||
protected void onCreate(Bundle savedInstanceState) { | protected void onCreate(Bundle savedInstanceState) { | ||||
super.onCreate(savedInstanceState); | super.onCreate(savedInstanceState); | ||||
setContentView(R.layout.activity_main); | setContentView(R.layout.activity_main); | ||||
this.track = new Track(defaultNoOfVehicles, defaultTrackLength, defaultBrakeProb, defaultMaxVelocity); | |||||
this.track = new Track(defaultNoOfVehicles, defaultTrackLength, defaultBrakeProb, | |||||
defaultMaxVelocity, defaultDelay); | |||||
this.track.addObserver(this); | this.track.addObserver(this); | ||||
this.viewStack = (LinearLayout) findViewById(R.id.trackViewStack); | this.viewStack = (LinearLayout) findViewById(R.id.trackViewStack); | ||||
@@ -49,6 +51,17 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||||
brakeProbabilitySeekBar.setOnSeekBarChangeListener(this); | brakeProbabilitySeekBar.setOnSeekBarChangeListener(this); | ||||
brakeProbabilitySeekBar.setProgress((int)(defaultBrakeProb*20)); | brakeProbabilitySeekBar.setProgress((int)(defaultBrakeProb*20)); | ||||
((TextView)(findViewById(R.id.brakeProbTextView))).setText(String.valueOf(defaultBrakeProb)); | ((TextView)(findViewById(R.id.brakeProbTextView))).setText(String.valueOf(defaultBrakeProb)); | ||||
SeekBar delaySeekBar = (SeekBar)(findViewById(R.id.simDelaySeekBar)); | |||||
delaySeekBar.setOnSeekBarChangeListener(this); | |||||
delaySeekBar.setProgress(defaultDelay); | |||||
this.update(this.track, null); | |||||
} | |||||
public static float round(float number, int digits) { | |||||
float div = (float) Math.pow(10.0f, digits); | |||||
return Math.round(number*div)/div; | |||||
} | } | ||||
@Override | @Override | ||||
@@ -58,6 +71,8 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||||
final MainActivity mainActivity = this; | final MainActivity mainActivity = this; | ||||
final TextView lastAvgView = (TextView) findViewById(R.id.avgVeloLastView); | final TextView lastAvgView = (TextView) findViewById(R.id.avgVeloLastView); | ||||
final TextView overallAvgView = (TextView) findViewById(R.id.avgVeloOverallView); | final TextView overallAvgView = (TextView) findViewById(R.id.avgVeloOverallView); | ||||
final TextView delayedAvgView = (TextView) findViewById(R.id.delayedAvgTextView); | |||||
final TextView stepsView = (TextView) findViewById(R.id.stepsTextView); | |||||
runOnUiThread(new Runnable() { | runOnUiThread(new Runnable() { | ||||
@Override | @Override | ||||
public void run() { | public void run() { | ||||
@@ -65,8 +80,11 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||||
if (viewStackRef.getChildCount() > 0) | if (viewStackRef.getChildCount() > 0) | ||||
viewStackRef.removeViewAt(0); | viewStackRef.removeViewAt(0); | ||||
viewStackRef.addView(newTrView); | viewStackRef.addView(newTrView); | ||||
lastAvgView.setText(String.valueOf(trackRef.getLastAvg())); | |||||
overallAvgView.setText(String.valueOf(trackRef.getOverallAvg())); | |||||
lastAvgView.setText(String.valueOf(round(trackRef.getLastAvg(), 2))); | |||||
overallAvgView.setText(String.valueOf(round(trackRef.getOverallAvg(), 2))); | |||||
stepsView.setText(String.valueOf(trackRef.getVtrList().size())); | |||||
delayedAvgView.setText(String.valueOf(round(trackRef.getDelayedAvg(), 2))); | |||||
} | } | ||||
}); | }); | ||||
} | } | ||||
@@ -82,6 +100,8 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||||
stepButton.setEnabled(false); | stepButton.setEnabled(false); | ||||
Button stopButton = (Button) findViewById(R.id.stopButton); | Button stopButton = (Button) findViewById(R.id.stopButton); | ||||
stopButton.setEnabled(true); | stopButton.setEnabled(true); | ||||
Button clearButton = (Button) findViewById(R.id.clearButton); | |||||
clearButton.setEnabled(false); | |||||
this.worker = new Worker(track); | this.worker = new Worker(track); | ||||
this.worker.start(); | this.worker.start(); | ||||
@@ -94,6 +114,8 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||||
stepButton.setEnabled(true); | stepButton.setEnabled(true); | ||||
Button stopButton = (Button) findViewById(R.id.stopButton); | Button stopButton = (Button) findViewById(R.id.stopButton); | ||||
stopButton.setEnabled(false); | stopButton.setEnabled(false); | ||||
Button clearButton = (Button) findViewById(R.id.clearButton); | |||||
clearButton.setEnabled(true); | |||||
this.worker.setStop(true); | this.worker.setStop(true); | ||||
try { | try { | ||||
@@ -104,6 +126,31 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||||
this.worker = null; | this.worker = null; | ||||
} | } | ||||
protected void stopWorker() { | |||||
this.worker.setStop(true); | |||||
try { | |||||
this.worker.join(); | |||||
} catch (InterruptedException ex) { | |||||
} | |||||
this.worker = null; | |||||
} | |||||
public void onClearButtonClick(View view) { | |||||
this.track.deleteObserver(this); | |||||
if (this.worker != null) { // There was a simulation running | |||||
this.stopWorker(); | |||||
} | |||||
Button playButton = (Button) findViewById(R.id.playButton); | |||||
playButton.setEnabled(true); | |||||
Button stepButton = (Button) findViewById(R.id.stepButton); | |||||
stepButton.setEnabled(true); | |||||
Button stopButton = (Button) findViewById(R.id.stopButton); | |||||
stopButton.setEnabled(false); | |||||
this.updateTrack(); | |||||
this.update(this.track, null); | |||||
} | |||||
protected void updateTrack() { | protected void updateTrack() { | ||||
int newTrackLength = ((SeekBar)(findViewById(R.id.trackLengthSeekBar))).getProgress(); | int newTrackLength = ((SeekBar)(findViewById(R.id.trackLengthSeekBar))).getProgress(); | ||||
SeekBar noOfVehiclesSeekBar = (SeekBar)(findViewById(R.id.noOfVehiclesSeekBar)); | SeekBar noOfVehiclesSeekBar = (SeekBar)(findViewById(R.id.noOfVehiclesSeekBar)); | ||||
@@ -123,14 +170,12 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||||
SeekBar brakeProbabilitySeekBar = (SeekBar) findViewById(R.id.brakeProbabilitySeekBar); | SeekBar brakeProbabilitySeekBar = (SeekBar) findViewById(R.id.brakeProbabilitySeekBar); | ||||
float newBrakeProb = (float)brakeProbabilitySeekBar.getProgress() / (float)brakeProbabilitySeekBar.getMax(); | float newBrakeProb = (float)brakeProbabilitySeekBar.getProgress() / (float)brakeProbabilitySeekBar.getMax(); | ||||
this.track = new Track(newNoOfVehicles, newTrackLength, newBrakeProb, newMaxVelocity); | |||||
int newDelay = ((SeekBar)(findViewById(R.id.simDelaySeekBar))).getProgress(); | |||||
this.track = new Track(newNoOfVehicles, newTrackLength, newBrakeProb, newMaxVelocity, newDelay); | |||||
this.track.addObserver(this); | this.track.addObserver(this); | ||||
if (this.worker != null) { // There was a simulation running already | if (this.worker != null) { // There was a simulation running already | ||||
this.worker.setStop(true); | |||||
try { | |||||
this.worker.join(); | |||||
} catch (InterruptedException ex) { | |||||
} | |||||
this.stopWorker(); | |||||
this.worker = new Worker(track); | this.worker = new Worker(track); | ||||
this.worker.start(); | this.worker.start(); | ||||
} | } | ||||
@@ -151,6 +196,10 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||||
tv.setText(String.valueOf(progress)); | tv.setText(String.valueOf(progress)); | ||||
} else if (seekBar == (SeekBar)(findViewById(R.id.trackLengthSeekBar))) { | } else if (seekBar == (SeekBar)(findViewById(R.id.trackLengthSeekBar))) { | ||||
this.updateTrack(); | this.updateTrack(); | ||||
} else if (seekBar == (SeekBar)(findViewById(R.id.simDelaySeekBar))) { | |||||
TextView tv = (TextView)(findViewById(R.id.simDelayTextView)); | |||||
tv.setText(String.valueOf(seekBar.getProgress())); | |||||
this.track.setWaitTime(seekBar.getProgress()); | |||||
} | } | ||||
} | } | ||||
@@ -10,22 +10,23 @@ public class Track extends Observable { | |||||
protected List<List<VehicleTimeRecord>> vtrList; | protected List<List<VehicleTimeRecord>> vtrList; | ||||
protected float trackLength; | protected float trackLength; | ||||
protected float sumAvgMemory; | protected float sumAvgMemory; | ||||
protected float sumDelAvgMemory; | |||||
protected int historyLength; | protected int historyLength; | ||||
protected float overallAvg; | protected float overallAvg; | ||||
protected float delayedAvg; | |||||
protected float lastAvg; | protected float lastAvg; | ||||
protected int waitTime; | protected int waitTime; | ||||
protected float maxVelocity; | protected float maxVelocity; | ||||
protected float brakeProb; | protected float brakeProb; | ||||
public List<List<VehicleTimeRecord>> getVtrList() { | |||||
return vtrList; | |||||
} | |||||
public List<List<VehicleTimeRecord>> getVtrList() { return vtrList; } | |||||
public float getOverallAvg() { | public float getOverallAvg() { | ||||
return overallAvg; | return overallAvg; | ||||
} | } | ||||
public float getLastAvg() { | public float getLastAvg() { | ||||
return lastAvg; | return lastAvg; | ||||
} | } | ||||
public float getDelayedAvg() { return delayedAvg; } | |||||
public List<Vehicle> getVehicles() { | public List<Vehicle> getVehicles() { | ||||
return vehicles; | return vehicles; | ||||
} | } | ||||
@@ -33,16 +34,19 @@ public class Track extends Observable { | |||||
return trackLength; | return trackLength; | ||||
} | } | ||||
public Track(int numberVehicles, float trackLength, float brakeProb, float maxVelocity) { | |||||
public Track(int numberVehicles, float trackLength, float brakeProb, float maxVelocity, int waitTime) { | |||||
this.trackLength = trackLength; | this.trackLength = trackLength; | ||||
this.brakeProb = brakeProb; | this.brakeProb = brakeProb; | ||||
this.maxVelocity = maxVelocity; | this.maxVelocity = maxVelocity; | ||||
this.vehicles = createVehiclesList(numberVehicles); | this.vehicles = createVehiclesList(numberVehicles); | ||||
this.vtrList = new LinkedList<>(); | this.vtrList = new LinkedList<>(); | ||||
this.sumAvgMemory = 0; | this.sumAvgMemory = 0; | ||||
this.sumDelAvgMemory = 0; | |||||
this.overallAvg = 0; | this.overallAvg = 0; | ||||
this.delayedAvg = 0; | |||||
this.lastAvg = 0; | this.lastAvg = 0; | ||||
this.historyLength = 25; | this.historyLength = 25; | ||||
this.waitTime = waitTime; | |||||
} | } | ||||
@@ -56,6 +60,10 @@ public class Track extends Observable { | |||||
return result; | return result; | ||||
} | } | ||||
public void setWaitTime(int waitTime) { | |||||
this.waitTime = waitTime; | |||||
} | |||||
public void setBrakeProb(float brakeProb) { | public void setBrakeProb(float brakeProb) { | ||||
for (Vehicle v : this.vehicles) { | for (Vehicle v : this.vehicles) { | ||||
v.setBrakeProb(brakeProb); | v.setBrakeProb(brakeProb); | ||||
@@ -108,8 +116,13 @@ public class Track extends Observable { | |||||
protected void update_avg(){ | protected void update_avg(){ | ||||
lastAvg = avg_step(vtrList.size()-1); | lastAvg = avg_step(vtrList.size()-1); | ||||
if (this.vtrList.size() > 10) { | |||||
sumDelAvgMemory += lastAvg; | |||||
delayedAvg = sumDelAvgMemory / (vtrList.size() - 10); | |||||
} | |||||
sumAvgMemory += lastAvg; | sumAvgMemory += lastAvg; | ||||
overallAvg = sumAvgMemory / vtrList.size(); | overallAvg = sumAvgMemory / vtrList.size(); | ||||
} | } | ||||
public float avg_span(int start, int end){ | public float avg_span(int start, int end){ | ||||
@@ -159,6 +159,29 @@ | |||||
android:paddingTop="8dp" | android:paddingTop="8dp" | ||||
android:paddingBottom="8dp"> | android:paddingBottom="8dp"> | ||||
<TableRow | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" > | |||||
<TextView | |||||
android:id="@+id/textView7" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:text="Steps" /> | |||||
<TextView | |||||
android:id="@+id/textView9" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:text=" " /> | |||||
<TextView | |||||
android:id="@+id/stepsTextView" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:text="0" /> | |||||
</TableRow> | |||||
<TableRow | <TableRow | ||||
android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
android:layout_height="match_parent"> | android:layout_height="match_parent"> | ||||
@@ -169,10 +192,17 @@ | |||||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
android:text="Average velocity (overall):" /> | android:text="Average velocity (overall):" /> | ||||
<TextView | |||||
android:id="@+id/textView10" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:text=" " /> | |||||
<TextView | <TextView | ||||
android:id="@+id/avgVeloOverallView" | android:id="@+id/avgVeloOverallView" | ||||
android:layout_width="wrap_content" | android:layout_width="wrap_content" | ||||
android:layout_height="wrap_content" /> | |||||
android:layout_height="wrap_content" | |||||
android:text="0.0" /> | |||||
</TableRow> | </TableRow> | ||||
<TableRow | <TableRow | ||||
@@ -185,11 +215,41 @@ | |||||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
android:text="Average velocity (last step):" /> | android:text="Average velocity (last step):" /> | ||||
<TextView | |||||
android:id="@+id/textView11" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:text=" " /> | |||||
<TextView | <TextView | ||||
android:id="@+id/avgVeloLastView" | android:id="@+id/avgVeloLastView" | ||||
android:layout_width="wrap_content" | android:layout_width="wrap_content" | ||||
android:layout_height="wrap_content" /> | |||||
android:layout_height="wrap_content" | |||||
android:text="0.0" /> | |||||
</TableRow> | |||||
<TableRow | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" > | |||||
<TextView | |||||
android:id="@+id/textView14" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:text="Delayed average velocity:" /> | |||||
<TextView | |||||
android:id="@+id/textView13" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:text=" " /> | |||||
<TextView | |||||
android:id="@+id/delayedAvgTextView" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:text="0.0" /> | |||||
</TableRow> | </TableRow> | ||||
</TableLayout> | </TableLayout> | ||||
@@ -209,14 +269,47 @@ | |||||
<LinearLayout | <LinearLayout | ||||
android:id="@+id/trackViewStack" | android:id="@+id/trackViewStack" | ||||
android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
android:layout_height="0dp" | |||||
android:layout_height="500dp" | |||||
android:orientation="vertical" | android:orientation="vertical" | ||||
app:layout_constraintBottom_toTopOf="@+id/linearLayout" | |||||
app:layout_constraintTop_toTopOf="parent" | app:layout_constraintTop_toTopOf="parent" | ||||
tools:layout_editor_absoluteX="8dp"> | tools:layout_editor_absoluteX="8dp"> | ||||
</LinearLayout> | </LinearLayout> | ||||
<androidx.constraintlayout.widget.ConstraintLayout | |||||
android:id="@+id/constraintLayout" | |||||
android:layout_width="0dp" | |||||
android:layout_height="wrap_content" | |||||
app:layout_constraintBottom_toTopOf="@+id/linearLayout" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent"> | |||||
<TextView | |||||
android:id="@+id/textView6" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:text="Delay:" /> | |||||
<SeekBar | |||||
android:id="@+id/simDelaySeekBar" | |||||
android:layout_width="0dp" | |||||
android:layout_height="wrap_content" | |||||
android:max="1000" | |||||
android:min="0" | |||||
app:layout_constraintEnd_toStartOf="@+id/simDelayTextView" | |||||
app:layout_constraintStart_toEndOf="@+id/textView6" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
<TextView | |||||
android:id="@+id/simDelayTextView" | |||||
android:layout_width="50dp" | |||||
android:layout_height="wrap_content" | |||||
android:gravity="right" | |||||
android:text="0" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | |||||
<LinearLayout | <LinearLayout | ||||
android:id="@+id/linearLayout" | android:id="@+id/linearLayout" | ||||
android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
@@ -252,6 +345,15 @@ | |||||
android:onClick="onStopButtonClick" | android:onClick="onStopButtonClick" | ||||
android:text="Stop" /> | android:text="Stop" /> | ||||
<Button | |||||
android:id="@+id/clearButton" | |||||
style="@style/Widget.AppCompat.Button.Borderless" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_weight="1" | |||||
android:onClick="onClearButtonClick" | |||||
android:text="clear" /> | |||||
</LinearLayout> | </LinearLayout> | ||||
</androidx.constraintlayout.widget.ConstraintLayout> | </androidx.constraintlayout.widget.ConstraintLayout> | ||||