otimizado trajetoria fixa

This commit is contained in:
Diego Freitas 2025-02-04 14:50:42 -03:00
parent d72f6c06ca
commit 7f95089d7b
11 changed files with 475 additions and 287 deletions

Binary file not shown.

View File

@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using static AgroBase.Models.Enums;
namespace AgroBase.Models
@ -13,84 +14,44 @@ namespace AgroBase.Models
RuasPlantacao = new List<List<GPSModel>>(RuasMapa);
}
public List<List<GPSModel>> RuasPlantacao { get; set; }
public List<List<GPSModel>> Corredores { get; set; }
public List<int> CorredoresNaoFinalizados
{
get
{
var corredores = _TrajetoriaFixa
.Where(x => !x.Visitado)
.GroupBy(x => x.idxCorredor)
.Select(x => x.Key)
.ToList();
#region PARAMETROS
return corredores;
}
}
private List<double> CorredoresLarguras { get; set; }
public List<PontoTrajetoriaModel> _TrajetoriaFixa { get; set; }
public List<GPSModel> TrajetoriaFixa
{
get
{
return _TrajetoriaFixa.Select(x => x.Posicao).ToList();
}
}
public List<GPSModel> TrajetoriaDinamica
{
get
{
List<GPSModel> Trajetoria = new List<GPSModel>() { GPSService.UltimaLeitura };
Trajetoria.AddRange(_TrajetoriaFixa.Where(x => !x.Visitado).OrderBy(x => x.idxPonto).Select(x => x.Posicao).ToList());
return Trajetoria;
}
}
public int IdxCorredorAtual
{
get
{
return PontoAtual?.idxCorredor ?? 0;
}
}
public DateTime UltimaAtualizacaoDados { get; set; } = DateTime.MinValue;
public double DistanciaProjecaoRua { get; set; } = 0.8;
public static double DistanciaEntrePontos { get; set; } = 1.0;
public static double DistanciaEntrePontosCurva { get; set; } = 0.25;
private double DistanciaManobraEntreRuas { get; set; } = 3.0;
private const int RANGE_ATUALIZACAO = 100; // Define o tamanho da janela de pontos a atualizar
#endregion
public DateTime UltimaAtualizacaoDados { get; set; } = DateTime.MinValue;
public List<List<GPSModel>> RuasPlantacao { get; set; }
public List<List<GPSModel>> Corredores { get; set; }
public GPSModel PrimeiroPontoRuaMapa
{
get
{
var Trajetoria = RuasPlantacao;
if (Trajetoria.Any(x => x.Any()) && Trajetoria.Count() > IdxCorredorAtual)
// Verifica se o índice é válido e se a rua não está vazia
if (IdxCorredorAtual < RuasPlantacao.Count && RuasPlantacao[IdxCorredorAtual].Count > 0)
{
var primeiroPontoRua = Trajetoria.Skip(IdxCorredorAtual).First().First();
return primeiroPontoRua;
}
else
{
return new GPSModel();
return RuasPlantacao[IdxCorredorAtual][0]; // Acessa diretamente o primeiro ponto da rua
}
return new GPSModel(); // Pode ser null se preferir
}
}
public GPSModel UltimoPontoRuaMapa
{
get
{
var Trajetoria = RuasPlantacao;
// Verifica se o índice é válido e se a rua não está vazia
if (IdxCorredorAtual < RuasPlantacao.Count && RuasPlantacao[IdxCorredorAtual].Count > 0)
{
return RuasPlantacao[IdxCorredorAtual][RuasPlantacao.Count - 1]; // Acessa diretamente o ultimo ponto da rua
}
if (Trajetoria.Any(x => x.Any()) && Trajetoria.Count() > IdxCorredorAtual)
{
var ultimoPontoRua = Trajetoria.Skip(IdxCorredorAtual).First().Last();
return ultimoPontoRua;
}
else
{
return new GPSModel();
}
return new GPSModel(); // Pode ser null se preferir
}
}
public int ExtremoMaisProximoMapa
@ -105,6 +66,91 @@ namespace AgroBase.Models
return (distPP < distUP) ? 0 : 1;
}
}
private List<int> _corredoresNaoFinalizados;
public List<int> CorredoresNaoFinalizados
{
get
{
return _corredoresNaoFinalizados;
}
}
private void AtualizarCorredoresNaoFinalizados()
{
var corredores = new HashSet<int>();
foreach (var ponto in _TrajetoriaFixa)
{
if (!ponto.Visitado)
{
corredores.Add(ponto.idxCorredor); // Adiciona apenas corredores com pontos não visitados
}
}
_corredoresNaoFinalizados = corredores.ToList();
}
private List<double> CorredoresLarguras { get; set; }
public List<PontoTrajetoriaModel> _TrajetoriaFixa { get; set; }
public Dictionary<int, List<PontoTrajetoriaModel>> _Corredores { get; set; }
public List<GPSModel> TrajetoriaFixa => _TrajetoriaFixa.ConvertAll(x => x.Posicao);
public List<GPSModel> TrajetoriaDinamica
{
get
{
// Cria a lista com a última leitura do robô
var trajetoria = new List<GPSModel> { GPSService.UltimaLeitura };
// Se a trajetória fixa estiver vazia, retorna apenas a leitura atual
if (_TrajetoriaFixa.Count == 0)
{
return trajetoria;
}
// Adiciona os pontos não visitados, já ordenados por idxPonto
foreach (var ponto in _TrajetoriaFixa)
{
if (!ponto.Visitado)
{
trajetoria.Add(ponto.Posicao);
}
}
return trajetoria;
}
}
public static double DistanciaMaximaEntreLeituras { get; private set; }
public void AtualizarDistanciaMaximaEntreLeituras(double velocidadeCarroMs)
{
double distanciaMaxima = (velocidadeCarroMs / GPSService.TaxaAmostragemHz);
DistanciaMaximaEntreLeituras = distanciaMaxima;
}
private void AtualizarPropriedadesPontosTrajetoria()
{
if (_TrajetoriaFixa.Count == 0) return;
// Define os limites da janela de atualização
int idxInicial = Math.Max(0, PontoAtual.idxPonto - RANGE_ATUALIZACAO / 2);
int idxFinal = Math.Min(_TrajetoriaFixa.Count, PontoAtual.idxPonto + RANGE_ATUALIZACAO / 2);
// Atualiza apenas os pontos dentro do intervalo definido
for (int i = idxInicial; i < idxFinal; i++)
{
_TrajetoriaFixa[i].AtualizarPropriedades();
}
}
public int IdxCorredorAtual
{
get
{
return PontoAtual?.idxCorredor ?? 0;
}
}
public Enums.DirecaoCarroRua DirecaoCaminho
{
get
@ -128,132 +174,196 @@ namespace AgroBase.Models
return angulo;
}
}
private double _distanciaEsquerda;
public double DistanciaEsquerda
{
get
{
if (IdxCorredorAtual >= Corredores.Count())
{
return 0;
}
double distancia = 0;
var primeiroPontoCorredor = Corredores[IdxCorredorAtual].FirstOrDefault();
var pontoCorredor = _TrajetoriaFixa.FirstOrDefault(x => x.Posicao.Latitude == primeiroPontoCorredor.Latitude && x.Posicao.Longitude == primeiroPontoCorredor.Longitude);
double distPP = GPSService.DistanciaEntrePontos(pontoCorredor.Posicao, PrimeiroPontoRuaMapa);
double distUP = GPSService.DistanciaEntrePontos(pontoCorredor.Posicao, UltimoPontoRuaMapa);
int extremoInicial = (distPP < distUP) ? 0 : 1;
List<GPSModel> rua = new List<GPSModel>();
if (extremoInicial == 0)
{
rua = RuasPlantacao[IdxCorredorAtual + 1];
}
else
{
rua = RuasPlantacao[IdxCorredorAtual];
}
// Calcula a menor distância entre o robô e a rua selecionada
distancia = GPSService.CalcularMenorDistanciaAteTrecho(GPSService.UltimaLeitura, rua);
distancia -= (VariaveisEquipamento.LarguraEsquerda / 100.0);
return distancia;
return _distanciaEsquerda;
}
}
private double _distanciaDireita;
public double DistanciaDireita
{
get
{
if (IdxCorredorAtual >= Corredores.Count())
{
return 0;
}
double distancia = 0;
var primeiroPontoCorredor = Corredores[IdxCorredorAtual].FirstOrDefault();
var pontoCorredor = _TrajetoriaFixa.FirstOrDefault(x => x.Posicao.Latitude == primeiroPontoCorredor.Latitude && x.Posicao.Longitude == primeiroPontoCorredor.Longitude);
double distPP = GPSService.DistanciaEntrePontos(pontoCorredor.Posicao, PrimeiroPontoRuaMapa);
double distUP = GPSService.DistanciaEntrePontos(pontoCorredor.Posicao, UltimoPontoRuaMapa);
int extremoInicial = (distPP < distUP) ? 0 : 1;
List<GPSModel> rua = new List<GPSModel>();
if (extremoInicial == 0)
{
rua = RuasPlantacao[IdxCorredorAtual];
}
else
{
rua = RuasPlantacao[IdxCorredorAtual + 1];
}
// Calcula a menor distância entre o robô e a rua selecionada
distancia = GPSService.CalcularMenorDistanciaAteTrecho(GPSService.UltimaLeitura, rua);
distancia -= (VariaveisEquipamento.LarguraDireita / 100.0);
return distancia;
return _distanciaDireita;
}
}
private void AtualizarDistanciasLaterais()
{
_distanciaEsquerda = CalcularDistanciaLateral(true);
_distanciaDireita = CalcularDistanciaLateral(false);
}
private double CalcularDistanciaLateral(bool ladoEsquerdo)
{
// Verifica se o corredor atual existe
if (!_Corredores.ContainsKey(IdxCorredorAtual))
{
return 0;
}
var pontosDoCorredor = _Corredores[IdxCorredorAtual];
if (pontosDoCorredor.Count == 0)
{
return 0;
}
// Pega o primeiro ponto do corredor atual
var pontoCorredor = pontosDoCorredor[0];
// Calcula as distâncias até os extremos da rua
double distPP = GPSService.DistanciaEntrePontos(pontoCorredor.Posicao, PrimeiroPontoRuaMapa);
double distUP = GPSService.DistanciaEntrePontos(pontoCorredor.Posicao, UltimoPontoRuaMapa);
int extremoInicial = (distPP < distUP) ? 0 : 1;
// Determina a rua correta de acordo com o lado e a posição do extremo inicial
List<GPSModel> rua;
if (ladoEsquerdo)
{
rua = (extremoInicial == 0) ? RuasPlantacao[IdxCorredorAtual + 1] : RuasPlantacao[IdxCorredorAtual];
}
else
{
rua = (extremoInicial == 0) ? RuasPlantacao[IdxCorredorAtual] : RuasPlantacao[IdxCorredorAtual + 1];
}
// Evita erro de índice (se for o último corredor, não há IdxCorredorAtual + 1)
int idxMax = RuasPlantacao.Count - 1;
int idxRua = Math.Min(IdxCorredorAtual + (ladoEsquerdo ? 1 : 0), idxMax);
rua = RuasPlantacao[idxRua];
// Calcula a menor distância entre o robô e a rua
double distancia = GPSService.CalcularMenorDistanciaAteTrecho(GPSService.UltimaLeitura, rua);
// Ajusta a largura do robô no cálculo final
double larguraAjuste = ladoEsquerdo ? VariaveisEquipamento.LarguraEsquerda : VariaveisEquipamento.LarguraDireita;
distancia -= (larguraAjuste / 100.0);
return distancia;
}
private PontoTrajetoriaModel _pontoAtual;
public PontoTrajetoriaModel PontoAtual
{
get
{
if (_TrajetoriaFixa == null)
{
return null;
}
return _TrajetoriaFixa.Where(x => x.Visitado).OrderBy(x => x.idxPonto).LastOrDefault();
return _pontoAtual;
}
}
private void DefinirPontoAtual()
{
if (_TrajetoriaFixa == null)
{
_pontoAtual = null;
}
// Busca eficiente: percorre de trás para frente para achar o último visitado
for (int i = _TrajetoriaFixa.Count - 1; i >= 0; i--)
{
if (_TrajetoriaFixa[i].Visitado)
{
_pontoAtual = _TrajetoriaFixa[i];
return;
}
}
_pontoAtual = null;
}
private PontoTrajetoriaModel _proximoPonto;
public PontoTrajetoriaModel ProximoPonto
{
get
{
if (_TrajetoriaFixa == null || !_TrajetoriaFixa.Any(x => !x.Visitado))
{
return PontoAtual;
}
return _TrajetoriaFixa.Where(x => !x.Visitado).OrderBy(x => x.idxPonto).FirstOrDefault();
return _proximoPonto;
}
}
private void DefinirProximoPonto()
{
if (_TrajetoriaFixa == null)
{
_proximoPonto = null;
}
// Busca eficiente: percorre do começo ao fim para achar o primeiro não visitado
for (int i = 0; i < _TrajetoriaFixa.Count; i++)
{
if (!_TrajetoriaFixa[i].Visitado)
{
_proximoPonto = _TrajetoriaFixa[i];
return;
}
}
_proximoPonto = PontoAtual; // Se não houver pontos não visitados, retorna o último ponto visitado
}
private bool _naMargemDoCorredor;
public bool NaMargemDoCorredor
{
get
{
bool naMargem = _TrajetoriaFixa.Any(x => x.NaMargem && x.PontoBorda);
return naMargem;
return _naMargemDoCorredor;
}
}
private void AtualizarNaMargemDoCorredor()
{
_naMargemDoCorredor = false;
foreach (var ponto in _TrajetoriaFixa)
{
if (ponto.NaMargem && ponto.PontoBorda)
{
_naMargemDoCorredor = true; // Paramos a busca assim que encontramos um ponto válido
return;
}
}
}
private bool _dentroCorredor;
public bool DentroCorredor
{
get
{
bool pontoRua = _TrajetoriaFixa.Any(x => x.idxCorredor == IdxCorredorAtual && x.NaMargem && x.Tipo == Enums.TipoPontoRua.Rua);
bool pontoBorda = _TrajetoriaFixa.Any(x => x.idxCorredor == IdxCorredorAtual && x.NaMargem && x.PontoBorda);
return pontoRua || pontoBorda;
return _dentroCorredor;
}
}
private void AtualizaDentroCorredor()
{
_dentroCorredor = false;
if (_Corredores == null || !_Corredores.ContainsKey(IdxCorredorAtual))
return;
// Itera diretamente sem criar uma lista temporária
foreach (var ponto in _Corredores[IdxCorredorAtual])
{
if (ponto.NaMargem && (ponto.Tipo == Enums.TipoPontoRua.Rua || ponto.PontoBorda))
{
_dentroCorredor = true;
return; // Encontramos um ponto válido, podemos sair
}
}
}
private bool _manobrandoEntreRuas;
public bool ManobrandoEntreRuas
{
get
{
// Caso o robo esteja manobrando em direcao a uma rua, qualquer movimento feito sera considerado aproximacao do primeiro ponto da rua
bool proximoAentrada = (ProximoPonto.PontoBorda || ProximoPonto.PontoLigacao) && ProximoPonto.DistanciaAtual < DistanciaManobraEntreRuas;
return (proximoAentrada && StatusAtual == StatusCarroMapa.Direcionando) || NaMargemDoCorredor;
return _manobrandoEntreRuas;
}
}
private void AtualizarManobrandoEntreRuas()
{
bool proximoAentrada = (ProximoPonto.PontoBorda || ProximoPonto.PontoLigacao) && ProximoPonto.DistanciaAtual < DistanciaManobraEntreRuas;
_manobrandoEntreRuas = (proximoAentrada && StatusAtual == StatusCarroMapa.Direcionando) || NaMargemDoCorredor;
}
private Enums.StatusCarroMapa _statusAtual = Enums.StatusCarroMapa.Parado;
public Enums.StatusCarroMapa StatusAtual
{
@ -262,8 +372,52 @@ namespace AgroBase.Models
return _statusAtual;
}
}
private void AtualizarStatusAtual()
{
_statusAtual = Enums.StatusCarroMapa.Parado;
if (ProximoPonto != null)
{
if (!DentroCorredor && (PontoAtual.Tipo == TipoPontoRua.PosicaoRobo || PontoAtual.PontoLigacao || ProximoPonto.PontoLigacao))
{
_statusAtual = Enums.StatusCarroMapa.Direcionando;
}
else if (DentroCorredor && !NaMargemDoCorredor)
{
_statusAtual = Enums.StatusCarroMapa.CaminhandoRua;
}
else if (!DentroCorredor && (!PontoAtual.PontoLigacao && !ProximoPonto.PontoLigacao))
{
_statusAtual = Enums.StatusCarroMapa.Manobrando;
}
else if (_TrajetoriaFixa.Any(x => x.NaMargem && x.Tipo == Enums.TipoPontoRua.BordaEntrada))
{
_statusAtual = Enums.StatusCarroMapa.EntrandoRua;
}
else if (_TrajetoriaFixa.Any(x => x.NaMargem && x.Tipo == Enums.TipoPontoRua.BordaSaida))
{
_statusAtual = Enums.StatusCarroMapa.SaindoRua;
}
}
}
private void AtualizarDadosTrajetoria()
{
DefinirPontoAtual();
DefinirProximoPonto();
AtualizarDistanciasLaterais();
AtualizarNaMargemDoCorredor();
AtualizaDentroCorredor();
AtualizarManobrandoEntreRuas();
AtualizarStatusAtual();
AtualizarCorredoresNaoFinalizados();
double velocidadeCarroMs = FuncoesMatematicas.CalculaVelocidadeMsPercentual(Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP);
AtualizarDistanciaMaximaEntreLeituras(velocidadeCarroMs);
}
public double DistanciaTotal { get; private set; }
public double DistanciaPercorrida
@ -339,44 +493,16 @@ namespace AgroBase.Models
public void LoopAtualizaDados()
{
#region ATUALIZACAO DE STATUS DO CARRO NO MAPA
bool dentroCorredor = DentroCorredor;
var proximoPonto = ProximoPonto;
var pontoAtual = PontoAtual;
Enums.StatusCarroMapa statusAtual = Enums.StatusCarroMapa.Parado;
if (proximoPonto != null)
{
if (!dentroCorredor && (pontoAtual.PontoLigacao || proximoPonto.PontoLigacao))
{
statusAtual = Enums.StatusCarroMapa.Direcionando;
}
else if (_TrajetoriaFixa.Any(x => x.NaMargem && x.Tipo == Enums.TipoPontoRua.BordaEntrada))
{
statusAtual = Enums.StatusCarroMapa.EntrandoRua;
}
else if (dentroCorredor && !NaMargemDoCorredor)
{
statusAtual = Enums.StatusCarroMapa.CaminhandoRua;
}
else if (_TrajetoriaFixa.Any(x => x.NaMargem && x.Tipo == Enums.TipoPontoRua.BordaSaida))
{
statusAtual = Enums.StatusCarroMapa.SaindoRua;
}
else if (!dentroCorredor && (!pontoAtual.PontoLigacao && !proximoPonto.PontoLigacao))
{
statusAtual = Enums.StatusCarroMapa.Manobrando;
}
}
_statusAtual = statusAtual;
#endregion
#region PONTO ATUAL
double dt = Math.Min((1.0 / GPSService.TaxaAmostragemHz), (UltimaAtualizacaoDados - GPSService.UltimaLeitura.Momento).TotalSeconds);
if (_TrajetoriaFixa.Any(x => x.NaMargem && !x.Visitado))
#region ATUALIZAR PONTOS VISITADOS
/*if (_TrajetoriaFixa.Any(x => x.NaMargem && !x.Visitado))
{
double velocidadeCarroMs = FuncoesMatematicas.CalculaVelocidadeMsPercentual(Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP);
@ -392,26 +518,38 @@ namespace AgroBase.Models
double limiteDistancia = pontosCobertos * distanciaEntrePontos;
var _trajetoriaFixa = _TrajetoriaFixa.Where(x => !x.Visitado).Take(pontosCobertos).ToList();
// Melhor filtro: Seleciona diretamente os pontos não visitados e que estão na margem
var pontosParaAtualizar = _TrajetoriaFixa
.Where(x => x.NaMargem && !x.Visitado && x.DistanciaTrajeto <= limiteDistancia)
.Take(pontosCobertos)
.ToList();
foreach (var ponto in _trajetoriaFixa.Where(x => x.NaMargem))
// Atualiza diretamente os pontos visitados
foreach (var ponto in pontosParaAtualizar)
{
if (ponto.DistanciaTrajeto <= limiteDistancia)
{
ponto.Visitado = true;
}
ponto.Visitado = true;
}
}
UltimaAtualizacaoDados = GPSService.UltimaLeitura.Momento;
}*/
double velocidadeCarroMs = FuncoesMatematicas.CalculaVelocidadeMsPercentual(Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP);
AtualizarDistanciaMaximaEntreLeituras(velocidadeCarroMs);
AtualizarPropriedadesPontosTrajetoria();
AtualizarDadosTrajetoria();
#endregion
UltimaAtualizacaoDados = GPSService.UltimaLeitura.Momento;
Variaveis.OperacaoEmAndamento.AtualizaInformacoesControleOperacao();
GPSService.AtualizarTrajetoriaDinamica();
}
private (List<List<GPSModel>>, List<double>) ProjetarCorredores()
{
var corredores = new List<List<GPSModel>>();
@ -576,14 +714,13 @@ namespace AgroBase.Models
double larguraCorredorPadrao = 1.5;
Enums.DirecaoCarroRua direcaoAtual = ExtremoMaisProximoMapa == 0 ? Enums.DirecaoCarroRua.Ida : Enums.DirecaoCarroRua.Volta;
PontoTrajetoriaModel PontoRobo = new PontoTrajetoriaModel()
PontoTrajetoriaModel PontoRobo = new PontoTrajetoriaModel(TipoPontoRua.PosicaoRobo)
{
idxCorredor = 0,
idxPonto = _trajetoriaFixa.Count(),
idxPontoCorredor = 0,
Posicao = GPSService.UltimaLeitura,
Direcao = direcaoAtual,
Tipo = Enums.TipoPontoRua.PosicaoRobo,
Orientacao = 0,
Visitado = true,
LarguraCorredor = 1.0
@ -606,14 +743,13 @@ namespace AgroBase.Models
var ultimoPontoTrajetoria = _trajetoriaFixa.LastOrDefault();
PontoTrajetoriaModel PontoInicial = new PontoTrajetoriaModel()
PontoTrajetoriaModel PontoInicial = new PontoTrajetoriaModel(TipoPontoRua.LigacaoEntrada)
{
idxCorredor = idx,
idxPonto = _trajetoriaFixa.Count(),
idxPontoCorredor = _trajetoriaFixa.Count(x => x.idxCorredor == idx),
Posicao = PrimeiroPonto,
Direcao = direcaoAtual,
Tipo = Enums.TipoPontoRua.LigacaoEntrada,
Orientacao = GPSService.CalcularOrientacao(ultimoPontoTrajetoria.Posicao, PrimeiroPonto),
Visitado = false,
LarguraCorredor = larguraCorredorPadrao
@ -636,18 +772,19 @@ namespace AgroBase.Models
foreach (var ponto in CurvaConexao)
{
_trajetoriaFixa.Add(new PontoTrajetoriaModel()
bool pontoLigacao = CurvaConexao.IndexOf(ponto) == CurvaConexao.Count() - 1;
_trajetoriaFixa.Add(new PontoTrajetoriaModel(pontoLigacao ? TipoPontoRua.LigacaoEntrada : TipoPontoRua.CruvaEntreCorredores)
{
idxCorredor = idx,
idxPonto = _trajetoriaFixa.Count(),
idxPontoCorredor = _trajetoriaFixa.Count(x => x.idxCorredor == idx),
Posicao = ponto,
Direcao = DirecaoCarroRua.Manobra,
Tipo = Enums.TipoPontoRua.CruvaEntreCorredores,
Direcao = pontoLigacao ? direcaoAtual : DirecaoCarroRua.Manobra,
Orientacao = GPSService.CalcularOrientacao(_trajetoriaFixa.Last().Posicao, ponto),
Visitado = false,
LarguraCorredor = larguraCorredorPadrao
});
pontoLigacao = false;
}
PontoInicialAdicionado = true;
}
@ -664,14 +801,13 @@ namespace AgroBase.Models
bool bordaEntrada = idxPonto == 0;
bool bordaSaida = idxPonto == CorredorAtual.Count() - 1;
PontoTrajetoriaModel PontoTrajetoria = new PontoTrajetoriaModel()
PontoTrajetoriaModel PontoTrajetoria = new PontoTrajetoriaModel(bordaEntrada ? TipoPontoRua.BordaEntrada : bordaSaida ? TipoPontoRua.BordaSaida : TipoPontoRua.Rua)
{
idxCorredor = idx,
idxPonto = _trajetoriaFixa.Count(),
idxPontoCorredor = _trajetoriaFixa.Count(x => x.idxCorredor == idx),
Posicao = pontoAtual,
Direcao = direcaoAtual,
Tipo = bordaEntrada ? Enums.TipoPontoRua.BordaEntrada : bordaSaida ? Enums.TipoPontoRua.BordaSaida : Enums.TipoPontoRua.Rua,
Orientacao = GPSService.CalcularOrientacao(_trajetoriaFixa.Last().Posicao, pontoAtual),
Visitado = false,
LarguraCorredor = CorredoresLarguras[idx]
@ -680,14 +816,13 @@ namespace AgroBase.Models
_trajetoriaFixa.Add(PontoTrajetoria);
}
PontoTrajetoriaModel PontoFinal = new PontoTrajetoriaModel()
PontoTrajetoriaModel PontoFinal = new PontoTrajetoriaModel(TipoPontoRua.LigacaoSaida)
{
idxCorredor = idx,
idxPonto = _trajetoriaFixa.Count(),
idxPontoCorredor = _trajetoriaFixa.Count(x => x.idxCorredor == idx),
Posicao = UltimoPonto,
Direcao = direcaoAtual,
Tipo = Enums.TipoPontoRua.LigacaoSaida,
Orientacao = GPSService.CalcularOrientacao(_trajetoriaFixa.Last().Posicao, UltimoPonto),
Visitado = false,
LarguraCorredor = larguraCorredorPadrao
@ -698,9 +833,13 @@ namespace AgroBase.Models
}
_TrajetoriaFixa = new List<PontoTrajetoriaModel>(_trajetoriaFixa);
_Corredores = _TrajetoriaFixa.GroupBy(x => x.idxCorredor).ToDictionary(g => g.Key, g => g.ToList());
DistanciaTotal = GPSService.DistanciaDoTrecho(_trajetoriaFixa.Select(x => x.Posicao).ToList());
AtualizarDadosTrajetoria();
AtualizarPropriedadesPontosTrajetoria();
return _TrajetoriaFixa;
}
@ -794,87 +933,136 @@ namespace AgroBase.Models
public class PontoTrajetoriaModel
{
public int idxCorredor { get; set; }
public int idxPonto { get; set; }
public int idxPontoCorredor { get; set; }
public int idxCorredor { get; set; }
public int idxPonto { get; set; }
public int idxPontoCorredor { get; set; }
public GPSModel Posicao { get; set; }
public double Orientacao { get; set; }
public Enums.DirecaoCarroRua Direcao { get; set; }
public double DistanciaTrajeto
{
get
{
var pontoAtual = Variaveis.OperacaoEmAndamento.Trajetoria.PontoAtual;
int idxPontoAtual = pontoAtual.idxPonto;
int qtdPontos = idxPonto - idxPontoAtual;
double distancia = 0;
if (qtdPontos == 1)
{
distancia = pontoAtual.DistanciaAtual;
}
else
{
distancia = GPSService.DistanciaDoTrecho(Variaveis.OperacaoEmAndamento.Trajetoria.TrajetoriaFixa.Skip(idxPontoAtual).ToList().Take(qtdPontos).ToList());
}
double ditanciaP0 = pontoAtual.Aproximando ? pontoAtual.DistanciaAtual : -pontoAtual.DistanciaAtual;
distancia += ditanciaP0;
return distancia;
}
}
public double DistanciaAtual
{
get
{
double Ditancia = GPSService.DistanciaEntrePontos(GPSService.UltimaLeitura, Posicao);
return Ditancia;
}
}
public double DistanciaAnterior
{
get
{
double Ditancia = GPSService.DistanciaEntrePontos(GPSService.PenultimaLeitura, Posicao);
return Ditancia;
}
}
public bool Aproximando
{
get
{
double OrientacaoAtual = GPSService.CalcularOrientacao(GPSService.UltimaLeitura, Posicao);
double OrientacaoAnterior = GPSService.CalcularOrientacao(GPSService.PenultimaLeitura, Posicao);
double Dif = Math.Abs(OrientacaoAtual - OrientacaoAnterior);
bool SeAproximando = (Dif <= 10.0 && DistanciaAtual < DistanciaAnterior); // Mesma orientacao entre as leituras de posicao do robo e a distancia atual for maior que a distancia anterior
bool PassouPeloPonto = Dif >= 90.0; // Se a orientacao entre a posicao atual do robo em relacao ao ponto for muito grande, indica que o sentido esta oposto, entao o ponto esta entre as posicoes atual e anterior
return SeAproximando && !PassouPeloPonto;
}
}
public Enums.TipoPontoRua Tipo { get; }
public double LarguraCorredor { get; set; }
public bool NaMargem
{
get
{
bool DentroDaMargem = DistanciaAtual < (LarguraCorredor / 1.2);
return DentroDaMargem;
}
}
public bool Visitado { get; set; } = false;
public Enums.TipoPontoRua Tipo { get; set; }
public bool PontoBorda
// ✅ Agora, propriedades podem ser atualizadas com `set; private`
public double OrientacaoAtual { get; private set; }
public double OrientacaoAnterior { get; private set; }
public double DistanciaTrajeto { get; private set; }
public double DistanciaAtual { get; private set; }
public double DistanciaAnterior { get; private set; }
public bool Aproximando { get; private set; }
public bool NaMargem { get; private set; }
public bool PontoBorda { get; private set; }
public bool PontoLigacao { get; private set; }
// ✅ Construtor: Calcula propriedades fixas uma única vez
public PontoTrajetoriaModel(TipoPontoRua tipo)
{
get
Tipo = tipo;
PontoBorda = Tipo == Enums.TipoPontoRua.BordaEntrada || Tipo == Enums.TipoPontoRua.BordaSaida;
PontoLigacao = Tipo == Enums.TipoPontoRua.LigacaoEntrada || Tipo == Enums.TipoPontoRua.LigacaoSaida;
}
public void AtualizarPropriedades()
{
AtualizarDistanciaAtual();
AtualizarDistanciaAnterior();
AtualizarOrientacaoAtual();
AtualizarOrientacaoAnterior();
AtualizarNaMargem();
AtualizarAproximando();
AtualizarDistanciaTrajeto();
AtualizarVisitado();
}
private void AtualizarVisitado()
{
if (Visitado) return; // Se já foi visitado, não faz nada
double distanciaEntrePontos =
Tipo == TipoPontoRua.CruvaEntreCorredores ? (TrajetoriaMapaOperacaoModel.DistanciaEntrePontosCurva * 1.0) :
TrajetoriaMapaOperacaoModel.DistanciaEntrePontos;
// Define o limite de distância para considerar o ponto como visitado
double limiteDistancia = Math.Ceiling(TrajetoriaMapaOperacaoModel.DistanciaMaximaEntreLeituras / distanciaEntrePontos) * 2 * distanciaEntrePontos;
// Se o ponto está dentro da margem e dentro do limite de distância, marca como visitado
if (NaMargem && DistanciaTrajeto <= limiteDistancia)
{
return Tipo == Enums.TipoPontoRua.BordaEntrada || Tipo == Enums.TipoPontoRua.BordaSaida;
Visitado = true;
}
}
public bool PontoLigacao
private void AtualizarOrientacaoAtual()
{
get
OrientacaoAtual = GPSService.CalcularOrientacao(GPSService.UltimaLeitura, Posicao);
}
private void AtualizarOrientacaoAnterior()
{
OrientacaoAnterior = GPSService.CalcularOrientacao(GPSService.PenultimaLeitura, Posicao);
}
private void AtualizarDistanciaTrajeto()
{
var pontoAtual = Variaveis.OperacaoEmAndamento.Trajetoria.PontoAtual;
int idxPontoAtual = pontoAtual.idxPonto;
int qtdPontos = Math.Abs(idxPonto - idxPontoAtual) + 1; // Sempre positivo
if (qtdPontos == 1)
{
return Tipo == Enums.TipoPontoRua.LigacaoEntrada || Tipo == Enums.TipoPontoRua.LigacaoSaida;
DistanciaTrajeto = pontoAtual.Aproximando ? pontoAtual.DistanciaAtual : -pontoAtual.DistanciaAtual;
return;
}
// ✅ Definimos corretamente o intervalo da trajetória
int idxInicio = Math.Min(idxPontoAtual, idxPonto);
int idxFim = Math.Max(idxPontoAtual, idxPonto);
// ✅ Pega os pontos corretos, independentemente de direção
List<GPSModel> trecho = Variaveis.OperacaoEmAndamento.Trajetoria._TrajetoriaFixa
.Skip(idxInicio)
.Take(qtdPontos)
.ToList()
.ConvertAll(x => x.Posicao);
double distancia = GPSService.DistanciaDoTrecho(trecho);
// ✅ Agora decidimos se devemos somar ou subtrair a distância do ponto atual
double distanciaP0 = pontoAtual.Aproximando ? pontoAtual.DistanciaAtual : -pontoAtual.DistanciaAtual;
// ✅ Se o ponto está atrás, invertemos a distância final
if (idxPonto < idxPontoAtual)
{
distanciaP0 *= -1;
distancia *= -1;
}
DistanciaTrajeto = distancia + distanciaP0;
}
private void AtualizarDistanciaAtual()
{
DistanciaAtual = GPSService.DistanciaEntrePontos(GPSService.UltimaLeitura, Posicao);
}
private void AtualizarDistanciaAnterior()
{
DistanciaAnterior = GPSService.DistanciaEntrePontos(GPSService.PenultimaLeitura, Posicao);
}
private void AtualizarAproximando()
{
// ✅ Agora verificamos tudo de uma vez sem variáveis intermediárias
Aproximando = Math.Abs(OrientacaoAtual - OrientacaoAnterior) <= 10.0
&& DistanciaAtual < DistanciaAnterior
&& Math.Abs(OrientacaoAtual - OrientacaoAnterior) < 90.0;
}
private void AtualizarNaMargem()
{
NaMargem = DistanciaAtual < (LarguraCorredor / 1.2);
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long