diff --git a/src/Solution1/ConsoleApp1/ConsoleApp1.csproj b/src/Solution1/ConsoleApp1/ConsoleApp1.csproj index 84e424c..5694124 100644 --- a/src/Solution1/ConsoleApp1/ConsoleApp1.csproj +++ b/src/Solution1/ConsoleApp1/ConsoleApp1.csproj @@ -28,4 +28,10 @@ + + + + + + diff --git a/src/Solution1/ConsoleApp1/Program.cs b/src/Solution1/ConsoleApp1/Program.cs index 59f6f82..c241dea 100644 --- a/src/Solution1/ConsoleApp1/Program.cs +++ b/src/Solution1/ConsoleApp1/Program.cs @@ -58,7 +58,7 @@ var cruisers = await Task.WhenAll(cruiserClients); var parkerClients = Enumerable.Range(0, parkerCount) - .Select(i => CarClient.Create(mqttClientFactory, new RandomParkerClientBehaviour(), physicalWorld, pgs, i, true)); + .Select(i => CarClient.Create(mqttClientFactory, new RandomParkerClientBehaviour(), physicalWorld, pgs, i, false)); var parkers = await Task.WhenAll(parkerClients); // init parkers diff --git a/src/Solution1/ConsoleApp1/clients/behaviour/CruiserClientBehaviour.cs b/src/Solution1/ConsoleApp1/clients/behaviour/CruiserClientBehaviour.cs index ca89f2b..6a3e5a1 100644 --- a/src/Solution1/ConsoleApp1/clients/behaviour/CruiserClientBehaviour.cs +++ b/src/Solution1/ConsoleApp1/clients/behaviour/CruiserClientBehaviour.cs @@ -21,12 +21,7 @@ public void DriveAlongPath(MockCar car) else { // turn on next street - var overlap = car.Position.DistanceFromSource - car.Position.StreetEdge.Length; - car.Position.StreetEdge.DecrementCarCount(); - car.Position = new StreetPosition(car.Path.First(), overlap); - car.Position.StreetEdge.IncrementCarCount(); - car.Path = car.Path.Skip(1); - + car.Turn(car.Path.First()); if(car.Logging) Console.WriteLine($"{car}\ttick | {car.Position.ToString()} | dest: {car.Destination.Id} | car count: {car.Position.StreetEdge.CarCount} | driving at {car.Position.StreetEdge.CurrentMaxSpeed():F2}kmh/{car.Position.StreetEdge.SpeedLimit:F2}kmh"); } diff --git a/src/Solution1/ConsoleApp1/clients/behaviour/RandomParkerClientBehaviour.cs b/src/Solution1/ConsoleApp1/clients/behaviour/RandomParkerClientBehaviour.cs index ca24655..c7c534d 100644 --- a/src/Solution1/ConsoleApp1/clients/behaviour/RandomParkerClientBehaviour.cs +++ b/src/Solution1/ConsoleApp1/clients/behaviour/RandomParkerClientBehaviour.cs @@ -50,6 +50,7 @@ public bool AttemptLocalParking(MockCar car) passedParkingSpots.Pop(); } + // no free parking spot if (passedParkingSpots.Count == 0) return false; // occupy @@ -60,7 +61,8 @@ public bool AttemptLocalParking(MockCar car) // physically park car.Position = new StreetPosition(car.Position.StreetEdge, nearestUnoccupiedSpot.DistanceFromSource); - car.Position.StreetEdge.DecrementCarCount(); + // todo car.Position.StreetEdge.DecrementCarCount(); + Random rand = new Random(); car.ParkTime = rand.Next(0, MockCar.MaxParkTime + 1); @@ -69,6 +71,9 @@ public bool AttemptLocalParking(MockCar car) car.KpiManager.DistanceTravelledParking += car.Position.DistanceFromSource; // car.KpiManager.PublishAll(); TODO publish kpis with async and await + var sum =car.World.StreetEdges.Sum(edge => edge.CarCount); + Console.WriteLine($"sum: {sum}"); + return true; } diff --git a/src/Solution1/ConsoleApp1/sim/KpiManager.cs b/src/Solution1/ConsoleApp1/sim/KpiManager.cs index 2f9c0d9..9001ff4 100644 --- a/src/Solution1/ConsoleApp1/sim/KpiManager.cs +++ b/src/Solution1/ConsoleApp1/sim/KpiManager.cs @@ -21,14 +21,12 @@ public class KpiManager public double DistanceTravelledParking { get; set; } private readonly IMqttClient _mqttClient; - private MockCar _car; - private List _kpis; + private readonly MockCar _car; public KpiManager(IMqttClient mqttClient, MockCar car) { _mqttClient = mqttClient; _car = car; - _kpis = new List(); } public void Reset() @@ -45,12 +43,7 @@ public async Task Publish(Kpi kpi) await _mqttClient.PublishAsync(new MqttApplicationMessage { Topic = kpi.Topic, Payload = kpi.Payload }); } - public byte[] Encode(string obj) - { - return Encoding.UTF8.GetBytes(obj); - } - - public void PublishAll() + public async Task PublishAll() { // calc the rest double distanceFromDestination = _car.Position.StreetEdge.Length - _car.Position.DistanceFromSource; @@ -68,11 +61,11 @@ public void PublishAll() int totalCo2EmissionsParking = (int)((DistanceTravelledParking / 1000) * Co2EmissionRate); // add all - Publish(new Kpi("kpi/distFromDest", Encode(distanceFromDestination.ToString()))); - Publish(new Kpi("kpi/distTravelledParking", Encode(DistanceTravelledParking.ToString()))); - Publish(new Kpi("kpi/timeSpentParking", Encode(TicksSpentParking.ToString()))); - Publish(new Kpi("kpi/speedReduction", Encode(SpeedReductionRunningAvg.ToString()))); - Publish(new Kpi("kpi/fuelConsumption", Encode(totalFuelConsumptionParking.ToString()))); - Publish(new Kpi("kpi/parkingEmissions", Encode(totalCo2EmissionsParking.ToString()))); + await Publish(new Kpi("kpi/distFromDest", Encoding.UTF8.GetBytes(distanceFromDestination.ToString()))); + await Publish(new Kpi("kpi/distTravelledParking", Encoding.UTF8.GetBytes(DistanceTravelledParking.ToString()))); + await Publish(new Kpi("kpi/timeSpentParking", Encoding.UTF8.GetBytes(TicksSpentParking.ToString()))); + await Publish(new Kpi("kpi/speedReduction", Encoding.UTF8.GetBytes(SpeedReductionRunningAvg.ToString()))); + await Publish(new Kpi("kpi/fuelConsumption", Encoding.UTF8.GetBytes(totalFuelConsumptionParking.ToString()))); + await Publish(new Kpi("kpi/parkingEmissions", Encoding.UTF8.GetBytes(totalCo2EmissionsParking.ToString()))); } } \ No newline at end of file diff --git a/src/Solution1/ConsoleApp1/sim/MockCar.cs b/src/Solution1/ConsoleApp1/sim/MockCar.cs index cd71ae9..22883f8 100644 --- a/src/Solution1/ConsoleApp1/sim/MockCar.cs +++ b/src/Solution1/ConsoleApp1/sim/MockCar.cs @@ -47,15 +47,16 @@ public bool TargetNodeReached() public void RespawnAtRandom() { - Position.StreetEdge.DecrementCarCount(); + // todo Position.StreetEdge.DecrementCarCount(); Position = StreetPosition.WithRandomDistance(World.StreetEdges.RandomElement()); - Position.StreetEdge.IncrementCarCount(); + // todo Position.StreetEdge.IncrementCarCount(); } public void ResetAfterParking() { OccupiedSpot.Occupied = false; - Position.StreetEdge.IncrementCarCount(); + + // todo Position.StreetEdge.IncrementCarCount(); // kpi KpiManager.Reset(); @@ -63,4 +64,20 @@ public void ResetAfterParking() // diagnostics World.IncrementUnoccupiedSpotCount(); } + + public void Turn(StreetEdge next) + { + lock (Position.StreetEdge) + { + var overlap = Position.DistanceFromSource - Position.StreetEdge.Length; + var previousPosition = Position; + Position = new StreetPosition(next, overlap); + lock (Position.StreetEdge) + { + previousPosition.StreetEdge.DecrementCarCount(); + Position.StreetEdge.IncrementCarCount(); + } + Path = Path.Skip(1); + } + } } \ No newline at end of file diff --git a/src/Solution1/ConsoleApp1/sim/Street.cs b/src/Solution1/ConsoleApp1/sim/Street.cs index a96ff2c..a0291cf 100644 --- a/src/Solution1/ConsoleApp1/sim/Street.cs +++ b/src/Solution1/ConsoleApp1/sim/Street.cs @@ -1,3 +1,4 @@ +using ConsoleApp1.sim.graph; using ConsoleApp1.util; namespace ConsoleApp1.sim; @@ -5,8 +6,11 @@ namespace ConsoleApp1.sim; public record Street { public required double Length { get; init; } - public int CarCount { get; set; } public static double CarLength { get; } = 5.0; + + + public int CarCount { get; set; } + public required double SpeedLimit { get; init; } public List ParkingSpots { get; set; } = new List(); public static double ParkingSpotDensity { get; set; } = 0.5; // between 0 and 1 @@ -19,7 +23,7 @@ public record Street // todo public double CurrentMaxSpeed() { - lock (this) + lock(this) { double freeStreetLength = Length - CarCount * CarLength; double recommendedSpeed = MathUtil.GetSafeSpeedMs(freeStreetLength / CarCount); @@ -36,6 +40,7 @@ public double CurrentCoverDuration() } } + /* public (bool parkingFound, int lastPassedOrFoundIndex) TryParkingLocally(double distanceFromSource, int lastPassedIndex) { @@ -65,8 +70,9 @@ public void FreeParkingSpot(int spotIndex) lock (this) { ParkingSpots[spotIndex].Occupied = false; - CarCount++; } + + Interlocked.Increment(ref _carCount); } private int CalculateLastPassedIndex(double distanceFromSource, int lastPassedIndex) @@ -75,6 +81,9 @@ private int CalculateLastPassedIndex(double distanceFromSource, int lastPassedIn (ParkingSpots[lastPassedIndex].Length + ParkingSpotSpacing)); return Math.Min(lastPassedIndexFromDistance, ParkingSpots.Count - 1); } + */ + + public void IncrementCarCount() { diff --git a/src/Solution1/ConsoleApp1/sim/graph/StreetEdge.cs b/src/Solution1/ConsoleApp1/sim/graph/StreetEdge.cs index d2702f2..6b1bc15 100644 --- a/src/Solution1/ConsoleApp1/sim/graph/StreetEdge.cs +++ b/src/Solution1/ConsoleApp1/sim/graph/StreetEdge.cs @@ -25,6 +25,7 @@ public string? StreetName } } + public int UnoccupiedSpotCount { get; set; } public void InitParkingSpots(Dictionary parkingSpotMap) { int maxParkingSpots = (int)Math.Floor(Length / ParkingSpotLength); @@ -45,7 +46,6 @@ public void InitParkingSpots(Dictionary parkingSpotMap) ParkingSpots.ForEach(parkingSpot => parkingSpotMap.Add(parkingSpot, this)); } - public int UnoccupiedSpotCount { get; set; } public required Dictionary Tags { get; init; }