refinado algoritmo de definicao de trajetoria dinamica

This commit is contained in:
Diego Freitas 2024-10-09 17:00:37 -03:00
parent 660d706cab
commit 7cabff2654
28 changed files with 885 additions and 608 deletions

Binary file not shown.

View File

@ -169,7 +169,7 @@ namespace AgroBase.Forms.Operacoes
txtCriadoEm.Text = new FileInfo(path).CreationTime.ToString("dd/MM/yyyy HH:mm");
txtRuasPercorrer.Text = Variaveis.OperacaoEmAndamento.Mapa.RuasPercorrer.Count().ToString();
txtDistanciaTotal.Text = Variaveis.OperacaoEmAndamento.Mapa.DistanciaTotal.ToString("0.00");
string tempo = Variaveis.OperacaoEmAndamento.TempoEstimado(velocidadeMax, velocidadeMin);
string tempo = Variaveis.OperacaoEmAndamento.TempoEstimadoOperacao(velocidadeMax, velocidadeMin);
txtTempoEstimado.Text = tempo;
pathOperacaoSelecionada = path;

View File

@ -79,6 +79,7 @@
this.lblAproximando = new System.Windows.Forms.Label();
this.lblDistProx = new System.Windows.Forms.Label();
this.lblDistAnt = new System.Windows.Forms.Label();
this.lblTempoEstimado = new System.Windows.Forms.Label();
this.pnlOpcoes.SuspendLayout();
this.gpbSonar.SuspendLayout();
this.gpbGPS.SuspendLayout();
@ -88,6 +89,7 @@
//
// pnlOpcoes
//
this.pnlOpcoes.Controls.Add(this.lblTempoEstimado);
this.pnlOpcoes.Controls.Add(this.lblStatusOperacao);
this.pnlOpcoes.Controls.Add(this.lblDistanciaLateral);
this.pnlOpcoes.Controls.Add(this.btnAtualizarLeitura);
@ -110,7 +112,7 @@
//
this.lblStatusOperacao.AutoSize = true;
this.lblStatusOperacao.Font = new System.Drawing.Font("Microsoft Sans Serif", 7.8F);
this.lblStatusOperacao.Location = new System.Drawing.Point(154, 35);
this.lblStatusOperacao.Location = new System.Drawing.Point(201, 35);
this.lblStatusOperacao.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblStatusOperacao.Name = "lblStatusOperacao";
this.lblStatusOperacao.Size = new System.Drawing.Size(133, 13);
@ -121,7 +123,7 @@
//
this.lblDistanciaLateral.AutoSize = true;
this.lblDistanciaLateral.Font = new System.Drawing.Font("Microsoft Sans Serif", 7.8F);
this.lblDistanciaLateral.Location = new System.Drawing.Point(154, 84);
this.lblDistanciaLateral.Location = new System.Drawing.Point(201, 84);
this.lblDistanciaLateral.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblDistanciaLateral.Name = "lblDistanciaLateral";
this.lblDistanciaLateral.Size = new System.Drawing.Size(117, 13);
@ -311,7 +313,7 @@
//
this.lblStatus.AutoSize = true;
this.lblStatus.Font = new System.Drawing.Font("Microsoft Sans Serif", 7.8F);
this.lblStatus.Location = new System.Drawing.Point(154, 70);
this.lblStatus.Location = new System.Drawing.Point(201, 69);
this.lblStatus.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblStatus.Name = "lblStatus";
this.lblStatus.Size = new System.Drawing.Size(96, 13);
@ -334,7 +336,7 @@
this.gpbGPS.Controls.Add(this.txtLongitude);
this.gpbGPS.Controls.Add(this.txtLatitude);
this.gpbGPS.Controls.Add(this.btnIniciarGPS);
this.gpbGPS.Location = new System.Drawing.Point(289, 2);
this.gpbGPS.Location = new System.Drawing.Point(378, 2);
this.gpbGPS.Margin = new System.Windows.Forms.Padding(2);
this.gpbGPS.Name = "gpbGPS";
this.gpbGPS.Padding = new System.Windows.Forms.Padding(2);
@ -672,6 +674,17 @@
this.lblDistAnt.TabIndex = 24;
this.lblDistAnt.Text = "Distância Ponto Anterior: 0,00 m";
//
// lblTempoEstimado
//
this.lblTempoEstimado.AutoSize = true;
this.lblTempoEstimado.Font = new System.Drawing.Font("Microsoft Sans Serif", 7.8F);
this.lblTempoEstimado.Location = new System.Drawing.Point(201, 54);
this.lblTempoEstimado.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblTempoEstimado.Name = "lblTempoEstimado";
this.lblTempoEstimado.Size = new System.Drawing.Size(133, 13);
this.lblTempoEstimado.TabIndex = 25;
this.lblTempoEstimado.Text = "Tempo estimado: 00:00:00";
//
// frmSimulacaoMapaGPS
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -764,5 +777,6 @@
private System.Windows.Forms.Label lblDistProx;
private System.Windows.Forms.Label lblDistAnt;
private System.Windows.Forms.Label lblStatusOperacao;
private System.Windows.Forms.Label lblTempoEstimado;
}
}

View File

@ -1,19 +1,11 @@
using AgroBase.Models;
using AgroBase.Services;
using CefSharp;
using SharpDX.Mathematics.Interop;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static AgroBase.Models.Enums;
using static Assimp.Metadata;
namespace AgroBase.Forms
{
@ -22,6 +14,7 @@ namespace AgroBase.Forms
Timer tmrSonar;
StatusCarroMapa StatusCarro = StatusCarroMapa.Parado;
MapaDinamicoModel MapaDinamico;
bool calc = false;
public frmSimulacaoMapaGPS()
{
@ -60,10 +53,10 @@ namespace AgroBase.Forms
lblDistProx.Text = "Distância Próximo Ponto: " + Variaveis.OperacaoEmAndamento.Mapa.DistanciaAteProximoPonto.ToString("0.00") + " m";
lblDistAnt.Text = "Distância Ponto Anterior: " + Variaveis.OperacaoEmAndamento.Mapa.DistanciaAtePontoAnterior.ToString("0.00") + " m";
lblTempoEstimado.Text = "Tempo Estimado: " + Variaveis.OperacaoEmAndamento.TempoEstimadoRestante();
if (Variaveis.OperacaoEmAndamento.Iniciado)
{
Variaveis.OperacaoEmAndamento.Mapa.GerarTrajetoriaDinamica();
pnlOrientacaoTrajeto.Invalidate();
pnlAnguloControle.Invalidate();
pnlOrientacaoCarro.Invalidate();
@ -178,7 +171,9 @@ namespace AgroBase.Forms
AtualizarPosicaoGPS();
calc = true;
Tmr_Tick(sender, e);
calc = false;
}
private void btnIniciarSimulacao_Click(object sender, EventArgs e)
@ -188,7 +183,7 @@ namespace AgroBase.Forms
MessageBox.Show("Selecione as ruas para realizar a operação!");
return;
}
Variaveis.OperacaoEmAndamento.Simulando = true;
Variaveis.OperacaoEmAndamento.IniciarSimulacao();
Variaveis.OperacaoEmAndamento.Iniciado = btnIniciarSimulacao.Text == "Iniciar Simulação";
btnIniciarSimulacao.Text = Variaveis.OperacaoEmAndamento.Iniciado ? "Parar Simulação" : "Iniciar Simulação";
if (Variaveis.OperacaoEmAndamento.Iniciado)
@ -302,9 +297,12 @@ namespace AgroBase.Forms
{
Variaveis.OperacaoEmAndamento.OpMapaGPS.CalculaDadosMovimentacaoAutonoma();
double anguloAtual = double.Parse(txtAnguloGPS.Text);
double novoAngulo = (anguloAtual + Variaveis.OperacaoEmAndamento.Controle.Angulo) % 360;
txtAnguloGPS.Text = novoAngulo.ToString("0.00");
if (calc)
{
double anguloAtual = double.Parse(txtAnguloGPS.Text);
double novoAngulo = (anguloAtual + Variaveis.OperacaoEmAndamento.Controle.Angulo) % 360;
txtAnguloGPS.Text = novoAngulo.ToString("0.00");
}
double anguloControle = Variaveis.OperacaoEmAndamento.Controle.Angulo;
txtAnguloControle.Text = anguloControle.ToString("0.00");

View File

@ -1,15 +1,9 @@
using AgroBase.Properties;
using AgroBase.Services;
using CefSharp.DevTools.Page;
using CefSharp.WinForms;
using Emgu.CV.Features2D;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static AgroBase.Models.Enums;
@ -25,13 +19,14 @@ namespace AgroBase.Models
public List<List<GPSModel>> TrajetoriaMapa { get; set; } = new List<List<GPSModel>>();
public List<List<GPSModel>> TrajetoriaProjetada { get; set; } = new List<List<GPSModel>>();
public List<GPSModel> TrajetoriaDinamica { get; set; } = new List<GPSModel>();
public readonly object TrajetoriaDinamica_Lock = new object();
public List<string> RuasPercorrer { get; set; } = new List<string>();
public List<string> RuasPercorridas { get; set; } = new List<string>();
public string RuaEmAndamento { get; set; }
public int IdxRuaAtual { get; set; } = 0;
public int IdxUltimoPontoTrajetoria { get; set;} = 0;
public bool AproximandoUltimoPontoTrajetoria { get; set;} = false;
public int IdxUltimoPontoTrajetoriaDinamica { get; set;} = 0;
public int IdxUltimoPontoTrajetoria { get; set; } = 0;
public bool AproximandoUltimoPontoTrajetoria { get; set; } = false;
public int IdxUltimoPontoTrajetoriaDinamica { get; set; } = 0;
public double DistanciaTotal
{
get
@ -51,21 +46,24 @@ namespace AgroBase.Models
get
{
DirecaoCarroRua direcaoCaminho = DirecaoCarroRua.Parado;
if (TrajetoriaDinamica.Any())
lock (TrajetoriaDinamica_Lock)
{
(GPSModel PontoMaisProximo, bool aproximando) = GPSService.PontoMaisProximoRuaProjetada(TrajetoriaDinamica, TrajetoriaTipo.Dinamica);
int idxPontoMaisProximo = TrajetoriaDinamica.IndexOf(PontoMaisProximo);
direcaoCaminho = TrajetoriaDinamica[idxPontoMaisProximo].DirecaoTrecho;
}
else
{
if (ExtremoMaisProximoMapa == 0)
if (TrajetoriaDinamica.Any())
{
direcaoCaminho = DirecaoCarroRua.Ida;
(GPSModel PontoMaisProximo, bool aproximando) = GPSService.PontoMaisProximoRuaProjetada(TrajetoriaDinamica, TrajetoriaTipo.Dinamica);
int idxPontoMaisProximo = TrajetoriaDinamica.IndexOf(PontoMaisProximo);
direcaoCaminho = TrajetoriaDinamica[idxPontoMaisProximo].DirecaoTrecho;
}
else
{
direcaoCaminho = DirecaoCarroRua.Volta;
if (ExtremoMaisProximoMapa == 0)
{
direcaoCaminho = DirecaoCarroRua.Ida;
}
else
{
direcaoCaminho = DirecaoCarroRua.Volta;
}
}
}
return direcaoCaminho;
@ -281,27 +279,30 @@ namespace AgroBase.Models
{
try
{
if (TrajetoriaDinamica.Any())
lock (TrajetoriaDinamica_Lock)
{
(GPSModel PontoMaisProximo, bool aproximando) = GPSService.PontoMaisProximoRuaProjetada(TrajetoriaDinamica, TrajetoriaTipo.Dinamica);
int idx = TrajetoriaDinamica.IndexOf(PontoMaisProximo);
if (TrajetoriaDinamica.Any())
{
(GPSModel PontoMaisProximo, bool aproximando) = GPSService.PontoMaisProximoRuaProjetada(TrajetoriaDinamica, TrajetoriaTipo.Dinamica);
int idx = TrajetoriaDinamica.IndexOf(PontoMaisProximo);
if ((idx + 1) >= TrajetoriaDinamica.Count())
if ((idx + 1) >= TrajetoriaDinamica.Count())
{
return 0;
}
double angulo = GPSService.CalcularOrientacao(TrajetoriaDinamica[idx], TrajetoriaDinamica[idx + 1]);
if (angulo == 0)
{
angulo = GPSService.CalcularOrientacao(TrajetoriaDinamica[idx + 1], TrajetoriaDinamica[idx + 2]);
}
return (!(angulo >= 0 || angulo <= 0)) ? 0 : angulo;
}
else
{
return 0;
}
double angulo = GPSService.CalcularOrientacao(TrajetoriaDinamica[idx], TrajetoriaDinamica[idx + 1]);
if (angulo == 0)
{
angulo = GPSService.CalcularOrientacao(TrajetoriaDinamica[idx + 1], TrajetoriaDinamica[idx + 2]);
}
return (!(angulo >= 0 || angulo <= 0)) ? 0 : angulo;
}
else
{
return 0;
}
}
catch
@ -498,6 +499,21 @@ namespace AgroBase.Models
}
}
private double distanciaInicialInicioParaFim = -1;
private double distanciaInicialFimParaInicio = -1;
public double DistanciaExtraTrajetoria
{
get
{
if (Math.Min(distanciaInicialInicioParaFim, distanciaInicialFimParaInicio) < 0)
{
return 0;
}
return Math.Min(distanciaInicialInicioParaFim, distanciaInicialFimParaInicio);
}
}
private bool GerandoTrajetoria = false;
public void btnCarregar_Click(object sender, EventArgs e, string caminhoArquivo = "", bool monitoramento = false)
{
@ -701,14 +717,33 @@ namespace AgroBase.Models
}
public void ReiniciarTrajetoriaDinamica()
{
distanciaInicialFimParaInicio = -1;
distanciaInicialInicioParaFim = -1;
}
public void GerarTrajetoriaDinamica()
{
if (GerandoTrajetoria)
{
return;
}
GerandoTrajetoria = true;
double distanciaEntreRuas = DistanciaEntreRuas(TrajetoriaMapa) / 2.0;
List<GPSModel> Caminho = new List<GPSModel>();
List<List<GPSModel>> _TrajetoriaProjetada = new List<List<GPSModel>>();
int _extremoMaisProximoMapa = ExtremoMaisProximoMapa;
StatusCarroMapa statusCarro = Variaveis.OperacaoEmAndamento.OpMapaGPS.ReferencialRuaGPS.StatusAtual;
DirecaoCarroRua direcaoRua = TrajetoriaDinamica.Any() && TrajetoriaDinamica[0].DirecaoTrecho != DirecaoCarroRua.Parado ? TrajetoriaDinamica[0].DirecaoTrecho : ExtremoMaisProximoMapa == 0 ? DirecaoCarroRua.Ida : DirecaoCarroRua.Volta;
StatusCarroMapa statusCarroAnterior = Variaveis.OperacaoEmAndamento.OpMapaGPS.ReferencialRuaGPS._EtapaAnterior;
DirecaoCarroRua direcaoRua = DirecaoCarroRua.Parado;
lock (TrajetoriaDinamica_Lock)
{
direcaoRua = TrajetoriaDinamica.Any() && TrajetoriaDinamica[0].DirecaoTrecho != DirecaoCarroRua.Parado ? TrajetoriaDinamica[0].DirecaoTrecho : _extremoMaisProximoMapa == 0 ? DirecaoCarroRua.Ida : DirecaoCarroRua.Volta;
}
for (int i = IdxRuaAtual; i < TrajetoriaMapa.Count(); i++)
{
@ -745,52 +780,94 @@ namespace AgroBase.Models
{
bool dentroRua = DentroDaRua;
(GPSModel PontoMaisProximo, bool aproximando) = GPSService.PontoMaisProximoRuaProjetada(RuaProjetada, TrajetoriaTipo.Rua);
int idxPontoMaisProximo = RuaProjetada.IndexOf(PontoMaisProximo);
GPSModel inicio = GPSService.UltimaLeitura;
List<GPSModel> _caminho = new List<GPSModel>();
GPSModel PontoComparar = new GPSModel();
// Se o robo estiver se aproximando do ponto mais proximo, e nao estiver vindo de fora da rua
if (aproximando && statusCarro != StatusCarroMapa.Direcionando)
GPSModel PontoComparar = new GPSModel();
int idxPontoMaisProximo = 0;
bool DefinirRotaInicial = false;
// O carro esta se direcionando para iniciar a operacao na primeira rua, entao escolhe o caminho mais proximo
if (DistanciaExtraTrajetoria == 0)
{
PontoComparar = PontoMaisProximo;
List<GPSModel> _caminhoDoInicioParaFim = GerarTrajetoLigacaoCarroPontoInicial(inicio, RuaAtual, RuaAtual[0], 0, DirecaoCarroRua.Ida, statusCarro);
distanciaInicialInicioParaFim = GPSService.DistanciaDoTrecho(_caminhoDoInicioParaFim);
List<GPSModel> _caminhoDoFimParaInicio = GerarTrajetoLigacaoCarroPontoInicial(inicio, RuaAtual, RuaAtual[RuaAtual.Count() - 1], RuaAtual.Count() - 1, DirecaoCarroRua.Volta, statusCarro);
distanciaInicialFimParaInicio = GPSService.DistanciaDoTrecho(_caminhoDoFimParaInicio);
DefinirRotaInicial = true;
}
// Se o robo estiver se aproximando do ponto mais proximo, e estiver vindo de fora da rua
else if (aproximando && statusCarro == StatusCarroMapa.Direcionando)
bool IrPeloInicio = distanciaInicialInicioParaFim < distanciaInicialFimParaInicio;
double dP0 = GPSService.DistanciaEntrePontos(inicio, RuaAtual[0]);
double dP1 = GPSService.DistanciaEntrePontos(inicio, RuaAtual[RuaAtual.Count() - 1]);
// Define manualmente a direcao para onde o carro deve ir, se orientando pela decisao inicial da melhor trajetoria, impedindo que ocorram mudancas no trajeto
if (DefinirRotaInicial || ( statusCarro == StatusCarroMapa.Direcionando && statusCarroAnterior == StatusCarroMapa.Parado && IdxRuaAtual == 0 && (IrPeloInicio ? dP0 > dP1 : dP1 > dP0)))
{
var _a = GPSService.DistanciaEntrePontos(inicio, PrimeiroPonto);
var _b = GPSService.DistanciaEntrePontos(inicio, PontoMaisProximo);
bool _c = GPSService.EstaEntrePontos(inicio, PontoMaisProximo, PrimeiroPonto);
// Verifica se o robo esta na margem da rua projetada e se a distancia do robo ate o ponto mais proximo da rua (0) e menor que a distancia ate o primeiro ponto projetado, ou entao se o robo esta entre ambos
if ((_b < DistanciaProjecaoRua && _b < _a) || _c)
{
PontoComparar = PontoMaisProximo;
}
else
{
PontoComparar = PrimeiroPonto;
}
}
// Se o robo estiver se afastando do ponto mais proximo, e estiver dentro da rua, e houver mais pontos na trajetoria
else if (!aproximando && dentroRua && RuaProjetada.Count() > (idxPontoMaisProximo + 1))
{
// Interpolar a posicao atual ate o proximo ponto, pois ja passou pelo ponto mais proximo
idxPontoMaisProximo++;
PontoComparar = RuaProjetada[idxPontoMaisProximo];
}
else if (!aproximando && !dentroRua && RuaProjetada.Count() == (idxPontoMaisProximo + 1))
{
PontoComparar = UltimoPonto;
idxPontoMaisProximo = IrPeloInicio ? 0 : RuaAtual.Count() - 1;
_extremoMaisProximoMapa = IrPeloInicio ? 0 : 1;
direcaoRua = IrPeloInicio ? DirecaoCarroRua.Ida : DirecaoCarroRua.Volta;
PontoComparar = RuaAtual[idxPontoMaisProximo];
}
else
{
PontoComparar = PontoMaisProximo;
(GPSModel PontoMaisProximo, bool aproximando) = GPSService.PontoMaisProximoRuaProjetada(RuaProjetada, TrajetoriaTipo.Rua);
idxPontoMaisProximo = RuaProjetada.IndexOf(PontoMaisProximo);
// Se o robo estiver se aproximando do ponto mais proximo, e nao estiver vindo de fora da rua
if (aproximando && statusCarro != StatusCarroMapa.Direcionando)
{
PontoComparar = PontoMaisProximo;
}
// Se o robo estiver se aproximando do ponto mais proximo, e estiver vindo de fora da rua
else if (aproximando && statusCarro == StatusCarroMapa.Direcionando)
{
var _a = GPSService.DistanciaEntrePontos(inicio, PrimeiroPonto);
var _b = GPSService.DistanciaEntrePontos(inicio, PontoMaisProximo);
bool _c = GPSService.EstaEntrePontos(inicio, PontoMaisProximo, PrimeiroPonto);
// Verifica se o robo esta na margem da rua projetada e se a distancia do robo ate o ponto mais proximo da rua (0) e menor que a distancia ate o primeiro ponto projetado, ou entao se o robo esta entre ambos
if ((_b < DistanciaProjecaoRua && _b < _a) || _c)
{
PontoComparar = PontoMaisProximo;
}
else
{
PontoComparar = PrimeiroPonto;
}
}
// Se o robo estiver se afastando do ponto mais proximo, e estiver dentro da rua, e houver mais pontos na trajetoria
else if (!aproximando && dentroRua && RuaProjetada.Count() > (idxPontoMaisProximo + 1))
{
// Interpolar a posicao atual ate o proximo ponto, pois ja passou pelo ponto mais proximo
idxPontoMaisProximo++;
PontoComparar = RuaProjetada[idxPontoMaisProximo];
}
else if (!aproximando && !dentroRua && RuaProjetada.Count() == (idxPontoMaisProximo + 1))
{
PontoComparar = UltimoPonto;
}
else
{
PontoComparar = PontoMaisProximo;
}
}
_caminho.AddRange(GPSService.InterpolarPontos(inicio, PontoComparar, 1.0));
List<GPSModel> _caminhoInterpolado = GerarTrajetoLigacaoCarroPontoInicial(inicio, RuaAtual, PontoComparar, _extremoMaisProximoMapa, direcaoRua, statusCarro);
_caminho.AddRange(_caminhoInterpolado);
// se a distancia entre a posicao do robo e proximo ponto for menor que 1 metro, significa que o ponto interpolado esta mais adiante que o proximo ponto, entao tambem ignoramos ele
var a = GPSService.DistanciaEntrePontos(inicio, _caminho.Last());
@ -879,31 +956,36 @@ namespace AgroBase.Models
// Limpa a trajetória dinâmica existente e adiciona os novos pontos
TrajetoriaProjetada = new List<List<GPSModel>>(_TrajetoriaProjetada);
TrajetoriaDinamica.Clear();
Caminho.ForEach(x =>
lock (TrajetoriaDinamica_Lock)
{
// Impede inclusão de pontos duplicados
if (!TrajetoriaDinamica.Contains(x))
TrajetoriaProjetada = new List<List<GPSModel>>(_TrajetoriaProjetada);
TrajetoriaDinamica.Clear();
Caminho.ForEach(x =>
{
TrajetoriaDinamica.Add(x);
}
});
Variaveis.OperacaoEmAndamento.Mapa.IdxUltimoPontoTrajetoriaDinamica = 0;
// Impede inclusão de pontos duplicados
if (!TrajetoriaDinamica.Contains(x))
{
TrajetoriaDinamica.Add(x);
}
});
Variaveis.OperacaoEmAndamento.Mapa.IdxUltimoPontoTrajetoriaDinamica = 0;
if (KinectService.Iniciado && Variaveis.OperacaoEmAndamento.Sensoriamento.SonarFrontal_Kinect.StatusDetecao)
{
if (Variaveis.OperacaoEmAndamento.OpMapaGPS.StatusDentroRua.Contains(statusCarro))
if (KinectService.Iniciado && Variaveis.OperacaoEmAndamento.Sensoriamento.SonarFrontal_Kinect.StatusDetecao)
{
TrajetoriaDinamica.Clear();
}
else
{
AjustarTrajetoriaParaDesvio(Variaveis.OperacaoEmAndamento.Sensoriamento.SonarFrontal_Kinect.ObstaculoCritico);
if (Variaveis.OperacaoEmAndamento.OpMapaGPS.StatusDentroRua.Contains(statusCarro))
{
TrajetoriaDinamica.Clear();
}
else
{
AjustarTrajetoriaParaDesvio(Variaveis.OperacaoEmAndamento.Sensoriamento.SonarFrontal_Kinect.ObstaculoCritico);
}
}
}
GPSService.AtualizarTrajetoriaDinamica();
GerandoTrajetoria = false;
}
public List<GPSModel> ProjetarRua(List<GPSModel> ruaOriginal, double offset, double anguloOffset)
@ -972,7 +1054,179 @@ namespace AgroBase.Models
return pontosCurva;
}
private List<GPSModel> GerarTrajetoLigacaoCarroPontoInicial(GPSModel inicio, List<GPSModel> RuaAtual, GPSModel PontoComparar, int _extremoMaisProximoMapa, DirecaoCarroRua direcaoRua, StatusCarroMapa statusCarro)
{
List<GPSModel> _caminho = new List<GPSModel>();
bool CopiarRuasLaterais = true;
if (CopiarRuasLaterais && statusCarro == StatusCarroMapa.Direcionando && IdxRuaAtual == 0 && ((_extremoMaisProximoMapa == 0 && direcaoRua == DirecaoCarroRua.Ida) || (_extremoMaisProximoMapa > 0 && direcaoRua == DirecaoCarroRua.Volta)))
{
int idx = 0;
double distMin = double.MaxValue;
var DadosMapa = Variaveis.OperacaoEmAndamento.Mapa.mapaService.DadosMapa;
double anguloCaminho = GPSService.CalcularOrientacao(inicio, PontoComparar);
var PontosOrdenados = DadosMapa.features
.Select(x => new
{
x.geometry.id,
dist = GPSService.DistanciaEntrePontos(inicio, new GPSModel() { Longitude = x.geometry.coordinates[GetIndexInicial(x.geometry.coordinates, _extremoMaisProximoMapa)][0], Latitude = x.geometry.coordinates[GetIndexInicial(x.geometry.coordinates, _extremoMaisProximoMapa)][1] }),
orientacao = GPSService.CalcularOrientacao(inicio, new GPSModel() { Longitude = x.geometry.coordinates[GetIndexInicial(x.geometry.coordinates, _extremoMaisProximoMapa)][0], Latitude = x.geometry.coordinates[GetIndexInicial(x.geometry.coordinates, _extremoMaisProximoMapa)][1] }),
coordenadas = new GPSModel()
{
Longitude = x.geometry.coordinates[GetIndexInicial(x.geometry.coordinates, _extremoMaisProximoMapa)][0],
Latitude = x.geometry.coordinates[GetIndexInicial(x.geometry.coordinates, _extremoMaisProximoMapa)][1],
}
})
.ToList()
.Where(x =>
{
// Normalizando os ângulos entre 0 e 360
double orientacaoNormalizada = (x.orientacao + 360) % 360;
double anguloCaminhoNormalizado = (anguloCaminho + 360) % 360;
// Definindo o intervalo de 90 graus para mais e para menos
double limiteInferior = (anguloCaminhoNormalizado - 90 + 360) % 360;
double limiteSuperior = (anguloCaminhoNormalizado + 90 + 360) % 360;
// Verificando se a orientação está dentro do intervalo permitido
if (limiteInferior < limiteSuperior)
{
return orientacaoNormalizada >= limiteInferior && orientacaoNormalizada <= limiteSuperior;
}
else // Caso o intervalo passe por 0 graus
{
return orientacaoNormalizada >= limiteInferior || orientacaoNormalizada <= limiteSuperior;
}
})
.OrderBy(x => x.dist)
.ToList();
foreach (var rua in PontosOrdenados)
{
double dist = GPSService.DistanciaEntrePontos(PontoComparar, rua.coordenadas);
if (dist < distMin)
{
distMin = dist;
idx = PontosOrdenados.IndexOf(rua);
}
};
double anguloDeslocar = CalcularDeslocamentoDinamico(_extremoMaisProximoMapa == 0 ? 0 : RuaAtual.Count() - 1, RuaAtual);
_caminho.Add(inicio);
double velocidade = MovimentacaoModel.CalculaVelocidadeRPM(Variaveis.OperacaoEmAndamento.Controle.RPM_SP);
double velocidadeMs = MovimentacaoModel.ConverteKmhParaMs(velocidade);
double distancia = velocidadeMs;
int pontosPular = 1;
PontosOrdenados.ForEach(p =>
{
double d = GPSService.DistanciaEntrePontos(inicio, p.coordenadas);
if (d <= (distancia + 2))
{
pontosPular++;
}
});
for (int iidx = pontosPular; iidx < idx; iidx++)
{
GPSModel p0 = GPSService.ProjetarPontoDeslocado(PontosOrdenados[iidx > 0 ? iidx - 1 : iidx].coordenadas, 3.0, anguloDeslocar);
GPSModel p = GPSService.ProjetarPontoDeslocado(PontosOrdenados[iidx > 0 ? iidx : iidx + 1].coordenadas, 3.0, anguloDeslocar);
double orientacao = PontosOrdenados[iidx].orientacao;
double orientacaoA = PontosOrdenados[iidx > 0 ? iidx - 1 : iidx].orientacao;
double distP1 = GPSService.DistanciaEntrePontos(inicio, PontoComparar);
double anguloP1 = GPSService.CalcularOrientacao(inicio, PontoComparar);
double distP = GPSService.DistanciaEntrePontos(inicio, p);
double anguloP = GPSService.CalcularOrientacao(inicio, p);
//if ((orientacao <= (orientacaoA + 90) && orientacao >= (orientacaoA - 90)))
if ((orientacao <= (orientacaoA + 90) && orientacao >= (orientacaoA - 90)) && distP1 > distP && (anguloP >= (anguloP1 - 45) && anguloP <= (anguloP1 + 45)))
{
_caminho.Add(p);
}
}
_caminho.Add(PontoComparar);
}
else
{
_caminho.AddRange(GPSService.InterpolarPontos(inicio, PontoComparar, 1.0));
}
return _caminho;
}
public static double CalcularDeslocamentoDinamico(int idxPontoExtremo, List<GPSModel> ruaAtual)
{
// Inicializar variáveis de deslocamento
double anguloDeslocamento = 0;
double anguloRua = 0;
bool naHorizontal = false;
// Calcular a orientação da rua com base no ponto extremo mais próximo
if (idxPontoExtremo == 0)
{
anguloRua = GPSService.CalcularOrientacao(ruaAtual[0], ruaAtual[1]);
}
else
{
anguloRua = GPSService.CalcularOrientacao(ruaAtual[idxPontoExtremo], ruaAtual[idxPontoExtremo - 1]);
}
// Normalizar o ângulo para o intervalo [0, 360)
anguloRua = (anguloRua + 360) % 360;
// Definir a tolerância para considerar uma rua como vertical ou horizontal
double tolerancia = 45.0;
// Verificar se a rua está na vertical (próxima de 0° ou 180°)
if ((anguloRua >= 0 && anguloRua <= tolerancia) || (anguloRua >= 180 - tolerancia && anguloRua <= 180 + tolerancia))
{
naHorizontal = false; // A rua está mais alinhada verticalmente
}
// Verificar se a rua está na horizontal (próxima de 90° ou 270°)
else if ((anguloRua >= 90 - tolerancia && anguloRua <= 90 + tolerancia) || (anguloRua >= 270 - tolerancia && anguloRua <= 270 + tolerancia))
{
naHorizontal = true; // A rua está mais alinhada horizontalmente
}
// Calcular o deslocamento com base na orientação da rua
if (naHorizontal)
{
if (idxPontoExtremo == 0)
{
anguloDeslocamento = 270 - 45; // Deslocar para a esquerda e ligeiramente para baixo
}
else
{
anguloDeslocamento = 90 + 45; // Deslocar para a direita e ligeiramente para baixo
}
}
else
{
if (idxPontoExtremo == 0)
{
anguloDeslocamento = 0 - 45; // Deslocar para cima e ligeiramente para a esquerda
}
else
{
anguloDeslocamento = 180 + 45; // Deslocar para baixo e ligeiramente para a esquerda
}
}
// Normalizar o ângulo de deslocamento para ficar entre 0 e 360 graus
anguloDeslocamento = (anguloDeslocamento + 360) % 360;
// Retornar o ângulo de deslocamento calculado
return anguloDeslocamento;
}
private static int GetIndexInicial(List<List<double>> coordinates, int extremoProximo)
{
return extremoProximo == 0 ? 0 : coordinates.Count() - 1;
}
@ -1020,32 +1274,11 @@ namespace AgroBase.Models
};
var idxRemover = EncontrarIndiceFinalDesvio(TrajetoriaDinamica, ponto3, distanciaObstaculo);
TrajetoriaDinamica.RemoveRange(1, idxRemover);
TrajetoriaDinamica.InsertRange(1, lista);
return;
// Identificar o waypoint mais próximo para iniciar o desvio
int indiceInicioDesvio = EncontrarIndiceInicioDesvio(TrajetoriaDinamica, posicaoAtual, distanciaObstaculo);
// Calcular os waypoints de desvio
var waypointsDesvio = CalcularWaypointsDesvio(posicaoAtual, obstaculo, indiceInicioDesvio);
// Determinar o intervalo de waypoints a serem removidos
double distanciaSeguranca = ((double)obstaculo.DeslocamentoNecessarioDesvio * 2 / 100);
int indiceFinalDesvio = EncontrarIndiceFinalDesvio(TrajetoriaDinamica, waypointsDesvio.Last(), distanciaSeguranca);
int quantidadeWaypointsRemover = indiceFinalDesvio - indiceInicioDesvio;
// Remover waypoints obsoletos
if (quantidadeWaypointsRemover > 0)
lock (TrajetoriaDinamica_Lock)
{
TrajetoriaDinamica.RemoveRange(indiceInicioDesvio + 1, quantidadeWaypointsRemover);
TrajetoriaDinamica.RemoveRange(1, idxRemover);
TrajetoriaDinamica.InsertRange(1, lista);
}
// Inserir waypoints de desvio na trajetória
TrajetoriaDinamica.InsertRange(indiceInicioDesvio + 1, waypointsDesvio);
}
private int EncontrarIndiceFinalDesvio(List<GPSModel> trajetoria, GPSModel ultimoWaypointDesvio, double distanciaSeguranca)
@ -1189,15 +1422,18 @@ namespace AgroBase.Models
// Ordena os pontos com offset pela proximidade com a posição atual
var pontosOrdenados = pontosRelevantes.OrderBy(p => GPSService.DistanciaEntrePontos(inicio, p)).ToList();
// Agora, conecta os pontos ordenados para formar a trajetória
TrajetoriaDinamica.Clear();
GPSModel pontoAnterior = inicio;
foreach (var ponto in pontosOrdenados)
lock (TrajetoriaDinamica_Lock)
{
//var caminho = GPSService.InterpolarPontos(pontoAnterior, ponto, 1.0);
//caminho.ForEach(x => TrajetoriaDinamica.Add(x));
//pontoAnterior = ponto;
TrajetoriaDinamica.Add(ponto);
// Agora, conecta os pontos ordenados para formar a trajetória
TrajetoriaDinamica.Clear();
GPSModel pontoAnterior = inicio;
foreach (var ponto in pontosOrdenados)
{
//var caminho = GPSService.InterpolarPontos(pontoAnterior, ponto, 1.0);
//caminho.ForEach(x => TrajetoriaDinamica.Add(x));
//pontoAnterior = ponto;
TrajetoriaDinamica.Add(ponto);
}
}
// Atualiza a trajetória dinâmica

View File

@ -1,17 +1,10 @@
using AgroBase.Forms.Operacoes;
using AgroBase.Models.Modules;
using AgroBase.Services;
using CefSharp.DevTools.Database;
using Emgu.CV;
using Emgu.CV.ML;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static AgroBase.Models.Enums;
@ -174,9 +167,29 @@ namespace AgroBase.Models.Operacoes
{
Controle.PercentualVelocidadeSP = Controle.PercentualVelocidadeMin;
}
else if (Variaveis.OperacaoEmAndamento.Mapa.IdxRuaAtual > 0 && Variaveis.OperacaoEmAndamento.Mapa.DistanciaAteProximoPonto < 10.0)
{
Controle.PercentualVelocidadeSP = Controle.PercentualVelocidadeMin;
}
else if (Math.Abs(Controle.Angulo) > (Controle.Angulo_Max * 0.4))
{
Controle.PercentualVelocidadeSP = Controle.PercentualVelocidadeMin;
}
else
{
Controle.PercentualVelocidadeSP = Controle.PercentualVelocidadeMax;
/*double ag0 = GPSService.CalcularOrientacao(GPSService.UltimaLeitura, Variaveis.OperacaoEmAndamento.Mapa.TrajetoriaDinamica[1]);
double ag1 = GPSService.CalcularOrientacao(GPSService.UltimaLeitura, Variaveis.OperacaoEmAndamento.Mapa.TrajetoriaDinamica[2]);
double ag2 = GPSService.CalcularOrientacao(GPSService.UltimaLeitura, Variaveis.OperacaoEmAndamento.Mapa.TrajetoriaDinamica[2]);
double ag3 = GPSService.CalcularOrientacao(GPSService.UltimaLeitura, Variaveis.OperacaoEmAndamento.Mapa.TrajetoriaDinamica[2]);
if (Math.Abs(ag0 - ag1) > (Controle.Angulo_Max * 0.4) || Math.Abs(ag1 - ag2) > (Controle.Angulo_Max * 0.4) || Math.Abs(ag2 - ag3) > (Controle.Angulo_Max * 0.4))
{
Controle.PercentualVelocidadeSP = Controle.PercentualVelocidadeMax * 0.6;
}
else
{
Controle.PercentualVelocidadeSP = Controle.PercentualVelocidadeMax;
}*/
Controle.PercentualVelocidadeSP = Controle.PercentualVelocidadeMax * 0.6;
}
}
else if (statusAtual == StatusCarroMapa.EntrandoRua)
@ -208,6 +221,11 @@ namespace AgroBase.Models.Operacoes
{
Controle.PercentualVelocidadeSP = Controle.PercentualVelocidadeMax / 2.0;
}
if (Variaveis.OperacaoEmAndamento.Iniciado)
{
Variaveis.OperacaoEmAndamento.Mapa.GerarTrajetoriaDinamica();
}
}
public void AtualizarRuasSelecionadas()
@ -237,7 +255,7 @@ namespace AgroBase.Models.Operacoes
public class OperacaoRefRuaGPS
{
private List<StatusCarroMapa> _EtapasAnteriores = new List<StatusCarroMapa>() { StatusCarroMapa.Parado };
private StatusCarroMapa _EtapaAnterior
public StatusCarroMapa _EtapaAnterior
{
get
{

View File

@ -130,6 +130,10 @@ namespace AgroBase.Models
{
etapaAtual = StatusOperacao.Parametrizando;
}
else
{
//etapaAtual = StatusOperacao.NaoIniciado;
}
}
// Operação em andamento
else
@ -140,10 +144,18 @@ namespace AgroBase.Models
etapaAtual = StatusOperacao.EmAndamento;
}
// Se o trajeto foi finalizado
else if (Variaveis.OperacaoEmAndamento.OpMapaGPS.Concluido)
else if (Variaveis.OperacaoEmAndamento.OpMapaGPS.Concluido && _EtapaAtual != StatusOperacao.Concluido)
{
etapaAtual = StatusOperacao.Concluido;
}
// Etapa atual é finalizada, então finaliza a operação
else if (_EtapaAtual == StatusOperacao.Concluido)
{
if (Variaveis.OperacaoEmAndamento.Iniciado)
{
Variaveis.OperacaoEmAndamento.FinalizarOperacao();
}
}
// Se a operação tiver algum item mandatório interrompido
else if (!Variaveis.OperacaoEmAndamento.OperacaoLiberada)
{
@ -160,14 +172,6 @@ namespace AgroBase.Models
Variaveis.OperacaoEmAndamento.TempoAguardando = DateTime.Now;
etapaAtual = StatusOperacao.Aguardando;
}
// Etapa atual é finalizada, então finaliza a operação
else if (_EtapaAtual == StatusOperacao.Concluido)
{
if (Variaveis.OperacaoEmAndamento.Iniciado)
{
Variaveis.OperacaoEmAndamento.FinalizarOperacao();
}
}
// Contagem regressiva para iniciar a operação
else if (Variaveis.OperacaoEmAndamento.TempoAguardando.AddSeconds(Variaveis.OperacaoEmAndamento.TempoIniciarOperacao) > DateTime.Now)
{
@ -474,24 +478,29 @@ namespace AgroBase.Models
}
}
public string TempoEstimado(double velocidadeSemErvas, double velocidadeComErvas)
public string TempoEstimadoOperacao(double velocidadeSemErvas, double velocidadeComErvas)
{
double velocidadeDirecionamento = velocidadeSemErvas * 0.6;
// Conversão de velocidades para m/s
double velocidadeSemErvasMs = (velocidadeSemErvas * 1000) / 3600;
double velocidadeComErvasMs = (velocidadeComErvas * 1000) / 3600;
double velocidadeTrajetoriaMs = (velocidadeDirecionamento * 1000) / 3600;
// Supondo que metade do percurso tem ervas e a outra metade não tem
double distanciaSemErvas = Variaveis.OperacaoEmAndamento.Mapa.DistanciaTotal * VariaveisOperacao.PercentualSemErvas;
double distanciaComErvas = Variaveis.OperacaoEmAndamento.Mapa.DistanciaTotal * VariaveisOperacao.PercentualComErvas;
double distanciaTrajetoria = Variaveis.OperacaoEmAndamento.Mapa.DistanciaExtraTrajetoria;
// Tempo em segundos para cada parte do percurso
double tempoSemErvas = distanciaSemErvas / velocidadeSemErvasMs;
double tempoComErvas = distanciaComErvas / velocidadeComErvasMs;
double tempoDirecionamento = distanciaTrajetoria / velocidadeTrajetoriaMs;
double tempoManobras = Variaveis.OperacaoEmAndamento.Mapa.RuasPercorrer.Count() * VariaveisOperacao.TempoManobra;
// Tempo total em segundos
double tempoTotalSegundos = tempoSemErvas + tempoComErvas + tempoManobras;
double tempoTotalSegundos = tempoSemErvas + tempoComErvas + tempoDirecionamento + tempoManobras;
// Conversão para horas, minutos e segundos
TimeSpan tempoTotal = TimeSpan.FromSeconds(tempoTotalSegundos);
@ -499,6 +508,74 @@ namespace AgroBase.Models
return $"{tempoTotal.Hours:D2}:{tempoTotal.Minutes:D2}:{tempoTotal.Seconds:D2}";
}
public string TempoEstimadoRestante()
{
// Velocidades em RPM
double velocidadeSemErvas = MovimentacaoModel.CalculaVelocidadeRPM(Variaveis.OperacaoEmAndamento.Controle.RPM_Max);
double velocidadeComErvas = MovimentacaoModel.CalculaVelocidadeRPM(Variaveis.OperacaoEmAndamento.Controle.RPM_Min);
double velocidadeDirecionamento = velocidadeSemErvas * 0.6;
// Conversão de velocidades para m/s
double velocidadeSemErvasMs = (velocidadeSemErvas * 1000) / 3600;
double velocidadeComErvasMs = (velocidadeComErvas * 1000) / 3600;
double velocidadeTrajetoriaMs = (velocidadeDirecionamento * 1000) / 3600;
// Distâncias (em metros)
double distanciaTotal = (Variaveis.OperacaoEmAndamento.Mapa.DistanciaTotal + Variaveis.OperacaoEmAndamento.Mapa.DistanciaExtraTrajetoria);
double distanciaDirecionamento = Variaveis.OperacaoEmAndamento.Mapa.DistanciaExtraTrajetoria;
double distanciaPercorrida = GPSService.DistanciaDoTrecho(Variaveis.OperacaoEmAndamento.GPSTrajetoria);
double distanciaRestante = distanciaTotal - distanciaPercorrida;
// Percentuais de distância sem ervas e com ervas
double distanciaSemErvasTotal = (Variaveis.OperacaoEmAndamento.Mapa.DistanciaTotal * VariaveisOperacao.PercentualSemErvas);
double distanciaComErvasTotal = (Variaveis.OperacaoEmAndamento.Mapa.DistanciaTotal * VariaveisOperacao.PercentualComErvas);
// Variáveis para armazenar o tempo restante para cada parte
double tempoRestanteDirecionamento = 0;
double tempoRestanteSemErvas = 0;
double tempoRestanteComErvas = 0;
// Se o robô ainda estiver na fase de direcionamento
if (distanciaPercorrida < distanciaDirecionamento)
{
// Calcula o tempo restante apenas para a fase de direcionamento
double distanciaDirecionamentoRestante = distanciaDirecionamento - distanciaPercorrida;
tempoRestanteDirecionamento = distanciaDirecionamentoRestante / velocidadeTrajetoriaMs;
}
else
{
// Robô já completou a fase de direcionamento, agora lida com a distância sem e com ervas
// Subtrai a distância de direcionamento já percorrida
distanciaPercorrida -= distanciaDirecionamento;
distanciaRestante -= distanciaDirecionamento;
// Calcular a distância restante sem ervas e com ervas
double distanciaSemErvasRestante = (distanciaSemErvasTotal > distanciaPercorrida)
? distanciaSemErvasTotal - distanciaPercorrida
: 0;
double distanciaComErvasRestante = (distanciaComErvasTotal > distanciaPercorrida)
? distanciaComErvasTotal - distanciaPercorrida
: 0;
// Calcular o tempo restante para as áreas sem ervas e com ervas
tempoRestanteSemErvas = distanciaSemErvasRestante / velocidadeSemErvasMs;
tempoRestanteComErvas = distanciaComErvasRestante / velocidadeComErvasMs;
}
// Tempo restante para as manobras
double tempoRestanteManobras = Variaveis.OperacaoEmAndamento.Mapa.RuasPercorrer.Count() * VariaveisOperacao.TempoManobra;
// Tempo total restante em segundos
double tempoTotalRestanteSegundos = tempoRestanteDirecionamento + tempoRestanteSemErvas + tempoRestanteComErvas + tempoRestanteManobras;
// Conversão para horas, minutos e segundos
TimeSpan tempoTotalRestante = TimeSpan.FromSeconds(tempoTotalRestanteSegundos);
return $"{tempoTotalRestante.Hours:D2}:{tempoTotalRestante.Minutes:D2}:{tempoTotalRestante.Seconds:D2}";
}
public static OperacaoModel CarregarParametrosOperacaoPadrao(ModoOperacao Modo)
@ -802,12 +879,13 @@ namespace AgroBase.Models
await RealizarCalibracaoInicialAsync();
Mapa.ReiniciarTrajetoriaDinamica();
Mapa.GerarTrajetoriaDinamica();
}
public void FinalizarOperacao()
{
if (!Iniciado)
if (!Variaveis.OperacaoEmAndamento.Iniciado)
{
Variaveis.OperacaoEmAndamento.CamerasSolo.ForEach(Camera =>
{
@ -818,18 +896,21 @@ namespace AgroBase.Models
PararCarroOperacaoInterrompida();
if (DispAtu.Dados.BombaPressurizadora.Inicializado)
if (Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombaPressurizadora.Inicializado)
{
GeneralJoystick.EnviarComandoAtuador(S_Code.sBMB, false);
}
Iniciado = false;
TimestampFim = DateTime.Now.Ticks;
Variaveis.OperacaoEmAndamento.Iniciado = false;
Variaveis.OperacaoEmAndamento.TimestampFim = DateTime.Now.Ticks;
//tmrLogs.Stop();
//tmrParametrizacao.Start();
SalvarLogs(false);
if (!Variaveis.OperacaoEmAndamento.Simulando)
{
SalvarLogs(false);
}
AtualizarSinaleiroOperacao();
}
@ -869,6 +950,50 @@ namespace AgroBase.Models
}
}
public void IniciarSimulacao()
{
Iniciado = true;
Simulando = true;
TimestampInicio = DateTime.Now.Ticks;
TempoAguardando = DateTime.Now;
TimestampFim = 0;
Mapa.IdxRuaAtual = 0;
if (DispMvd != null)
{
DispMvd.Dados.DistanciaPercorridaOperacao = 0;
DispMvd.Dados.TempoEmAtividade = 0;
}
Sensoriamento.DistanciaPercorrida = new List<double>();
if (Modo == ModoOperacao.MapaGPS)
{
OpMapaGPS.Sensoriamento = new OperacaoMapaGPSSensoriamentoModel();
if (DispAtu != null)
{
DispAtu.Dados.BombaPressurizadora.BombaAtuada = false;
for (int i = 0; i < DispAtu.Dados.QuantidadeBicos; i++)
{
OpMapaGPS.Sensoriamento.AtuacoesPorBico.Add(0);
DispAtu.Dados.BicosPulverizadores[i].Atuado = false;
}
DispAtu.Dados.VolumeVazaoML = 0;
}
Controle.PIDdirecional = new PIDModel()
{
LimiteSaida = Controle.Angulo_Max,
SetPoint = 0,
Kp = 1.0,
Ki = 0.1,
Kd = 0.01,
};
}
GPSTrajetoria = new List<GPSModel>();
Mapa.ReiniciarTrajetoriaDinamica();
Mapa.GerarTrajetoriaDinamica();
}
#endregion
#region CAMERAS
@ -1230,7 +1355,7 @@ namespace AgroBase.Models
}
if (!Variaveis.OperacaoEmAndamento.Simulando)
if (!Variaveis.OperacaoEmAndamento.Simulando || true)
{
AtualizaInformacoesControleOperacao();
}

View File

@ -4,10 +4,8 @@ using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Windows.Forms;
using static AgroBase.Models.Enums;
using static AgroBase.Services.SerialService;
@ -517,7 +515,9 @@ namespace AgroBase.Services
double d = 0;
for (int i = 0; i < Trecho.Count - 1; i++)
{
d += DistanciaEntrePontos(Trecho[i], Trecho[i + 1]);
double _d = DistanciaEntrePontos(Trecho[i], Trecho[i + 1]);
//Console.WriteLine($"{i} - {_d}");
d += _d;
}
return d;
}
@ -656,15 +656,19 @@ namespace AgroBase.Services
public static void AtualizarTrajetoriaDinamica()
{
var Trajetoria = Variaveis.OperacaoEmAndamento.Mapa.TrajetoriaDinamica.Select(x => new
lock (Variaveis.OperacaoEmAndamento.Mapa.TrajetoriaDinamica_Lock)
{
latitude = x.Latitude,
longitude = x.Longitude
}).ToArray();
Variaveis.MqttService.PublishAsync(
Variaveis.MqttService.Topicos.First(x => x.Topico == MapasVariaveisModel.TopicoTrajetoriaDinamica),
JsonConvert.SerializeObject(Trajetoria)
).ConfigureAwait(false);
List<GPSModel> TJ = new List<GPSModel>(Variaveis.OperacaoEmAndamento.Mapa.TrajetoriaDinamica);
var Trajetoria = TJ.Select(x => new
{
latitude = x.Latitude,
longitude = x.Longitude
}).ToArray();
Variaveis.MqttService.PublishAsync(
Variaveis.MqttService.Topicos.First(x => x.Topico == MapasVariaveisModel.TopicoTrajetoriaDinamica),
JsonConvert.SerializeObject(Trajetoria)
).ConfigureAwait(false);
}
}
public static void AtualizarRuasSelecionadas(List<string> RuasSelecionadas)
@ -723,79 +727,6 @@ namespace AgroBase.Services
}
private static MapaFeatureCollectionModel TrajetoFake = new MapaFeatureCollectionModel();
private static int idxPonto = 0;
private static int idxRuaA = 0;
public static void SimularGPS()
{
var dados = File.ReadAllText("trajetoFakeGps.json");
TrajetoFake = JsonConvert.DeserializeObject<MapaFeatureCollectionModel>(dados);
int i = 0;
TrajetoFake.features.ForEach(feature =>
{
feature.geometry.id = i.ToString();
i++;
});
Timer tmr = new Timer() { Interval = 1000 };
tmr.Tick += Tmr_Tick;
tmr.Start();
}
private static void Tmr_Tick(object sender, EventArgs e)
{
if (Variaveis.OperacaoEmAndamento.Mapa.IdxRuaAtual >= TrajetoFake.features.Count) // Verifica se chegou ao fim do trajeto total
{
((Timer)sender).Stop();
return; // Encerra a execução para evitar processamento adicional
}
AtualizaLeituraSimulacao();
}
public static void AtualizaLeituraSimulacao()
{
if (idxRuaA != Variaveis.OperacaoEmAndamento.Mapa.IdxRuaAtual)
{
idxPonto = 0;
idxRuaA = Variaveis.OperacaoEmAndamento.Mapa.IdxRuaAtual;
//double distPP = DistanciaEntrePontos(UltimaLeitura, new GPSModel() { Longitude = TrajetoFake.features[idxRuaA].geometry.coordinates[0][0], Latitude = TrajetoFake.features[idxRuaA].geometry.coordinates[0][1] });
//double distUP = DistanciaEntrePontos(UltimaLeitura, new GPSModel() { Longitude = TrajetoFake.features[idxRuaA].geometry.coordinates[TrajetoFake.features[idxRuaA].geometry.coordinates.Count - 1][0], Latitude = TrajetoFake.features[idxRuaA].geometry.coordinates[TrajetoFake.features[idxRuaA].geometry.coordinates.Count - 1][1] });
if (idxRuaA % 2 != 0)
{
TrajetoFake.features[idxRuaA].geometry.coordinates.Reverse();
}
}
PenultimaLeitura = new GPSModel()
{
DataHora = UltimaLeitura.DataHora,
Longitude = UltimaLeitura.Longitude,
Latitude = UltimaLeitura.Latitude,
};
UltimaLeitura = new GPSModel()
{
DataHora = DateTime.Now,
Longitude = TrajetoFake.features[idxRuaA].geometry.coordinates[idxPonto][0],
Latitude = TrajetoFake.features[idxRuaA].geometry.coordinates[idxPonto][1],
};
//APIService.AtualizarCoordenadasGPS(UltimaLeitura, APIService.GPS_IDcoordenadasRobo);
AtualizarCoordenadasGPS();
var StatusCarro = Variaveis.OperacaoEmAndamento.OpMapaGPS.ReferencialRuaGPS.StatusAtual;
if (StatusCarro == Enums.StatusCarroMapa.Parado || StatusCarro == Enums.StatusCarroMapa.Direcionando)
{
return;
}
if (idxPonto < TrajetoFake.features[idxRuaA].geometry.coordinates.Count - 1)
{
idxPonto++;
}
}
}
}

View File

@ -781,7 +781,7 @@ namespace AgroBase.Services
TempoOperacao = Convert.ToInt32(Variaveis.OperacaoEmAndamento.Tempo.TotalSeconds),
PercentualRua = Variaveis.OperacaoEmAndamento.OpMapaGPS.Sensoriamento.ProgressoRua,
PercentualOperacao = Variaveis.OperacaoEmAndamento.OpMapaGPS.Sensoriamento.ProgressoTrajeto,
TempoEstimado = Variaveis.OperacaoEmAndamento.TempoEstimado(velocidadeMax, velocidadeMin),
TempoEstimado = Variaveis.OperacaoEmAndamento.TempoEstimadoOperacao(velocidadeMax, velocidadeMin),
},
Coordenadas = new LoRaProtocoloTransmissaoCoordenadasModel()
{

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -25,7 +25,7 @@
<meta name="viewport" content="width=device-width,
initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<style>
#map_cf8fae86d957a7a3939b7c65a7c2f6f9 {
#map_6ebe7d676636a464bcda2698ef3dd0bc {
position: relative;
width: 100.0%;
height: 100.0%;
@ -39,14 +39,14 @@
<body>
<div class="folium-map" id="map_cf8fae86d957a7a3939b7c65a7c2f6f9" ></div>
<div class="folium-map" id="map_6ebe7d676636a464bcda2698ef3dd0bc" ></div>
</body>
<script>
var map_cf8fae86d957a7a3939b7c65a7c2f6f9 = L.map(
"map_cf8fae86d957a7a3939b7c65a7c2f6f9",
var map_6ebe7d676636a464bcda2698ef3dd0bc = L.map(
"map_6ebe7d676636a464bcda2698ef3dd0bc",
{
center: [0.0, 0.0],
crs: L.CRS.EPSG3857,
@ -60,13 +60,13 @@
var tile_layer_2abdffe44d7eeb0bdc7f918520a25537 = L.tileLayer(
var tile_layer_a492f19b6d3542b6b52ca525e7345e29 = L.tileLayer(
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
{"attribution": "\u0026copy; \u003ca href=\"https://www.openstreetmap.org/copyright\"\u003eOpenStreetMap\u003c/a\u003e contributors", "detectRetina": false, "maxNativeZoom": 19, "maxZoom": 19, "minZoom": 0, "noWrap": false, "opacity": 1, "subdomains": "abc", "tms": false}
);
tile_layer_2abdffe44d7eeb0bdc7f918520a25537.addTo(map_cf8fae86d957a7a3939b7c65a7c2f6f9);
tile_layer_a492f19b6d3542b6b52ca525e7345e29.addTo(map_6ebe7d676636a464bcda2698ef3dd0bc);
</script>
@ -87,7 +87,7 @@
}
trajeto_json_add({"features": []});
trajeto_json.addTo(map_cf8fae86d957a7a3939b7c65a7c2f6f9);
trajeto_json.addTo(map_6ebe7d676636a464bcda2698ef3dd0bc);
function adicionarGeometria(novaGeometria) {
trajeto_json.addData(novaGeometria);
@ -145,7 +145,7 @@
var marcadorDinamico = L.marker([0, 0], {
icon: customIcon
}).addTo(map_cf8fae86d957a7a3939b7c65a7c2f6f9);
}).addTo(map_6ebe7d676636a464bcda2698ef3dd0bc);
// Conectar ao broker MQTT
const client = mqtt.connect('ws://localhost:9001'); // Use wss para conexão segura
@ -183,7 +183,7 @@
marcadorDinamico.setRotationAngle(angulo);
adicionarCoordenada("Tj", [novaLongitude, novaLatitude]);
map_cf8fae86d957a7a3939b7c65a7c2f6f9.setView(novaPosicao, map_cf8fae86d957a7a3939b7c65a7c2f6f9.getZoom());
map_6ebe7d676636a464bcda2698ef3dd0bc.setView(novaPosicao, map_6ebe7d676636a464bcda2698ef3dd0bc.getZoom());
});
function calcularOrientacao(P1latitude, P1longitude, P2latitude, P2longitude) {

File diff suppressed because one or more lines are too long

View File

@ -109,7 +109,7 @@ namespace AgroMonitor.Forms
double.TryParse(txtVelocidadeSemErvas.Text, out double velocidadeSemErvas);
double.TryParse(txtVelocidadeComErvas.Text, out double velocidadeComErvas);
string tempo = Variaveis.OperacaoEmAndamento.TempoEstimado(velocidadeSemErvas, velocidadeComErvas);
string tempo = Variaveis.OperacaoEmAndamento.TempoEstimadoOperacao(velocidadeSemErvas, velocidadeComErvas);
lblTempoEstimado.Text = $"Tempo estimado: {tempo}";
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long