• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

kłopot z symulacją pojazdów

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
0 głosów
55 wizyt
pytanie zadane 12 kwietnia w C# przez Michalecekxd Użytkownik (850 p.)
DeliveryController:
        [HttpPost]
        public async Task<ActionResult<DeliveryDto>> CreateDelivery([FromBody] AddDeliveryDto dto)
        {
            var vehicle = await _context.Vehicles
                .Include(v => v.Driver)
                .FirstOrDefaultAsync(v => v.Id == dto.VehicleId);
            var driver = vehicle.Driver;
            double startLatitude = Math.Round(dto.StartLatitude, 6);
            double startLongitude = Math.Round(dto.StartLongitude, 6);
            double endLatitude = Math.Round(dto.EndLatitude, 6);
            double endLongitude = Math.Round(dto.EndLongitude, 6);
            var activeDelivery = await _context.Deliveries
                .FirstOrDefaultAsync(d => d.VehicleId == dto.VehicleId && d.Status == DeliveryStatus.InProgress);

            var delivery = new Delivery
            {
                VehicleId = dto.VehicleId,
                LoadDescription = dto.LoadDescription,
                StartLatitude = startLatitude,
                StartLongitude = startLongitude,
                EndLatitude = endLatitude,
                EndLongitude = endLongitude,
                Status = activeDelivery != null ? DeliveryStatus.Pending : DeliveryStatus.InProgress,
                CreatedAt = DateTime.UtcNow,
                CompletedAt = null,
                ClientName = dto.ClientName,
                ClientPhone = dto.ClientPhone,
                Order = orderToAssign
            };
            using var transaction = await _context.Database.BeginTransactionAsync();
            try
            {
                if (vehicle.Status == VehicleStatus.ReturningToBase)
                {
                    await _webSocketService.CancelSimulationAsync(vehicle.Id);
                }
                _context.Deliveries.Add(delivery);

                if (delivery.Status == DeliveryStatus.InProgress)
                {
                    vehicle.Status = VehicleStatus.OnTheRoad;
                    _context.Entry(vehicle).State = EntityState.Modified;
                }
                await _context.SaveChangesAsync();
                if (delivery.Status == DeliveryStatus.InProgress)
                {
                    List<(double lat, double lng)> routeToStart = await _routeService.GetRouteCoordinatesAsync(
                        vehicle.Longitude ?? 0.0,
                        vehicle.Latitude ?? 0.0,
                        startLongitude,
                        startLatitude);
                    List<(double lat, double lng)> routeToDestination = await _routeService.GetRouteCoordinatesAsync(
                        startLongitude,
                        startLatitude,
                        endLongitude,
                        endLatitude,
                        dto.SelectedRouteIndex);
                    // Uruchamiamy symulację dostawy
                    _ = _webSocketService.SimulateDeliveryAsync(dto.VehicleId, routeToStart, routeToDestination);
                }
                await transaction.CommitAsync();
                var deliveryDto = new DeliveryDto
                {
                    Id = delivery.Id,
                    VehicleId = delivery.VehicleId,
                    LoadDescription = delivery.LoadDescription,
                    StartLatitude = delivery.StartLatitude,
                    StartLongitude = delivery.StartLongitude,
                    EndLatitude = delivery.EndLatitude,
                    EndLongitude = delivery.EndLongitude,
                    Status = delivery.Status,
                    CreatedAt = delivery.CreatedAt,
                    ClientName = delivery.ClientName,
                    ClientPhone = delivery.ClientPhone
                };
            }

WebSocketService.cs:
public class WebSocketService
{
    private readonly IServiceScopeFactory _scopeFactory;
    private readonly ConfigService _configService;
    private readonly List<WebSocket> _sockets = new List<WebSocket>();
    private List<VehicleData> _cachedVehicles = new List<VehicleData>();
    private DateTime _lastCacheUpdate = DateTime.MinValue;
    private readonly RouteService _routeService;
    private readonly Dictionary<int, List<(Task task, CancellationTokenSource cancellationTokenSource)>> _simulationTasks = new();
    public async Task HandleWebSocketAsync(HttpContext context)
    {
        var socket = await context.WebSockets.AcceptWebSocketAsync();
        _sockets.Add(socket);
        try
        {
            while (socket.State == WebSocketState.Open)
            {
                using (var scope = _scopeFactory.CreateScope())
                {
                    var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();

                    var vehicles = await dbContext.Vehicles
                        .Include(v => v.Driver)
                        .ThenInclude(d => d!.User)
                        .Select(v => new VehicleData
                        {
                            Id = v.Id,
                            Status = v.Status,
                            Latitude = Math.Round(v.Latitude ?? 0.0, 6),
                            Longitude = Math.Round(v.Longitude ?? 0.0, 6),
                            RegistrationNumber = v.RegistrationNumber ?? "",
                            Brand = v.Brand ?? "",
                            Model = v.Model ?? "",
                            YearOfProduction = v.YearOfProduction,
                            BodyworkType = v.BodyworkType,
                            Capacity = v.Capacity,
                            Type = (int)v.Type,
                            LastModified = v.LastModified,
                            DriverId = v.Driver != null ? v.Driver.Id : null,
                            DriverFirstName = v.Driver != null ? v.Driver.User!.FirstName : null,
                            DriverLastName = v.Driver != null ? v.Driver.User!.LastName : null,
                            DriverPhoneNumber = v.Driver != null ? v.Driver.User!.PhoneNumber : null,
                            Deliveries = v.Status == VehicleStatus.OnTheRoad && v.Deliveries != null
                                ? v.Deliveries.Select(d => new DeliveryData
                                {
                                    Id = d.Id,
                                    LoadDescription = d.LoadDescription,
                                    Status = (int)d.Status,
                                    StartLatitude = Math.Round(d.StartLatitude, 6),
                                    StartLongitude = Math.Round(d.StartLongitude, 6),
                                    EndLatitude = Math.Round(d.EndLatitude, 6),
                                    EndLongitude = Math.Round(d.EndLongitude, 6),
                                    CreatedAt = d.CreatedAt,
                                    CompletedAt = d.CompletedAt,
                                    ClientName = d.ClientName ?? string.Empty,
                                    ClientPhone = d.ClientPhone ?? string.Empty
                                }).ToList()
                                : new List<DeliveryData>(),
                            SemiTrailer = v.Type == VehicleType.SemiTrailerTruck && v.SemiTrailerId.HasValue
                                ? dbContext.Vehicles.Where(s => s.Id == v.SemiTrailerId.Value)
                                    .Select(s => new SemiTrailerData
                                    {
                                        Id = s.Id,
                                        RegistrationNumber = s.RegistrationNumber ?? "",
                                        Brand = s.Brand ?? "",
                                        Model = s.Model ?? "",
                                        YearOfProduction = s.YearOfProduction,
                                        BodyworkType = s.BodyworkType,
                                        Capacity = s.Capacity
                                    }).FirstOrDefault()
                                : null
                        })
                        .ToListAsync();

                    _cachedVehicles = vehicles;
                    _lastCacheUpdate = DateTime.UtcNow;
                }
                var json = JsonSerializer.Serialize(_cachedVehicles);
                var buffer = Encoding.UTF8.GetBytes(json);
                foreach (var client in _sockets)
                {
                    if (client.State == WebSocketState.Open)
                    {
                        await client.SendAsync(new ArraySegment<byte>(buffer),
                                               WebSocketMessageType.Text,
                                               true,
                                               CancellationToken.None);
                    }
                }
                await Task.Delay(3000); 
            }
        }
public async Task SimulateDeliveryAsync(int vehicleId, List<(double lat, double lng)> routeToStart, List<(double lat, double lng)> routeToDestination)
    {
        using var scope = _scopeFactory.CreateScope();
        var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
        var vehicle = await dbContext.Vehicles.FindAsync(vehicleId, CancellationToken.None);
        await SimulateRouteAsync(vehicleId, routeToStart, CancellationToken.None);
        await SimulateRouteAsync(vehicleId, routeToDestination, CancellationToken.None);
        var delivery = await dbContext.Deliveries
            .Where(d => d.VehicleId == vehicleId && d.Status == DeliveryStatus.InProgress)
            .FirstOrDefaultAsync(CancellationToken.None);
        if (delivery != null)
        {
            delivery.Status = DeliveryStatus.Completed;
            delivery.CompletedAt = DateTime.UtcNow;
            await dbContext.SaveChangesAsync();
            var activeNewOrder = await dbContext.Deliveries
                .Where(d => d.VehicleId == vehicleId && (d.Status == DeliveryStatus.Pending || d.Status == DeliveryStatus.InProgress))
                .FirstOrDefaultAsync();
            if (activeNewOrder == null)
            {
                vehicle.Status = VehicleStatus.ReturningToBase;
                await dbContext.SaveChangesAsync();
                await SimulateRouteToBaseAsync(vehicleId, CancellationToken.None);
            }
        }
    }
private async Task SimulateRouteAsync(int vehicleId, List<(double lat, double lng)> routeCoordinates, CancellationToken cancellationToken)
    {
        using var scope = _scopeFactory.CreateScope();
        var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
        foreach (var point in routeCoordinates)
        {
            cancellationToken.ThrowIfCancellationRequested();
            var vehicle = await dbContext.Vehicles.FindAsync(vehicleId, cancellationToken);
            if (vehicle != null)
            {
                vehicle.Latitude = Math.Round(point.lat, 6);
                vehicle.Longitude = Math.Round(point.lng, 6);
                vehicle.LastModified = DateTime.UtcNow;
                await dbContext.SaveChangesAsync(cancellationToken);
            }
            await Task.Delay(3000, cancellationToken);
        }
    }
public async Task SimulateRouteToBaseAsync(int vehicleId, CancellationToken cancellationToken)
    {
        using var scope = _scopeFactory.CreateScope();
        var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
        var vehicle = await dbContext.Vehicles.FindAsync(vehicleId, cancellationToken);

        var baseLocation = _configService.GetBaseLocation();
        List<(double lat, double lng)> routeToBase = await _routeService.GetRouteCoordinatesAsync(
            vehicle.Longitude ?? 0.0,
            vehicle.Latitude ?? 0.0,
            baseLocation.Longitude,
            baseLocation.Latitude);
        
        //Nowy token dla symulacji powrotu do bazy
        var ctsBase = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
        var baseTask = Task.Run(async () =>
        {
            await SimulateRouteAsync(vehicleId, routeToBase, ctsBase.Token);
          });
        AddSimulationTask(vehicleId, baseTask, ctsBase);
        await baseTask;
    }
public async Task CancelSimulationAsync(int vehicleId)
    {
        if (_simulationTasks.ContainsKey(vehicleId))
        {
            var tasksForVehicle = _simulationTasks[vehicleId];
            foreach (var (task, cancellationTokenSource) in tasksForVehicle)
            {
                cancellationTokenSource.Cancel(); 
                try
                {
                    await task;
                }
                catch (TaskCanceledException)
                {
                    Console.WriteLine($"Symulacja dla pojazdu {vehicleId} została anulowana.");
                }
            }
            _simulationTasks.Remove(vehicleId);
        }
    }
private void AddSimulationTask(int vehicleId, Task task, CancellationTokenSource cts)
    {
        if (!_simulationTasks.ContainsKey(vehicleId))
        {
            _simulationTasks[vehicleId] = new List<(Task, CancellationTokenSource)>();
        }
        _simulationTasks[vehicleId].Add((task, cts)); // Dodajemy tylko zadanie powrotu do bazy
    }


Witam. Któryś dzień rozwiązuję ten sam problem. Nie mogę sobie poradzić. Mam mapę i mam na niej pojazdy. Dodaję zlecenie dla pojazdu ((CreateDelivery w kodzie)- wysyłam go w trasę- w aplikacji wpisuję tu miejsce początkowe i miejsce docelowe)- wtedy on rusza z bazy do miejsca początkowego.Dociera do miejsca początkowego (np. Kraków Graniczna 15..., potem jedzie do miejsca docelowego (np. Warszawa Graniczna 20...). Po tym wszystkim wraca do bazy. Podczas tego powrotu do bazy mogę dodac mu kolejne zlecenie. Czyli znowu dodaje zlecenie (pojazd caly czas wraca do bazy). Dodaję to zlecenie (wpisuje znowu miejsce poczatkowe i docelowe) i on jedzie mi z miejsca w którym jest do miejsca początkowego zlecenia które wpisałem podczas dodawania zlecenia. Dojeżdza do miejsca początkowego, potem z miejsca początkowego jedzie do docelowego. Dociera do docelowego- i wraca do bazy. I TERAZ JEŚLI DODAJĘ mu kolejne zlecenie (on caly czas wraca do bazy) to zamiast jechac do miejsca poczatkowego tego zlecenia które wpisłaem podczas dodawania zlecenia to jedzie mi DO BAZY (oraz wykonuje dziwne przeskoki, "teleportacje" zmierzając raz w stronę miejsca początkowego, raz w stronę bazy. A powinien jechac po prostu do miejsca początkowego). Wiem że temat jest skomplikowany ale nie wiem już gdzie szukać pomocy. Dziekuję bardzo za każdą wskazówkę

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

+1 głos
1 odpowiedź 613 wizyt
pytanie zadane 6 czerwca 2022 w Python przez NEFOS Początkujący (320 p.)
+5 głosów
0 odpowiedzi 498 wizyt
pytanie zadane 19 sierpnia 2022 w Nasze projekty przez wojtek_suchy Mądrala (6,880 p.)
0 głosów
1 odpowiedź 984 wizyt
pytanie zadane 30 sierpnia 2020 w Python przez 12332112332121 Dyskutant (8,270 p.)

93,440 zapytań

142,432 odpowiedzi

322,679 komentarzy

62,802 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

...