public Bus(IVehicle.Physics p) { length = (GlobalRandom.Instance.Next(2) == 0) ? 120 : 180; _physics = p; color = Color.FromArgb(GlobalRandom.Instance.Next(256), GlobalRandom.Instance.Next(256), GlobalRandom.Instance.Next(256)); _vehicleType = VehicleTypes.BUS; // maximale Beschleunigung a = 0.9; // komfortable Bremsverzögerung b = 1.0; }
public Tram(IVehicle.Physics p) { length = (GlobalRandom.Instance.Next(2) == 0) ? 250 : 400; _physics = p; color = Color.FromArgb(GlobalRandom.Instance.Next(256), GlobalRandom.Instance.Next(256), GlobalRandom.Instance.Next(256)); // maximale Beschleunigung a = 1.0; // komfortable Bremsverzögerung b = 1.0; _vehicleType = VehicleTypes.TRAM; }
public Car(IVehicle.Physics p) { length = GlobalRandom.Instance.Next(28, 45); _physics = p; // etwas Zufall: a *= (GlobalRandom.Instance.NextDouble() + 0.5); b *= (GlobalRandom.Instance.NextDouble() + 0.5); s0 *= (GlobalRandom.Instance.NextDouble() + 0.5); T *= (GlobalRandom.Instance.NextDouble() + 0.5); _physics.targetVelocity += ((GlobalRandom.Instance.NextDouble() - 0.5) * 4); color = Color.FromArgb(GlobalRandom.Instance.Next(256), GlobalRandom.Instance.Next(256), GlobalRandom.Instance.Next(256)); _vehicleType = VehicleTypes.CAR; }
public Truck(IVehicle.Physics p) { length = (GlobalRandom.Instance.Next(2) == 0) ? 100 : 165; _physics = p; color = Color.FromArgb(GlobalRandom.Instance.Next(256), GlobalRandom.Instance.Next(256), GlobalRandom.Instance.Next(256)); // maximale Beschleunigung a = 0.6; // komfortable Bremsverzögerung b = 0.7; // etwas Zufall: a *= (GlobalRandom.Instance.NextDouble() + 0.5); b *= (GlobalRandom.Instance.NextDouble() + 0.5); s0 *= (GlobalRandom.Instance.NextDouble() + 0.5); T *= (GlobalRandom.Instance.NextDouble() + 0.5); _physics.targetVelocity += ((GlobalRandom.Instance.NextDouble() - 0.5) * 4); _vehicleType = VehicleTypes.CAR; }
/// <summary> /// Creates new VehicleDiedEventArgs /// </summary> /// <param name="vehicleStatistics">Statistics record of the died vehicle</param> /// <param name="reachedDestination">Flag, whether the vehicle reached its destination or not</param> public VehicleDiedEventArgs(IVehicle.Statistics vehicleStatistics, bool reachedDestination) { this.vehicleStatistics = vehicleStatistics; this.reachedDestination = reachedDestination; }
/// <summary> /// Sets the LineChangeVehicleInteraction: otherVehicle will be told to wait for me to change line. Therefore, it will try to keep behind myTailPositionOnTargetConnection. /// </summary> /// <param name="lineChangingVehicle">vehicle, that wants to change line</param> /// <param name="otherVehicle">vehicle on the target connection, that will wait for me to change line</param> /// <param name="targetConnection">Target NodeConnection</param> /// <param name="myTailPositionOnTargetConnection">My projected tail position on targetConnection. otherVehicle will try to keep behind this arc position.</param> public void SetLineChangeVehicleInteraction(IVehicle lineChangingVehicle, IVehicle otherVehicle, NodeConnection targetConnection, double myTailPositionOnTargetConnection) { UnsetLineChangeVehicleInteraction(); if (otherVehicle.currentNodeConnection == targetConnection && myTailPositionOnTargetConnection >= 0) { // Make sure that no two LineChangeVehicleInteractions cross each other: // Therefore, we here check die vehicles on the two NodeConnections of the LineChangePoint. This simplifies the algorithm and should be enough here. LinkedListNode<IVehicle> myNode = lineChangingVehicle.listNode.Previous; while (myNode != null) { // we have found a vehicle (call it vehicle B) behind me waiting for another vehicle (call it vehicle C) changing line if (myNode.Value._state.letVehicleChangeLine) { // check whether vehicle C is in front of the vehicle, that will wait for me if (myNode.Value._state.vehicleToChangeLine.currentPosition > otherVehicle.currentPosition) { // We have found two LineChangeVehicleInteraction crossing each other. To solve the problem, simply let vehicle C wait for me. otherVehicle = myNode.Value._state.vehicleToChangeLine; break; } } myNode = myNode.Previous; } m_vehicleThatLetsMeChangeLine = otherVehicle; otherVehicle._state.m_letVehicleChangeLine = true; otherVehicle._state.m_tailPositionOfOtherVehicle = myTailPositionOnTargetConnection; otherVehicle._state.m_vehicleToChangeLine = lineChangingVehicle; } else { // TODO: think about s.th. clever to do in this case. :) } }
/// <summary> /// Resets the LineChangeVehicleInteraction: If another vehicle is waiting for me to change line, it will not continue to do so. /// </summary> public void UnsetLineChangeVehicleInteraction() { if (m_vehicleThatLetsMeChangeLine != null) { m_vehicleThatLetsMeChangeLine._state.m_letVehicleChangeLine = false; m_vehicleThatLetsMeChangeLine._state.m_vehicleToChangeLine = null; } m_vehicleThatLetsMeChangeLine = null; }
/// <summary> /// Konstruktor, der nur die Position initialisiert. Der Rest ist uninitialisiert! /// </summary> /// <param name="p">Zeitposition auf der Linie</param> public State(double p) { currentNodeConnection = null; m_Position = p; m_PositionAbs = null; m_Orientation = null; m_letVehicleChangeLine = false; m_tailPositionOfOtherVehicle = 0; m_vehicleThatLetsMeChangeLine = null; m_vehicleToChangeLine = null; _freeDrive = true; }
/// <summary> /// Standardkonstruktor, benötigt eine Nodeconnection und Zeitposition. Der Rest wird intern berechnet /// </summary> /// <param name="nc">aktuelle NodeConnection</param> /// <param name="p">Zeitposition auf nc</param> public State(NodeConnection nc, double p) { currentNodeConnection = nc; m_Position = p; double t = currentNodeConnection.lineSegment.PosToTime(p); m_PositionAbs = currentNodeConnection.lineSegment.AtTime(t); m_Orientation = currentNodeConnection.lineSegment.DerivateAtTime(t); m_letVehicleChangeLine = false; m_tailPositionOfOtherVehicle = 0; m_vehicleThatLetsMeChangeLine = null; m_vehicleToChangeLine = null; _freeDrive = true; }
/// <summary> /// Updates the already registered vehicle v crossing on nc. /// </summary> /// <param name="v">Vehicle to update (must already be registered!).</param> /// <param name="nc">NodeConnection the vehicle is going to use (must participate on this Intersection!).</param> /// <param name="willWaitInFrontOfIntersection">Set true if vehicle will wait before intersection (and thus not cross it in the meantime).</param> public void UpdateVehicle(IVehicle v, NodeConnection nc, bool willWaitInFrontOfIntersection) { Debug.Assert(nc == _aConnection || nc == _bConnection); if (nc == _aConnection) { Debug.Assert(aCrossingVehicles.ContainsKey(v)); CrossingVehicleTimes cvt = aCrossingVehicles[v]; // CrossingVehicleTimes is a Value-Type! cvt.willWaitInFrontOfIntersection = willWaitInFrontOfIntersection; aCrossingVehicles[v] = cvt; } else { Debug.Assert(bCrossingVehicles.ContainsKey(v)); CrossingVehicleTimes cvt = bCrossingVehicles[v]; // CrossingVehicleTimes is a Value-Type! cvt.willWaitInFrontOfIntersection = willWaitInFrontOfIntersection; bCrossingVehicles[v] = cvt; } }
/// <summary> /// Standardkonstruktor /// </summary> /// <param name="vehicleType">Fahrzeugtyp</param> /// <param name="startNodes">Liste von Startknoten</param> /// <param name="endNodes">Liste von Zielknoten</param> /// <param name="trafficDensity">Häufigkeit in Ticks</param> public Auftrag(IVehicle.VehicleTypes vehicleType, List<LineNode> startNodes, List<LineNode> endNodes, int trafficDensity) { this.m_vehicleType = vehicleType; foreach (LineNode ln in startNodes) this.startNodes.Add(ln); foreach (LineNode ln in endNodes) this.endNodes.Add(ln); this.trafficDensity = trafficDensity; }
/// <summary> /// Standardkonstruktor /// </summary> /// <param name="vehicle">Fahrzeug, welches gekapselt wird</param> /// <param name="distance">Distanz, die gekapselt wird</param> /// <param name="time">Zeit, die gekapselt wird</param> public VehicleDistanceTime(IVehicle vehicle, double distance, double time) { this.distance = distance; this.vehicle = vehicle; this.time = time; }
/// <summary> /// To be called, when a vehicle which was spawned by this TrafficVolume has died /// </summary> /// <param name="sender">sender</param> /// <param name="e">VehicleDiedEventArgs</param> public void SpawnedVehicleDied(object sender, IVehicle.VehicleDiedEventArgs e) { ++_statistics.numVehicles; if (e.reachedDestination) ++_statistics.numVehiclesReachedDestination; _statistics.numStops += e.vehicleStatistics.numStops; _statistics.sumMilage += e.vehicleStatistics.totalMilage; _statistics.sumTravelTime += GlobalTime.Instance.currentTime - e.vehicleStatistics.startTime; }
void Handler_VehicleLeftNodeConnection(object sender, IVehicle.VehicleLeftNodeConnectionEventArgs e) { float averageSpeed = (float)((e.partsUsed.right - e.partsUsed.left) / (10 * (e.timeInterval.right - e.timeInterval.left))); if (averageSpeed > 0) { _countOfVehicles++; _sumOfAverageSpeeds += averageSpeed; if (_visualizeAverageSpeed) UpdatePen(); } }
/// <summary> /// Fügt der Linie ein Auto hinzu und sorgt dafür /// </summary> /// <param name="veh">hinzuzufügendes Vehicle</param> /// <returns>true, if Vehicle was successfully created - otherwise false</returns> public bool AddVehicle(IVehicle veh) { if (CanSpawnVehicleAt(0)) { AddVehicleAt(veh, 0); return true; } return false; }
/// <summary> /// Konstruktor, der nur die Position initialisiert. Der Rest ist uninitialisiert! /// </summary> /// <param name="p">Zeitposition auf der Linie</param> public State(double p) { currentNodeConnection = null; m_Position = p; m_PositionAbs = new Vector2(); m_Orientation = new Vector2(); m_letVehicleChangeLine = false; m_tailPositionOfOtherVehicle = 0; m_vehicleThatLetsMeChangeLine = null; m_vehicleToChangeLine = null; m_BrkLightState = 0; _freeDrive = true; m_TurnLightState.Left = 0; m_TurnLightState.Right = 0; m_Speed = 0.0; }
/// <summary> /// Unregisters the given vehicle from this intersection. /// </summary> /// <param name="v">Vehicle to unregister (must already be registered!).</param> /// <param name="nc">NodeConnection the vehicle is going to use (must participate on this Intersection!).</param> public void UnregisterVehicle(IVehicle v, NodeConnection nc) { Debug.Assert(nc == _aConnection || nc == _bConnection); if (nc == _aConnection) { Debug.Assert(aCrossingVehicles.ContainsKey(v)); aCrossingVehicles.Remove(v); } else { Debug.Assert(bCrossingVehicles.ContainsKey(v)); bCrossingVehicles.Remove(v); } }
private double CalculateArrivingTime(IVehicle v, double distance) { if (v.state._freeDrive) { //double timeToArrive = (v.physics.desiredVelocity * Math2.Acosh (Math.Exp(v.a * distance / Math2.Square(v.physics.desiredVelocity)))) / (10 * v.a); return v.GetTimeToCoverDistance(distance, false);//timeToArrive; } else { return v.GetTimeToCoverDistance(distance, true); } }
/// <summary> /// Registers that the given vehicle is going to cross this intersection via the given NodeConnection. /// </summary> /// <param name="v">Vehicle to cross intersection (must not be registered yet!).</param> /// <param name="nc">NodeConnection the vehicle is going to use (must participate on this Intersection!).</param> /// <param name="distance">Current distance of the vehicle to the Intersection</param> /// <param name="currentTime">current world time.</param> public void RegisterVehicle(IVehicle v, NodeConnection nc, double distance, double currentTime) { Debug.Assert(nc == _aConnection || nc == _bConnection); // TODO: add some safety space before and behind double blockingStartTime = currentTime + CalculateArrivingTime(v, distance - (_frontWaitingDistance / 2)) - v.SafetyTime/8; double blockingEndTime = currentTime + CalculateArrivingTime(v, distance + v.length) + v.SafetyTime/8; double originalArrivingTime = currentTime + v.GetTimeToCoverDistance(distance, false); if (nc == _aConnection) { //if (aCrossingVehicles.ContainsKey(v)) //{ aCrossingVehicles.Add(v, new CrossingVehicleTimes(originalArrivingTime, distance, new Interval<double>(blockingStartTime, blockingEndTime), false)); // } } else { // if (bCrossingVehicles.ContainsKey(v)) // { bCrossingVehicles.Add(v, new CrossingVehicleTimes(originalArrivingTime, distance, new Interval<double>(blockingStartTime, blockingEndTime), false)); /* } */ } }
/// <summary> /// Returns the CrossingVehicleTimes data of the given vehicle. /// </summary> /// <param name="v">Vehicle to search for (must already be registered!).</param> /// <param name="nc">NodeConnection the vehicle is going to use (must participate on this Intersection!).</param> /// <returns>The CrossingVehicleTimes data of the given vehicle.</returns> public CrossingVehicleTimes GetCrossingVehicleTimes(IVehicle v, NodeConnection nc) { Debug.Assert(nc == _aConnection || nc == _bConnection); if (nc == _aConnection) { Debug.Assert(aCrossingVehicles.ContainsKey(v)); return aCrossingVehicles[v]; } else { Debug.Assert(bCrossingVehicles.ContainsKey(v)); return bCrossingVehicles[v]; } }
/// <summary> /// fügt das IVehicle v an der Position arcPosition ein und sorgt dabei für eine weiterhin korrekte Verkettung von m_vehicles /// </summary> /// <param name="v">einzufügendes Auto</param> /// <param name="arcPosition">Bogenlängenposition, wo das Auto eingefügt werden soll</param> public void AddVehicleAt(IVehicle v, double arcPosition) { LinkedListNode<IVehicle> lln = GetVehicleListNodeBehindArcPosition(arcPosition); if (lln != null) { if (lln.Value.currentPosition - lln.Value.length < arcPosition) { throw new Exception("Das neue Fahrzeug überlappt sich mit einem anderen Fahrzeug!"); } v.listNode = vehicles.AddBefore(lln, v); } else { v.listNode = vehicles.AddLast(v); } v.VehicleLeftNodeConnection += new IVehicle.VehicleLeftNodeConnectionEventHandler(Handler_VehicleLeftNodeConnection); }
/// <summary> /// Updates the already registered vehicle v crossing on nc. /// </summary> /// <param name="v">Vehicle to update (must already be registered!).</param> /// <param name="nc">NodeConnection the vehicle is going to use (must participate on this Intersection!).</param> /// <param name="distance">Current distance of the vehicle to the Intersection</param> /// <param name="currentTime">current world time.</param> public void UpdateVehicle(IVehicle v, NodeConnection nc, double distance, double currentTime) { Debug.Assert(nc == _aConnection || nc == _bConnection); // TODO: add some safety space before and behind double blockingStartTime = currentTime + CalculateArrivingTime(v, distance - (_frontWaitingDistance / 2)) - v.SafetyTime / 8; double blockingEndTime = currentTime + CalculateArrivingTime(v, distance + v.length) + v.SafetyTime / 8; if (nc == _aConnection) { Debug.Assert(aCrossingVehicles.ContainsKey(v)); CrossingVehicleTimes cvt = aCrossingVehicles[v]; // CrossingVehicleTimes is a Value-Type! cvt.remainingDistance = distance; cvt.blockingTime.left = blockingStartTime; cvt.blockingTime.right = blockingEndTime; aCrossingVehicles[v] = cvt; } else { Debug.Assert(bCrossingVehicles.ContainsKey(v)); CrossingVehicleTimes cvt = bCrossingVehicles[v]; // CrossingVehicleTimes is a Value-Type! cvt.remainingDistance = distance; cvt.blockingTime.left = blockingStartTime; cvt.blockingTime.right = blockingEndTime; bCrossingVehicles[v] = cvt; } }
/// <summary> /// Standardkonstruktor /// </summary> /// <param name="vehicle">Fahrzeug, welches gekapselt wird</param> /// <param name="distance">Distanz, die gekapselt wird</param> public VehicleDistance(IVehicle vehicle, double distance) { this.distance = distance; this.vehicle = vehicle; }
/// <summary> /// Meldet das IVehicle v von dieser NodeConnection ab. (Effektiv wird dieses Auto erst am Ende des Ticks entfernt) /// </summary> /// <param name="v">zu entfernendes Auto</param> public void RemoveVehicle(IVehicle v) { if (! vehicles.Contains(v)) { throw new Exception("Vehicle " + v + " nicht auf dieser NodeConnection!"); } vehiclesToRemove.Add(v); }
/// <summary> /// Creates new VehicleSpawnedEventArgs /// </summary> /// <param name="v">The vehicle to spawn</param> /// <param name="tv">Corresponding TrafficVolume</param> public VehicleSpawnedEventArgs(IVehicle v, TrafficVolume tv) { this.vehicleToSpawn = v; this.tv = tv; }
/// <summary> /// Calculates all interfering vehicles from registered vehicles. /// </summary> public List<CrossingVehicleTimes> CalculateInterferingVehicles(IVehicle v, NodeConnection nc) { Debug.Assert(nc == _aConnection || nc == _bConnection); // hopefully these are references... ;) List<CrossingVehicleTimes> toReturn = new List<CrossingVehicleTimes>(); Dictionary<IVehicle, CrossingVehicleTimes> myCrossingVehicles = (nc == _aConnection ? aCrossingVehicles : bCrossingVehicles); Dictionary<IVehicle, CrossingVehicleTimes> otherCrossingVehicles = (nc == _aConnection ? bCrossingVehicles : aCrossingVehicles); CrossingVehicleTimes myCvt = myCrossingVehicles[v]; if (_aConnection.startNode != _bConnection.startNode || (_frontWaitingDistance < aArcPosition && _frontWaitingDistance < bArcPosition)) { // check each vehicle in aCrossingVehicles with each in bCrossingVehicles for interference foreach (KeyValuePair<IVehicle, CrossingVehicleTimes> ocv in otherCrossingVehicles) { if ( (!ocv.Value.willWaitInFrontOfIntersection || ocv.Value.remainingDistance < 0) && myCvt.blockingTime.IntersectsTrue(ocv.Value.blockingTime)) { toReturn.Add(ocv.Value); } } } return toReturn; }