private int startPosn; // Starting position of front edge of platoon #endregion Fields #region Constructors /// <summary> /// Class constructor /// </summary> /// <param name="_vehicles">Array of vehicles to be included in platoon</param> /// <param name="_sizeLimit">Max number of vehicles in platoon</param> /// <param name="_initDirn">Initial direction</param> /// <param name="_initSpeed">Initial speed</param> /// <param name="_initPosn">Initial position</param> /// <param name="_r">Reference of road on which it is moving</param> public Platoon(Vehicle[] _vehicles, int _sizeLimit, int _initDirn, int _initSpeed, int _initPosn, Road _r) { vehicles = new ArrayList(_vehicles); this.sizeLimit = _sizeLimit; this.dirn = _initDirn; this.currSpeed = _initSpeed; this.currPosn = _initPosn; this.startPosn = _initPosn; this.r = _r; this.interPlatoonDist = r.getInputParameters().interPlatoonDist; this.intraPlatoonDist = r.getInputParameters().intraPlatoonDist; this.speedLimit = r.getSpeedLimit(); if(this.currPosn != this.r.getStartPosition() && (dirn == Direction.NS || dirn == Direction.EW)) { Console.WriteLine("NS/EW Platoon starting at " + _initPosn ); } if(this.currPosn != this.r.getEndPosition() && (dirn == Direction.SN || dirn == Direction.WE)) { Console.WriteLine("SN/WE Platoon starting at " + _initPosn); } /** * Platoon length is the sum of the lengths of all vehicles and the sum of the length of intra-platoon distance for * all but the first vehicle. */ platoonLen = vehicles.Count * r.getInputParameters().vehicleLen + (vehicles.Count - 1) * intraPlatoonDist; platoonID = totalPlatoons++; #if DDEBUG Console.WriteLine("Platoon " + totalPlatoons + " created"); #endif }
/// <summary> /// Helper method used by createPlatoon to create platoons. /// </summary> /// <param name="currTime">Current time</param> /// <param name="laneID">Lane ID for which platoon must be created 0 - downLane, 1 - upLane</param> private void createPlatoonHelper(int currTime, int laneID) { Platoon p; // Temp object Platoon int posn; // Rear position of last platoon on that lane int numVeh; // Number of vehicles to add in platoon int startPt; // Starting position for platoon Vehicle []v; // Array of vehicles to add to platoon int platoonDirn;// Platoon's direction Queue waitQ; // Waiting queue ArrayList lane; // Lane /** * Select values corresponding to either downlane or uplane */ if(laneID == 0) { lane = downLane; waitQ = downQueue; startPt = this.startPos; // For downlane, direction is either NS or EW if(orient == RoadOrientation.NS) platoonDirn = Direction.NS; else platoonDirn = Direction.EW; } else { lane = upLane; waitQ = upQueue; startPt = this.endPos; // For upLane, direction is either SN or WE if(orient == RoadOrientation.NS) platoonDirn = Direction.SN; else platoonDirn = Direction.WE; } /** * If this is the time to create a platoon and some vehicles are waiting to join a platoon * then only create a platoon. */ if((currTime % period == 0) && (waitQ.Count > 0)) { /** * Get the position of the last platoon on that lane. */ if(lane.Count > 0) { p = (Platoon) lane[lane.Count - 1]; posn = p.rearPosition(); /** * If there isn't place to create a new platoon such that minimum inter platoon distance * is maintained with last platoon on that lane, don't attempt to create a platoon and return. */ if(laneID == 0) { if(posn < this.startPos + ip.interPlatoonDist) { /** * Increment platoon not created counter. */ roadCntr.incrementPlatoonNotCreatedCount(); return; } } else { if(this.endPos - posn < ip.interPlatoonDist) { /** * Increment platoon not created counter. */ roadCntr.incrementPlatoonNotCreatedCount(); return; } } } // Get how many vehicles to add to this platoon numVeh = Math.Min(numVehiclesInPlatoon, waitQ.Count); v = new Vehicle[numVeh]; // Remove those many vehicles from the waiting queue for(int i = 0; i < numVeh; i++) { v[i] = (Vehicle) waitQ.Dequeue(); // Set vehicles start journey time - this determines vehicle's wait time v[i].setStartJourneyTime(currTime); } p = new Platoon(v, numVehiclesInPlatoon, platoonDirn, travelSpeed, startPt, this); if(laneID == 1) { // Console.WriteLine("Platoon created at posn {0} Dirn {1} on Road {2} Orient {3}", startPt, platoonDirn, this.roadNum, this.orient); } lane.Add(p); /** * Update platoon arrival counter in road perf counter */ roadCntr.platoonCreated(); } }
/// <summary> /// Helper method to add vehicles to downQueue or upQueue /// </summary> /// <param name="currTime">Current time</param> /// <param name="q">Queue to add vehicles to</param> private void addVehiclesToQueue(int currTime, Queue q) { Vehicle v; int numArrivals; /** * When arrivals are to be generated using poisson process */ numArrivals = pG.getNumArrivals(ip.getArrivalRate(this.orient, this.roadNum), this.rN); /** * Log vehicle arrival only for NS and EW directions, not for SN and WE directions */ if(q == downQueue) ns.logArrivals(currTime, numArrivals, this.roadNum, this.orient); for(int i = 0; i < numArrivals; i++) { v = new Vehicle(currTime, ip.vehicleLen, null); q.Enqueue(v); /** * Update vehicle arrival counter here */ roadCntr.vehicleCreated(); } }
/// <summary> /// Method to add vehicles to input queue based on reading arrivals from an input file /// </summary> /// <param name="currTime"></param> private void addVehiclesUsingInputLog(int currTime) { int numArrivals; int dirn; Vehicle v; // Since we have data only for NS and EW direction, we only add to downQueue if (this.orient == RoadOrientation.NS) dirn = Direction.NS; else dirn = Direction.EW; numArrivals = ip.getNumCars(this.roadNum, dirn, currTime); for (int i = 0; i < numArrivals; i++) { v = new Vehicle(currTime, ip.vehicleLen, null); downQueue.Enqueue(v); roadCntr.vehicleCreated(); } }
/// <summary> /// Computes the statistics for all the platoons in the system /// </summary> /// <param name="currTime">Current Time</param> public void getRoadPlatoonStatistics(int currTime) { Platoon p; /** * Add the counters for all the platoons in transit. */ for(int i = 0; i < downLane.Count; i++) { p = (Platoon) downLane[i]; roadCntr.addPlatoonCounter(p.getCounters(currTime)); } for(int i = 0; i < upLane.Count; i++) { p = (Platoon) upLane[i]; roadCntr.addPlatoonCounter(p.getCounters(currTime)); } /** * Create a new platoon containing all the vehicles in the holding queue and then * add that to the roadCntr so that transit time of these vehicles get counted also. */ Vehicle []v = new Vehicle[downQueue.Count]; int cnt = downQueue.Count; for(int i = 0; i < cnt; i++) { v[i] = (Vehicle) downQueue.Dequeue(); } p = new Platoon(v, v.Length, Direction.NS, ip.speedLimit, 0, this); roadCntr.addPlatoonCounter(p.getCounters(currTime)); /** * Do the same for up queue */ v = new Vehicle[upQueue.Count]; cnt = upQueue.Count; for(int i = 0; i < cnt; i++) { v[i] = (Vehicle) upQueue.Dequeue(); } p = new Platoon(v, v.Length, Direction.SN, ip.speedLimit, 0, this); roadCntr.addPlatoonCounter(p.getCounters(currTime)); }