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 int Atuacoes { get; set; } = 0;
public double TempoAtuado { 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() public AtuadorBicoModel Clone()
{ {
AtuadorBicoModel clone = new AtuadorBicoModel() AtuadorBicoModel clone = new AtuadorBicoModel()

View File

@ -149,7 +149,7 @@ namespace AgroBase.Models.Operacoes
public TipoMapaOperacao TipoMapa { get; set; } public TipoMapaOperacao TipoMapa { get; set; }
public MapaFeatureCollectionModel Mapa { get; set; } public MapaFeatureCollectionModel Mapa { get; set; }
public List<string> RuasPercorrer { 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; } public OperacaoParametrosDadosModel DadosLeitura { get; set; }
@ -707,7 +707,7 @@ namespace AgroBase.Models.Operacoes
VolumeVazadoML = x.VolumeVazadoML, VolumeVazadoML = x.VolumeVazadoML,
QtdAtuacoes = x.Atuacoes, QtdAtuacoes = x.Atuacoes,
TempoAtuado = x.TempoAtuado, 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 UltimoComandoRespondido = x.UltimaLeitura
}).ToList(), }).ToList(),
Bombas = dAtu?.BombasPressurizadoras?.Select(x => new OperacaoParametrosDadosBombaModel() Bombas = dAtu?.BombasPressurizadoras?.Select(x => new OperacaoParametrosDadosBombaModel()
@ -1075,7 +1075,7 @@ namespace AgroBase.Models.Operacoes
public double VazaoInstantaneaMLs { get; set; } public double VazaoInstantaneaMLs { get; set; }
public double VolumeVazadoML { get; set; } public double VolumeVazadoML { get; set; }
public double AnguloAbertura { 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; } 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) private static void PortaGPS_DataReceived(object sender, SerialDataReceivedEventArgs e)
{ {
try try
{ {
if (!PortaGPS.IsOpen) if (!(PortaGPS?.IsOpen ?? false))
{
return; return;
}
// Lê os dados disponíveis na porta
string recebido = PortaGPS.ReadExisting(); string recebido = PortaGPS.ReadExisting();
//Console.WriteLine(recebido); if (string.IsNullOrEmpty(recebido))
return;
// Adiciona ao buffer string blocoCompleto;
_buffer.Append(recebido);
// Processa mensagens completas (separadas por "\n") lock (_bufferLock)
string[] mensagens = _buffer.ToString().Split('\n');
// Processa todas as mensagens completas
for (int i = 0; i < mensagens.Length - 1; i++)
{ {
string mensagem = mensagens[i].Trim(); _buffer.Append(recebido);
if (mensagem.Length > 0)
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); ProcessarDadosNMEA(mensagem);
} }
} catch (Exception ex)
{
if (mensagens.Length > 0) Variaveis.MostrarLog(
{ $"[GPSService.PortaGPS_DataReceived] " +
// Mantém o que sobrou no buffer (última mensagem incompleta) $"Erro ao processar a sentença '{mensagem}': {ex}"
_buffer.Clear(); );
_buffer.Append(mensagens[mensagens.Length - 1]); }
} }
var obj = UltimaLeitura.Clone(); var obj = UltimaLeitura.Clone();
obj.Momento = DateTime.Now; obj.Momento = DateTime.Now;
Logs.Add(JsonConvert.SerializeObject(obj)); Logs.Add(JsonConvert.SerializeObject(obj));
VariaveisOperacao.RegistrarLogDispositivo(Logs, T_Code.Gps, ".json", 300);
VariaveisOperacao.RegistrarLogDispositivo(
Logs,
T_Code.Gps,
".json",
300
);
} }
catch (Exception ex) 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 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: * 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() 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.Latitude = latCor;
UltimaLeitura.Longitude = lonCorr; 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) 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 imuIniciado = Variaveis.OperacaoEmAndamento.Sensoriamento?.IMU?.Iniciado ?? false;
bool gpsIniciado = Iniciado; bool gpsIniciado = Iniciado;
bool headingValido = UltimaLeitura.TimestampOri.frequencia >= 1.0; bool headingValido = PossuiHeadingValido(UltimaLeitura);
if (imuIniciado) if (imuIniciado)
{ {