You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

301 lines
7.6KB

  1. package de.hems.trafficsim;
  2. import java.util.ArrayList;
  3. import java.util.LinkedList;
  4. import java.util.List;
  5. import java.util.Observable;
  6. import java.util.concurrent.Semaphore;
  7. /**
  8. * Main model class of TrafficSim. Represents a round course containing vehicles.
  9. */
  10. public class Track extends Observable {
  11. /**
  12. * list a vehicles on the track
  13. */
  14. final protected List<Vehicle> vehicles;
  15. /**
  16. * list of resulting time records of the simulation
  17. */
  18. final protected List<List<VehicleTimeRecord>> vtrList;
  19. /**
  20. * length of the track
  21. */
  22. final protected float trackLength;
  23. /**
  24. * sum of all vehicle speeds during the simulation, used for average calculation
  25. */
  26. protected float sumAvgMemory;
  27. /**
  28. * sum of all vehicle speeds during the simulation ignoring the first ten steps,
  29. * used for average calculation
  30. */
  31. protected float sumDelAvgMemory;
  32. /**
  33. * length of the history kept
  34. */
  35. final protected int historyLength;
  36. /**
  37. * average over all velocities in the simulation
  38. */
  39. protected float overallAvg;
  40. /**
  41. * average over all velocities in the simulation, ignoring the first ten steps
  42. */
  43. protected float delayedAvg;
  44. /**
  45. * average over all velocities in the last step
  46. */
  47. protected float lastAvg;
  48. /**
  49. * current configured wait time between two simulation steps
  50. */
  51. protected int waitTime;
  52. /**
  53. * currently configured max velocity for all vehicles
  54. */
  55. final protected float maxVelocity;
  56. /**
  57. * currently configured brake probability for all vehicles
  58. */
  59. final protected float brakeProb;
  60. /**
  61. * counter for executed simulation steps
  62. */
  63. protected long steps;
  64. /**
  65. * semaphore protecting the vtrlist
  66. */
  67. final protected Semaphore listSemaphore;
  68. /**
  69. * Constructor for a new Track.
  70. *
  71. * @param numberVehicles number of vehicles on the Track
  72. * @param trackLength length of the new Track
  73. * @param brakeProb probability of a vehicle to suddenly brake without reason
  74. * @param maxVelocity maxmimum velocity of the vehicles
  75. * @param waitTime time between two simulation steps to slow down the simulation artificially
  76. * @param historyLength length of the history to keep
  77. */
  78. public Track(int numberVehicles, float trackLength, float brakeProb, float maxVelocity, int waitTime, int historyLength) {
  79. this.trackLength = trackLength;
  80. this.brakeProb = brakeProb;
  81. this.maxVelocity = maxVelocity;
  82. this.vehicles = createVehiclesList(numberVehicles);
  83. this.vtrList = new LinkedList<>();
  84. this.sumAvgMemory = 0;
  85. this.sumDelAvgMemory = 0;
  86. this.overallAvg = 0;
  87. this.delayedAvg = 0;
  88. this.lastAvg = 0;
  89. this.historyLength = historyLength;
  90. this.waitTime = waitTime;
  91. this.steps = 0;
  92. this.listSemaphore = new Semaphore(1);
  93. }
  94. /**
  95. * Getter for vtrList
  96. *
  97. * @return vtrList
  98. */
  99. public List<List<VehicleTimeRecord>> getVtrList() {
  100. return vtrList;
  101. }
  102. /**
  103. * Getter for overallAvg
  104. *
  105. * @return overallAvg
  106. */
  107. public float getOverallAvg() {
  108. return overallAvg;
  109. }
  110. /**
  111. * Getter for lastAvg
  112. *
  113. * @return lastAvg
  114. */
  115. public float getLastAvg() {
  116. return lastAvg;
  117. }
  118. /**
  119. * Getter for delayedAvg
  120. *
  121. * @return delayedAvg
  122. */
  123. public float getDelayedAvg() {
  124. return delayedAvg;
  125. }
  126. /**
  127. * Getter for trackLength
  128. *
  129. * @return trackLength
  130. */
  131. public float getTrackLength() {
  132. return trackLength;
  133. }
  134. /**
  135. * Getter for steps
  136. *
  137. * @return steps
  138. */
  139. public long getSteps() {
  140. return steps;
  141. }
  142. /**
  143. * Getter for listSemaphore
  144. *
  145. * @return listSemaphore
  146. */
  147. public Semaphore getListSemaphore() {
  148. return listSemaphore;
  149. }
  150. /**
  151. * Getter for historyLength
  152. *
  153. * @return historyLength
  154. */
  155. public int getHistoryLength() {
  156. return historyLength;
  157. }
  158. /**
  159. * Utility function to add vehicles to the Track.
  160. *
  161. * @param numberVehicles number of vehicles to add
  162. * @return filled list with vehicles
  163. */
  164. protected List<Vehicle> createVehiclesList(int numberVehicles) {
  165. List<Vehicle> result = new ArrayList<>();
  166. for (int i = 0; i < numberVehicles; i++) {
  167. Vehicle vehicle = new Vehicle(i, i, this.maxVelocity, this.brakeProb, this.trackLength);
  168. result.add(vehicle);
  169. }
  170. return result;
  171. }
  172. /**
  173. * Update the wait time of the simulation.
  174. *
  175. * @param waitTime new wait time in ms
  176. */
  177. public void setWaitTime(int waitTime) {
  178. this.waitTime = waitTime;
  179. }
  180. /**
  181. * Update the brake probability of all vehicles.
  182. *
  183. * @param brakeProb new brake probability
  184. */
  185. public void setBrakeProb(float brakeProb) {
  186. for (Vehicle v : this.vehicles) {
  187. v.setBrakeProb(brakeProb);
  188. }
  189. }
  190. /**
  191. * Update the maximum velocity of all vehicles.
  192. *
  193. * @param maxVelocity new maximum velocity
  194. */
  195. public void setMaxVelocity(float maxVelocity) {
  196. for (Vehicle v : this.vehicles) {
  197. v.setMaxVelocity(maxVelocity);
  198. }
  199. }
  200. /**
  201. * Calculates on simulation step ahead and then waits for the configured wait time.
  202. */
  203. public void timeElapse() {
  204. for (int i = 0; i < vehicles.size(); i++) {
  205. Vehicle v = vehicles.get(i);
  206. int forerunnerIndex = i + 1;
  207. if (forerunnerIndex >= vehicles.size()) {
  208. forerunnerIndex -= vehicles.size();
  209. }
  210. Vehicle forerunner = vehicles.get(forerunnerIndex);
  211. float distanceForerunner = forerunner.getPosition() - v.getPosition() - 1;
  212. if (distanceForerunner < 0.0) {
  213. distanceForerunner += this.trackLength;
  214. }
  215. v.updateVelocity(distanceForerunner);
  216. }
  217. try {
  218. this.listSemaphore.acquire();
  219. } catch (InterruptedException ex) {return;}
  220. List <VehicleTimeRecord> records = new ArrayList<>(vehicles.size());
  221. this.vtrList.add(records);
  222. if (this.vtrList.size() > this.historyLength) {
  223. this.vtrList.remove(0);
  224. }
  225. for(Vehicle v: vehicles){
  226. v.timeElapse();
  227. VehicleTimeRecord vtr = new VehicleTimeRecord(v.position, v.curVelocity, v.maxVelocity);
  228. records.add(vtr);
  229. }
  230. steps++;
  231. this.listSemaphore.release();
  232. update_avg();
  233. try {
  234. Thread.sleep(waitTime);
  235. } catch (InterruptedException ignored) {
  236. }
  237. }
  238. /**
  239. * Returns the average velocity of the given simulation step.
  240. *
  241. * @param step index of the step in the history list
  242. * @return average velocity
  243. */
  244. public float avg_step(int step) {
  245. float sum_step = 0;
  246. for (VehicleTimeRecord r : vtrList.get(step)) {
  247. sum_step += r.velocity;
  248. }
  249. return sum_step / vehicles.size();
  250. }
  251. /**
  252. * Utility function which updates the averages values with the results from the last simulation
  253. * step.
  254. */
  255. protected void update_avg() {
  256. lastAvg = avg_step(vtrList.size() - 1);
  257. if (this.steps > 10) {
  258. sumDelAvgMemory += lastAvg;
  259. delayedAvg = sumDelAvgMemory / (this.steps - 10);
  260. }
  261. sumAvgMemory += lastAvg;
  262. overallAvg = sumAvgMemory / this.steps;
  263. }
  264. }