agrobot_base/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs

914 lines
39 KiB
C#

using AgroBase.Comum;
using AgroBase.Forms;
using AgroBase.Forms.Operacoes;
using AgroBase.Models.Modules;
using AgroBase.Services;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using static AgroBase.Models.Enuns;
namespace AgroBase.Models
{
public class OperacaoModel
{
public OperacaoModel(ModoOperacao Modo, DispositivosService<MovimentacaoModel> Mov = null, DispositivosService<DirecionalModel> Dir = null, DispositivosService<AtuadorModel> Atu = null)
{
if (APIService.pythonProcess == null)
{
APIService.Inicializar();
}
this.Modo = Modo;
this.Controle = new OperacaoControleModel()
{
TiposControle = new List<OperacaoControleTipoModel>()
{
new OperacaoControleTipoModel()
{
Tipo = T_Code.Mov,
DelayEnvioComando = 500,
Comandos = new List<string>(),
UltimoComando = DateTime.Now
},
new OperacaoControleTipoModel()
{
Tipo = T_Code.Dir,
DelayEnvioComando = 1000,
Comandos = new List<string>(),
UltimoComando = DateTime.Now
},
new OperacaoControleTipoModel()
{
Tipo = T_Code.Atu,
DelayEnvioComando = 100,
Comandos = new List<string>(),
UltimoComando = DateTime.Now
},
},
};
this.ControleAnterior = new OperacaoControleModel();
this.DispMov = Mov;
this.DispDir = Dir;
this.DispAtu = Atu;
this.Sensoriamento.AtuacoesPorBico = new List<int>();
if (DispAtu != null)
{
for (int i = 0; i < DispAtu.Dados.QuantidadeBicos; i++)
{
this.Sensoriamento.AtuacoesPorBico.Add(0);
}
}
this.tmrLogs.Tick -= TmrLogs_Tick;
this.tmrLogs.Tick += TmrLogs_Tick;
this.tmrParametrizacao.Tick -= TmrParametrizacao_Tick;
this.tmrParametrizacao.Tick += TmrParametrizacao_Tick;
this.tmrParametrizacao.Start();
}
public ModoOperacao Modo { get; set; }
public DispositivosService<MovimentacaoModel> DispMov { get; set; }
public DispositivosService<DirecionalModel> DispDir { get; set; }
public DispositivosService<AtuadorModel> DispAtu { get; set; }
public MapasModel Mapa { get; set; } = new MapasModel();
public Form frmOperacao { get; set; }
public string frmOperacaoNome { get; set; }
public bool Iniciado { get; set; }
public long TimestampInicio { get; set; }
public long TimestampFim { get; set; }
public TimeSpan Tempo { get; set; }
public OperacaoControleModel Controle { get; set; }
public OperacaoControleModel ControleAnterior { get; set; }
public List<OperacaoModulosMandatoriosModel> ModulosMandatorios { get; set; } = new List<OperacaoModulosMandatoriosModel>();
public OperacaoSensoriamentoModel Sensoriamento { get; set; } = new OperacaoSensoriamentoModel();
public List<OperacaoSensoriamentoModel> Logs { get; set; } = new List<OperacaoSensoriamentoModel>();
public List<GPSModel> GPSTrajetoria { get; set; } = new List<GPSModel>();
public OperacaoRefRuaGPS ReferencialRuaGPS { get; set; } = new OperacaoRefRuaGPS();
public int TempoIniciarOperacao { get; set; } = 10;
public string PastaSaida { get; set; } = "Operacoes/";
public string ID { get; set; }
public Timer tmrLogs = new Timer() { Interval = 5000 };
public Timer tmrParametrizacao = new Timer() { Interval = 1000 };
public static OperacaoModel CarregarParametrosOperacaoPadrao(ModoOperacao Modo)
{
var MovConectado = (DispositivosService<MovimentacaoModel>)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == T_Code.Mov && (x._Porta.IsOpen));
var DirConectado = (DispositivosService<DirecionalModel>)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == T_Code.Dir && (x._Porta.IsOpen));
var AtuConectado = (DispositivosService<AtuadorModel>)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == T_Code.Atu && (x._Porta.IsOpen));
OperacaoModel OperacaoCarregar = new OperacaoModel(Modo)
{
Controle = new OperacaoControleModel(),
ControleAnterior = new OperacaoControleModel(),
Iniciado = false,
TimestampInicio = 0,
TimestampFim = 0,
DispAtu = AtuConectado,
DispDir = DirConectado,
DispMov = MovConectado,
Sensoriamento = new OperacaoSensoriamentoModel()
{
AtuacoesPorBico = new List<int>(),
BateriaConsumida = 0,
DistanciaPercorrida = new List<double>(),
ErvasIdentificadas = 0,
ErvasNoRadar = 0,
HerbicidaConsumido = 0,
HerbicidaPorErva = 0,
ProgressoTrajeto = 0,
VelocidadeMedia = 0,
DistanciaDireita = 0,
DistanciaEsquerda = 0,
},
Logs = new List<OperacaoSensoriamentoModel>(),
};
if (OperacaoCarregar.DispAtu != null)
{
for (int i = 0; i < OperacaoCarregar.DispAtu.Dados.QuantidadeBicos; i++)
{
OperacaoCarregar.Sensoriamento.AtuacoesPorBico.Add(0);
}
}
switch (Modo)
{
case ModoOperacao.Manual:
OperacaoCarregar.frmOperacao = new frmAcompanhamento();
OperacaoCarregar.Controle = new OperacaoControleModel()
{
TiposControle = new List<OperacaoControleTipoModel>()
{
new OperacaoControleTipoModel()
{
Tipo = T_Code.Mov,
DelayEnvioComando = 10,
Comandos = new List<string>(),
UltimoComando = DateTime.Now
},
new OperacaoControleTipoModel()
{
Tipo = T_Code.Dir,
DelayEnvioComando = 10,
Comandos = new List<string>(),
UltimoComando = DateTime.Now
},
},
};
OperacaoCarregar.ModulosMandatorios = new List<OperacaoModulosMandatoriosModel>()
{
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Mov,
Mandatorio = false,
},
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Dir,
Mandatorio = false,
},
};
break;
case ModoOperacao.MapaGPS:
OperacaoCarregar.frmOperacao = new frmOperacaoMapaGPS();
OperacaoCarregar.Controle = new OperacaoControleModel()
{
RPM_Max = 45,
RPM_Min = 15,
Angulo_Max = 30,
Angulo_Min = -30,
VelocidadeMP = 50,
TiposControle = new List<OperacaoControleTipoModel>()
{
new OperacaoControleTipoModel()
{
Tipo = T_Code.Mov,
DelayEnvioComando = 500,
Comandos = new List<string>(),
UltimoComando = DateTime.Now
},
new OperacaoControleTipoModel()
{
Tipo = T_Code.Dir,
DelayEnvioComando = 1000,
Comandos = new List<string>(),
UltimoComando = DateTime.Now
},
new OperacaoControleTipoModel()
{
Tipo = T_Code.Atu,
DelayEnvioComando = 100,
Comandos = new List<string>(),
UltimoComando = DateTime.Now
},
},
};
OperacaoCarregar.ModulosMandatorios = new List<OperacaoModulosMandatoriosModel>()
{
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Mov,
Mandatorio = true,
},
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Dir,
Mandatorio = true,
},
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Atu,
Mandatorio = true,
},
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Gps,
Mandatorio = true,
},
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Sen,
Mandatorio = false,
}
};
break;
}
if (OperacaoCarregar.DispAtu != null)
{
for (int i = 0; i < OperacaoCarregar.DispAtu.Dados.QuantidadeBicos; i++)
{
OperacaoCarregar.Sensoriamento.AtuacoesPorBico.Add(0);
}
}
return OperacaoCarregar;
}
public static void SalvarOperacaoPersonalizada(OperacaoModel Operacao)
{
Operacao.frmOperacaoNome = Operacao.frmOperacao.Name;
Form frm = Operacao.frmOperacao;
Operacao.frmOperacao = null;
File.WriteAllText("operacao" + Enum.GetName(typeof(ModoOperacao), Operacao.Modo) + ".opr", JsonConvert.SerializeObject(Operacao));
Operacao.frmOperacao = frm;
}
public static OperacaoModel CarregarOperacaoPersonalizada(string nomeArquivo)
{
string modoOpStr = nomeArquivo.Split('\\')[nomeArquivo.Split('\\').Length - 1].Replace("operacao", "").Split('.')[0];
ModoOperacao modo = (ModoOperacao)Enum.Parse(typeof(ModoOperacao), modoOpStr);
OperacaoModel Operacao = new OperacaoModel(modo);
if (!File.Exists(nomeArquivo))
{
Operacao = CarregarParametrosOperacaoPadrao(modo);
SalvarOperacaoPersonalizada(Operacao);
}
var operacaoText = File.ReadAllText(nomeArquivo);
Operacao = JsonConvert.DeserializeObject<OperacaoModel>(operacaoText);
Type tipoDoForm = Type.GetType(Operacao.frmOperacaoNome);
if (tipoDoForm != null)
{
Operacao.frmOperacao = (Form)Activator.CreateInstance(tipoDoForm);
}
return Operacao;
}
public void IniciarOperacao(OperacaoControleModel controle = null, bool DaIHM = true)
{
Iniciado = true;
TimestampInicio = DateTime.Now.Ticks;
TimestampFim = 0;
if (DispMov != null)
{
DispMov.Dados.DistanciaPercorridaOperacao = 0;
}
Sensoriamento = new OperacaoSensoriamentoModel();
if (DispAtu != null)
{
for (int i = 0; i < DispAtu.Dados.QuantidadeBicos; i++)
{
Sensoriamento.AtuacoesPorBico.Add(0);
}
}
Logs = new List<OperacaoSensoriamentoModel>();
GPSTrajetoria = new List<GPSModel>();
ID = (new DateTime(TimestampInicio)).ToString("dd_MM_yyyy_HH_mm_ss");
Directory.CreateDirectory(PastaSaida + ID + "/");
GPSService.IniciarRecepcaoDados();
Controle = new OperacaoControleModel();
ControleAnterior = new OperacaoControleModel();
if (controle != null)
{
Controle = controle;
}
if (DaIHM)
{
frmOperacao.Show();
}
tmrLogs.Start();
tmrParametrizacao.Stop();
}
public void FinalizarOperacao()
{
Controle.Angulo = 0;
Controle.RPM = 0;
AtualizarDadosControle();
Iniciado = false;
TimestampFim = DateTime.Now.Ticks;
tmrLogs.Stop();
tmrParametrizacao.Start();
GPSService.PararRecepcaoDados();
}
public void AtualizarDadosControle()
{
DateTime Agora = DateTime.Now;
OperacaoControleTipoModel ControleMov = Controle.TiposControle != null ? Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Mov) : null;
OperacaoControleTipoModel ControleDir = Controle.TiposControle != null ? Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Dir) : null;
OperacaoControleTipoModel ControleAtu = Controle.TiposControle != null ? Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Atu) : null;
if (ControleMov != null && Controle.RPM != ControleAnterior.RPM && (Agora - ControleMov.UltimoComando).Milliseconds > ControleMov.DelayEnvioComando)
{
// Enviar comando MOV
var Protocolos = EnviarProtocoloComando(DispMov);
ControleMov.UltimoComando = Agora;
ControleMov.Comandos.AddRange(Protocolos);
}
if (ControleDir != null && Controle.Angulo != ControleAnterior.Angulo && (Agora - ControleDir.UltimoComando).Milliseconds > ControleDir.DelayEnvioComando)
{
// Enviar comando DIR
var Protocolos = EnviarProtocoloComando(DispDir);
ControleDir.UltimoComando = Agora;
ControleDir.Comandos.AddRange(Protocolos);
}
if (ControleAtu != null && Controle.BicosAtuados.Select(x => x.Atuado).ToList() != ControleAnterior.BicosAtuados.Select(x => x.Atuado).ToList() && (Agora - ControleAtu.UltimoComando).Milliseconds > ControleAtu.DelayEnvioComando)
{
// Enviar comando ATU
var Protocolos = EnviarProtocoloComando(DispAtu);
ControleAtu.UltimoComando = Agora;
ControleAtu.Comandos.AddRange(Protocolos);
}
ControleAnterior.Angulo = Controle.Angulo;
ControleAnterior.RPM = Controle.RPM;
ControleAnterior.BicosAtuados = Controle.BicosAtuados.ToList();
AtualizarDadosOperacao();
}
private void AtualizarDadosOperacao()
{
if (DispMov == null)
{
return;
}
Sensoriamento.VelocidadeMedia = DispMov.Dados.Motores.Average(x => x.VelocidadeInstantanea);
//Sensoriamento.DistanciaPercorrida = DispMov.Dados.DistanciaPercorridaOperacao;
Sensoriamento.ProgressoTrajeto = Mapa == null ? 0 : Sensoriamento.DistanciaPercorrida.Sum() / Mapa.DistanciaTotal * 100;
Sensoriamento.ProgressoRua =
Mapa == null ? 0 :
(ReferencialRuaGPS.Direcao == DirecaoCarroRua.Ida ? ((double)ReferencialRuaGPS.IdxPontoAproximadoRua / (double)(Mapa.Trajetoria[Mapa.IdxRuaAtual].Count - 1)) :
ReferencialRuaGPS.Direcao == DirecaoCarroRua.Volta ? ((double)(Mapa.Trajetoria[Mapa.IdxRuaAtual].Count - 1 - ReferencialRuaGPS.IdxPontoAproximadoRua) / (double)(Mapa.Trajetoria[Mapa.IdxRuaAtual].Count - 1)) :
0) * 100;
}
public List<string> EnviarProtocoloComando(IDispositivosService Dispositivo)
{
if (Dispositivo == null)
{
return new List<string>();
}
Direcao DirecaoAtual = Direcao.Parado;
if (Dispositivo.Dispositivo == T_Code.Mov)
{
GeneralJoystick.RPM = Controle.RPM;
if (Controle.RPM == 0)
{
DirecaoAtual = Direcao.Parado;
}
else
{
if (Controle.RPM < 0)
{
GeneralJoystick.RPM *= -1;
DirecaoAtual = Direcao.Tras;
}
else
{
DirecaoAtual = Direcao.Frente;
}
}
}
else if (Dispositivo.Dispositivo == T_Code.Dir)
{
GeneralJoystick.Angulo = Controle.Angulo;
if (Controle.Angulo < 0)
{
GeneralJoystick.Angulo *= -1;
DirecaoAtual = Direcao.Baixo;
}
else
{
DirecaoAtual = Direcao.Cima;
}
}
var Protocolos =
Dispositivo.Dados is MovimentacaoModel ? ((MovimentacaoModel)Dispositivo.Dados).Motores.Select(x => x.ProtocoloComando(DirecaoAtual)) :
Dispositivo.Dados is DirecionalModel ? ((DirecionalModel)Dispositivo.Dados).Motores.Select(x => x.ProtocoloComando(DirecaoAtual)) :
Dispositivo.Dados is AtuadorModel ? ((AtuadorModel)Dispositivo.Dados).BicosPulverizadores.Select(x => x.ProtocoloComando()) :
null;
foreach (var ProtocoloMotor in Protocolos)
{
Dispositivo.EnviarDadosSerial(ProtocoloMotor);
Task.Delay(10);
}
return Protocolos.ToList();
}
public void SalvarLog()
{
Logs.Add(new OperacaoSensoriamentoModel()
{
Momento = DateTime.Now,
AtuacoesPorBico = Sensoriamento.AtuacoesPorBico,
BateriaConsumida = Sensoriamento.BateriaConsumida,
DistanciaDireita = Sensoriamento.DistanciaDireita,
DistanciaEsquerda = Sensoriamento.DistanciaEsquerda,
DistanciaPercorrida = Sensoriamento.DistanciaPercorrida,
ErvasIdentificadas = Sensoriamento.ErvasIdentificadas,
ErvasNoRadar = Sensoriamento.ErvasNoRadar,
HerbicidaConsumido = Sensoriamento.HerbicidaConsumido,
HerbicidaPorErva = Sensoriamento.HerbicidaPorErva,
ProgressoTrajeto = Sensoriamento.ProgressoTrajeto,
VelocidadeMedia = Sensoriamento.VelocidadeMedia
});
File.WriteAllText(PastaSaida + ID + "/logs.json", JsonConvert.SerializeObject(Logs, Formatting.None));
GPSTrajetoria.Add(new GPSModel()
{
NumeroSatelites = GPSService.UltimaLeitura.NumeroSatelites,
Altitude = GPSService.UltimaLeitura.Altitude,
DataHora = GPSService.UltimaLeitura.DataHora,
Latitude = GPSService.UltimaLeitura.Latitude,
Longitude = GPSService.UltimaLeitura.Longitude,
PrecisaoHorizontal = GPSService.UltimaLeitura.PrecisaoHorizontal
});
if (GPSTrajetoria.Count > 1)
{
if (ReferencialRuaGPS.DentroDaRua || true)
{
if (Mapa.IdxRuaAtual > Sensoriamento.DistanciaPercorrida.Count - 1)
{
Sensoriamento.DistanciaPercorrida.Add(0);
}
Sensoriamento.DistanciaPercorrida[Mapa.IdxRuaAtual] += GPSService.DistanciaEntrePontos(GPSTrajetoria[GPSTrajetoria.Count - 1], GPSTrajetoria[GPSTrajetoria.Count - 2]);
//Sensoriamento.DistanciaPercorrida[Mapa.IdxRuaAtual] = GPSService.DistanciaEntrePontos(Mapa.Trajetoria[Mapa.IdxRuaAtual][0], Mapa.Trajetoria[Mapa.IdxRuaAtual][ReferencialRuaGPS.IdxPontoAproximadoRua]);
}
}
File.WriteAllText(PastaSaida + ID + "/trajetoria.json", JsonConvert.SerializeObject(GPSTrajetoria, Formatting.None));
}
public void CalculaDadosMovimentacaoAutonoma()
{
}
private void TmrLogs_Tick(object sender, EventArgs e)
{
SalvarLog();
}
private void TmrParametrizacao_Tick(object sender, EventArgs e)
{
if (Mapa != null)
{
APIService.AtualizarRuasSelecionadas();
}
}
}
public class OperacaoControleModel
{
public int RPM_Max { get; set; } = 45;
public int RPM_Min { get; set; } = 15;
public double Angulo_Max { get; set; } = 30;
public double Angulo_Min { get; set; } = -30;
public double Angulo { get; set; } = 0;
public int RPM { get; set; } = 0;
public Direcao Direcao { get; set; } = Direcao.Parado;
public double VelocidadeMP { get; set; } = 50;
public List<AtuadorBicoModel> BicosAtuados { get; set; } = new List<AtuadorBicoModel>();
public List<OperacaoControleTipoModel> TiposControle { get; set; }
}
public class OperacaoControleTipoModel
{
public T_Code Tipo { get; set; }
public int DelayEnvioComando { get; set; }
public DateTime UltimoComando { get; set; }
public List<string> Comandos { get; set; }
}
public class OperacaoModulosMandatoriosModel
{
public T_Code Dispositivo { get; set; }
public bool Mandatorio { get; set; }
public bool Utilizar { get; set; }
public bool Conectado { get; set; }
}
public class OperacaoSensoriamentoModel
{
public DateTime Momento { get; set; }
public int ErvasNoRadar { get; set; } = 0;
public double VelocidadeMedia { get; set; } = 0;
public double HerbicidaConsumido { get; set; } = 0;
public double HerbicidaPorErva { get; set; } = 0;
public double PorcentagemBateria { get; set; } = 0;
public double BateriaConsumida { get; set; } = 0;
public int ErvasIdentificadas { get; set; } = 0;
public List<int> AtuacoesPorBico { get; set; } = new List<int>();
public List<double> DistanciaPercorrida { get; set; } = new List<double>();
public double ProgressoTrajeto { get; set; } = 0;
public double ProgressoRua { get; set; } = 0;
public double DistanciaEsquerda { get; set; } = 0;
public double DistanciaDireita { get; set; } = 0;
}
public class OperacaoRefRuaGPS
{
public bool ManobraConcluida { get; set; } = false;
private StatusOperacao _EtapaAtual;
public StatusOperacao StatusAtual
{
get
{
StatusOperacao etapaAtual = _EtapaAtual;
// Se a operação não estiver iniciada
if (!Variaveis.OperacaoEmAndamento.Iniciado)
{
// Etapa atual não é Finalizado, então a etapa é Parametrizando
if (_EtapaAtual != StatusOperacao.Concluida)
{
etapaAtual = StatusOperacao.Parametrizando;
}
}
// Operação em andamento
else
{
// Etapa atual é finalizada, então finaliza a operação
if (_EtapaAtual == StatusOperacao.Concluida)
{
Variaveis.OperacaoEmAndamento.FinalizarOperacao();
}
// Contagem regressiva para iniciar a operação
else if (Variaveis.OperacaoEmAndamento.Tempo.Minutes == 0 && Variaveis.OperacaoEmAndamento.Tempo.Seconds < Variaveis.OperacaoEmAndamento.TempoIniciarOperacao)
{
etapaAtual = StatusOperacao.Aguardando;
}
// Robô está manobrando para seguir a próxima rota do mapa
else if (_EtapaAtual == StatusOperacao.Manobrando)
{
// Aguarda a mudança de rua até que o robô tenha terminado a manobra e tenha ficado parado em frente à rua
if (ManobraConcluida && Direcao == DirecaoCarroRua.Parado)
{
Variaveis.OperacaoEmAndamento.Mapa.IdxRuaAtual++;
ManobraConcluida = false;
etapaAtual = StatusOperacao.EntrandoRua;
Task.Delay(500);
}
}
// Se o robô não estiver dentro da entrelinha de cana
else if (!DentroDaRua)
{
// Está mais próximo do ponto inicial da rota, e a direção do carro é IDA ou então PARADO, logo está entrando na rua, do começo para o final
if (ExtremoMaisProximo == 0 && (Direcao == DirecaoCarroRua.Ida || Direcao == DirecaoCarroRua.Parado) && etapaAtual != StatusOperacao.SaindoRua)
{
etapaAtual = StatusOperacao.EntrandoRua;
}
// Está mais próximo do ponto final da rota, e a direção do carro é VOLTA ou então PARADO, logo está entrando na rua, do final para o começo
else if (ExtremoMaisProximo == 1 && (Direcao == DirecaoCarroRua.Volta || Direcao == DirecaoCarroRua.Parado) && etapaAtual != StatusOperacao.SaindoRua)
{
etapaAtual = StatusOperacao.EntrandoRua;
}
// Robô não está entrando na rua do começo para o fim, nem do fim para o começo
else
{
// Se a etapa anterior era CaminhandoRua, ou seja, robô estava na rua e agora não está mais, então esta saindo da rua
if (_EtapaAtual == StatusOperacao.CaminhandoRua)
{
etapaAtual = StatusOperacao.SaindoRua;
}
// Se a etapa anterior não for CaminhandoRua, então significa que ele já iniciou a etapa de sair da rua
else
{
// O índice de rua para realizar o trabalho já ultrapassou a quantidade de ruas definidas pelo operador, então a operação foi concluída
if (Variaveis.OperacaoEmAndamento.Mapa.IdxRuaAtual >= Variaveis.OperacaoEmAndamento.Mapa.Trajetoria.Count - 1)
{
etapaAtual = StatusOperacao.Concluida;
}
// Ainda tem ruas a serem percorridas, logo, o robô precisa realizar a manobra para seguir para a próxima rua
else
{
etapaAtual = StatusOperacao.Manobrando;
}
}
}
}
// Se o robô estiver dentro da entrelinha da cana
else if (DentroDaRua)
{
etapaAtual = StatusOperacao.CaminhandoRua;
}
}
_EtapaAtual = etapaAtual;
return etapaAtual;
}
}
public int PontosConsiderarAngulo { get; set; } = 2;
public double Distancia { get; set; } = 0;
public double AnguloCarro
{
get
{
try
{
double somaAngulo = 0;
var Pontos = Variaveis.OperacaoEmAndamento.GPSTrajetoria.Count > PontosConsiderarAngulo ?
Variaveis.OperacaoEmAndamento.GPSTrajetoria.OrderByDescending(x => x.DataHora).Take(PontosConsiderarAngulo).ToList() :
Variaveis.OperacaoEmAndamento.GPSTrajetoria.OrderByDescending(x => x.DataHora).ToList();
Pontos = Pontos.OrderBy(x => x.DataHora).ToList();
for (int i = 0; i < Pontos.Count - 1; i++)
{
somaAngulo += GPSService.CalcularOrientacao(Pontos[i + 1], Pontos[i]);
}
double mediaAngulo = somaAngulo / (Pontos.Count - 1);
return (!(mediaAngulo >= 0 || mediaAngulo <= 0)) ? 0 : mediaAngulo;
}
catch
{
return 0;
}
}
}
public double AnguloRua
{
get
{
try
{
double somaAnguloRua = 0;
var Rua = Variaveis.OperacaoEmAndamento.Mapa.Trajetoria.Skip(Variaveis.OperacaoEmAndamento.Mapa.IdxRuaAtual).First();
var PontosRua = IdxPontoAproximadoRua + PontosConsiderarAngulo < Rua.Count ?
Rua.Skip(IdxPontoAproximadoRua).Take(PontosConsiderarAngulo).ToList() :
Rua.Skip(PontosConsiderarAngulo).Take(IdxPontoAproximadoRua).ToList();
/*var Pontos = Rua.Count > PontosConsiderarAngulo ?
Rua.OrderByDescending(x => x.DataHora).Take(PontosConsiderarAngulo).ToList() :
Rua.OrderByDescending(x => x.DataHora).ToList();*/
for (int i = 0; i < PontosRua.Count - 1; i++)
{
somaAnguloRua += GPSService.CalcularOrientacao(PontosRua[i + 1], PontosRua[i]);
}
double mediaAnguloRua = somaAnguloRua / (PontosRua.Count - 1);
return (!(mediaAnguloRua >= 0 || mediaAnguloRua <= 0)) ? 0 : mediaAnguloRua;
}
catch
{
return 0;
}
}
}
public DirecaoCarroRua Direcao
{
get
{
double MargemErroAngulo = 45;
double mediaAngulo = AnguloCarro;
double anguloOposto = (mediaAngulo + 180) % 360;
double mediaAnguloRua = AnguloRua;
if ((mediaAngulo + MargemErroAngulo) >= mediaAnguloRua && (mediaAngulo - MargemErroAngulo) <= mediaAnguloRua)
{
return DirecaoCarroRua.Ida;
}
else if ((anguloOposto + MargemErroAngulo) >= mediaAnguloRua && (anguloOposto - MargemErroAngulo) <= mediaAnguloRua)
{
return DirecaoCarroRua.Volta;
}
else
{
return DirecaoCarroRua.Parado;
}
}
}
public GPSModel PrimeiroPontoRua
{
get
{
try
{
var primeiroPontoRua = Variaveis.OperacaoEmAndamento.Mapa.Trajetoria.Skip(Variaveis.OperacaoEmAndamento.Mapa.IdxRuaAtual).First().First();
return primeiroPontoRua;
}
catch
{
return new GPSModel();
}
}
}
public GPSModel UltimoPontoRua
{
get
{
try
{
var ultimoPontoRua = Variaveis.OperacaoEmAndamento.Mapa.Trajetoria.Skip(Variaveis.OperacaoEmAndamento.Mapa.IdxRuaAtual).First().Last();
return ultimoPontoRua;
}
catch
{
return new GPSModel();
}
}
}
public bool DentroDaRua
{
get
{
try
{
double MargemErroAngulo = 15;
double ToleranciaDistanciaRua = 1;
// Calcula a distância até o ponto de início e fim
double angRua = AnguloRua;
double distPP = GPSService.DistanciaEntrePontos(GPSService.UltimaLeitura, PrimeiroPontoRua);
double angPP = GPSService.CalcularOrientacao(GPSService.UltimaLeitura, PrimeiroPontoRua);
double angPPO = (angPP + 180) % 360;
/*if ((angPP + MargemErroAngulo) >= angRua && (angPP - MargemErroAngulo) <= angRua)
{
distPP = distPP * -1;
}
else */
if ((angPPO + MargemErroAngulo) >= angRua && (angPPO - MargemErroAngulo) <= angRua)
{
distPP = distPP * -1;
}
double distUP = GPSService.DistanciaEntrePontos(GPSService.UltimaLeitura, UltimoPontoRua);
double angUP = GPSService.CalcularOrientacao(GPSService.UltimaLeitura, UltimoPontoRua);
double angUPO = (angUP + 180) % 360;
if ((angUP + MargemErroAngulo) >= angRua && (angUP - MargemErroAngulo) <= angRua)
{
distUP = distUP * -1;
}
string IDruaAtual = Variaveis.OperacaoEmAndamento.Mapa.RuasPercorrer[Variaveis.OperacaoEmAndamento.Mapa.IdxRuaAtual];
var Rua = Variaveis.OperacaoEmAndamento.Mapa.mapaService.DadosMapa.features.Where(x => x.geometry.id == IDruaAtual).First();
// Calcula a diferença entre a soma das distâncias e a distância real entre os pontos
double diferencaDistancia = (distPP + distUP) - Rua.properties.Length;
bool dentro = false;
//double DistanciaPercorridaRua = Variaveis.OperacaoEmAndamento.Sensoriamento.DistanciaPercorrida.Count - 1 >= Variaveis.OperacaoEmAndamento.Mapa.IdxRuaAtual ? Variaveis.OperacaoEmAndamento.Sensoriamento.DistanciaPercorrida[Variaveis.OperacaoEmAndamento.Mapa.IdxRuaAtual] : 0;
if (distPP > Rua.properties.Length || distUP > Rua.properties.Length/* || DistanciaPercorridaRua > Rua.properties.Length*/)
{
List<GPSModel> Trecho = new List<GPSModel>();
var PontosRua = Variaveis.OperacaoEmAndamento.Mapa.Trajetoria[Variaveis.OperacaoEmAndamento.Mapa.IdxRuaAtual].ToList();
int idx = Variaveis.OperacaoEmAndamento.ReferencialRuaGPS.IdxPontoAproximadoRua;
if (Variaveis.OperacaoEmAndamento.Mapa.IdxRuaAtual % 2 != 0)
{
PontosRua.Reverse();
idx = (PontosRua.Count - 1) - idx;
}
for (int i = 0; i <= idx; i++)
{
Trecho.Add(PontosRua[i]);
}
double d = GPSService.DistanciaDoTrecho(Trecho);
dentro = d < Rua.properties.Length;
}
else
{
dentro = true;
}
return dentro;
}
catch
{
return false;
}
}
}
public int ExtremoMaisProximo {
get
{
double distPP = GPSService.DistanciaEntrePontos(GPSService.UltimaLeitura, PrimeiroPontoRua);
double distUP = GPSService.DistanciaEntrePontos(GPSService.UltimaLeitura, UltimoPontoRua);
// 0 para mais próximo do primeiro ponto da rua (ENTRANDO)
// 1 para mais próximo do último ponto da rua (SAINDO)
return (distPP < distUP) ? 0 : 1;
}
}
private DateTime UltimaLeituraDistancia;
private int idxPontoAproximadoRua = 0;
public int IdxPontoAproximadoRua
{
get
{
try
{
if (UltimaLeituraDistancia == null)
{
UltimaLeituraDistancia = DateTime.Now.Add(new TimeSpan(0, 0, -10));
}
else if (UltimaLeituraDistancia.Add(new TimeSpan(0, 0, 5)) < DateTime.Now)
{
int idx = -1;
double menorDistancia = 9999;
double distanciaAnterior = 9999;
var Rua = Variaveis.OperacaoEmAndamento.Mapa.Trajetoria[Variaveis.OperacaoEmAndamento.Mapa.IdxRuaAtual];
foreach (var Ponto in Rua)
{
double dist = GPSService.DistanciaEntrePontos(GPSService.UltimaLeitura, Ponto);
if (dist < menorDistancia)
{
menorDistancia = dist;
idx = Rua.IndexOf(Ponto);
}
else if (dist > distanciaAnterior)
{
break;
}
distanciaAnterior = dist;
}
idxPontoAproximadoRua = idx;
UltimaLeituraDistancia = DateTime.Now;
}
}
catch
{
}
return idxPontoAproximadoRua;
}
}
}
}