otimizado trajetoria fixa
This commit is contained in:
parent
d72f6c06ca
commit
7f95089d7b
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue