914 lines
39 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|