@@ -17,6 +17,7 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||
public static final int defaultTrackLength = 100; | |||
public static final float defaultBrakeProb = 0.3f; | |||
public static final float defaultMaxVelocity = 5.0f; | |||
public static final int defaultDelay = 0; | |||
protected Track track; | |||
protected TimeRecordView trackView; | |||
protected Worker worker; | |||
@@ -26,7 +27,8 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||
protected void onCreate(Bundle savedInstanceState) { | |||
super.onCreate(savedInstanceState); | |||
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.viewStack = (LinearLayout) findViewById(R.id.trackViewStack); | |||
@@ -49,6 +51,17 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||
brakeProbabilitySeekBar.setOnSeekBarChangeListener(this); | |||
brakeProbabilitySeekBar.setProgress((int)(defaultBrakeProb*20)); | |||
((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 | |||
@@ -58,6 +71,8 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||
final MainActivity mainActivity = this; | |||
final TextView lastAvgView = (TextView) findViewById(R.id.avgVeloLastView); | |||
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() { | |||
@Override | |||
public void run() { | |||
@@ -65,8 +80,11 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||
if (viewStackRef.getChildCount() > 0) | |||
viewStackRef.removeViewAt(0); | |||
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); | |||
Button stopButton = (Button) findViewById(R.id.stopButton); | |||
stopButton.setEnabled(true); | |||
Button clearButton = (Button) findViewById(R.id.clearButton); | |||
clearButton.setEnabled(false); | |||
this.worker = new Worker(track); | |||
this.worker.start(); | |||
@@ -94,6 +114,8 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||
stepButton.setEnabled(true); | |||
Button stopButton = (Button) findViewById(R.id.stopButton); | |||
stopButton.setEnabled(false); | |||
Button clearButton = (Button) findViewById(R.id.clearButton); | |||
clearButton.setEnabled(true); | |||
this.worker.setStop(true); | |||
try { | |||
@@ -104,6 +126,31 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||
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() { | |||
int newTrackLength = ((SeekBar)(findViewById(R.id.trackLengthSeekBar))).getProgress(); | |||
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); | |||
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); | |||
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.start(); | |||
} | |||
@@ -151,6 +196,10 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||
tv.setText(String.valueOf(progress)); | |||
} else if (seekBar == (SeekBar)(findViewById(R.id.trackLengthSeekBar))) { | |||
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 float trackLength; | |||
protected float sumAvgMemory; | |||
protected float sumDelAvgMemory; | |||
protected int historyLength; | |||
protected float overallAvg; | |||
protected float delayedAvg; | |||
protected float lastAvg; | |||
protected int waitTime; | |||
protected float maxVelocity; | |||
protected float brakeProb; | |||
public List<List<VehicleTimeRecord>> getVtrList() { | |||
return vtrList; | |||
} | |||
public List<List<VehicleTimeRecord>> getVtrList() { return vtrList; } | |||
public float getOverallAvg() { | |||
return overallAvg; | |||
} | |||
public float getLastAvg() { | |||
return lastAvg; | |||
} | |||
public float getDelayedAvg() { return delayedAvg; } | |||
public List<Vehicle> getVehicles() { | |||
return vehicles; | |||
} | |||
@@ -33,16 +34,19 @@ public class Track extends Observable { | |||
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.brakeProb = brakeProb; | |||
this.maxVelocity = maxVelocity; | |||
this.vehicles = createVehiclesList(numberVehicles); | |||
this.vtrList = new LinkedList<>(); | |||
this.sumAvgMemory = 0; | |||
this.sumDelAvgMemory = 0; | |||
this.overallAvg = 0; | |||
this.delayedAvg = 0; | |||
this.lastAvg = 0; | |||
this.historyLength = 25; | |||
this.waitTime = waitTime; | |||
} | |||
@@ -56,6 +60,10 @@ public class Track extends Observable { | |||
return result; | |||
} | |||
public void setWaitTime(int waitTime) { | |||
this.waitTime = waitTime; | |||
} | |||
public void setBrakeProb(float brakeProb) { | |||
for (Vehicle v : this.vehicles) { | |||
v.setBrakeProb(brakeProb); | |||
@@ -108,8 +116,13 @@ public class Track extends Observable { | |||
protected void update_avg(){ | |||
lastAvg = avg_step(vtrList.size()-1); | |||
if (this.vtrList.size() > 10) { | |||
sumDelAvgMemory += lastAvg; | |||
delayedAvg = sumDelAvgMemory / (vtrList.size() - 10); | |||
} | |||
sumAvgMemory += lastAvg; | |||
overallAvg = sumAvgMemory / vtrList.size(); | |||
} | |||
public float avg_span(int start, int end){ | |||
@@ -159,6 +159,29 @@ | |||
android:paddingTop="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 | |||
android:layout_width="match_parent" | |||
android:layout_height="match_parent"> | |||
@@ -169,10 +192,17 @@ | |||
android:layout_height="wrap_content" | |||
android:text="Average velocity (overall):" /> | |||
<TextView | |||
android:id="@+id/textView10" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:text=" " /> | |||
<TextView | |||
android:id="@+id/avgVeloOverallView" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" /> | |||
android:layout_height="wrap_content" | |||
android:text="0.0" /> | |||
</TableRow> | |||
<TableRow | |||
@@ -185,11 +215,41 @@ | |||
android:layout_height="wrap_content" | |||
android:text="Average velocity (last step):" /> | |||
<TextView | |||
android:id="@+id/textView11" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:text=" " /> | |||
<TextView | |||
android:id="@+id/avgVeloLastView" | |||
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> | |||
</TableLayout> | |||
@@ -209,14 +269,47 @@ | |||
<LinearLayout | |||
android:id="@+id/trackViewStack" | |||
android:layout_width="match_parent" | |||
android:layout_height="0dp" | |||
android:layout_height="500dp" | |||
android:orientation="vertical" | |||
app:layout_constraintBottom_toTopOf="@+id/linearLayout" | |||
app:layout_constraintTop_toTopOf="parent" | |||
tools:layout_editor_absoluteX="8dp"> | |||
</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 | |||
android:id="@+id/linearLayout" | |||
android:layout_width="match_parent" | |||
@@ -252,6 +345,15 @@ | |||
android:onClick="onStopButtonClick" | |||
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> | |||
</androidx.constraintlayout.widget.ConstraintLayout> | |||