public void SegmentConfigurationShouldDeserializeFromString() { string jsonValue = @"{ ""segmentId"": ""9"", ""numberOfLanes"": 3, ""speedLimit"": 120, ""rushHours"": ""07:00-08:00,17:00-18:00"", ""maxSpeed"": 166, ""minSpeed"": 2, ""averageCarsPerMinute"": 20, ""speedingPercentage"": 3, ""cameraDistance"": 2000 }"; var segmentConfig = JsonConvert.DeserializeObject <TrafficSegmentConfiguration>(jsonValue); var config = new TrafficSegmentSituation(null, segmentConfig); Assert.NotNull(config); Assert.Equal(2, config.RushHours.Count()); TimePeriod currentRushHour; Assert.True(config.IsRushHour(new DateTime(2019, 1, 1, 7, 1, 1), out currentRushHour)); Assert.True(config.IsRushHour(new DateTime(2019, 1, 1, 17, 59, 1), out currentRushHour)); Assert.False(config.IsRushHour(new DateTime(2019, 1, 1, 8, 1, 1), out currentRushHour)); }
public async Task Run(CancellationToken cancellationToken) { SimulatedClock.Init(_simulationSettings.TimeSimulationAccelerator); var segmentId = _configurationReader.GetConfigValue <string>("SEGMENT_ID", true); var startCameraEventTransmitter = await _transmitterConfigurator.CreateTransmitter(segmentId, CameraType.Camera1); var endCameraEventTransmitter = await _transmitterConfigurator.CreateTransmitter(segmentId, CameraType.Camera2); var segmentConfiguration = await _configurator.GetConfiguration(); if (segmentConfiguration == null) { _logger.Error($"The segment configuration was not found and resulted to null"); return; } if (string.IsNullOrEmpty(segmentConfiguration.SegmentId)) { segmentConfiguration.SegmentId = segmentId; } var segmentSituation = new TrafficSegmentSituation(_configurator, segmentConfiguration); var random = new Random(); // Initialize transmitters try { while (!cancellationToken.IsCancellationRequested) { segmentSituation.Resimulate(random); var releaseInterval = TimeSpan.FromMilliseconds(Convert.ToInt32(60000 / segmentSituation.AverageCarsPerMinute)); // replace with function var currentMinute = SimulatedClock.Time.Minute; while (SimulatedClock.Time.Minute == currentMinute) { cancellationToken.ThrowIfCancellationRequested(); Task.Factory.StartNew(() => MakeOneCarDrive(random, segmentConfiguration, segmentSituation, startCameraEventTransmitter, endCameraEventTransmitter, cancellationToken), cancellationToken); await Task.Delay(releaseInterval, cancellationToken); } } } catch (TaskCanceledException) { } catch (Exception ex) { _logger.Error(ex, "Error happened in the simulator: " + ex.ToString()); } }
/// <summary> /// Gets random car /// </summary> /// <param name="random">Randomizer used to generate random values</param> /// <param name="speeding">Is the car driving faster than the limit?</param> /// <returns></returns> public static SimulatedCar Randomize(Random random, TrafficSegmentSituation segmentSituation, string licensePlateFormat = "1-###-000") { var car = new SimulatedCar { LicensePlate = random.GetString(licensePlateFormat), Color = Colors[random.Next(Colors.Count)], Make = Makes[random.Next(Makes.Count)], Country = Countries[random.NextTriangularValue(0, Countries.Count - 1, Convert.ToInt32(Countries.Count / 2))], // weighted randomization (to get more belgian cars) Speeding = random.GetBooleanWithProbability(segmentSituation.SpeedingPercentage), }; car.ExpectedSpeed = car.Speeding ? random.NextTriangularValue(segmentSituation.SpeedLimit, segmentSituation.MaxSpeed, segmentSituation.SpeedLimit + 15) // Generate speeding cars with weight of speeding around 15 more than allowed : random.NextTriangularValue(segmentSituation.MinSpeed, segmentSituation.SpeedLimit, segmentSituation.AverageSpeed); // Generate non speeding cars, with weight closest to maxAllowed return(car); }
private async Task MakeOneCarDrive(Random random, TrafficSegmentConfiguration trafficConfiguration, TrafficSegmentSituation segmentSituation, IEventTransmitter startCameraEventTransmitter, IEventTransmitter endCameraEventTransmitter, CancellationToken cancellationToken) { // Wait random short interval to add randomness await Task.Delay(TimeSpan.FromMilliseconds(random.Next(2000)), cancellationToken); var car = SimulatedCar.Randomize ( random, segmentSituation ); try { //regenerate new license plate for every run var carTimespan = car.CalculateTime(trafficConfiguration.CameraDistance, _simulationSettings.TimeSimulationAccelerator); await startCameraEventTransmitter.Transmit( new CameraEvent { TrajectId = trafficConfiguration.SegmentId, CameraId = CameraType.Camera1.ToString(), EventTime = SimulatedClock.Time, Car = car, Lane = LaneCalculator.CalculateLane(trafficConfiguration, segmentSituation, car) }, cancellationToken); _logger.Trace($"{car.Color} {car.Make} with license plate {car.LicensePlate} detected by camera 01 (limit {segmentSituation.SpeedLimit})"); await Task.Delay(carTimespan, cancellationToken); await endCameraEventTransmitter.Transmit( new CameraEvent { TrajectId = trafficConfiguration.SegmentId, CameraId = CameraType.Camera2.ToString(), EventTime = SimulatedClock.Time, Car = car, Lane = LaneCalculator.CalculateLane(trafficConfiguration, segmentSituation, car) }, cancellationToken); _logger.Trace($"{car.Color} {car.Make} with license plate {car.LicensePlate} detected by camera 02 (limit {segmentSituation.SpeedLimit})"); } catch (TaskCanceledException) { } catch (Exception ex) { _logger.Error(ex, "Error happened in one of the simulation threads"); } }
public static int CalculateLane(TrafficSegmentConfiguration segmentConfiguration, TrafficSegmentSituation segmentSituation, SimulatedCar car) { if (segmentConfiguration.NumberOfLanes > 2) { // do complexity if (car.Speeding && segmentSituation.IsRushHour(SimulatedClock.Time, out var rushHour)) { // Only take the two most left lanes return(new Random().Next(1, 3)); } } return(new Random().Next(1, segmentConfiguration.NumberOfLanes + 1)); }