acompanhamento das ruas do mapa antes de iniciar a operacao

This commit is contained in:
Diego Freitas 2024-10-10 16:58:57 -03:00
parent b2e76cca8a
commit 2f72e17abc
19 changed files with 334 additions and 135 deletions

Binary file not shown.

View File

@ -29,6 +29,7 @@
private void InitializeComponent()
{
this.pnlOpcoes = new System.Windows.Forms.Panel();
this.lblTempoEstimado = new System.Windows.Forms.Label();
this.lblStatusOperacao = new System.Windows.Forms.Label();
this.lblDistanciaLateral = new System.Windows.Forms.Label();
this.btnAtualizarLeitura = new System.Windows.Forms.Button();
@ -79,7 +80,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.chbAutomatico = new System.Windows.Forms.CheckBox();
this.pnlOpcoes.SuspendLayout();
this.gpbSonar.SuspendLayout();
this.gpbGPS.SuspendLayout();
@ -89,6 +90,7 @@
//
// pnlOpcoes
//
this.pnlOpcoes.Controls.Add(this.chbAutomatico);
this.pnlOpcoes.Controls.Add(this.lblTempoEstimado);
this.pnlOpcoes.Controls.Add(this.lblStatusOperacao);
this.pnlOpcoes.Controls.Add(this.lblDistanciaLateral);
@ -108,6 +110,17 @@
this.pnlOpcoes.Size = new System.Drawing.Size(1379, 100);
this.pnlOpcoes.TabIndex = 0;
//
// 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";
//
// lblStatusOperacao
//
this.lblStatusOperacao.AutoSize = true;
@ -674,16 +687,17 @@
this.lblDistAnt.TabIndex = 24;
this.lblDistAnt.Text = "Distância Ponto Anterior: 0,00 m";
//
// lblTempoEstimado
// chbAutomatico
//
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";
this.chbAutomatico.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.chbAutomatico.AutoSize = true;
this.chbAutomatico.Location = new System.Drawing.Point(1231, 72);
this.chbAutomatico.Margin = new System.Windows.Forms.Padding(2);
this.chbAutomatico.Name = "chbAutomatico";
this.chbAutomatico.Size = new System.Drawing.Size(137, 17);
this.chbAutomatico.TabIndex = 30;
this.chbAutomatico.Text = "Atualização Automática";
this.chbAutomatico.UseVisualStyleBackColor = true;
//
// frmSimulacaoMapaGPS
//
@ -778,5 +792,6 @@
private System.Windows.Forms.Label lblDistAnt;
private System.Windows.Forms.Label lblStatusOperacao;
private System.Windows.Forms.Label lblTempoEstimado;
private System.Windows.Forms.CheckBox chbAutomatico;
}
}

View File

@ -12,17 +12,19 @@ namespace AgroBase.Forms
public partial class frmSimulacaoMapaGPS : Form
{
Timer tmrSonar;
Timer tmrLeitura = new Timer() { Interval = 500 };
StatusCarroMapa StatusCarro = StatusCarroMapa.Parado;
MapaDinamicoModel MapaDinamico;
bool calc = false;
bool parar = false;
DateTime UltimaAtualizacao = DateTime.MinValue;
public frmSimulacaoMapaGPS()
{
InitializeComponent();
Timer tmr = new Timer() { Interval = 500 };
tmr.Tick += Tmr_Tick;
//tmr.Start();
tmrLeitura.Tick += Tmr_Tick;
tmrLeitura.Start();
// Ativa o double buffering
this.DoubleBuffered = true;
@ -35,7 +37,15 @@ namespace AgroBase.Forms
private void Tmr_Tick(object sender, EventArgs e)
{
btnCalcularAngulo_Click(sender, e);
if (chbAutomatico.Checked)
{
btnAcrescentarGPS_Click(sender, e);
}
}
private void AtualizarDadosTela()
{
btnCalcularAngulo_Click(new object(), new EventArgs());
StatusCarro = Variaveis.OperacaoEmAndamento.OpMapaGPS.ReferencialRuaGPS.StatusAtual;
@ -73,6 +83,13 @@ namespace AgroBase.Forms
}
else
{
if (btnIniciarSimulacao.Text.Contains("Parar"))
{
parar = true;
btnIniciarSimulacao_Click(new object(), new EventArgs());
parar = false;
}
Variaveis.OperacaoEmAndamento.OpMapaGPS.AtualizarRuasSelecionadas();
}
}
@ -94,6 +111,10 @@ namespace AgroBase.Forms
{
tmrSonar.Stop();
}
if (tmrLeitura != null && tmrLeitura.Enabled)
{
tmrLeitura.Stop();
}
Variaveis.OperacaoEmAndamento.Iniciado = false;
}
@ -172,7 +193,7 @@ namespace AgroBase.Forms
AtualizarPosicaoGPS();
calc = true;
Tmr_Tick(sender, e);
AtualizarDadosTela();
calc = false;
}
@ -183,8 +204,12 @@ namespace AgroBase.Forms
MessageBox.Show("Selecione as ruas para realizar a operação!");
return;
}
if (!Variaveis.OperacaoEmAndamento.Iniciado && !parar)
{
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)
{
@ -192,7 +217,7 @@ namespace AgroBase.Forms
GPSService.PenultimaLeitura.Longitude = GPSService.UltimaLeitura.Longitude;
Variaveis.OperacaoEmAndamento.Mapa.GerarTrajetoriaDinamica();
Tmr_Tick(sender, e);
AtualizarDadosTela();
}
}
@ -290,7 +315,7 @@ namespace AgroBase.Forms
private void btnAtualizarLeitura_Click(object sender, EventArgs e)
{
Tmr_Tick(new Timer(), e);
AtualizarDadosTela();
}
private void btnCalcularAngulo_Click(object sender, EventArgs e)
@ -311,9 +336,11 @@ namespace AgroBase.Forms
double velocidadeMs = MovimentacaoModel.ConverteKmhParaMs(velocidade);
txtVelocidade.Text = velocidade.ToString("0.00");
//double distancia = Math.Round((double)Variaveis.OperacaoEmAndamento.OpMapaGPS.Controle.RPM / 45.0, 2);
double distancia = velocidadeMs;
TimeSpan tempoPassado = !chbAutomatico.Checked || UltimaAtualizacao == DateTime.MinValue ? new TimeSpan(10000000) : DateTime.Now - UltimaAtualizacao;
// Calcula a distância com base no tempo passado (em segundos)
double distancia = velocidadeMs * tempoPassado.TotalSeconds;
txtDistanciaGPS.Text = distancia.ToString("0.00");
UltimaAtualizacao = DateTime.Now;
pnlOrientacaoTrajeto.Invalidate();
pnlOrientacaoCarro.Invalidate();

View File

@ -2,9 +2,6 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AgroBase.Models
@ -152,6 +149,8 @@ namespace AgroBase.Models
trajectory = new List<GPSModel>();
}
try
{
for (int i = 0; i < trajectory.Count; i++)
{
var trajPoint = trajectory[i];
@ -173,6 +172,11 @@ namespace AgroBase.Models
}
}
}
catch
{
}
}
private void DrawPoint(Graphics g, float x, float y, Color color)
{

View File

@ -4,6 +4,7 @@ using CefSharp.WinForms;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Windows.Forms;
using static AgroBase.Models.Enums;
@ -513,6 +514,7 @@ namespace AgroBase.Models
}
}
private bool GerandoTrajetoria = false;
private DateTime UltimaAtualizacaoTrajetoriaDinamica = DateTime.MinValue;
public void btnCarregar_Click(object sender, EventArgs e, string caminhoArquivo = "", bool monitoramento = false)
@ -791,10 +793,10 @@ namespace AgroBase.Models
// O carro esta se direcionando para iniciar a operacao na primeira rua, entao escolhe o caminho mais proximo
if (DistanciaExtraTrajetoria == 0)
{
List<GPSModel> _caminhoDoInicioParaFim = GerarTrajetoLigacaoCarroPontoInicial(inicio, RuaAtual, RuaAtual[0], 0, DirecaoCarroRua.Ida, statusCarro);
List<GPSModel> _caminhoDoInicioParaFim = GerarTrajetoLigacaoCarroPontoInicial(inicio, RuaAtual, RuaProjetada, 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);
List<GPSModel> _caminhoDoFimParaInicio = GerarTrajetoLigacaoCarroPontoInicial(inicio, RuaAtual, RuaProjetada, RuaAtual[RuaAtual.Count() - 1], RuaAtual.Count() - 1, DirecaoCarroRua.Volta, statusCarro);
distanciaInicialFimParaInicio = GPSService.DistanciaDoTrecho(_caminhoDoFimParaInicio);
DefinirRotaInicial = true;
@ -863,7 +865,7 @@ namespace AgroBase.Models
List<GPSModel> _caminhoInterpolado = GerarTrajetoLigacaoCarroPontoInicial(inicio, RuaAtual, PontoComparar, _extremoMaisProximoMapa, direcaoRua, statusCarro);
List<GPSModel> _caminhoInterpolado = GerarTrajetoLigacaoCarroPontoInicial(inicio, RuaAtual, RuaProjetada, PontoComparar, _extremoMaisProximoMapa, direcaoRua, statusCarro);
_caminho.AddRange(_caminhoInterpolado);
@ -905,6 +907,7 @@ namespace AgroBase.Models
Variaveis.OperacaoEmAndamento.OpMapaGPS.ReferencialRuaGPS.VerificaFimRuaAtual();
if (!Variaveis.OperacaoEmAndamento.OpMapaGPS.Concluido)
{
GerandoTrajetoria = false;
GerarTrajetoriaDinamica();
}
return;
@ -923,7 +926,7 @@ namespace AgroBase.Models
List<GPSModel> _caminho = new List<GPSModel>();
// Verifica se a distância entre o ultimo ponto da rua anterior e o primeiro ponto da nova rua é curto o bastante para gerar a curva de manobra
double distancia = GPSService.DistanciaEntrePontos(Caminho[Caminho.Count() - 1], PrimeiroPonto);
bool distanciaMinima = distancia < MargemLimiteEntradaRua * 3;
bool distanciaMinima = distancia < MargemLimiteEntradaRua * 3.0;
// Verifica se o angulo formado entre a rua anterior e a rua atual é grande o bastante para gerar a curva de manobra
double anguloEntreRuas = GPSService.CalcularOrientacao(Caminho.Last(), PrimeiroPonto);
@ -931,7 +934,7 @@ namespace AgroBase.Models
double difAngulo = anguloFinalRuaAnterior - anguloEntreRuas;
bool anguloMinimo = difAngulo >= -45.0 && difAngulo <= 45.0;
if (distanciaMinima && !anguloMinimo)
/*if (distanciaMinima && !anguloMinimo)
{
bool CurvaParaEsquerda = ExtremoMaisProximoMapa == 0;
GPSModel P0 = CalcularPontoControle(Caminho.Last(), PrimeiroPonto, distanciaEntreRuas * 2, CurvaParaEsquerda);
@ -943,7 +946,9 @@ namespace AgroBase.Models
else
{
_caminho.Add(PrimeiroPonto);
}
}*/
_caminho.Add(PrimeiroPonto);
//_caminho.AddRange(GPSService.InterpolarPontos(inicio, PrimeiroPonto, 1.0));
_caminho.AddRange(RuaProjetada);
_caminho.Add(UltimoPonto);
@ -1054,52 +1059,90 @@ namespace AgroBase.Models
return pontosCurva;
}
private List<GPSModel> GerarTrajetoLigacaoCarroPontoInicial(GPSModel inicio, List<GPSModel> RuaAtual, GPSModel PontoComparar, int _extremoMaisProximoMapa, DirecaoCarroRua direcaoRua, StatusCarroMapa statusCarro)
private List<GPSModel> GerarTrajetoLigacaoCarroPontoInicial(GPSModel inicio, List<GPSModel> RuaAtual, List<GPSModel> RuaProjetada, 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)))
if (CopiarRuasLaterais && new List<StatusCarroMapa>() { StatusCarroMapa.Parado, StatusCarroMapa.Direcionando }.Contains(statusCarro) && 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);
double tolerancia = 90; // Tolerância de 90 graus
GPSModel pontoAnterior = inicio; // Inicializamos com a posição inicial do robô
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] }),
dist = GPSService.DistanciaEntrePontos(pontoAnterior, 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(pontoAnterior, 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],
}
},
distParaPontoFinal = GPSService.DistanciaEntrePontos(new GPSModel()
{
Longitude = x.geometry.coordinates[GetIndexInicial(x.geometry.coordinates, _extremoMaisProximoMapa)][0],
Latitude = x.geometry.coordinates[GetIndexInicial(x.geometry.coordinates, _extremoMaisProximoMapa)][1]
}, PontoComparar),
orientacaoParaPontoFinal = GPSService.CalcularOrientacao(new GPSModel()
{
Longitude = x.geometry.coordinates[GetIndexInicial(x.geometry.coordinates, _extremoMaisProximoMapa)][0],
Latitude = x.geometry.coordinates[GetIndexInicial(x.geometry.coordinates, _extremoMaisProximoMapa)][1]
}, PontoComparar)
})
.OrderBy(x => x.dist) // Ordena os pontos pela distância
.Select((x, i) => new
{
x.id,
idx = i,
x.dist,
x.orientacao,
x.coordenadas,
x.distParaPontoFinal,
x.orientacaoParaPontoFinal
})
.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)
// Verificar se o ponto está se aproximando do ponto final
if (x.distParaPontoFinal > GPSService.DistanciaEntrePontos(pontoAnterior, PontoComparar))
{
return orientacaoNormalizada >= limiteInferior && orientacaoNormalizada <= limiteSuperior;
return false; // Se o ponto atual está se afastando, desconsiderar
}
else // Caso o intervalo passe por 0 graus
// Calcular a orientação entre o ponto atual e o ponto final
double orientacaoAtualParaPontoFinalNormalizada = (x.orientacaoParaPontoFinal + 360) % 360;
double orientacaoAnteriorParaPontoFinalNormalizada = GPSService.CalcularOrientacao(pontoAnterior, PontoComparar);
orientacaoAnteriorParaPontoFinalNormalizada = (orientacaoAnteriorParaPontoFinalNormalizada + 360) % 360;
// Verificar se a orientação leva o robô para o ponto final, ou se está se desviando
double diferencaAnguloFinal = Math.Abs(orientacaoAtualParaPontoFinalNormalizada - orientacaoAnteriorParaPontoFinalNormalizada);
diferencaAnguloFinal = diferencaAnguloFinal > 180 ? 360 - diferencaAnguloFinal : diferencaAnguloFinal;
// Se a diferença de ângulo for maior que a tolerância, desconsiderar o ponto
if (diferencaAnguloFinal > tolerancia)
{
return orientacaoNormalizada >= limiteInferior || orientacaoNormalizada <= limiteSuperior;
return false;
}
// Atualizar o ponto anterior para o próximo ponto
pontoAnterior = new GPSModel() { Longitude = x.coordenadas.Longitude, Latitude = x.coordenadas.Latitude };
return true;
})
.OrderBy(x => x.dist)
.ToList();
foreach (var rua in PontosOrdenados)
@ -1112,22 +1155,25 @@ namespace AgroBase.Models
}
};
double anguloDeslocar = CalcularDeslocamentoDinamico(_extremoMaisProximoMapa == 0 ? 0 : RuaAtual.Count() - 1, RuaAtual);
double anguloDeslocar = CalcularDeslocamentoDinamico(_extremoMaisProximoMapa == 0 ? 0 : RuaProjetada.Count() - 1, RuaProjetada);
_caminho.Add(inicio);
double velocidade = MovimentacaoModel.CalculaVelocidadeRPM(Variaveis.OperacaoEmAndamento.Controle.RPM_SP);
double velocidadeMs = MovimentacaoModel.ConverteKmhParaMs(velocidade);
double distancia = velocidadeMs;
int pontosPular = 1;
// Calcula o tempo que passou desde a última atualização
TimeSpan tempoPassado = UltimaAtualizacaoTrajetoriaDinamica == DateTime.MinValue ? new TimeSpan(10000000) : DateTime.Now - UltimaAtualizacaoTrajetoriaDinamica;
// Calcula a distância com base no tempo passado (em segundos)
double distancia = velocidadeMs * tempoPassado.TotalSeconds;
int pontosPular = 0;
PontosOrdenados.ForEach(p =>
{
double d = GPSService.DistanciaEntrePontos(inicio, p.coordenadas);
if (d <= (distancia + 2))
if (p.dist <= (distancia + MargemLimiteEntradaRua))
{
pontosPular++;
}
});
UltimaAtualizacaoTrajetoriaDinamica = DateTime.Now;
for (int iidx = pontosPular; iidx < idx; iidx++)
{
@ -1142,15 +1188,55 @@ namespace AgroBase.Models
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)))
if (FuncoesMatematicas.ValorEstaEntre(orientacao, orientacaoA, 90) && distP1 > distP) // && FuncoesMatematicas.ValorEstaEntre(anguloP, anguloP1, 45)
{
_caminho.Add(p);
}
}
if (idx == 1)
{
double distPi = GPSService.DistanciaEntrePontos(inicio, RuaProjetada[0]);
GPSModel PrimeiroPonto = RuaProjetada[0];
GPSModel UltimoPonto = RuaProjetada[RuaProjetada.Count() - 1];
(GPSModel PontoMaisProximo, bool aproximando) = GPSService.PontoMaisProximoRuaProjetada(RuaProjetada, TrajetoriaTipo.Rua);
int idxPontoMaisProximo = RuaProjetada.IndexOf(PontoMaisProximo);
// Se o robo estiver se aproximando do ponto mais proximo, e estiver vindo de fora da rua
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;
}
}
else if (!aproximando && RuaProjetada.Count() == (idxPontoMaisProximo + 1))
{
PontoComparar = UltimoPonto;
}
else
{
PontoComparar = PontoMaisProximo;
}
_caminho.Add(PontoComparar);
}
else
{
_caminho.Add(PontoComparar);
}
}
else
{
_caminho.AddRange(GPSService.InterpolarPontos(inicio, PontoComparar, 1.0));
}

View File

@ -109,6 +109,31 @@ namespace AgroBase.Models.Modules
}
}
public double VolumeVazaoML { get; set; }
public DateTime InicioAtuacao { get; set; } = DateTime.MinValue;
public DateTime FimAtuacao { get; set; } = DateTime.MinValue;
public double TempoAtuado { get; set; } = 0;
public void InicializaTempoAtuado()
{
bool atuadoAnteriormente = BicosPulverizadores.Any(x => x.Atuado);
if (!atuadoAnteriormente && InicioAtuacao == DateTime.MinValue)
{
InicioAtuacao = DateTime.Now;
FimAtuacao = DateTime.MinValue;
}
}
public void AtualizaTempoAtuado()
{
bool atuadoAnteriormente = BicosPulverizadores.Any(x => x.Atuado);
if (atuadoAnteriormente && FimAtuacao == DateTime.MinValue)
{
FimAtuacao = DateTime.Now;
TimeSpan duracao = FimAtuacao - InicioAtuacao;
TempoAtuado += duracao.TotalMilliseconds;
InicioAtuacao = DateTime.MinValue;
}
}
#endregion
#region PRESSAO
@ -261,6 +286,9 @@ namespace AgroBase.Models.Modules
Dados.BombaPressurizadora.Potencia = 0;
Dados.VolumeVazaoAferido = 0;
Dados.VolumeVazaoML = 0;
Dados.TempoAtuado = 0;
Dados.InicioAtuacao = DateTime.MinValue;
Dados.FimAtuacao = DateTime.MinValue;
Dados._LeituraPeriodo = 0;
Dados._LeituraPressao = 0;
Dados._LeituraPulsos = 0;
@ -707,6 +735,16 @@ namespace AgroBase.Models.Modules
((int)F_Code.Cmd).ToString() + SerialService.SplitMessage +
ID + SerialService.SplitParams +
(Atuado ? "1" : "0");
if (Atuado)
{
Variaveis.OperacaoEmAndamento.DispAtu.Dados.InicializaTempoAtuado();
}
else
{
Variaveis.OperacaoEmAndamento.DispAtu.Dados.AtualizaTempoAtuado();
}
return ProtocoloBico;
}
return "";

View File

@ -151,7 +151,7 @@ namespace AgroBase.Models
// Etapa atual é finalizada, então finaliza a operação
else if (_EtapaAtual == StatusOperacao.Concluido)
{
if (Variaveis.OperacaoEmAndamento.Iniciado)
if (Variaveis.OperacaoEmAndamento.Iniciado && !Variaveis.OperacaoEmAndamento.Finalizando)
{
Variaveis.OperacaoEmAndamento.FinalizarOperacao();
}
@ -305,6 +305,7 @@ namespace AgroBase.Models
}
public bool Iniciado { get; set; }
public bool Simulando { get; set; } = false;
public bool Finalizando { get; set; } = false;
public long TimestampInicio { get; set; }
public long TimestampFim { get; set; }
public TimeSpan Tempo
@ -526,14 +527,8 @@ namespace AgroBase.Models
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)
@ -541,31 +536,20 @@ namespace AgroBase.Models
// Calcula o tempo restante apenas para a fase de direcionamento
double distanciaDirecionamentoRestante = distanciaDirecionamento - distanciaPercorrida;
tempoRestanteDirecionamento = distanciaDirecionamentoRestante / velocidadeTrajetoriaMs;
distanciaRestante = Variaveis.OperacaoEmAndamento.Mapa.DistanciaTotal;
}
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 distanciaSemErvasRestante = distanciaRestante * VariaveisOperacao.PercentualSemErvas;
double distanciaComErvasRestante = (distanciaComErvasTotal > distanciaPercorrida)
? distanciaComErvasTotal - distanciaPercorrida
: 0;
double distanciaComErvasRestante = distanciaRestante * VariaveisOperacao.PercentualComErvas;
// Calcular o tempo restante para as áreas sem ervas e com ervas
tempoRestanteSemErvas = distanciaSemErvasRestante / velocidadeSemErvasMs;
tempoRestanteComErvas = distanciaComErvasRestante / velocidadeComErvasMs;
}
double tempoRestanteSemErvas = distanciaSemErvasRestante / velocidadeSemErvasMs;
double tempoRestanteComErvas = distanciaComErvasRestante / velocidadeComErvasMs;
// Tempo restante para as manobras
double tempoRestanteManobras = Variaveis.OperacaoEmAndamento.Mapa.RuasPercorrer.Count() * VariaveisOperacao.TempoManobra;
double tempoRestanteManobras = Variaveis.OperacaoEmAndamento.Mapa.TrajetoriaProjetada.Count() * VariaveisOperacao.TempoManobra;
// Tempo total restante em segundos
double tempoTotalRestanteSegundos = tempoRestanteDirecionamento + tempoRestanteSemErvas + tempoRestanteComErvas + tempoRestanteManobras;
@ -885,6 +869,8 @@ namespace AgroBase.Models
public void FinalizarOperacao()
{
Variaveis.OperacaoEmAndamento.Finalizando = true;
if (!Variaveis.OperacaoEmAndamento.Iniciado)
{
Variaveis.OperacaoEmAndamento.CamerasSolo.ForEach(Camera =>
@ -913,6 +899,8 @@ namespace AgroBase.Models
}
AtualizarSinaleiroOperacao();
Variaveis.OperacaoEmAndamento.Finalizando = false;
}
public async Task RealizarCalibracaoInicialAsync()
@ -3037,6 +3025,18 @@ namespace AgroBase.Models
public (bool, List<string>) MovEsq_Status { get; set; }
public (bool, List<string>) MovDir_Status { get; set; }
public (bool, List<string>) Dir_Status { get; set; }
public double PercentualErvasTerreno
{
get
{
if (Variaveis.OperacaoEmAndamento.Tempo.TotalMilliseconds == 0)
{
return 0;
}
double p = Math.Round((Variaveis.OperacaoEmAndamento.DispAtu.Dados.TempoAtuado / Variaveis.OperacaoEmAndamento.Tempo.TotalMilliseconds) * 100, 2);
return p;
}
}
}
public class PzmSensoriamentoLogModel

View File

@ -199,9 +199,29 @@ namespace AgroBase.Models
public static class VariaveisOperacao
{
public static double TempoManobra { get; set; } = 15;
public static double PercentualComErvas { get; set; } = 0.3;
public static double PercentualSemErvas { get; set; } = 0.7;
public static double TempoManobra { get; set; } = 10;
public static double PercentualComErvas
{
get
{
if (!Variaveis.IsAgroMonitor && Variaveis.OperacaoEmAndamento.DispAtu != null)
{
return Variaveis.OperacaoEmAndamento.Sensoriamento.PercentualErvasTerreno / 100.0;
}
return 0.3;
}
}
public static double PercentualSemErvas
{
get
{
if (!Variaveis.IsAgroMonitor && Variaveis.OperacaoEmAndamento.DispAtu != null)
{
return (100.0 - Variaveis.OperacaoEmAndamento.Sensoriamento.PercentualErvasTerreno) / 100.0;
}
return 0.7;
}
}
public static GPSModel PosicaoBase { get; set; }
}
@ -748,6 +768,15 @@ namespace AgroBase.Models
return Tc;
}
public static bool ValorEstaEntre(double valorAtual, double valorComparar, double margem)
{
if (valorAtual <= (valorComparar + margem) && valorAtual >= (valorComparar - margem))
{
return true;
}
return false;
}
}
}

View File

@ -1 +1 @@
{"Modulo_ID":"Atu","RequisitarDados":false,"Conectado":false,"QuantidadeBicos":4,"DensidadeHerbicida":1.05,"AtuacaoNivelAlto":true,"BicosPulverizadores":[{"ID":"B01","Posicao":1,"Atuado":false,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0},{"ID":"B02","Posicao":2,"Atuado":false,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0},{"ID":"B03","Posicao":3,"Atuado":false,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0},{"ID":"B04","Posicao":4,"Atuado":false,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0}],"BombaPressurizadora":{"ID":"BOMBA","BombaAtuada":false,"Ligado":false,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[14,35,36,37,5],"Pressao":0.0,"Potencia":0.0},"Sensores":[{"LogGrafico":[],"ID":"FLXLN","Prioridade":23,"Descricao":"Fluxo na linha principal","Componente":198,"Aferir":true,"DelayAmostragem":300,"Inicializado":false,"Testando":false,"Funcoes":[25],"Parametros":[],"UnidadeMedida":"mL/s","Leituras":[],"ValorMinimo":0.0,"ValorMaximo":0.0,"LimiteMaximo":0.0,"LimiteMinimo":0.0},{"LogGrafico":[],"ID":"MASRS","Prioridade":3,"Descricao":"Massa do reservatório de herbicida","Componente":532,"Aferir":true,"DelayAmostragem":1000,"Inicializado":false,"Testando":false,"Funcoes":[22,23],"Parametros":[],"UnidadeMedida":"Kg","Leituras":[],"ValorMinimo":0.0,"ValorMaximo":0.0,"LimiteMaximo":50.0,"LimiteMinimo":5.0},{"LogGrafico":[],"ID":"PRSLN","Prioridade":3,"Descricao":"Pressão na linha principal","Componente":333,"Aferir":true,"DelayAmostragem":1000,"Inicializado":false,"Testando":false,"Funcoes":[24],"Parametros":[["Vmin","000.00"],["Vmax","004.50"],["Pmax","174.04"]],"UnidadeMedida":"psi","Leituras":[],"ValorMinimo":0.0,"ValorMaximo":0.0,"LimiteMaximo":120.0,"LimiteMinimo":60.0}],"ScriptDeteccaoErvas":"weed-detector-v7.py","_MassaRef":0.8,"_MassaLeituraRef":40876.37,"_MassaLeituraExtra":1895800.0,"_MassaLeitura":1895800.0,"MassaReservatorio":0.0,"VolumeReservatorio":0.0,"PercentualReservatorio":0.0,"VolumeVazaoAferido":0.0,"_FluxoMlRef":102.0,"_FluxoPulsoRef":80.0,"_LeituraPulsos":0,"_LeituraPeriodo":0,"VazaoFluxoMLpS":0.0,"VolumeVazaoML":0.0,"_PressaoVmin":0.0,"_PressaoVmax":4.5,"_PressaoMax":174.045,"_LeituraPressao":0.0,"PressaoLinha":0.0,"PressaoLinhaCalc":0.0}
{"Modulo_ID":"Atu","RequisitarDados":false,"Conectado":false,"QuantidadeBicos":4,"DensidadeHerbicida":1.05,"AtuacaoNivelAlto":true,"BicosPulverizadores":[{"ID":"B01","Posicao":1,"Atuado":false,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0},{"ID":"B02","Posicao":2,"Atuado":false,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0},{"ID":"B03","Posicao":3,"Atuado":false,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0},{"ID":"B04","Posicao":4,"Atuado":false,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0}],"BombaPressurizadora":{"ID":"BOMBA","BombaAtuada":false,"Ligado":false,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[14,35,36,37,5],"Pressao":0.0,"Potencia":0.0},"Sensores":[{"LogGrafico":[],"ID":"FLXLN","Prioridade":23,"Descricao":"Fluxo na linha principal","Componente":198,"Aferir":true,"DelayAmostragem":300,"Inicializado":false,"Testando":false,"Funcoes":[25],"Parametros":[],"UnidadeMedida":"mL/s","Leituras":[],"ValorMinimo":0.0,"ValorMaximo":0.0,"LimiteMaximo":0.0,"LimiteMinimo":0.0},{"LogGrafico":[],"ID":"MASRS","Prioridade":3,"Descricao":"Massa do reservatório de herbicida","Componente":532,"Aferir":true,"DelayAmostragem":1000,"Inicializado":false,"Testando":false,"Funcoes":[22,23],"Parametros":[],"UnidadeMedida":"Kg","Leituras":[],"ValorMinimo":0.0,"ValorMaximo":0.0,"LimiteMaximo":50.0,"LimiteMinimo":5.0},{"LogGrafico":[],"ID":"PRSLN","Prioridade":3,"Descricao":"Pressão na linha principal","Componente":333,"Aferir":true,"DelayAmostragem":1000,"Inicializado":false,"Testando":false,"Funcoes":[24],"Parametros":[["Vmin","000.00"],["Vmax","004.50"],["Pmax","174.04"]],"UnidadeMedida":"psi","Leituras":[],"ValorMinimo":0.0,"ValorMaximo":0.0,"LimiteMaximo":120.0,"LimiteMinimo":60.0}],"ScriptDeteccaoErvas":"weed-detector-v7.py","_MassaRef":0.8,"_MassaLeituraRef":40876.37,"_MassaLeituraExtra":1895800.0,"_MassaLeitura":1895800.0,"MassaReservatorio":0.0,"VolumeReservatorio":0.0,"PercentualReservatorio":0.0,"VolumeVazaoAferido":0.0,"_FluxoMlRef":102.0,"_FluxoPulsoRef":80.0,"_LeituraPulsos":0,"_LeituraPeriodo":0,"VazaoFluxoMLpS":0.0,"VolumeVazaoML":0.0,"InicioAtuacao":"0001-01-01T00:00:00","FimAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0,"_PressaoVmin":0.0,"_PressaoVmax":4.5,"_PressaoMax":174.045,"_LeituraPressao":0.0,"PressaoLinha":0.0,"PressaoLinhaCalc":0.0}

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_6ebe7d676636a464bcda2698ef3dd0bc {
#map_ffb413d2f3fe7abcaee361ff364b756f {
position: relative;
width: 100.0%;
height: 100.0%;
@ -39,14 +39,14 @@
<body>
<div class="folium-map" id="map_6ebe7d676636a464bcda2698ef3dd0bc" ></div>
<div class="folium-map" id="map_ffb413d2f3fe7abcaee361ff364b756f" ></div>
</body>
<script>
var map_6ebe7d676636a464bcda2698ef3dd0bc = L.map(
"map_6ebe7d676636a464bcda2698ef3dd0bc",
var map_ffb413d2f3fe7abcaee361ff364b756f = L.map(
"map_ffb413d2f3fe7abcaee361ff364b756f",
{
center: [0.0, 0.0],
crs: L.CRS.EPSG3857,
@ -60,13 +60,13 @@
var tile_layer_a492f19b6d3542b6b52ca525e7345e29 = L.tileLayer(
var tile_layer_8ae61ec8796e266ae86c1b58594227d5 = 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_a492f19b6d3542b6b52ca525e7345e29.addTo(map_6ebe7d676636a464bcda2698ef3dd0bc);
tile_layer_8ae61ec8796e266ae86c1b58594227d5.addTo(map_ffb413d2f3fe7abcaee361ff364b756f);
</script>
@ -87,7 +87,7 @@
}
trajeto_json_add({"features": []});
trajeto_json.addTo(map_6ebe7d676636a464bcda2698ef3dd0bc);
trajeto_json.addTo(map_ffb413d2f3fe7abcaee361ff364b756f);
function adicionarGeometria(novaGeometria) {
trajeto_json.addData(novaGeometria);
@ -145,7 +145,7 @@
var marcadorDinamico = L.marker([0, 0], {
icon: customIcon
}).addTo(map_6ebe7d676636a464bcda2698ef3dd0bc);
}).addTo(map_ffb413d2f3fe7abcaee361ff364b756f);
// 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_6ebe7d676636a464bcda2698ef3dd0bc.setView(novaPosicao, map_6ebe7d676636a464bcda2698ef3dd0bc.getZoom());
map_ffb413d2f3fe7abcaee361ff364b756f.setView(novaPosicao, map_ffb413d2f3fe7abcaee361ff364b756f.getZoom());
});
function calcularOrientacao(P1latitude, P1longitude, P2latitude, P2longitude) {

File diff suppressed because one or more lines are too long