From b88852cbab3b05f670e585b5ffb60f8561404358 Mon Sep 17 00:00:00 2001 From: Diego Freitas Date: Thu, 18 Jun 2026 16:55:07 -0300 Subject: [PATCH] ajustes ao salvar trechos no qual o pulverizador estava atuado --- AgroBase/AgroBase/Models/GPSModel.cs | 12 ++ .../AgroBase/Models/Modules/AtuadorModel.cs | 23 ++- .../Operacoes/OperacaoParametrosModel.cs | 6 +- AgroBase/AgroBase/Services/GPSService.cs | 151 ++++++++++++++---- 4 files changed, 158 insertions(+), 34 deletions(-) diff --git a/AgroBase/AgroBase/Models/GPSModel.cs b/AgroBase/AgroBase/Models/GPSModel.cs index a99cee43a..53037982b 100644 --- a/AgroBase/AgroBase/Models/GPSModel.cs +++ b/AgroBase/AgroBase/Models/GPSModel.cs @@ -569,4 +569,16 @@ namespace AgroBase.Models } + public struct PontoGeo + { + public double Latitude; + public double Longitude; + + public PontoGeo(double latitude, double longitude) + { + Latitude = latitude; + Longitude = longitude; + } + } + } diff --git a/AgroBase/AgroBase/Models/Modules/AtuadorModel.cs b/AgroBase/AgroBase/Models/Modules/AtuadorModel.cs index e58efb3de..227f660ba 100644 --- a/AgroBase/AgroBase/Models/Modules/AtuadorModel.cs +++ b/AgroBase/AgroBase/Models/Modules/AtuadorModel.cs @@ -1361,11 +1361,32 @@ namespace AgroBase.Models.Modules } - public List> TrechosAtuado { get; set; } = new List>(); + public List> TrechosAtuado { get; set; } = new List>(); public int Atuacoes { get; set; } = 0; public double TempoAtuado { get; set; } = 0; + public void AdicionarPontoTrechoAtivo(double latitude, double longitude) + { + lock (TrechosAtuado) + { + if (TrechosAtuado.Count == 0) + return; + + var trechoAtual = TrechosAtuado[TrechosAtuado.Count - 1]; + + if (trechoAtual == null) + return; + + trechoAtual.Add(new PontoGeo() + { + Latitude = latitude, + Longitude = longitude + }); + } + } + + public AtuadorBicoModel Clone() { AtuadorBicoModel clone = new AtuadorBicoModel() diff --git a/AgroBase/AgroBase/Models/Operacoes/OperacaoParametrosModel.cs b/AgroBase/AgroBase/Models/Operacoes/OperacaoParametrosModel.cs index 446f670f8..082b6f3f3 100644 --- a/AgroBase/AgroBase/Models/Operacoes/OperacaoParametrosModel.cs +++ b/AgroBase/AgroBase/Models/Operacoes/OperacaoParametrosModel.cs @@ -149,7 +149,7 @@ namespace AgroBase.Models.Operacoes public TipoMapaOperacao TipoMapa { get; set; } public MapaFeatureCollectionModel Mapa { get; set; } public List RuasPercorrer { get; set; } - public List PontosRetorno { get; set; } + public List PontosRetorno { get; set; } public OperacaoParametrosDadosModel DadosLeitura { get; set; } @@ -707,7 +707,7 @@ namespace AgroBase.Models.Operacoes VolumeVazadoML = x.VolumeVazadoML, QtdAtuacoes = x.Atuacoes, TempoAtuado = x.TempoAtuado, - TrechosPulverizando = new List>(x.TrechosAtuado ?? new List>()), + TrechosPulverizando = new List>(x.TrechosAtuado ?? new List>()), UltimoComandoRespondido = x.UltimaLeitura }).ToList(), Bombas = dAtu?.BombasPressurizadoras?.Select(x => new OperacaoParametrosDadosBombaModel() @@ -1075,7 +1075,7 @@ namespace AgroBase.Models.Operacoes public double VazaoInstantaneaMLs { get; set; } public double VolumeVazadoML { get; set; } public double AnguloAbertura { get; set; } - public List> TrechosPulverizando { get; set; } + public List> TrechosPulverizando { get; set; } public DateTime UltimoComandoRespondido { get; set; } } diff --git a/AgroBase/AgroBase/Services/GPSService.cs b/AgroBase/AgroBase/Services/GPSService.cs index 33b345216..724ddca18 100644 --- a/AgroBase/AgroBase/Services/GPSService.cs +++ b/AgroBase/AgroBase/Services/GPSService.cs @@ -207,54 +207,92 @@ namespace AgroBase.Services - private static StringBuilder _buffer = new StringBuilder(); + private static readonly object _bufferLock = new object(); + private static readonly StringBuilder _buffer = new StringBuilder(); private static void PortaGPS_DataReceived(object sender, SerialDataReceivedEventArgs e) { try { - if (!PortaGPS.IsOpen) - { + if (!(PortaGPS?.IsOpen ?? false)) return; - } - // Lê os dados disponíveis na porta string recebido = PortaGPS.ReadExisting(); - //Console.WriteLine(recebido); + if (string.IsNullOrEmpty(recebido)) + return; - // Adiciona ao buffer - _buffer.Append(recebido); + string blocoCompleto; - // Processa mensagens completas (separadas por "\n") - string[] mensagens = _buffer.ToString().Split('\n'); - - // Processa todas as mensagens completas - for (int i = 0; i < mensagens.Length - 1; i++) + lock (_bufferLock) { - string mensagem = mensagens[i].Trim(); - if (mensagem.Length > 0) + _buffer.Append(recebido); + + string acumulado = _buffer.ToString(); + int ultimaQuebraLinha = acumulado.LastIndexOf('\n'); + + // Ainda não chegou nenhuma sentença completa. + if (ultimaQuebraLinha < 0) + return; + + blocoCompleto = acumulado.Substring( + 0, + ultimaQuebraLinha + 1 + ); + + string restante = acumulado.Substring( + ultimaQuebraLinha + 1 + ); + + /* + * Retiramos as sentenças completas do buffer antes + * de processá-las. Assim, uma exceção em qualquer + * consumidor não reapresenta as mesmas sentenças. + */ + _buffer.Clear(); + _buffer.Append(restante); + } + + string[] mensagens = blocoCompleto.Split('\n'); + + foreach (string mensagemRaw in mensagens) + { + string mensagem = mensagemRaw.Trim(); + + if (mensagem.Length == 0) + continue; + + try { ProcessarDadosNMEA(mensagem); } - } - - if (mensagens.Length > 0) - { - // Mantém o que sobrou no buffer (última mensagem incompleta) - _buffer.Clear(); - _buffer.Append(mensagens[mensagens.Length - 1]); + catch (Exception ex) + { + Variaveis.MostrarLog( + $"[GPSService.PortaGPS_DataReceived] " + + $"Erro ao processar a sentença '{mensagem}': {ex}" + ); + } } var obj = UltimaLeitura.Clone(); obj.Momento = DateTime.Now; Logs.Add(JsonConvert.SerializeObject(obj)); - VariaveisOperacao.RegistrarLogDispositivo(Logs, T_Code.Gps, ".json", 300); + + VariaveisOperacao.RegistrarLogDispositivo( + Logs, + T_Code.Gps, + ".json", + 300 + ); } catch (Exception ex) { - Variaveis.MostrarLog($"[GPSService.PortaGPS_DataReceived] Erro ao processar dados da porta serial: " + ex.Message); + Variaveis.MostrarLog( + $"[GPSService.PortaGPS_DataReceived] " + + $"Erro geral na porta serial: {ex}" + ); } } @@ -622,6 +660,14 @@ namespace AgroBase.Services try { + //var bicos = Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.BicosPulverizadores?.Select(x => x.ComandoAtuar ? "ON" : "OFF").ToList(); + //string estadoSolenoides = bicos == null ? "INDISPONIVEL" : string.Join(",", bicos); + //Variaveis.MostrarLog( + // $"[GPSService.ProcessarGNTHS] " + + // $"Sentença recebida: {sentenca}, " + + // $"Solenoides: {estadoSolenoides}" + //); + /* * Exemplos: * @@ -1072,9 +1118,48 @@ namespace AgroBase.Services } + private static bool PossuiHeadingValido(GPSModel leitura) + { + if (leitura == null) + return false; + + string status = + (leitura.TipoOrientacao ?? string.Empty) + .Trim() + .ToUpperInvariant(); + + double heading = leitura.OrientacaoReal; + + return + status == "A" && + leitura.TimestampOri.frequencia >= 1.0 && + !double.IsNaN(heading) && + !double.IsInfinity(heading) && + heading >= 0.0 && + heading < 360.0; + } + private static void AplicarPosicaoCorrigida() { - (double latCor, double lonCorr) = LeverArm.FixLeverArmLatLon_Fast(UltimaLeitura.LatitudeAnt, UltimaLeitura.LongitudeAnt, UltimaLeitura.OrientacaoReal, UltimaLeitura.TimestampOri.frequencia); + if (!PossuiHeadingValido(UltimaLeitura)) + { + UltimaLeitura.Latitude = + UltimaLeitura.LatitudeAnt; + + UltimaLeitura.Longitude = + UltimaLeitura.LongitudeAnt; + + return; + } + + (double latCor, double lonCorr) = + LeverArm.FixLeverArmLatLon_Fast( + UltimaLeitura.LatitudeAnt, + UltimaLeitura.LongitudeAnt, + UltimaLeitura.OrientacaoReal, + UltimaLeitura.TimestampOri.frequencia + ); + UltimaLeitura.Latitude = latCor; UltimaLeitura.Longitude = lonCorr; } @@ -1131,11 +1216,17 @@ namespace AgroBase.Services } } - foreach (var bico in Variaveis.OperacaoEmAndamento.Controle?.Bicos ?? new List()) + var bicos = Variaveis.OperacaoEmAndamento.Controle?.Bicos; + if (bicos != null) { - if (bico.Inicializado && bico.Comandar && bico._EstadoLeitura == Estado.Ligado) + foreach (var bico in bicos) { - bico.TrechosAtuado[bico.TrechosAtuado.Count - 1].Add(new double[] { UltimaLeitura.Latitude, UltimaLeitura.Longitude }); + if (!bico.Inicializado || !bico.Comandar || bico._EstadoLeitura != Estado.Ligado) + { + continue; + } + + bico.AdicionarPontoTrechoAtivo(UltimaLeitura.Latitude, UltimaLeitura.Longitude); } } @@ -1167,7 +1258,7 @@ namespace AgroBase.Services } } - + public static void EnviarCoordenadasParaMapa(double Latitude, double Longitude, double Orientacao, bool EmFoco, int ID) { @@ -1289,7 +1380,7 @@ namespace AgroBase.Services bool imuIniciado = Variaveis.OperacaoEmAndamento.Sensoriamento?.IMU?.Iniciado ?? false; bool gpsIniciado = Iniciado; - bool headingValido = UltimaLeitura.TimestampOri.frequencia >= 1.0; + bool headingValido = PossuiHeadingValido(UltimaLeitura); if (imuIniciado) {