ajustes ao salvar trechos no qual o pulverizador estava atuado

This commit is contained in:
Diego Freitas 2026-06-18 16:55:07 -03:00
parent c1a2106e04
commit b88852cbab
4 changed files with 158 additions and 34 deletions

View File

@ -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;
}
}
}

View File

@ -1361,11 +1361,32 @@ namespace AgroBase.Models.Modules
}
public List<List<double[]>> TrechosAtuado { get; set; } = new List<List<double[]>>();
public List<List<PontoGeo>> TrechosAtuado { get; set; } = new List<List<PontoGeo>>();
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()

View File

@ -149,7 +149,7 @@ namespace AgroBase.Models.Operacoes
public TipoMapaOperacao TipoMapa { get; set; }
public MapaFeatureCollectionModel Mapa { get; set; }
public List<string> RuasPercorrer { get; set; }
public List<double[]> PontosRetorno { get; set; }
public List<PontoGeo> 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<List<double[]>>(x.TrechosAtuado ?? new List<List<double[]>>()),
TrechosPulverizando = new List<List<PontoGeo>>(x.TrechosAtuado ?? new List<List<PontoGeo>>()),
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<List<double[]>> TrechosPulverizando { get; set; }
public List<List<PontoGeo>> TrechosPulverizando { get; set; }
public DateTime UltimoComandoRespondido { get; set; }
}

View File

@ -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<Models.Modules.AtuadorBicoModel>())
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)
{