Compare commits

..

2 Commits

Author SHA1 Message Date
Loch Christian (uib05376)
05fe67bc12 Add history length constant
Optimize view update
Add semaphore to TimeRecordList
Add waiting timer to model update
2020-11-12 21:18:29 +01:00
Loch Christian (uib05376)
457c9662c3 Add rounding compensation while rendering track 2020-11-12 15:12:10 +01:00
4 changed files with 59 additions and 17 deletions

View File

@ -18,6 +18,7 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar
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; public static final int defaultDelay = 0;
public static final int defaultHistoryLength = 50;
protected Track track; protected Track track;
protected TimeRecordView trackView; protected TimeRecordView trackView;
protected Worker worker; protected Worker worker;
@ -28,9 +29,11 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
this.track = new Track(defaultNoOfVehicles, defaultTrackLength, defaultBrakeProb, this.track = new Track(defaultNoOfVehicles, defaultTrackLength, defaultBrakeProb,
defaultMaxVelocity, defaultDelay); defaultMaxVelocity, defaultDelay, defaultHistoryLength);
this.track.addObserver(this); this.track.addObserver(this);
this.viewStack = (LinearLayout) findViewById(R.id.trackViewStack); this.viewStack = (LinearLayout) findViewById(R.id.trackViewStack);
this.trackView = new TimeRecordView(this, track, defaultHistoryLength);
viewStack.addView(this.trackView);
SeekBar trackLengthSeekBar = (SeekBar) findViewById(R.id.trackLengthSeekBar); SeekBar trackLengthSeekBar = (SeekBar) findViewById(R.id.trackLengthSeekBar);
trackLengthSeekBar.setOnSeekBarChangeListener(this); trackLengthSeekBar.setOnSeekBarChangeListener(this);
@ -73,18 +76,22 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar
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 delayedAvgView = (TextView) findViewById(R.id.delayedAvgTextView);
final TextView stepsView = (TextView) findViewById(R.id.stepsTextView); final TextView stepsView = (TextView) findViewById(R.id.stepsTextView);
final TimeRecordView view = this.trackView;
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
TimeRecordView newTrView = new TimeRecordView(mainActivity, trackRef);
if (viewStackRef.getChildCount() > 0) //TimeRecordView newTrView = new TimeRecordView(mainActivity, trackRef);
viewStackRef.removeViewAt(0); trackView.invalidate();
viewStackRef.addView(newTrView); //if (viewStackRef.getChildCount() > 0)
// viewStackRef.removeViewAt(0);
//viewStackRef.addView(newTrView);
lastAvgView.setText(String.valueOf(round(trackRef.getLastAvg(), 2))); lastAvgView.setText(String.valueOf(round(trackRef.getLastAvg(), 2)));
overallAvgView.setText(String.valueOf(round(trackRef.getOverallAvg(), 2))); overallAvgView.setText(String.valueOf(round(trackRef.getOverallAvg(), 2)));
stepsView.setText(String.valueOf(trackRef.getVtrList().size())); stepsView.setText(String.valueOf(trackRef.getSteps()));
delayedAvgView.setText(String.valueOf(round(trackRef.getDelayedAvg(), 2))); delayedAvgView.setText(String.valueOf(round(trackRef.getDelayedAvg(), 2)));
} }
}); });
} }
@ -172,7 +179,8 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar
int newDelay = ((SeekBar)(findViewById(R.id.simDelaySeekBar))).getProgress(); int newDelay = ((SeekBar)(findViewById(R.id.simDelaySeekBar))).getProgress();
this.track = new Track(newNoOfVehicles, newTrackLength, newBrakeProb, newMaxVelocity, newDelay); this.track = new Track(newNoOfVehicles, newTrackLength, newBrakeProb, newMaxVelocity, newDelay, defaultHistoryLength);
this.trackView.setTrack(this.track);
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.stopWorker(); this.stopWorker();

View File

@ -5,7 +5,6 @@ import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import java.util.ConcurrentModificationException; import java.util.ConcurrentModificationException;
import java.util.List; import java.util.List;
@ -14,15 +13,23 @@ public class TimeRecordView extends View {
protected Paint paint; protected Paint paint;
protected Track track; protected Track track;
protected int pixelPerVehicle; protected int pixelPerVehicle;
protected float tooShortPerTrackLength;
protected int historyLength;
public TimeRecordView(Context context, Track track) { public TimeRecordView(Context context, Track track, int historyLength) {
super(context); super(context);
this.track = track; this.track = track;
this.paint = new Paint(); this.paint = new Paint();
this.historyLength = historyLength;
paint.setColor(Color.BLACK); paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL_AND_STROKE); paint.setStyle(Paint.Style.FILL_AND_STROKE);
this.setBackgroundColor(Color.BLACK); this.setBackgroundColor(Color.BLACK);
this.pixelPerVehicle = (int) (this.getWidth() / this.track.getTrackLength()); this.pixelPerVehicle = (int) (this.getWidth() / this.track.getTrackLength());
this.tooShortPerTrackLength = (this.getWidth() - this.pixelPerVehicle*this.track.getTrackLength())/this.track.getTrackLength();
}
public void setTrack(Track track) {
this.track = track;
} }
protected int getColor(float curVelocity, float maxVelocity) { protected int getColor(float curVelocity, float maxVelocity) {
@ -52,23 +59,32 @@ public class TimeRecordView extends View {
protected void onSizeChanged(int w, int h, int oldw, int oldh) { protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh); super.onSizeChanged(w, h, oldw, oldh);
this.pixelPerVehicle = (int) (this.getWidth() / this.track.getTrackLength()); this.pixelPerVehicle = (int) (this.getWidth() / this.track.getTrackLength());
this.tooShortPerTrackLength = (this.getWidth() - this.pixelPerVehicle*this.track.getTrackLength())/this.track.getTrackLength();
} }
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw(Canvas canvas) {
int y = 0; int y = 0;
List<List<VehicleTimeRecord>> stepList = this.track.getVtrList(); List<List<VehicleTimeRecord>> stepList = this.track.getVtrList();
for (int curStepIdx = stepList.size()-1; curStepIdx >= stepList.size()-1-50 && curStepIdx >= 0; curStepIdx--) { for (int curStepIdx = this.historyLength-1;
curStepIdx >= 0 && stepList.size() >= curStepIdx;
curStepIdx--) {
try { try {
try {
track.getListSemaphore().acquire();
} catch (InterruptedException ex) { return; }
List<VehicleTimeRecord> step = stepList.get(curStepIdx); List<VehicleTimeRecord> step = stepList.get(curStepIdx);
int i = 0; int i = 0;
for (VehicleTimeRecord r : step) { for (VehicleTimeRecord r : step) {
int left = (int) (this.pixelPerVehicle * r.getPosition()); int left = (int) (this.pixelPerVehicle * r.getPosition());
int compensate = Math.round(r.getPosition()*this.tooShortPerTrackLength);
this.paint.setColor(getColor(r.getVelocity(), r.getMaxVelocity())); this.paint.setColor(getColor(r.getVelocity(), r.getMaxVelocity()));
canvas.drawRect(left, y, left + this.pixelPerVehicle - 1, canvas.drawRect(left+compensate, y,
left + this.pixelPerVehicle - 1+compensate,
y + 10, this.paint); y + 10, this.paint);
i++; i++;
} }
track.getListSemaphore().release();
y += 10; y += 10;
} catch (ConcurrentModificationException ex) { } catch (ConcurrentModificationException ex) {
System.out.println("Concurrent Exception occured, skipping record"); System.out.println("Concurrent Exception occured, skipping record");

View File

@ -4,6 +4,8 @@ import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Observable; import java.util.Observable;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.LockSupport;
public class Track extends Observable { public class Track extends Observable {
protected List<Vehicle> vehicles; protected List<Vehicle> vehicles;
@ -18,6 +20,8 @@ public class Track extends Observable {
protected int waitTime; protected int waitTime;
protected float maxVelocity; protected float maxVelocity;
protected float brakeProb; protected float brakeProb;
protected long steps;
protected Semaphore listSemaphore;
public List<List<VehicleTimeRecord>> getVtrList() { return vtrList; } public List<List<VehicleTimeRecord>> getVtrList() { return vtrList; }
public float getOverallAvg() { public float getOverallAvg() {
@ -33,8 +37,10 @@ public class Track extends Observable {
public float getTrackLength() { public float getTrackLength() {
return trackLength; return trackLength;
} }
public long getSteps() { return steps; }
public Semaphore getListSemaphore() { return listSemaphore; }
public Track(int numberVehicles, float trackLength, float brakeProb, float maxVelocity, int waitTime) { public Track(int numberVehicles, float trackLength, float brakeProb, float maxVelocity, int waitTime, int historyLength) {
this.trackLength = trackLength; this.trackLength = trackLength;
this.brakeProb = brakeProb; this.brakeProb = brakeProb;
this.maxVelocity = maxVelocity; this.maxVelocity = maxVelocity;
@ -45,8 +51,10 @@ public class Track extends Observable {
this.overallAvg = 0; this.overallAvg = 0;
this.delayedAvg = 0; this.delayedAvg = 0;
this.lastAvg = 0; this.lastAvg = 0;
this.historyLength = 25; this.historyLength = historyLength;
this.waitTime = waitTime; this.waitTime = waitTime;
this.steps = 0;
this.listSemaphore = new Semaphore(1);
} }
@ -90,17 +98,28 @@ public class Track extends Observable {
} }
v.updateVelocity(distanceForerunner); v.updateVelocity(distanceForerunner);
} }
try {
this.listSemaphore.acquire();
} catch (InterruptedException ex) {return;}
List <VehicleTimeRecord> records = new ArrayList<>(vehicles.size()); List <VehicleTimeRecord> records = new ArrayList<>(vehicles.size());
this.vtrList.add(records); this.vtrList.add(records);
if (this.vtrList.size() > this.historyLength) {
this.vtrList.remove(0);
}
for(Vehicle v: vehicles){ for(Vehicle v: vehicles){
v.timeElapse(); v.timeElapse();
VehicleTimeRecord vtr = new VehicleTimeRecord(v.id, v.position, v.curVelocity, v.maxVelocity); VehicleTimeRecord vtr = new VehicleTimeRecord(v.id, v.position, v.curVelocity, v.maxVelocity);
records.add(vtr); records.add(vtr);
} }
steps++;
this.listSemaphore.release();
update_avg(); update_avg();
this.setChanged(); this.setChanged();
this.notifyObservers(); this.notifyObservers();
this.clearChanged(); this.clearChanged();
LockSupport.parkNanos(1);
try { try {
Thread.sleep(waitTime); Thread.sleep(waitTime);
} catch (InterruptedException ex) { } } catch (InterruptedException ex) { }
@ -116,12 +135,12 @@ 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) { if (this.steps > 10) {
sumDelAvgMemory += lastAvg; sumDelAvgMemory += lastAvg;
delayedAvg = sumDelAvgMemory / (vtrList.size() - 10); delayedAvg = sumDelAvgMemory / (this.steps - 10);
} }
sumAvgMemory += lastAvg; sumAvgMemory += lastAvg;
overallAvg = sumAvgMemory / vtrList.size(); overallAvg = sumAvgMemory / this.steps;
} }

View File

@ -46,7 +46,6 @@ public class Vehicle {
curVelocity = curVelocity + 1; curVelocity = curVelocity + 1;
} }
if (r < brakeProb && curVelocity > 0) { if (r < brakeProb && curVelocity > 0) {
System.out.println("vehicle: "+brakeProb);
curVelocity = curVelocity - 1; curVelocity = curVelocity - 1;
} }
if (curVelocity > distanceForerunner) { if (curVelocity > distanceForerunner) {