diff --git a/AgroBase/AgroBase/Models/GeneralJoystick.cs b/AgroBase/AgroBase/Models/GeneralJoystick.cs index 31702d557..a2948543f 100644 --- a/AgroBase/AgroBase/Models/GeneralJoystick.cs +++ b/AgroBase/AgroBase/Models/GeneralJoystick.cs @@ -747,7 +747,7 @@ namespace AgroBase if (!Forcar) { if (!Variaveis.OperacaoEmAndamento.Iniciado) return; - bool componente_em_uso = Variaveis.OperacaoEmAndamento.Parametros.ModulosMandatorios.Any(x => x.Dispositivo == T_Code.Atu && x.ComponentesEmUso != null && x.ComponentesEmUso[ID].Item2); + bool componente_em_uso = Variaveis.OperacaoEmAndamento.Parametros.ModulosMandatorios.Any(x => x.Dispositivo == T_Code.Atu && (x.ComponentesEmUso?.ContainsKey(ID) ?? false) && x.ComponentesEmUso[ID].Item2); if (!componente_em_uso && (Status ?? false)) return; // Impede execucao de comandos que liguem componentes quando estiver marcado para nao utilizar } @@ -803,7 +803,7 @@ namespace AgroBase if (!Forcar) { - bool componente_em_uso = Variaveis.OperacaoEmAndamento.Parametros.ModulosMandatorios.Any(x => x.Dispositivo == T_Code.Sen && x.ComponentesEmUso != null && x.ComponentesEmUso[ID].Item2); + bool componente_em_uso = Variaveis.OperacaoEmAndamento.Parametros.ModulosMandatorios.Any(x => x.Dispositivo == T_Code.Sen && (x.ComponentesEmUso?.ContainsKey(ID) ?? false) && x.ComponentesEmUso[ID].Item2); if (!componente_em_uso) { // Impede execucao de comandos que liguem componentes quando estiver marcado para nao utilizar diff --git a/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs b/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs index 2fb86045e..2cf5a2365 100644 --- a/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs +++ b/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs @@ -1075,6 +1075,7 @@ namespace AgroBase.Models SalvarLogs(false); Variaveis.OperacaoEmAndamento.Finalizando = false; + Variaveis.OperacaoEmAndamento.Trajetoria?.AutonomiaCorredor?.Parar(); } public async Task RealizarCalibragemInicialAsync(bool forcar) @@ -1659,8 +1660,13 @@ namespace AgroBase.Models if (controleBase.Dispositivo == T_Code.Trj) { - var (posicaoBase, pontosRetorno) = ((JObject)controleBase._comp_value).ToObject<(GPSModel, List)>(); - Variaveis.OperacaoEmAndamento.Trajetoria?.IniciarRetornoBase(posicaoBase, pontosRetorno); + var (lat, lon, pontosRetorno) = ((JObject)controleBase._comp_value).ToObject<(double?, double?, List)>(); + if (lat == null || lon == null) return; + GPSModel posicaoBase = new GPSModel() { Latitude = lat.Value, Longitude = lon.Value }; + List pontosRetornoPos = null; + if (pontosRetorno?.Any() ?? false) + pontosRetornoPos = pontosRetorno.Select(x => new GPSModel() { Latitude = x[0], Longitude = x[1] }).ToList(); + Variaveis.OperacaoEmAndamento.Trajetoria?.IniciarRetornoBase(posicaoBase, pontosRetornoPos); return; } diff --git a/AgroBase/AgroBase/Models/TrajetoriaMapaOperacaoModel.cs b/AgroBase/AgroBase/Models/TrajetoriaMapaOperacaoModel.cs index 1872d23e1..7e57ddf1e 100644 --- a/AgroBase/AgroBase/Models/TrajetoriaMapaOperacaoModel.cs +++ b/AgroBase/AgroBase/Models/TrajetoriaMapaOperacaoModel.cs @@ -750,7 +750,7 @@ namespace AgroBase.Models private bool VerificaInicioOperacaoMeioRua(bool considerarStatus) { - if (!VerificacaoInicialMeioRuaConcluida && ((considerarStatus && new List() { StatusOperacao.Aguardando, StatusOperacao.EmAndamento }.Contains(Variaveis.OperacaoEmAndamento.StatusAtual)) || !considerarStatus)) + if (_TrajetoriaFixaDefinida && !VerificacaoInicialMeioRuaConcluida && ((considerarStatus && new List() { StatusOperacao.Aguardando, StatusOperacao.EmAndamento }.Contains(Variaveis.OperacaoEmAndamento.StatusAtual)) || !considerarStatus)) { VerificacaoInicialMeioRuaConcluida = true; (bool noCoredor, var idxPontoMaisProximo) = VerificaEquipamentoDentroCorredorMontado(_TrajetoriaFixa[0].Posicao); @@ -1572,6 +1572,8 @@ namespace AgroBase.Models RetornandoBase = false; + CorredorAtual = _Corredores[0]; + AutonomiaCorredor.Iniciar(); AtualizarDadosTrajetoria(); @@ -1791,25 +1793,27 @@ namespace AgroBase.Models }); var pontos_corrigidos = RemoverPontosMuitoProximos(pontos, DistanciaEntrePontos, 0, DistanciaEntrePontosCurva); - + double distanciaPararAntecipado = 3.5; int idx = 1; - + int qtdPontosRemoverFinal = (int)(distanciaPararAntecipado / DistanciaEntrePontos); foreach (var p in pontos_corrigidos) { - traj.Add(new PontoTrajetoriaModel(TipoPontoRua.Rua) + if (idx < (pontos_corrigidos.Count - qtdPontosRemoverFinal) || idx == pontos_corrigidos.Count - 1) { - idxCorredor = 0, - idxPonto = idx, - idxPontoCorredor = idx, - Posicao = p, - Visitado = false, - LarguraCorredor = 1.5 - }); - + traj.Add(new PontoTrajetoriaModel(TipoPontoRua.Rua) + { + idxCorredor = 0, + idxPonto = traj.Count, + idxPontoCorredor = traj.Count, + Posicao = p, + Visitado = false, + LarguraCorredor = 1.5 + }); + } idx++; } - //traj[traj.Count - 1].LarguraCorredor = 3.0; // Considerar que chegou na base a 2,5 m + traj[traj.Count - 1].LarguraCorredor = distanciaPararAntecipado; // Considerar que chegou na base a 2,5 m DistanciaTotal = GPSUtils.DistanciaDoTrecho(traj.Select(x => x.Posicao).ToList()); DistanciaPercorrida = 0.0; @@ -2780,6 +2784,7 @@ namespace AgroBase.Models // ========================== public void Iniciar() { + Reiniciar(); Iniciado = true; } @@ -3028,6 +3033,24 @@ namespace AgroBase.Models Motivos = res.Motivos; } + // ========================== + // Reiniciar + // ========================== + public void Reiniciar() + { + Iniciado = false; + Liberado = false; + Motivos = new List(); + Motivo = ""; + Status = AutonomiaCorredorStatus.Desconhecido; + DistanciaCorredor_m = 0; + DistanciaSeguraBateria_m = 0; + DistanciaSeguraHerbicida_m = 0; + CorredoresLiberados.Clear(); + _corredoresTravados.Clear(); + _inicioCriticoUtc.Clear(); + } + // ========================== // Clone (mantido) // ========================== @@ -3037,6 +3060,7 @@ namespace AgroBase.Models { Iniciado = Iniciado, Liberado = Liberado, + Motivo = Motivo, Motivos = new List(Motivos ?? new List()), Status = Status, DistanciaCorredor_m = DistanciaCorredor_m, diff --git a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/health_worker/modulos/ponte_ip.py b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/health_worker/modulos/ponte_ip.py index 506c99e49..53771490c 100644 --- a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/health_worker/modulos/ponte_ip.py +++ b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/health_worker/modulos/ponte_ip.py @@ -76,8 +76,8 @@ class ModuloIPBribge(ModuloDiagnosticoBase): self._ping_count = 2 # recomendado: 1 (janela já suaviza) self._ping_min_interval = 0.6 # não precisa pingar a cada 100ms - self.bw_max_mbps = 3.0 # capacidade aproximada do link (ajuste por teste) - self.bw_safe_mbps = 2.0 # alvo saudável (até aqui não penaliza) + self.bw_max_mbps = 10.0 # capacidade aproximada do link (ajuste por teste) + self.bw_safe_mbps = 05.0 # alvo saudável (até aqui não penaliza) self.bw_hard_mbps = 2.5 # acima disso é zona vermelha @@ -618,9 +618,9 @@ class ModuloIPBribge(ModuloDiagnosticoBase): """ # fallback quando não há posição válida if distancia_m is None or distancia_m < 0: - self.bw_max_mbps = 3.0 - self.bw_safe_mbps = 2.0 - self.bw_hard_mbps = 2.5 + self.bw_max_mbps = 10.0 + self.bw_safe_mbps = 05.0 + self.bw_hard_mbps = 02.5 return # limita a curva diff --git a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/main.py b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/main.py index 9ca03fd10..2f3d48906 100644 --- a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/main.py +++ b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/main.py @@ -59,12 +59,16 @@ def main(): if acao == ManagerWorkerCommandType.IniciarMPC: try: _p = dados.get("params") - if _p is not None: + + from manager_worker.modulos.mpc import inicializar as iniciar_mpc, get_iniciado + _mpc_iniciado = get_iniciado() + if _mpc_iniciado and _p is None: + ContextoGlobalRedis()._atualizar_mpc(do_manager=True, iniciar_operacao=True) + elif _p is not None: parametros = _p.get("parametros") mapa = _p.get("mapa") iniciar_operacao = _p.get("iniciar_operacao", False) p_ref = _p.get("p_ref", []) - from manager_worker.modulos.mpc import inicializar as iniciar_mpc iniciar_mpc(parametros, mapa, p_ref, iniciar_operacao) else: ContextoGlobalRedis()._atualizar_mpc(do_manager=True, iniciar_operacao=False) diff --git a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/modulos/mpc.py b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/modulos/mpc.py index 05115ee1a..c1e8fc8c3 100644 --- a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/modulos/mpc.py +++ b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/modulos/mpc.py @@ -13,7 +13,8 @@ _iniciado = False def inicializar(parametros, mapa, p_ref, forcar): global _mpc, _iniciado - if not _iniciado or len(_mpc.pontos_info) != len(mapa) or forcar: + mostrar_log(f"[MPC] Inicializar chamado. iniciado: {_iniciado}, len_pontosinfo: {(len(_mpc.pontos_info) if _mpc is not None else 0)}, len_mapa: {len(mapa)}, forcar: {forcar}") + if not _iniciado or (_mpc is not None and len(_mpc.pontos_info) != len(mapa)) or forcar: _mpc = ControladorMPC(parametros_mpc=parametros, pontos_mapa=mapa, p_ref=p_ref) mostrar_log(f"MPC iniciado! Trajetoria com {len(_mpc.pontos_info)} pontos") _iniciado = True @@ -22,6 +23,10 @@ def get_mpc(): global _mpc return _mpc +def get_iniciado(): + global _iniciado + return _iniciado + def comando_parado(): return 0.0, TipoMovimentoDirecional.RodasDianteiras @@ -77,7 +82,7 @@ class ControladorMPC: self._precompute_centerline() except Exception as e: - mostrar_log(f"Erro ao inicializar MPC: {e}") + mostrar_log(f"Erro ao inicializar __init__ MPC: {e}") def _precompute_centerline(self): cl = np.array([p["xy"] for p in self.pontos_info], dtype=float) # N x 2 diff --git a/AgroBase/OperationControl/Models/Variaveis.cs b/AgroBase/OperationControl/Models/Variaveis.cs index 3c537ff1a..dd36d4547 100644 --- a/AgroBase/OperationControl/Models/Variaveis.cs +++ b/AgroBase/OperationControl/Models/Variaveis.cs @@ -539,6 +539,17 @@ namespace OperationControl.Models }); } + public static void EnviarComandoRetornoBase(double? lat = null, double? lon = null, List pontosRetorno = null) + { + var cmd = new OperacaoComandoBaseModel() + { + Momento = DateTime.Now, + Dispositivo = AgroBase.Models.Enums.T_Code.Trj, + _comp_value = (lat, lon, pontosRetorno) + }; + EnviarDadosControle(SelectedRoverId, cmd); + } + #endregion } diff --git a/AgroBase/OperationControl/ViewModels/Views/Operacao/Monitoramento/MonitoramentoViewModel.cs b/AgroBase/OperationControl/ViewModels/Views/Operacao/Monitoramento/MonitoramentoViewModel.cs index 851ab7a0c..862ccf328 100644 --- a/AgroBase/OperationControl/ViewModels/Views/Operacao/Monitoramento/MonitoramentoViewModel.cs +++ b/AgroBase/OperationControl/ViewModels/Views/Operacao/Monitoramento/MonitoramentoViewModel.cs @@ -1,7 +1,11 @@ -using AgroBase.Models.Operadores; +using AgroBase.Models; +using AgroBase.Models.Operadores; +using OperationControl.Helpers; +using OperationControl.Models; using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.CompilerServices; +using System.Windows.Input; using static AgroBase.Models.Enums; namespace OperationControl.ViewModels.Views.Operacao.Monitoramento @@ -98,6 +102,8 @@ namespace OperationControl.ViewModels.Views.Operacao.Monitoramento public event Action? CameraFrontalFrameTipoAlterado; public event Action? CameraErvasFrameTipoAlterado; + public ICommand RetornoBaseCommand { get; } + public MonitoramentoViewModel() { var itens = Enum.GetValues(typeof(TipoFrameCamera)) @@ -114,6 +120,8 @@ namespace OperationControl.ViewModels.Views.Operacao.Monitoramento CameraFrontalFrameTipoSelecionado = CameraFrontalFrameTipos.FirstOrDefault(); CameraErvasFrameTipoSelecionado = CameraErvasFrameTipos.FirstOrDefault(); + + RetornoBaseCommand = new RelayCommand(_ => ExecutarRetornoBase(), _ => PodeExecutarRetornoBase()); } public void AtualizarDadosCameras(CameraWorkerItemModel? snr, CameraWorkerItemModel? cam, StatusCarroMapa? status_carro, double? pct_ervas) @@ -134,6 +142,18 @@ namespace OperationControl.ViewModels.Views.Operacao.Monitoramento } + private void ExecutarRetornoBase() + { + double lat = OperationControl.Models.Variaveis.GpsService.UltimaLeitura.Latitude; + double lon = OperationControl.Models.Variaveis.GpsService.UltimaLeitura.Longitude; + VariaveisControleOperacao.EnviarComandoRetornoBase(lat, lon); + } + + private bool PodeExecutarRetornoBase() + { + return true; + } + public event PropertyChangedEventHandler? PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) diff --git a/AgroBase/OperationControl/ViewModels/Windows/DockWindowViewModel.cs b/AgroBase/OperationControl/ViewModels/Windows/DockWindowViewModel.cs index 59e1bdee1..bd4b79111 100644 --- a/AgroBase/OperationControl/ViewModels/Windows/DockWindowViewModel.cs +++ b/AgroBase/OperationControl/ViewModels/Windows/DockWindowViewModel.cs @@ -335,7 +335,6 @@ namespace OperationControl.ViewModels CenterContent = _viewPreparacaoMapa; BottomContent = _viewPreparacaoMapaBottom; RightContent = CriarBotaoNextSimples(); - CriarMarcadorBase(_viewPreparacaoMapa?.MapaPreparacao); break; case DockStep.ParametrizacaoRover: @@ -344,7 +343,6 @@ namespace OperationControl.ViewModels CenterContent = _viewOperacaoCenter; RightContent = _viewOperacaoRight; BottomContent = _viewOperacaoBottom; - CriarMarcadorBase(_viewOperacaoCenter?.Mapa); AtualizarDadosMapa(null); AtualizarBarraSuperior(StatusModulo.Conectado, "BASE", "VISÃO GERAL", "Selecione um equipamento na lista à direita para configurá-lo", "NORMAL", "Aguardando"); break; @@ -612,6 +610,7 @@ namespace OperationControl.ViewModels { _viewPreparacaoMapaTop?._vm?.AtualizarDados(dados); } + CriarMarcadorBase(Mapa); Mapa?.markers?.UpdateMarkerPosition(VariaveisControleOperacao.BaseMarkerID, lat: dados?.Latitude, lon: dados?.Longitude, heading: dados?.OrientacaoReal); } diff --git a/AgroBase/OperationControl/Views/Operacao/MonitoramentoView.xaml b/AgroBase/OperationControl/Views/Operacao/MonitoramentoView.xaml index c535f70e7..d25110826 100644 --- a/AgroBase/OperationControl/Views/Operacao/MonitoramentoView.xaml +++ b/AgroBase/OperationControl/Views/Operacao/MonitoramentoView.xaml @@ -134,7 +134,7 @@ -