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

3484 lines
159 KiB
C#

using AgroBase.Comum;
using AgroBase.Forms.Operacoes;
using AgroBase.Models.Modules;
using AgroBase.Models.Operacoes;
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.Enums;
using System.Drawing;
using System.Text;
using System.Windows.Forms.DataVisualization.Charting;
using static AgroBase.Services.OIDCanService.OidHandler;
using Microsoft.Web.WebView2.WinForms;
namespace AgroBase.Models
{
public class OperacaoModel
{
public OperacaoModel(ModoOperacao Modo)
{
this.Modo = Modo;
if (Variaveis.OperacaoEmAndamento != null)
{
tmrLogs?.Dispose();
tmrLogs = new AsyncTaskTimerModel("tmrLogs", tmrLogs_Tick, 1000);
tmrLeituras?.Dispose();
tmrLeituras = new AsyncTaskTimerModel("tmrLeitura", tmrLeituras_Tick, 500, chartGraficos);
tmrLeituras.Start();
}
}
public ModoOperacao Modo { get; set; }
public string Descricao { get; set; }
public OperacaoMapaGPSModel OpMapaGPS { get; set; } = new OperacaoMapaGPSModel();
public OperacaoControleModel Controle { get; set; } = new OperacaoControleModel();
public OperacaoControleModel ControleAnterior { get; set; } = new OperacaoControleModel();
public DispositivosService<MovimentacaoUnificadaModel> DispMvd { get; set; }
public DispositivosService<SensoriamentoModel> DispSen { get; set; }
public DispositivosService<AtuadorModel> DispAtu { get; set; }
public MapasModel Mapa { get; set; } = new MapasModel();
public TrajetoriaMapaOperacaoModel Trajetoria { get; set; }
public OperacaoSensoriamentoLogModel Sensoriamento { get; set; } = new OperacaoSensoriamentoLogModel();
public PerformanceModel DadosPerformance { get; set; } = new PerformanceModel();
public Form frmOperacao { get; set; }
public StatusOperacao StatusAtual { get; private set; }
private StatusOperacao _EtapaAnteriorParada = StatusOperacao.Parado;
public void AtualizarStatusAtual()
{
StatusOperacao etapaAtual = StatusAtual;
// Se a operação não estiver iniciada
if (!Variaveis.OperacaoEmAndamento.Iniciado)
{
// Etapa atual não é Finalizado, então a etapa é Parametrizando
if (StatusAtual != StatusOperacao.Concluido)
{
etapaAtual = StatusOperacao.Parametrizando;
}
else
{
//etapaAtual = StatusOperacao.NaoIniciado;
}
}
// Operação em andamento
else
{
switch (Variaveis.OperacaoEmAndamento.Modo)
{
case ModoOperacao.Manual:
{
if (Variaveis.OperacaoEmAndamento.OperacaoLiberada)
{
etapaAtual = StatusOperacao.EmAndamento;
}
else
{
etapaAtual = StatusOperacao.Parado;
}
break;
}
case ModoOperacao.MapaGPS:
{
// Contagem regressiva para iniciar a operação
if (Variaveis.OperacaoEmAndamento.TempoAguardando.AddSeconds(Variaveis.OperacaoEmAndamento.TempoIniciarOperacao) > DateTime.Now)
{
etapaAtual = StatusOperacao.Aguardando;
}
// Não existem corredores pendentes e a etapa atual ainda não foi marcada como concluída
else if ((Variaveis.OperacaoEmAndamento.Trajetoria?.CorredorAtual?.Ultimo ?? false) && (Variaveis.OperacaoEmAndamento.Trajetoria?.CorredorAtual?.Concluido ?? false) && StatusAtual != StatusOperacao.Concluido)
{
etapaAtual = StatusOperacao.Concluido;
}
// Etapa atual é finalizada, então finaliza a operação
else if (StatusAtual == StatusOperacao.Concluido)
{
if (Variaveis.OperacaoEmAndamento.Iniciado && !Variaveis.OperacaoEmAndamento.Finalizando)
{
Task.Run(async () => await Variaveis.OperacaoEmAndamento.FinalizarOperacao());
}
}
// Se a operação tiver algum item mandatório interrompido
else if (!Variaveis.OperacaoEmAndamento.OperacaoLiberada)
{
// Da primeira vez, salva a etapa atual anterior à parada para possível retomada
if (etapaAtual != StatusOperacao.Parado)
{
_EtapaAnteriorParada = etapaAtual;
}
etapaAtual = StatusOperacao.Parado;
}
// Se a etapa atual for parado, mas a operação foi liberada, retoma de onde parou
else if (etapaAtual == StatusOperacao.Parado && Variaveis.OperacaoEmAndamento.OperacaoLiberada)
{
Variaveis.OperacaoEmAndamento.TempoAguardando = DateTime.Now;
etapaAtual = StatusOperacao.Aguardando;
}
else if (_EtapaAnteriorParada != StatusOperacao.Parado)
{
etapaAtual = _EtapaAnteriorParada;
_EtapaAnteriorParada = StatusOperacao.Parado;
}
else
{
etapaAtual = StatusOperacao.EmAndamento;
}
break;
}
}
}
StatusAtual = etapaAtual;
}
public (bool, List<T_Code>) ModulosConectados { get; private set; }
public void AtualizarModulosConectados()
{
var _modulosMandatorios = Variaveis.OperacaoEmAndamento.ModulosMandatorios;
_modulosMandatorios.ForEach(Modulo =>
{
Modulo.Conectado = SerialService.DispositivosMapeados.Any(x => x.Dispositivo == Modulo.Dispositivo && x.Conectado);
});
List<T_Code> _modsComFalha = _modulosMandatorios.Where(x => !x.Liberado).Select(x => x.Dispositivo).ToList();
bool nenhumModuloMandatorio = _modulosMandatorios.All(x => !x.Mandatorio);
bool algumModuloConectado = _modulosMandatorios.Any(x => x.Conectado);
bool todosMandatoriosOK = !nenhumModuloMandatorio && !_modsComFalha.Any();
bool semMandatoriosMasAlgumConectado = nenhumModuloMandatorio && algumModuloConectado;
bool _opLiberada = todosMandatoriosOK || semMandatoriosMasAlgumConectado;
Variaveis.OperacaoEmAndamento.ModulosConectados = (_opLiberada, _modsComFalha);
Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada = GerarMensagemErroModulos();
}
public bool Emergencia { get; set; } = false;
public bool OperacaoLiberada { get; private set; }
public void AtualizarOperacaoLiberada()
{
(bool _modsConectados, List<T_Code> _modsComFalha) = Variaveis.OperacaoEmAndamento.ModulosConectados;
bool _parametrosNaoLiberados = Variaveis.OperacaoEmAndamento.ParametrosMandatorios.Any(x => !x.Liberado);
bool _operacaoLiberada = _modsConectados && !_parametrosNaoLiberados;
if (Variaveis.DebugMode) _operacaoLiberada = true;
if (Variaveis.OperacaoEmAndamento.Emergencia) _operacaoLiberada = false;
Variaveis.OperacaoEmAndamento.OperacaoLiberada = _operacaoLiberada;
}
public string ErroOperacaoLiberada { get; private set; }
private string GerarMensagemErroModulos()
{
var sb = new StringBuilder();
sb.AppendLine($"Para iniciar a operação {Modo}, é necessário que todos os módulos e parâmetros mandatórios estejam devidamente conectados ao equipamento, ou pelo menos um dos módulos:");
Variaveis.OperacaoEmAndamento.ModulosMandatorios.ForEach(mod =>
{
sb.AppendLine($"{mod.Dispositivo,-20}: ( {(mod.Liberado ? "OK" : " ")} ) - Mandatório: {(mod.Mandatorio ? "Sim" : "Não")}");
});
Variaveis.OperacaoEmAndamento.ParametrosMandatorios.ForEach(par =>
{
sb.AppendLine($"{par.Parametro,-20}: ( {(par.Liberado ? "OK" : " ")} ) - Mandatório: {(par.Mandatorio ? "Sim" : "Não")}");
});
return sb.ToString();
}
public bool Iniciado { get; set; }
public bool Simulando { get; set; } = false;
public bool Treinando { get; set; } = false;
public double SimulacaoAnguloControle { get; set; } = 0;
public double SimulacaoRpmControle { get; set; } = 0;
public bool Finalizando { get; set; } = false;
public DateTime DataInicio { get; set; } = DateTime.MinValue;
public DateTime DataFim { get; set; } = DateTime.MinValue;
public double TempoDecorridoSegs
{
get
{
return (StatusAtual == StatusOperacao.Parametrizando ? 0 : ((Variaveis.OperacaoEmAndamento.DataFim != DateTime.MinValue ? Variaveis.OperacaoEmAndamento.DataFim : DateTime.Now) - Variaveis.OperacaoEmAndamento.DataInicio).TotalSeconds);
}
}
public DateTime TempoAguardando { get; set; }
public List<OperacaoModulosMandatoriosModel> ModulosMandatorios { get; set; } = new List<OperacaoModulosMandatoriosModel>();
public List<OperacaoParametrosMandatoriosModel> ParametrosMandatorios { get; set; } = new List<OperacaoParametrosMandatoriosModel>();
public List<GPSModel> GPSTrajetoria { get; set; } = new List<GPSModel>();
public double CapacidadeReservatorio { get; set; } = 30;
public int QuantidadeCamerasSolo { get; set; } = 1;
public List<CameraSoloModel> CamerasSolo { get; set; } = new List<CameraSoloModel>();
public CameraCaminhoModel CameraCaminho { get; set; }
public int TempoIniciarOperacao { get; set; } = 25;
public string ID { get; set; }
public double tmrLogsInterval
{
get
{
return tmrLogs.Interval;
}
set
{
tmrLogs.SetInterval((int)value);
}
}
private static AsyncTaskTimerModel tmrLogs;
private static AsyncTaskTimerModel tmrLeituras;
public Chart chartGraficos = new Chart();
#region PARAMETRIZACAO
public bool SalvarParametrizacaoOperacao(
string descricao,
double capacidadeReservatorio,
double pressaoLinha,
int duracaoAtuacao,
int percentualAtuacao,
int anguloMaximo,
int velocidadeMovimento,
int velocidadeServasPercent,
int velocidadeCervasPercent,
UltrasonicA05Configuracoes ConfigUltrassom,
bool sonarAtivado,
int qtdCamerasSolo,
TiposControladorDirecional tipoControleDirecional)
{
if (string.IsNullOrEmpty(descricao))
{
MessageBox.Show("Preencha a descrição para identificação da operação!", "Aviso", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
if (Variaveis.OperacaoEmAndamento.ParametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Mapa && x.Mandatorio) && string.IsNullOrEmpty(Variaveis.OperacaoEmAndamento.Mapa?.mapaService?.CaminhoMapa) && !(Variaveis.OperacaoEmAndamento.Mapa?.RuasPercorrer ?? new List<string>()).Any())
{
MessageBox.Show("Selecione o mapa da operação e selecione as ruas a serem percorridas!", "Aviso", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
OperacaoParametrosModel Parametros = new OperacaoParametrosModel()
{
Modo = Variaveis.OperacaoEmAndamento.Modo,
Descricao = descricao,
AtuCapacidadeReservatorio = capacidadeReservatorio,
AtuDuracaoAtuacao = duracaoAtuacao,
AtuPercentualDeteccaoVertical = percentualAtuacao,
AtuPressaoLinha = pressaoLinha,
DirAnguloMaximo = anguloMaximo,
DirVelocidadeMovimento = velocidadeMovimento,
DirTipoMovimento = tipoControleDirecional,
MovVelocidadeCErvasPercent = velocidadeCervasPercent,
MovVelocidadeSErvasPercent = velocidadeServasPercent,
ModulosMandatorios = new List<OperacaoModulosMandatoriosModel>(Variaveis.OperacaoEmAndamento.ModulosMandatorios),
ParametrosMandatorios = new List<OperacaoParametrosMandatoriosModel>(Variaveis.OperacaoEmAndamento.ParametrosMandatorios),
Mapa = Variaveis.OperacaoEmAndamento.Mapa,
ConfiguracaoUltrassom = ConfigUltrassom,
SonarAtivado = sonarAtivado,
QtdCamerasSolo = qtdCamerasSolo
};
Parametros.Mapa.LimparDados(true);
string ParametrosJson = JsonConvert.SerializeObject(Parametros, Formatting.None);
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "Arquivo de Operação (*.opr)|*.opr";
saveFileDialog.DefaultExt = "opr";
saveFileDialog.AddExtension = true;
saveFileDialog.InitialDirectory = Variaveis.CaminhoSistema + Variaveis.CaminhoOperacoes;
saveFileDialog.FileName = descricao;
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
string filePath = saveFileDialog.FileName;
File.WriteAllText(filePath, ParametrosJson, Encoding.UTF8);
MessageBox.Show("Operação salva com sucesso!", "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
return true;
}
public (bool, List<string>) CarregarParametrizacaoOperacao(Panel pnlMapa, Label lblMapa, string opPath = "")
{
string path = Variaveis.CaminhoSistema + Variaveis.CaminhoOperacoes + MapasVariaveisModel.NomeArquivoMapaInterativoSaida;
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Arquivo de Operação (*.opr)|*.opr";
openFileDialog.DefaultExt = "opr";
openFileDialog.AddExtension = true;
openFileDialog.InitialDirectory = Variaveis.CaminhoSistema + Variaveis.CaminhoOperacoes;
if (!string.IsNullOrEmpty(opPath) || openFileDialog.ShowDialog() == DialogResult.OK)
{
string filePath = !string.IsNullOrEmpty(opPath) ? opPath : openFileDialog.FileName;
string ParametrosJson = File.ReadAllText(filePath, Encoding.UTF8);
var Parametros = JsonConvert.DeserializeObject<OperacaoParametrosModel>(ParametrosJson);
CarregarParametrosOperacaoPadrao(Parametros.Modo);
OperacaoControleModel controle = new OperacaoControleModel()
{
RPM_Max = (int)(VariaveisEquipamento.RPM_Max_Roda * (Parametros.MovVelocidadeSErvasPercent / 100.0)),
RPM_Min = (int)(VariaveisEquipamento.RPM_Max_Roda * (Parametros.MovVelocidadeCErvasPercent / 100.0)),
Angulo_Max = Parametros.DirAnguloMaximo,
Angulo_Min = Parametros.DirAnguloMaximo * -1,
VelocidadeMP = Parametros.DirVelocidadeMovimento,
TempoAtuacao = Parametros.AtuDuracaoAtuacao,
PercentualInicioPulverizacao = Parametros.AtuPercentualDeteccaoVertical / 100.0,
PressaoLinha = Parametros.AtuPressaoLinha,
Angulo = 0,
Direcao = Direcao.Parado,
PercentualVelocidadeSP = 0,
PIDdirecional = new PIDModel(),
FiltroVelocidade = new KalmanFilter(),
ControladorMPC = new MPCController(),
TiposControle = Variaveis.OperacaoEmAndamento.Controle.TiposControle.ToList(),
SonarAtivado = Parametros.SonarAtivado,
SegmentacaoSemantica = Parametros.Modo == ModoOperacao.MapaGPS,
TipoControleDirecional = Parametros.DirTipoMovimento,
PulverizadorAutomatico = Parametros.Modo == ModoOperacao.MapaGPS,
TipoMovimento = TipoMovimentoDirecional.RodasDianteiras,
SonarDesvioAutomatico = false,
};
Variaveis.OperacaoEmAndamento.Descricao = Parametros.Descricao;
Variaveis.OperacaoEmAndamento.QuantidadeCamerasSolo = Parametros.QtdCamerasSolo;
Variaveis.OperacaoEmAndamento.ModulosMandatorios = new List<OperacaoModulosMandatoriosModel>(Parametros.ModulosMandatorios ?? new List<OperacaoModulosMandatoriosModel>());
Variaveis.OperacaoEmAndamento.ParametrosMandatorios = new List<OperacaoParametrosMandatoriosModel>(Parametros.ParametrosMandatorios ?? new List<OperacaoParametrosMandatoriosModel>());
Variaveis.OperacaoEmAndamento.CapacidadeReservatorio = Parametros.AtuCapacidadeReservatorio;
Variaveis.OperacaoEmAndamento.Controle = controle;
if (Variaveis.OperacaoEmAndamento.DispSen == null)
{
Variaveis.OperacaoEmAndamento.DispSen = new DispositivosService<SensoriamentoModel>();
}
Variaveis.OperacaoEmAndamento.DispSen.Dados.ConfiguracaoSensorUltrassom = Parametros.ConfiguracaoUltrassom;
List<string> ruasSelecionadas = new List<string>();
if (Parametros.Mapa.mapaService.DadosMapa != null)
{
ruasSelecionadas = Parametros.Mapa.RuasPercorrer.ToList();
string geoJson = JsonConvert.SerializeObject(Parametros.Mapa.mapaService.DadosMapa, Formatting.None);
File.WriteAllText(path, geoJson, Encoding.UTF8);
Variaveis.OperacaoEmAndamento.Mapa = Parametros.Mapa;
/*Panel pnlMapa = FuncoesGlobais.FindControlRecursive<Panel>(Variaveis.OperacaoEmAndamento.frmOperacao, "pnlMapa");
Label lblMapa = FuncoesGlobais.FindControlRecursive<Label>(Variaveis.OperacaoEmAndamento.frmOperacao, "lblMapaCarregado");*/
Variaveis.OperacaoEmAndamento.Mapa.pnlMapa = pnlMapa;
Variaveis.OperacaoEmAndamento.Mapa.lblMapa = lblMapa;
Variaveis.OperacaoEmAndamento.Mapa.btnCarregar_Click(new object(), new EventArgs(), path);
//bool condicaoMapaCarregado() => Variaveis.OperacaoEmAndamento.Mapa.mapaService.Carregado;
//bool resultado = await FuncoesGlobais.AguardarCondicaoAsync(condicaoMapaCarregado, 5000, 200);
}
return (true, ruasSelecionadas);
}
else
{
return (false, new List<string>());
}
}
public static void CarregarParametrosOperacaoPadrao(ModoOperacao Modo)
{
var SenConectado = (DispositivosService<SensoriamentoModel>)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == T_Code.Sen);
var AtuConectado = (DispositivosService<AtuadorModel>)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == T_Code.Atu);
var MvdConectado = (DispositivosService<MovimentacaoUnificadaModel>)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == T_Code.Mvd);
tmrLogs?.Stop();
Variaveis.OperacaoEmAndamento.Controle.ControladorMPC?.Dispose();
Variaveis.OperacaoEmAndamento = new OperacaoModel(Modo)
{
Iniciado = false,
DataInicio = DateTime.MinValue,
DataFim = DateTime.MinValue,
DispAtu = AtuConectado,
DispSen = SenConectado,
DispMvd = MvdConectado,
Sensoriamento = new OperacaoSensoriamentoLogModel(),
QuantidadeCamerasSolo = 1,
};
switch (Modo)
{
case ModoOperacao.Manual:
Variaveis.OperacaoEmAndamento.frmOperacao = new frmOperacaoManual();
Variaveis.OperacaoEmAndamento.ControleAnterior = new OperacaoControleModel();
Variaveis.OperacaoEmAndamento.Controle = new OperacaoControleModel()
{
RPM_Max = 100,
RPM_Min = 15,
Angulo_Max = 25,
Angulo_Min = -25,
VelocidadeMP = 40,
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
},
new OperacaoControleTipoModel()
{
Tipo = T_Code.Atu,
DelayEnvioComando = 10,
Comandos = new List<string>(),
UltimoComando = DateTime.Now
},
},
SonarAtivado = false,
SonarDesvioAutomatico = false,
SegmentacaoSemantica = false,
PulverizadorAutomatico = false,
TipoMovimento = TipoMovimentoDirecional.RodasDianteiras,
TipoControleDirecional = TiposControladorDirecional.Manual
};
Variaveis.OperacaoEmAndamento.ModulosMandatorios = new List<OperacaoModulosMandatoriosModel>()
{
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Mov,
Mandatorio = false,
Utilizar = true,
},
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Dir,
Mandatorio = false,
Utilizar = true,
},
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Atu,
Mandatorio = false,
Utilizar = true,
}
};
Variaveis.OperacaoEmAndamento.ParametrosMandatorios = new List<OperacaoParametrosMandatoriosModel>()
{
new OperacaoParametrosMandatoriosModel()
{
Parametro = ParametrosOperacao.Joystick,
Mandatorio = false,
Utilizar = true,
},
new OperacaoParametrosMandatoriosModel()
{
Parametro = ParametrosOperacao.LoRa,
Mandatorio = false,
Utilizar = true,
},
};
break;
case ModoOperacao.MapaGPS:
Variaveis.OperacaoEmAndamento.frmOperacao = new frmOperacaoMapaGPS();
Variaveis.OperacaoEmAndamento.ControleAnterior = new OperacaoControleModel();
Variaveis.OperacaoEmAndamento.Controle = new OperacaoControleModel()
{
RPM_Max = 50,
RPM_Min = 20,
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 = 200,
Comandos = new List<string>(),
UltimoComando = DateTime.Now
},
new OperacaoControleTipoModel()
{
Tipo = T_Code.Atu,
DelayEnvioComando = 500,
Comandos = new List<string>(),
UltimoComando = DateTime.Now
},
},
SonarAtivado = false,
SonarDesvioAutomatico = false,
SegmentacaoSemantica = false,
PulverizadorAutomatico = true,
TipoMovimento = TipoMovimentoDirecional.RodasDianteiras,
TipoControleDirecional = TiposControladorDirecional.MPC,
};
Variaveis.OperacaoEmAndamento.ModulosMandatorios = new List<OperacaoModulosMandatoriosModel>()
{
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Mov,
Mandatorio = true,
Utilizar = true,
},
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Dir,
Mandatorio = true,
Utilizar = true,
},
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Sen,
Mandatorio = true,
Utilizar = true,
},
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Atu,
Mandatorio = true,
Utilizar = true,
},
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Gps,
Mandatorio = true,
Utilizar = true,
}
};
Variaveis.OperacaoEmAndamento.ParametrosMandatorios = new List<OperacaoParametrosMandatoriosModel>()
{
new OperacaoParametrosMandatoriosModel()
{
Parametro = ParametrosOperacao.CameraSolo,
Mandatorio = true,
Utilizar = true,
},
new OperacaoParametrosMandatoriosModel()
{
Parametro = ParametrosOperacao.Sonar,
Mandatorio = false,
Utilizar = true,
},
new OperacaoParametrosMandatoriosModel()
{
Parametro = ParametrosOperacao.Mapa,
Mandatorio = true,
Utilizar = true,
},
new OperacaoParametrosMandatoriosModel()
{
Parametro = ParametrosOperacao.LoRa,
Mandatorio = true,
Utilizar = true,
}
};
Variaveis.OperacaoEmAndamento.OpMapaGPS.Sensoriamento = new OperacaoMapaGPSSensoriamentoModel();
break;
case ModoOperacao.TreinamentoIA:
Variaveis.OperacaoEmAndamento.ControleAnterior = new OperacaoControleModel();
Variaveis.OperacaoEmAndamento.Controle = new OperacaoControleModel()
{
RPM_Max = 100,
RPM_Min = 20,
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 = 500,
Comandos = new List<string>(),
UltimoComando = DateTime.Now
},
},
SonarAtivado = true,
SonarDesvioAutomatico = true,
SegmentacaoSemantica = true,
PulverizadorAutomatico = true,
TipoMovimento = TipoMovimentoDirecional.RodasDianteiras,
TipoControleDirecional = TiposControladorDirecional.IA,
};
Variaveis.OperacaoEmAndamento.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,
},
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Wit,
Mandatorio = true,
},
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Pzm,
Mandatorio = true,
},
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Lra,
Mandatorio = true,
}
};
Variaveis.OperacaoEmAndamento.ParametrosMandatorios = new List<OperacaoParametrosMandatoriosModel>()
{
new OperacaoParametrosMandatoriosModel()
{
Parametro = ParametrosOperacao.CameraSolo,
Mandatorio = true,
},
new OperacaoParametrosMandatoriosModel()
{
Parametro = ParametrosOperacao.Sonar,
Mandatorio = true,
},
new OperacaoParametrosMandatoriosModel()
{
Parametro = ParametrosOperacao.Mapa,
Mandatorio = true,
}
};
Variaveis.OperacaoEmAndamento.OpMapaGPS.Sensoriamento = new OperacaoMapaGPSSensoriamentoModel();
break;
}
Variaveis.OperacaoEmAndamento.OpMapaGPS.Sensoriamento.ReiniciarLeituras();
Variaveis.OperacaoEmAndamento.AtualizaListaCameras(new List<Panel>(), new List<Panel>(), false);
if (Variaveis.OperacaoEmAndamento.DispSen != null)
{
if (Variaveis.OperacaoEmAndamento.DispSen.Dados.ConfiguracaoSensorUltrassom == null)
{
Variaveis.OperacaoEmAndamento.DispSen.Dados.ConfiguracaoSensorUltrassom = UltrasonicA05Helper.CarregarConfiguracaoPadrao(ConfiguracaoSensorUltrassonico.NaoUtilizado);
}
if (Variaveis.OperacaoEmAndamento.DispSen.Dados.Conectado)
{
Variaveis.OperacaoEmAndamento.DispSen.Dados.Sinaleiros.ForEach(x => x.Comportamento = VariaveisEquipamento.ComportamentoPorStatus(StatusOperacao.NaoIniciado));
Variaveis.OperacaoEmAndamento.DispSen.Dados.Sinaleiros.First(x => x.ID == (Modo == ModoOperacao.Manual ? "LEDMN" : "LEDAT")).Comportamento.statusLED = StatusLED.Aceso;
Variaveis.OperacaoEmAndamento.DispSen.Dados.Sinaleiros.First(x => x.ID == "LEDOP").Comportamento = VariaveisEquipamento.ComportamentoPorStatus();
//OperacaoCarregar.DispSen.Dados.Sinaleiros.ForEach(x => OperacaoCarregar.DispSen.AdicionarMensagemFila(OperacaoCarregar.DispSen.Dados.Modulo_ID, x.ProtocoloComando(), true, false));
foreach (var Sinaleiro in Variaveis.OperacaoEmAndamento.DispSen.Dados.Sinaleiros)
{
GeneralJoystick.EnviarComandoSensoriamento(S_Code.sLED, Sinaleiro.ID, Sinaleiro.Comportamento);
}
}
}
Variaveis.OperacaoEmAndamento.Controle.Angulo = Variaveis.OperacaoEmAndamento.Controle.Angulo_Max;
Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP = Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeMin;
Variaveis.OperacaoEmAndamento.Sensoriamento.AtualizarDados();
}
public async Task IniciarOperacao()
{
tmrLogs?.Start();
Iniciado = true;
Simulando = false;
Treinando = false;
DataInicio = DateTime.Now;
TempoAguardando = DateTime.Now;
DataFim = DateTime.MinValue;
idxLog = 0;
ID = DataInicio.ToString("dd_MM_yyyy_HH_mm_ss");
Directory.CreateDirectory(Variaveis.CaminhoOperacoes + ID + "/");
DispMvd?.Dados?.ReiniciarLeituras(DispMvd?.Dados);
DispAtu?.Dados?.ReiniciarLeituras(DispAtu?.Dados);
DispSen?.Dados?.ReiniciarLeituras(DispSen?.Dados);
Sensoriamento.AtualizarDados();
OpMapaGPS.Sensoriamento.ReiniciarLeituras();
if (Modo == ModoOperacao.MapaGPS)
{
Controle.PIDdirecional = new PIDModel()
{
LimiteSaida = Controle.Angulo_Max,
SetPoint = 0
};
Controle.FiltroVelocidade = new KalmanFilter(erroMedicao: 2.0, erroProcesso: 0.05);
Controle.ControladorMPC = new MPCController();
bool mpcIniciado = await Controle.ControladorMPC.Inicializar();
if (mpcIniciado)
{
await Controle.ControladorMPC.EnviarDadosTrajetoria(Variaveis.OperacaoEmAndamento.Trajetoria._TrajetoriaFixa);
}
}
Controle.Angulo = 0;
Controle.PercentualVelocidadeSP = 0;
Controle.TiposControle.ForEach(x => x.UltimaDirecao = Direcao.Parado);
Controle.TipoMovimento = TipoMovimentoDirecional.RodasDianteiras;
GPSTrajetoria = new List<GPSModel>();
await RealizarCalibragemInicialAsync();
if (Modo == ModoOperacao.Manual)
{
await Task.Run(async () =>
{
await Task.Delay(3000);
Controle.Angulo = 25;
Controle.PercentualVelocidadeSP = 25;
});
}
}
public async Task FinalizarOperacao()
{
if (Variaveis.OperacaoEmAndamento.Finalizando)
{
return;
}
Variaveis.OperacaoEmAndamento.Finalizando = true;
Variaveis.OperacaoEmAndamento.Trajetoria?.LoopAtualizaDados();
Variaveis.OperacaoEmAndamento.PararCarroOperacaoInterrompida(true);
Variaveis.OperacaoEmAndamento.Controle.ControladorMPC?.Dispose();
await Task.Delay(2000);
Variaveis.OperacaoEmAndamento.Iniciado = false;
Variaveis.OperacaoEmAndamento.DataFim = DateTime.Now;
tmrLogs?.Stop();
SalvarLogs(false);
Variaveis.OperacaoEmAndamento.Finalizando = false;
}
public async Task RealizarCalibragemInicialAsync()
{
var DispAtu = Variaveis.OperacaoEmAndamento.DispAtu;
if (DispAtu != null)
{
// Ligar bomba
var Bomba = DispAtu.Dados.BombaPressurizadora;
if (Bomba.Inicializado)
{
GeneralJoystick.EnviarComandoAtuador(S_Code.sBMB, true, Bomba.ID);
await Task.Delay(5000);
}
// Testar os bicos
for (int i = 0; i < DispAtu.Dados.QuantidadeBicos; i++)
{
var Bico = DispAtu.Dados.BicosPulverizadores[i];
if (Bico.Inicializado)
{
GeneralJoystick.EnviarComandoAtuador(S_Code.sBIC, true, Bico.ID);
await Task.Delay(200);
GeneralJoystick.EnviarComandoAtuador(S_Code.sBIC, false, Bico.ID);
}
}
await Task.Delay(1000);
}
var DispMvd = Variaveis.OperacaoEmAndamento.DispMvd;
if (DispMvd != null)
{
// Referenciar motores de passo
if (DispMvd.Dados.Modulos.Any(x => x.DirMotor.Inicializado))
{
//GeneralJoystick.EnviaComandoMotor(Keys.R);
}
}
/*if (KinectService.Iniciado)
{
KinectService.RecalibrarSubdivisoes();
}*/
}
public void IniciarSimulacao()
{
Iniciado = true;
Simulando = true;
Treinando = false;
DataInicio = DateTime.Now;
TempoAguardando = DateTime.Now;
DataFim = DateTime.MinValue;
ID = "";
DispMvd?.Dados?.ReiniciarLeituras(DispMvd.Dados);
DispAtu?.Dados?.ReiniciarLeituras(DispAtu.Dados);
DispSen?.Dados?.ReiniciarLeituras(DispSen.Dados);
Sensoriamento?.AtualizarDados();
OpMapaGPS?.Sensoriamento?.ReiniciarLeituras();
if (Modo == ModoOperacao.MapaGPS)
{
Controle.PIDdirecional = new PIDModel()
{
LimiteSaida = Controle.Angulo_Max,
SetPoint = 0
};
Controle.FiltroVelocidade = new KalmanFilter(erroMedicao: 2.0, erroProcesso: 0.05);
Controle.ControladorMPC = new MPCController();
Task.Run(async () =>
{
bool mpcIniciado = await Controle.ControladorMPC.Inicializar();
if (mpcIniciado)
{
await Controle.ControladorMPC.EnviarDadosTrajetoria(Variaveis.OperacaoEmAndamento.Trajetoria._TrajetoriaFixa);
}
});
}
Controle.Angulo = 0;
Controle.PercentualVelocidadeSP = 0;
GPSTrajetoria = new List<GPSModel>();
}
public void ReiniciarSimulacao()
{
Variaveis.OperacaoEmAndamento.Controle.ControladorMPC?.Dispose();
Variaveis.OperacaoEmAndamento.StatusAtual = StatusOperacao.Parametrizando;
Variaveis.OperacaoEmAndamento.Iniciado = false;
Variaveis.OperacaoEmAndamento.Simulando = false;
Variaveis.OperacaoEmAndamento.Mapa = new MapasModel();
Variaveis.OperacaoEmAndamento.Trajetoria = new TrajetoriaMapaOperacaoModel(new List<List<GPSModel>>());
Variaveis.OperacaoEmAndamento.GPSTrajetoria = new List<GPSModel>();
var Topico = Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == MapasVariaveisModel.TopicoSelecaoRuasMapa);
Topico.Mensagens.Add(new MqttService.MqttTopicosMensagensModel()
{
Mensagem = "[]",
Momento = DateTime.Now
});
}
public void IniciarTreinamento()
{
Iniciado = true;
Treinando = true;
DataInicio = DateTime.Now;
TempoAguardando = DateTime.Now;
DataFim = DateTime.MinValue;
ID = "";
if (DispMvd != null)
{
DispMvd.Dados.ReiniciarLeituras(DispMvd.Dados);
}
if (DispAtu != null)
{
DispAtu.Dados.ReiniciarLeituras(DispAtu.Dados);
}
if (DispSen != null)
{
DispSen.Dados.ReiniciarLeituras(DispSen.Dados);
}
Sensoriamento.AtualizarDados();
OpMapaGPS.Sensoriamento.ReiniciarLeituras();
if (Modo == ModoOperacao.MapaGPS)
{
Controle.PIDdirecional = new PIDModel()
{
LimiteSaida = Controle.Angulo_Max,
SetPoint = 0
};
Controle.FiltroVelocidade = new KalmanFilter(erroMedicao: 2.0, erroProcesso: 0.05);
}
Controle.Angulo = 0;
Controle.PercentualVelocidadeSP = 0;
GPSTrajetoria = new List<GPSModel>();
}
public static string DeserializarDadosOperacao(string caminho, string arquivo)
{
string opPath = caminho.Replace("data.lgop", arquivo) + ".json";
string opStr = File.ReadAllText(opPath);
if (!opStr.EndsWith("]"))
{
opStr += "]";
}
return opStr;
}
#endregion
#region CAMERAS
public void AtualizaListaCameras(List<Panel> pnlCameraCaminho, List<Panel> pnlCameraSolo, bool Iniciar)
{
if (DispSen == null)
{
return;
}
Variaveis.OperacaoEmAndamento.DesligarCameras();
//var listaCameras = CameraService.ObterListaCameras().Values.ToArray();
var listaCameras = OAKCameraService.GetListaCameras();
CamerasSolo.Clear();
for (int i = 0; i < QuantidadeCamerasSolo; i++)
{
string CamNome = "Cam_Solo_" + i.ToString();
string deviceId =
pnlCameraSolo.Count(x => x != null) > i && pnlCameraSolo[i].Tag != null && !string.IsNullOrEmpty(pnlCameraSolo[i].Tag.ToString()) ? pnlCameraSolo[i].Tag.ToString() :
DispSen.Dados.CameraID_Solo.Count > i ? DispSen.Dados.CameraID_Solo[i] :
null;
CameraSoloModel CameraSolo = new CameraSoloModel()
{
ID = T_Code.Cam.ToString() + "_" + i.ToString(),
Nome = CamNome,
DeviceID = deviceId,
Posicao = CamerasSolo.Count(),
ArquivoLeitura = "ervas_" + CamNome + ".json",
browser = null,
camera = new CameraService()
{
InverterDadosLeitura = true,
},
combo = new ComboBox(),
MaxLeituras = 1,
VideoPorta = (VariaveisPortas.CameraSolo + CamerasSolo.Count()).ToString(),
VideoUrl = "green_objects_" + CamNome,
MqttTopico = "green_objects_" + CamNome,
};
CamerasSolo.Add(CameraSolo);
//CameraSolo.camera.selectedCamera = true ? 1 : 0;
CameraSolo.camera.cameraIndex = listaCameras.FirstOrDefault(x => x.Id == CameraSolo.DeviceID)?.Index ?? -1;
if (CameraSolo.camera.cameraIndex > -1 && Iniciar)
{
CameraSolo.panel = pnlCameraSolo[i];
IniciarCameraSolo(CameraSolo);
}
}
string deviceIdCaminho =
pnlCameraCaminho != null && pnlCameraCaminho.Any(x => x.Tag != null) && !string.IsNullOrEmpty(pnlCameraCaminho.FirstOrDefault().Tag.ToString()) ? pnlCameraCaminho.FirstOrDefault().Tag.ToString() :
DispSen.Dados.CameraID_Caminho;
var cameraCaminho = new CameraCaminhoModel()
{
ID = T_Code.Snr.ToString(),
Nome = "Cam_Caminho",
DeviceID = deviceIdCaminho,
ArquivoLeitura = "leitura_ruas.json",
browserRgb = null,
camera = new CameraService(),
MaxLeituras = 10,
Angulo = 0,
AnguloDireito = 0,
AnguloEsquerdo = 0,
Leitura = new CameraDeepLabV3PlusModel(),
PontosExtremos = new List<System.Drawing.Point>(),
VideoPorta = (VariaveisPortas.CameraCaminho).ToString(),
VideoRgbUrl = "oak_rgb",
VideoHeatmapUrl = "oak_heatmap",
MqttTopico = "street_detector",
};
CameraCaminho = cameraCaminho;
//CameraCaminhoKinect.camera.selectedCamera = KinectService.Iniciado ? 1 : 0;
CameraCaminho.camera.cameraIndex = listaCameras.FirstOrDefault(x => x.Id == CameraCaminho.DeviceID)?.Index ?? -1;
if (CameraCaminho.camera.cameraIndex > -1 && Iniciar) // && Variaveis.OperacaoEmAndamento.Controle.SegmentacaoSemantica
{
if (pnlCameraCaminho.Count > 0)
{
CameraCaminho.panelRgb = pnlCameraCaminho[0];
}
if (pnlCameraCaminho.Count > 1)
{
CameraCaminho.panelHeatmap = pnlCameraCaminho[1];
}
IniciarCameraCaminho(CameraCaminho);
}
}
public void IniciarCameraSolo(CameraSoloModel CameraSolo)
{
DesligarCameraSolo(CameraSolo);
if (CameraSolo.camera.cameraIndex > -1)
{
VersaoArquivoModel ArquivoVersao = VersionamentoService.ArquivoModeloWeedDetector;
//CameraSolo.IniciarRotinaProcesso();
CameraSolo.camera.IniciarCamera(
Variaveis.OperacaoEmAndamento.DispAtu.Dados.ScriptDeteccaoErvas,
new string[] {
CameraSolo.MaxLeituras.ToString(),
CameraSolo.VideoPorta,
CameraSolo.VideoUrl,
CameraSolo.ArquivoLeitura,
"0",
CameraSolo.MqttTopico,
ArquivoVersao.Diretorio,
ArquivoVersao.Versao,
},
CameraSolo.VideoPorta,
new List<string>() { CameraSolo.VideoUrl },
CameraSolo.MqttTopico,
async (Mensagem) =>
{
CameraSolo.UltimaMensagemRecebida = Mensagem.Momento;
if (Mensagem.Momento > CameraSolo.camera.IniciadoEm && Mensagem.Mensagem == "OK")
{
CameraSolo.camera.ProntoEm = Mensagem.Momento;
if (CameraSolo.browser == null && CameraSolo.panel != null)
{
CameraSolo.Iniciada = true;
CameraSolo.browser = new WebView2();
CameraSolo.browser.Source = new Uri(CameraSolo.camera.URLcamera[0]);
CameraSolo.browser.Dock = DockStyle.Fill;
CameraSolo.panel.Invoke(new Action(() =>
{
CameraSolo.panel.Controls.Add(CameraSolo.browser);
CameraSolo.panel.Refresh();
}));
}
}
}
);
}
else
{
Console.Write("Camera " + CameraSolo.Nome + " não foi configurada!");
}
}
public void DesligarCameraSolo(CameraSoloModel CameraSolo)
{
CameraSolo.DesligarCamera();
}
public void IniciarCameraCaminho(CameraCaminhoModel cameraCaminho)
{
DesligarCameraCaminho(cameraCaminho);
if (cameraCaminho.camera.cameraIndex > -1)
{
VersaoArquivoModel ArquivoVersao = VersionamentoService.ArquivoModeloStreetDetector;
cameraCaminho.camera.IniciarCamera(
PythonService.ScriptStreetDetector,
new string[] {
cameraCaminho.MqttTopico,
cameraCaminho.VideoPorta,
cameraCaminho.VideoRgbUrl,
cameraCaminho.VideoHeatmapUrl,
cameraCaminho.MaxLeituras.ToString(),
cameraCaminho.camera.cameraIndex.ToString(),
},
cameraCaminho.VideoPorta,
new List<string>() { cameraCaminho.VideoRgbUrl, cameraCaminho.VideoHeatmapUrl },
cameraCaminho.MqttTopico,
async (Mensagem) =>
{
cameraCaminho.UltimaMensagemRecebida = Mensagem.Momento;
if (Mensagem.Momento > cameraCaminho.camera.IniciadoEm && Mensagem.Mensagem == "OK_1")
{
cameraCaminho.camera.ProntoEm = Mensagem.Momento;
if (cameraCaminho.browserRgb == null)
{
cameraCaminho.Iniciada = true;
if (cameraCaminho.camera.URLcamera.Count > 0)
{
cameraCaminho.browserRgb = new WebView2();
cameraCaminho.browserRgb.Source = new Uri(cameraCaminho.camera.URLcamera[0]);
cameraCaminho.browserRgb.Dock = DockStyle.Fill;
cameraCaminho.panelRgb.Invoke(new Action(() =>
{
cameraCaminho.panelRgb.Controls.Add(cameraCaminho.browserRgb);
cameraCaminho.browserRgb.Refresh();
}));
FuncoesGlobais.ValidarImagemCameraBrowser(cameraCaminho.browserRgb, cameraCaminho.panelRgb);
}
}
}
else if (Mensagem.Momento > cameraCaminho.camera.IniciadoEm && Mensagem.Mensagem == "OK_2")
{
cameraCaminho.camera.ProntoEm = Mensagem.Momento;
if (cameraCaminho.browserHeatmap == null && cameraCaminho.panelHeatmap != null)
{
cameraCaminho.Iniciada = true;
if (cameraCaminho.camera.URLcamera.Count > 1)
{
cameraCaminho.browserHeatmap = new WebView2();
cameraCaminho.browserHeatmap.Source = new Uri(cameraCaminho.camera.URLcamera[1]);
cameraCaminho.browserHeatmap.Dock = DockStyle.Fill;
cameraCaminho.panelHeatmap.Invoke(new Action(() =>
{
cameraCaminho.panelHeatmap.Controls.Add(cameraCaminho.browserHeatmap);
cameraCaminho.browserHeatmap.Refresh();
}));
FuncoesGlobais.ValidarImagemCameraBrowser(cameraCaminho.browserHeatmap, cameraCaminho.panelHeatmap);
}
}
}
}
);
}
}
public void DesligarCameraCaminho(CameraCaminhoModel cameraCaminho)
{
cameraCaminho.DesligarCamera();
}
public void DesligarCameras()
{
Variaveis.OperacaoEmAndamento.CamerasSolo.ForEach(Camera =>
{
Camera.DesligarCamera();
});
Variaveis.OperacaoEmAndamento.CameraCaminho?.DesligarCamera();
}
#endregion
#region CONTROLE DA OPERACAO
public void AtualizaInformacoesControleOperacao()
{
if (Variaveis.OperacaoEmAndamento.Modo == ModoOperacao.MapaGPS)
{
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(false);
}
}
public void AtualizarDadosControle(bool ForcarEnvio)
{
DateTime Agora = DateTime.Now;
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
bool MovimentoLiberado = Variaveis.OperacaoEmAndamento.StatusAtual == StatusOperacao.EmAndamento && !Variaveis.OperacaoEmAndamento.Finalizando && !MKS057DCanService.Referenciando;
if (ForcarEnvio || MovimentoLiberado)
{
foreach (var Ctrl in _Controle.TiposControle)
{
if (ForcarEnvio || ((Agora - Ctrl.UltimoComando).TotalMilliseconds > Ctrl.DelayEnvioComando))
{
if (Ctrl.Tipo == T_Code.Atu && !_Controle.PulverizadorAutomatico)
{
return;
}
IDispositivosService disp = Ctrl.Tipo == T_Code.Atu ?
(IDispositivosService)Variaveis.OperacaoEmAndamento.DispAtu :
(IDispositivosService)Variaveis.OperacaoEmAndamento.DispMvd;
var Protocolos = EnviarProtocoloComando(disp, Ctrl.Tipo, ForcarEnvio);
Ctrl.UltimoComando = Agora;
Ctrl.Comandos.AddRange(Protocolos);
}
}
}
}
public List<string> EnviarProtocoloComando(IDispositivosService Dispositivo, T_Code Tipo, bool ForcarEnvio)
{
if (Dispositivo == null || !Variaveis.OperacaoEmAndamento.Iniciado)
{
return new List<string>();
}
List<string> Protocolos = new List<string>();
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
var _ControleAnterior = Variaveis.OperacaoEmAndamento.ControleAnterior;
if (Dispositivo.Dados is MovimentacaoUnificadaModel)
{
switch (Tipo)
{
case T_Code.Mov:
{
Variaveis.OperacaoEmAndamento.OpMapaGPS.DefinirDadosControleMov();
if (_Controle.RPM_SP == 0)
{
_Controle.Direcao = Direcao.Parado;
}
else if(_Controle.RPM_SP < 0)
{
_Controle.PercentualVelocidadeSP *= -1;
_Controle.Direcao = Direcao.Tras;
}
else if (_Controle.RPM_SP > 0)
{
_Controle.Direcao = Direcao.Frente;
}
if (ForcarEnvio || _Controle.RPM_SP != _ControleAnterior.RPM_SP)
{
((MovimentacaoUnificadaModel)Dispositivo.Dados).Modulos.ForEach(Mod => Mod.MovMotor.EnviarComandoControle(_Controle.Direcao));
_Controle.TiposControle.FirstOrDefault(x => x.Tipo == Tipo).UltimaDirecao = _Controle.Direcao;
}
_ControleAnterior.PercentualVelocidadeSP = _Controle.PercentualVelocidadeSP;
break;
}
case T_Code.Dir:
{
Variaveis.OperacaoEmAndamento.OpMapaGPS.DefinirDadosControleDir();
if (_Controle.Angulo > 0)
{
_Controle.Direcao = Direcao.Direita;
}
else if (_Controle.Angulo < 0)
{
_Controle.Direcao = Direcao.Esquerda;
}
else
{
_Controle.Direcao = Direcao.Parado;
}
// Só enviar comando se a direção realmente mudou
if (ForcarEnvio || _ControleAnterior.Angulo != _Controle.Angulo)
{
((MovimentacaoUnificadaModel)Dispositivo.Dados).Modulos.ForEach(Mod => Mod.DirMotor.EnviarComandoControle(_Controle.Direcao));
_Controle.TiposControle.FirstOrDefault(x => x.Tipo == Tipo).UltimaDirecao = _Controle.Direcao;
}
_ControleAnterior.Angulo = _Controle.Angulo;
break;
}
}
Protocolos = new List<string>()
{
Tipo.ToString() + ";" + _Controle.Direcao.ToString() + ";" + _Controle.RPM_SP.ToString() + ";" + _Controle.Angulo.ToString()
};
}
else if (Dispositivo.Dados is AtuadorModel)
{
Variaveis.OperacaoEmAndamento.OpMapaGPS.DefinirDadosControleAtu();
if (ForcarEnvio || _ControleAnterior.BicosAtuados.Count() >= _Controle.BicosAtuados.Count())
{
for (int i = 0; i < _Controle.BicosAtuados.Count; i++)
{
if (_Controle.BicosAtuados[i].ComandoAtuar != _ControleAnterior.BicosAtuados[i].ComandoAtuar)
{
GeneralJoystick.EnviarComandoAtuador(S_Code.sBIC, _Controle.BicosAtuados[i].ComandoAtuar, _Controle.BicosAtuados[i].ID);
}
}
}
_ControleAnterior.BicosAtuados = _Controle.BicosAtuados.Select(x => x.Clone()).ToList();
Protocolos = new List<string>()
{
Tipo.ToString() + ";" + string.Join(";", _Controle.BicosAtuados.Select(x => x.ComandoAtuar ? "1" : "0"))
};
}
return Protocolos;
}
private void VerificarDesvioPorObstaculos()
{
if (Variaveis.OperacaoEmAndamento.Controle.SonarAtivado)
{
var Camera = Variaveis.OperacaoEmAndamento.CameraCaminho;
var Sonar = CameraCaminho?.Sonar;
if ((Camera?.Iniciada ?? false) && (Sonar?.DesvioNecessario ?? false))
{
Keys TeclaComando =
Sonar.DirecaoDesvio == Direcao.Esquerda ? Keys.Left :
Sonar.DirecaoDesvio == Direcao.Direita ? Keys.Right :
Keys.Escape;
if (Variaveis.OperacaoEmAndamento.Controle.SonarDesvioAutomatico)
{
Variaveis.OperacaoEmAndamento.Controle.Angulo = Sonar.AnguloDesvio;
GeneralJoystick.EnviaComandoMotor(TeclaComando, T_Code.Dir);
}
if (Sonar.DirecaoDesvio == Direcao.Parado)
{
GeneralJoystick.EnviaComandoMotor(Keys.Escape, T_Code.Mov);
}
}
var Ultrassom = UltrasonicA05Service.DadosLeitura.Configuracao;
if (UltrasonicA05Service.Iniciado && Ultrassom.DesvioNecessario)
{
Keys TeclaComando =
Ultrassom.DirecaoDesvio == Direcao.Esquerda ? Keys.Left :
Ultrassom.DirecaoDesvio == Direcao.Direita ? Keys.Right :
Keys.Escape;
if (Ultrassom.ParadaNecessaria)
{
GeneralJoystick.EnviaComandoMotor(Keys.Escape, T_Code.Mov);
}
else if (Ultrassom.DesvioNecessario)
{
Variaveis.OperacaoEmAndamento.Controle.Angulo = Variaveis.OperacaoEmAndamento.Controle.Angulo_Max;
GeneralJoystick.EnviaComandoMotor(TeclaComando, T_Code.Dir);
}
}
}
}
private async Task tmrLeituras_Tick()
{
if (Variaveis.IsAgroMonitor)
{
return;
}
Variaveis.OperacaoEmAndamento.Sensoriamento.AtualizarDados();
// Algum módulo mandatório foi interrompido durante a operação iniciada
if (!Variaveis.OperacaoEmAndamento.OperacaoLiberada && Variaveis.OperacaoEmAndamento.Iniciado)
{
PararCarroOperacaoInterrompida(false);
return;
}
if (Variaveis.OperacaoEmAndamento.Iniciado)
{
foreach (var CameraSolo in Variaveis.OperacaoEmAndamento.CamerasSolo.Where(x => x.Iniciada))
{
try
{
AtualizaLeituraCameraSolo(CameraSolo);
}
catch (Exception ex)
{
Console.WriteLine("Erro ao ler dados da câmera do solo (" + CameraSolo.Nome + "): " + ex.Message);
}
}
try
{
AtualizaLeituraCameraCaminho();
}
catch (Exception ex)
{
Console.WriteLine("Erro ao ler dados da câmera do caminho: " + ex.Message);
}
}
else
{
Variaveis.OperacaoEmAndamento.Mapa.AtualizarRuasSelecionadas();
}
try
{
AtualizarGrafico();
}
catch (Exception ex)
{
}
}
private void AtualizaLeituraCameraSolo(CameraSoloModel CameraSolo)
{
if (CameraSolo.UltimaMensagemRecebida == CameraSolo.UltimaMensagemProcessada)
{
return;
}
if (CameraSolo.camera._mqttTopico?.Mensagens?.Any(x => x.Momento > CameraSolo.camera.IniciadoEm && x.Mensagem != "OK") ?? false)
{
try
{
var Mensagem = CameraSolo.camera._mqttTopico.Mensagens.LastOrDefault(x => x.Momento > CameraSolo.camera.IniciadoEm);
if (Mensagem != null)
{
CameraSolo.Leitura = JsonConvert.DeserializeObject<CameraCoordenadasFrameModel>(Mensagem.Mensagem);
CameraSolo.UltimaMensagemProcessada = CameraSolo.UltimaMensagemRecebida;
}
}
catch (Exception ex)
{
Console.WriteLine("Erro ao parsear json da camera solo: " + ex.Message);
}
var Atuador = Variaveis.OperacaoEmAndamento.DispAtu;
int BicosPorCamera = Atuador.Dados.QuantidadeBicos / Variaveis.OperacaoEmAndamento.CamerasSolo.Count();
var Verdes = CameraSolo.Leitura.objetos.ToList();
int intervaloPorBico = Convert.ToInt32(CameraSolo.Leitura.x_max) / BicosPorCamera;
int inicioBarraPulverizadora = Convert.ToInt32(CameraSolo.Leitura.y_max * (1 - Variaveis.OperacaoEmAndamento.Controle.PercentualInicioPulverizacao));
List<string> BicosJaAtuados = Atuador.Dados.BicosPulverizadores.Where(x => x.ComandoAtuar).Select(x => x.ID).ToList();
for (int i = 0; i < BicosPorCamera; i++)
{
int iBico = i + (CameraSolo.Posicao * BicosPorCamera);
bool atuarBico = false;
foreach (var verde in Verdes)
{
// Calcule a posição final (y + altura) do objeto verde
int posicaoFinalVerdeY = verde.y + verde.altura;
if (posicaoFinalVerdeY > inicioBarraPulverizadora)
{
// Calcule a posição final (x + largura) do objeto verde
int posicaoFinalVerdeX = verde.x + verde.largura;
// Determina o intervalo no eixo x para o bico atual
int limiteInferior = intervaloPorBico * i;
int limiteSuperior = limiteInferior + intervaloPorBico;
// Verifica se o objeto 'verde' está dentro do intervalo deste bico
// A condição foi ajustada para verificar se qualquer parte do objeto verde cruza com o intervalo do bico
bool ervaNoRange = verde.x < limiteSuperior && posicaoFinalVerdeX > limiteInferior;
if (ervaNoRange && Variaveis.OperacaoEmAndamento.Sensoriamento.StatusOperacao == StatusOperacao.EmAndamento)
{
atuarBico = true;
}
}
}
Atuador.Dados.BicosPulverizadores[iBico].ComandoAtuar = atuarBico;
}
CameraSolo.ErvasNoRadar = Verdes.Count();
// Registra as atuações dos bicos para cada erva detectada
for (int i = 0; i < BicosPorCamera; i++)
{
int iBico = i + (CameraSolo.Posicao * BicosPorCamera);
var Bico = Atuador.Dados.BicosPulverizadores[iBico];
if (Bico.ComandoAtuar && !BicosJaAtuados.Contains(Bico.ID))
{
var atuacao = Variaveis.OperacaoEmAndamento.OpMapaGPS.Sensoriamento.AtuacoesPorBico[iBico];
// Registra ervas associadas apenas aos bicos que realmente atuaram
foreach (var erva in CameraSolo.Leitura.objetos)
{
if (!atuacao.ContainsKey(erva.descricao))
{
atuacao[erva.descricao] = 1;
}
else
{
atuacao[erva.descricao]++;
}
Bico.Atuacoes = atuacao.Sum(x => x.Value);
}
}
}
//Variaveis.OperacaoEmAndamento.AtualizarDadosControlePulverizador(false);
}
}
private void AtualizaLeituraCameraCaminho()
{
try
{
var cameraCaminho = Variaveis.OperacaoEmAndamento.CameraCaminho;
if (cameraCaminho == null || !cameraCaminho.Iniciada)
{
return;
}
if (cameraCaminho.UltimaMensagemRecebida == cameraCaminho.UltimaMensagemProcessada)
{
return;
}
var MqttTopico = cameraCaminho.camera._mqttTopico;
if (MqttTopico != null && MqttTopico.Mensagens.Any(x => x.Momento > cameraCaminho.camera.IniciadoEm && !x.Mensagem.StartsWith("OK")))
{
try
{
var Mensagem = MqttTopico.Mensagens.LastOrDefault(x => x.Momento > cameraCaminho.camera.IniciadoEm);
if (Mensagem != null)
{
cameraCaminho.Leitura = JsonConvert.DeserializeObject<CameraDeepLabV3PlusModel>(Mensagem.Mensagem);
cameraCaminho.Sonar.DetectarObstaculos(cameraCaminho.Leitura.subdivisoes);
cameraCaminho.UltimaMensagemProcessada = cameraCaminho.UltimaMensagemRecebida;
}
}
catch (Exception ex)
{
Console.WriteLine("Erro ao processar leitura da camera caminho: " + ex.Message);
}
}
// Atualizar representação gráfica do resultado da leitura do caminho
//pnlCaminho.Invalidate();
if (cameraCaminho.PontosExtremos.Any())
{
double esq_CA = cameraCaminho.PontosExtremos[2].X - cameraCaminho.PontosExtremos[1].X;
double esq_CO = cameraCaminho.PontosExtremos[1].Y - cameraCaminho.PontosExtremos[2].Y;
double esq_AG = Math.Atan(esq_CO / esq_CA) * (180 / Math.PI);
double dir_CA = cameraCaminho.PontosExtremos[4].X - cameraCaminho.PontosExtremos[3].X;
double dir_CO = cameraCaminho.PontosExtremos[4].Y - cameraCaminho.PontosExtremos[3].Y;
double dir_AG = Math.Atan(dir_CO / dir_CA) * (180 / Math.PI);
cameraCaminho.Angulo = dir_AG - esq_AG;
cameraCaminho.AnguloDireito = dir_AG;
cameraCaminho.AnguloEsquerdo = esq_AG;
}
else
{
cameraCaminho.Angulo = 0;
cameraCaminho.AnguloDireito = 0;
cameraCaminho.AnguloEsquerdo = 0;
}
// Atualizar angulo de inclinação calculado através do modelo de IA para reconhecimento do caminho
//pnlAnguloCamera.Invalidate();
//AtualizaInformacoesControleOperacao();
}
catch (Exception ex)
{
Console.WriteLine("Erro ao receber dados da Camera Caminho: " + ex.Message);
}
}
bool atualizandoGrafico = false;
private void AtualizarGrafico()
{
if (atualizandoGrafico || !Variaveis.DebugMode)
{
return;
}
Chart chart = Variaveis.OperacaoEmAndamento.chartGraficos;
if (Variaveis.OperacaoEmAndamento.DispMvd == null || chart == null || chart.IsDisposed)
{
return;
}
atualizandoGrafico = true;
MvdMotorMOVSensorimanetoGrafico Log = null;
// Primeiro, coletar todos os logs alinhados por índice em uma lista de tuplas (index, moduloLog)
var Logs = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos
.Where(x => x.MovMotor.Inicializado)
.SelectMany(m => m.MovMotor.LogGrafico.Select((log, index) => new { Index = index, Log = log }))
.GroupBy(x => x.Index) // Agrupa por índice
.OrderBy(g => g.Key) // Ordena pelos índices (opcional, mas ajuda na leitura)
.Select(g => new MvdMotorMOVSensorimanetoGrafico()
{
// Calcula a média de cada propriedade no grupo
Momento = new DateTime((long)g.Average(x => x.Log.Momento.Ticks)),
Velocidade = g.Average(x => x.Log.Velocidade),
RPM_Motor = Convert.ToInt32(g.Average(x => x.Log.RPM_Motor)),
RPM_Roda = Convert.ToInt32(g.Average(x => x.Log.RPM_Roda)),
RPM_SP = Convert.ToInt32(g.Average(x => x.Log.RPM_SP)),
Temperatura = g.Average(x => x.Log.Temperatura),
Tensao = g.Average(x => x.Log.Tensao),
})
.ToList();
if (Logs.Count > 0)
{
Log = Logs.Last();
}
double Minimo = 0;
double Maximo = 0;
FuncoesGlobais.ExecutarMetodoComVerificacaoCrossThread(chart, () =>
{
try
{
chart.Titles.Clear();
chart.Titles.Add("Acompanhamento");
//var Logs = (Motor.LogGrafico.Count > MovimentacaoModel.LogsManter ? Motor.LogGrafico.Skip(Math.Max(0, Motor.LogGrafico.Count - MovimentacaoModel.LogsManter)).Take(MovimentacaoModel.LogsManter).ToList() : Motor.LogGrafico).Where(log => log.Modulo_ID == Modulo.Modulo_ID).ToList();
chart.Series.Clear();
List<string> Momentos = Logs.Select(x => x.Momento.ToString("mm:ss:fff")).ToList();
var serieVelocidade = new Series("Velocidade: " + (Log != null ? Log.Velocidade : 0));
serieVelocidade.Points.DataBindXY(Momentos, Logs.Select(x => x.Velocidade).ToList());
serieVelocidade.ChartType = SeriesChartType.Line;
chart.Series.Add(serieVelocidade);
Minimo = !Logs.Any() ? 0 : Logs.Min(x => x.Velocidade) < Minimo ? Logs.Min(x => x.Velocidade) : Minimo;
Maximo = !Logs.Any() ? 0 : Logs.Min(x => x.Velocidade) > Maximo ? Logs.Min(x => x.Velocidade) : Maximo;
var serieRPMsp = new Series("RPM SP: " + (Log != null ? Log.RPM_SP : 0));
serieRPMsp.Points.DataBindXY(Momentos, Logs.Select(x => x.RPM_SP).ToList());
serieRPMsp.ChartType = SeriesChartType.Spline;
chart.Series.Add(serieRPMsp);
Minimo = !Logs.Any() ? 0 : Logs.Min(x => x.RPM_SP) < Minimo ? Logs.Min(x => x.RPM_SP) : Minimo;
Maximo = !Logs.Any() ? 0 : Logs.Max(x => x.RPM_SP) > Maximo ? Logs.Max(x => x.RPM_SP) : Maximo;
var serieRPM = new Series("RPM Roda: " + (Log != null ? Log.RPM_Roda : 0));
serieRPM.Points.DataBindXY(Momentos, Logs.Select(x => x.RPM_Roda).ToList());
serieRPM.ChartType = SeriesChartType.Spline;
chart.Series.Add(serieRPM);
Minimo = !Logs.Any() ? 0 : Logs.Min(x => x.RPM_Roda) < Minimo ? Logs.Min(x => x.RPM_Roda) : Minimo;
Maximo = !Logs.Any() ? 0 : Logs.Max(x => x.RPM_Roda) > Maximo ? Logs.Max(x => x.RPM_Roda) : Maximo;
var serieMotor = new Series("RPM Motor: " + (Log != null ? Log.RPM_Motor : 0));
serieMotor.Points.DataBindXY(Momentos, Logs.Select(x => x.RPM_Motor).ToList());
serieMotor.ChartType = SeriesChartType.Spline;
chart.Series.Add(serieMotor);
Minimo = !Logs.Any() ? 0 : Logs.Min(x => x.RPM_Motor) < Minimo ? Logs.Min(x => x.RPM_Motor) : Minimo;
Maximo = !Logs.Any() ? 0 : Logs.Max(x => x.RPM_Motor) > Maximo ? Logs.Max(x => x.RPM_Motor) : Maximo;
var serieTemperatura = new Series("Temperatura: " + (Log != null ? Log.Temperatura : 0));
serieTemperatura.Points.DataBindXY(Momentos, Logs.Select(x => x.Temperatura).ToList());
serieTemperatura.ChartType = SeriesChartType.Line;
chart.Series.Add(serieTemperatura);
Minimo = !Logs.Any() ? 0 : Logs.Min(x => x.Temperatura) < Minimo ? Logs.Min(x => x.Temperatura) : Minimo;
Maximo = !Logs.Any() ? 0 : Logs.Max(x => x.Temperatura) > Maximo ? Logs.Max(x => x.Temperatura) : Maximo;
foreach (var legend in chart.Legends)
{
legend.Docking = Docking.Bottom;
}
if (chart.ChartAreas.Any())
{
chart.ChartAreas[0].AxisY.Minimum = Minimo - 5;
chart.ChartAreas[0].AxisY.Maximum = Maximo + 5;
}
}
catch (Exception ex)
{
Console.WriteLine("Erro ao atualizar gráficos da operação: " + ex.Message);
}
return true;
});
atualizandoGrafico = false;
}
public void ExecutaComandoDaBase(OperacaoControleBaseModel controleBase)
{
Emergencia = controleBase.Emergencia;
if (Emergencia)
{
return;
}
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
// Salvar estado anterior
double oldPercentualVelocidade = _Controle.PercentualVelocidadeSP;
double oldAngulo = _Controle.Angulo;
double oldVelocidadeMP = _Controle.VelocidadeMP;
TipoMovimentoDirecional oldTipoMovimento = _Controle.TipoMovimento;
// Atualizar estado atual com os valores do controleBase
_Controle.PercentualVelocidadeSP = controleBase.PercentualVelocidadeSP;
_Controle.Angulo = controleBase.AnguloMP;
_Controle.VelocidadeMP = controleBase.VelocidadeMP;
_Controle.TipoMovimento = controleBase.TipoMovimento;
// Enviar comando
GeneralJoystick.EnviaComandoMotor(controleBase.Tecla, controleBase.Dispositivo, true);
// Restaurar estado anterior
_Controle.PercentualVelocidadeSP = oldPercentualVelocidade;
_Controle.Angulo = oldAngulo;
_Controle.VelocidadeMP = oldVelocidadeMP;
_Controle.TipoMovimento = oldTipoMovimento;
}
private void PararCarroOperacaoInterrompida(bool finalizar)
{
var Controle = Variaveis.OperacaoEmAndamento.Controle;
if (Variaveis.OperacaoEmAndamento.Modo == ModoOperacao.MapaGPS)
{
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(true);
}
else if (Variaveis.OperacaoEmAndamento.Modo == ModoOperacao.Manual)
{
GeneralJoystick.EnviaComandoMotor(Keys.Escape, T_Code.Mov, true);
if (!MKS057DCanService.Referenciando)
{
GeneralJoystick.EnviaComandoMotor(Keys.Escape, T_Code.Dir, true);
}
foreach (var bico in Variaveis.OperacaoEmAndamento.DispAtu.Dados.BicosPulverizadores)
{
GeneralJoystick.EnviarComandoAtuador(S_Code.sBIC, false, bico.ID, true);
}
}
if (finalizar)
{
var Bomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombaPressurizadora;
if (Bomba.Inicializado)
{
GeneralJoystick.EnviarComandoAtuador(S_Code.sBMB, false, Bomba.ID);
}
}
Controle.TiposControle.ForEach(x => x.UltimaDirecao = Direcao.Parado);
}
#endregion
#region REGISTRO DE LOGS
private int idxLog = 0;
private async Task tmrLogs_Tick()
{
if (Variaveis.OperacaoEmAndamento.Iniciado)
{
SalvarLogs(false);
}
}
public void SalvarLogs(bool Fim)
{
try
{
if (!string.IsNullOrEmpty(Variaveis.OperacaoEmAndamento.ID))
{
DateTime Agora = DateTime.Now;
OperacaoSensoriamentoLogModel logGeral = Variaveis.OperacaoEmAndamento.Sensoriamento.Clone();
logGeral.Momento = Agora;
SalvarLog("operacao", logGeral, Fim);
GPSModel logGps = GPSService.UltimaLeitura.Clone();
logGps.Momento = Agora;
SalvarLog(T_Code.Gps.ToString(), logGps, Fim);
Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.ForEach(Modulo =>
{
MovSensoriamentoLogModel logMov = new MovSensoriamentoLogModel()
{
Momento = Agora,
Modulo_ID = Modulo.Modulo_ID,
Inicializado = Modulo.MovMotor.Inicializado,
RPM_SP = Modulo.MovMotor.RPM_SP,
RPM_Motor = Modulo.MovMotor.RPM_Motor,
RPM_Roda = Modulo.MovMotor.RPM_Roda,
Corrente_Motor = Modulo.MovMotor.Corrente_Motor,
Temperatura = Modulo.MovMotor.Temperatura,
TemperaturaDriver = Modulo.MovMotor.TemperaturaDriver,
Tensao = Modulo.MovMotor.Tensao,
Sentido_SP = Modulo.MovMotor.Sentido_SP,
Sentido = Modulo.MovMotor.Sentido,
Velocidade = Modulo.MovMotor.VelocidadeInstantanea,
CodAlarme = Modulo.MovMotor.CodigoAlarme,
AlarmeSensores = Modulo.MovMotor.AlarmeSensores,
AlarmeComando = Modulo.MovMotor.AlarmeComando,
EmFreio = Modulo.MovMotor.ConfigFreio.Leitura,
Ativado = Modulo.MovMotor.LeituraLigado,
UltimoComandoRespondido = Modulo.MovMotor.Leitura?.UltimoComandoRecebido ?? DateTime.MinValue,
Corrente_Barramento = Modulo.MovMotor.Corrente_Barramento,
Potencia = Modulo.MovMotor.Potencia,
CicloTrabalho = Modulo.MovMotor.CicloTrabalho
};
SalvarLog(T_Code.Mov.ToString(), logMov, false);
DirSensoriamentoLogModel logDir = new DirSensoriamentoLogModel()
{
Momento = Agora,
Modulo_ID = Modulo.Modulo_ID,
Inicializado = Modulo.DirMotor.Inicializado,
Angulo = Modulo.DirMotor.Angulo,
Angulo_SP = Modulo.DirMotor.Angulo_SP,
Controlar = Modulo.DirMotor.Comandar,
Sentido_SP = Modulo.DirMotor.Sentido_SP,
Sentido = Modulo.DirMotor.Sentido,
SentidoReal = Modulo.DirMotor.SentidoReal,
Velocidade = (Modulo.DirMotor.Velocidade / Modulo.DirMotor.Velocidade_Max) * 100.0,
UltimoComandoRespondido = Modulo.DirMotor.Leitura?.UltimoComandoRecebido ?? DateTime.MinValue,
};
SalvarLog(T_Code.Dir.ToString(), logDir, false);
});
AtuSensoriamentoLogModel logAtu = new AtuSensoriamentoLogModel()
{
Momento = Agora,
Inicializado = Variaveis.OperacaoEmAndamento.DispAtu.Dados.Conectado,
QualidadeWifi = Variaveis.OperacaoEmAndamento.DispAtu.Dados.DadosLeitura.QualidadeWifi,
LatenciaLoop = Variaveis.OperacaoEmAndamento.DispAtu.Dados.DadosLeitura.LatenciaLoop,
MassaReservatorio = Variaveis.OperacaoEmAndamento.DispAtu.Dados.MassaReservatorio,
PercentualReservatorio = Variaveis.OperacaoEmAndamento.DispAtu.Dados.PercentualReservatorio,
VolumeReservatorio = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VolumeReservatorio,
PressaoLinha_SP = Variaveis.OperacaoEmAndamento.Controle.PressaoLinha,
PressaoLinha = Variaveis.OperacaoEmAndamento.DispAtu.Dados.PressaoLinha,
PotenciaBomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombaPressurizadora.LeituraPotencia,
BombaLigada = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombaPressurizadora.ComandoAtuar,
VazaoFluxoMLpSInstantanea = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VazaoFluxoMLpSInstantanea,
VazaoFluxoMLpSMedia = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VazaoFluxoMLpSMedia,
VolumeVazaoML = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VolumeVazaoML,
QuantidadeBicos = Variaveis.OperacaoEmAndamento.DispAtu.Dados.QuantidadeBicos,
TempoPulverizadorAtuado = Variaveis.OperacaoEmAndamento.DispAtu.Dados.TempoAtuado,
Bicos = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BicosPulverizadores.Select(Bico => new AtuBicoSensoriamentoLogModel()
{
ID = Bico.ID,
Inicializado = Bico.Inicializado,
Comandar = Bico.Comandar,
Atuado = Bico.ComandoAtuar,
MediaNivelFluxo = Bico.MediaNivelFluxo,
Posicao = Bico.Posicao,
StatusBico = Bico.LeituraStatusBico,
Atuacoes = Bico.Atuacoes,
TempoAtuado = Bico.TempoAtuado,
}).ToList(),
UltimoComandoRespondido = Variaveis.OperacaoEmAndamento.DispAtu.Dados.DadosLeitura.Momento,
};
SalvarLog(T_Code.Atu.ToString(), logAtu, false);
var senLeitura = Variaveis.OperacaoEmAndamento.DispSen.Dados.DadosLeitura;
SensoriamentoMensagemJsonModel logSen = new SensoriamentoMensagemJsonModel()
{
Momento = Agora,
Conectado = senLeitura.Conectado,
LatenciaLoop = senLeitura.LatenciaLoop,
QualidadeWifi = senLeitura.QualidadeWifi,
Mod_ID = senLeitura.Mod_ID,
Reles = new List<FirmwareRele>(senLeitura.Reles),
SensoresCorrente = new List<FirmwareSensorCorrente>(senLeitura.SensoresCorrente),
SensoresTemperaturaNTC = new List<FirmwareSensorTemperaturaNTC>(senLeitura.SensoresTemperaturaNTC),
ServoFreios = new List<FirmwareServoFreio>(senLeitura.ServoFreios),
Sinaleiros = new List<FirmwareSinaleiro>(senLeitura.Sinaleiros),
SensoresIMU = new List<FirmwareSensorIMU>(senLeitura.SensoresIMU),
UltimoComandoRespondido = senLeitura.Momento,
};
SalvarLog(T_Code.Sen.ToString(), logSen, false);
SonarCamModel logSnr = Variaveis.OperacaoEmAndamento.Sensoriamento.Sonar?.Clone();
logSnr.Momento = Agora;
SalvarLog(T_Code.Snr.ToString(), logSnr, Fim);
Task.Run(async () => await SalvarLogCameras(Agora));
string ArquivoOp = Variaveis.CaminhoOperacoes + Variaveis.OperacaoEmAndamento.ID + "/data.lgop";
if (!File.Exists(ArquivoOp))
{
var data = new OperacaoDadosModel()
{
id = Variaveis.OperacaoEmAndamento.ID,
operacao = "operacao",
gps = T_Code.Gps.ToString(),
dir = T_Code.Dir.ToString(),
mov = T_Code.Mov.ToString(),
atu = T_Code.Atu.ToString(),
sen = T_Code.Sen.ToString(),
pzm = T_Code.Pzm.ToString(),
a05 = T_Code.A05.ToString(),
snr = T_Code.Snr.ToString(),
cam_caminho = Variaveis.OperacaoEmAndamento.CameraCaminho.Nome,
cam_solo = Variaveis.OperacaoEmAndamento.CamerasSolo.Select( x=> x.Nome).ToList(),
};
File.WriteAllText(ArquivoOp, JsonConvert.SerializeObject(data));
}
Variaveis.OperacaoEmAndamento.idxLog++;
if (Variaveis.OperacaoEmAndamento.idxLog % 5 == 0)
{
LoRaService.EnviarDadosParaBase();
}
}
}
catch (Exception ex)
{
Console.WriteLine("Erro ao salvar log: " + ex.Message);
}
}
private void SalvarLog<T>(string Arquivo, T Objeto, bool Fim)
{
var Caminho = Variaveis.CaminhoOperacoes + Variaveis.OperacaoEmAndamento.ID;
if (!Directory.Exists(Caminho))
{
Directory.CreateDirectory(Caminho);
}
Caminho += "/" + Arquivo + ".json";
string jsonLog = JsonConvert.SerializeObject(Objeto, Formatting.None);
if (!File.Exists(Caminho))
{
File.WriteAllText(Caminho, "[" + jsonLog);
}
else
{
File.AppendAllText(Caminho, "," + jsonLog + (Fim ? "]" : ""));
}
}
private async Task SalvarLogCameras(DateTime Agora)
{
var cameraCaminho = Variaveis.OperacaoEmAndamento.CameraCaminho;
var Cameras = Variaveis.OperacaoEmAndamento.CamerasSolo.Select(x => new
{
tipo = typeof(CamSoloSensoriamentoLogModel),
nome = x.Nome,
browsers = new List<WebView2>() { x.browser }
})
.Union(new[] {
new {
tipo = typeof(CamCaminhoSensoriamentoLogModel),
nome = cameraCaminho.Nome,
browsers = new List<WebView2>() { cameraCaminho.browserRgb, cameraCaminho.browserHeatmap },
}
})
.ToList();
foreach (var Camera in Cameras)
{
string Caminho = Variaveis.CaminhoOperacoes + Variaveis.OperacaoEmAndamento.ID + "/" + Camera.nome;
if (!Directory.Exists(Caminho))
{
Directory.CreateDirectory(Caminho);
}
Caminho += "/" + Variaveis.OperacaoEmAndamento.idxLog + ".jpg";
Bitmap frame = null;
if (Camera.tipo == typeof(CamSoloSensoriamentoLogModel))
{
var leitura = Variaveis.OperacaoEmAndamento.CamerasSolo.First(x => x.Nome == Camera.nome).Leitura;
CamSoloSensoriamentoLogModel logCam = new CamSoloSensoriamentoLogModel()
{
Momento = Agora,
Leitura = leitura.Clone()
};
SalvarLog(Camera.nome, logCam, false);
foreach (var browser in Camera.browsers)
{
frame = await FuncoesGlobais.GetBrowserImage(browser);
FuncoesGlobais.SalvarImagemComprimida(frame, Caminho, 100L, 716, 403);
}
}
else if (Camera.tipo == typeof(CamCaminhoSensoriamentoLogModel))
{
var leitura = cameraCaminho.Leitura;
CamCaminhoSensoriamentoLogModel logCam = new CamCaminhoSensoriamentoLogModel()
{
Momento = Agora,
ClassMap = new Dictionary<string, Color>(cameraCaminho.ClassMap),
PontosExtremos = new List<System.Drawing.Point>(cameraCaminho.PontosExtremos),
Angulo = cameraCaminho.Angulo,
AnguloDireito = cameraCaminho.AnguloDireito,
AnguloEsquerdo = cameraCaminho.AnguloEsquerdo,
Leitura = leitura.Clone(),
UltimaMensagemRecebida = cameraCaminho.UltimaMensagemRecebida
};
SalvarLog(Camera.nome, logCam, false);
foreach (var browser in Camera.browsers)
{
int idx = Camera.browsers.IndexOf(browser);
frame = await FuncoesGlobais.GetBrowserImage(browser);
if (idx == 1)
{
Caminho = Caminho.Replace(".jpg", "_heat.jpg");
}
FuncoesGlobais.SalvarImagemComprimida(frame, Caminho, 30L, 716, 403);
}
//Bitmap heatBitmap = cameraCaminho.GenerateHeatmapBitmap();
}
}
}
private void SalvarLogKinect(DateTime Agora)
{
KinectModel logKnt = new KinectModel()
{
Momento = Agora,
AccW = KinectService.Leitura.AccW,
AccX = KinectService.Leitura.AccX,
AccY = KinectService.Leitura.AccY,
AccZ = KinectService.Leitura.AccZ,
AnguloElevacao = KinectService.Leitura.AnguloElevacao,
Colisao = KinectService.Leitura.Colisao,
DistanciaDaDireita = KinectService.Leitura.DistanciaDaDireita,
DistanciaDaEsquerda = KinectService.Leitura.DistanciaDaEsquerda,
Obstaculos = new List<Obstaculo>(KinectService.Leitura.Obstaculos),
Subdivisoes = new List<Subdivisao>(KinectService.Parametros.Subdivisoes),
Pitch = KinectService.Leitura.Pitch,
Roll = KinectService.Leitura.Roll,
VelX = KinectService.Leitura.VelX,
VelY = KinectService.Leitura.VelY,
VelZ = KinectService.Leitura.VelZ,
Yaw = KinectService.Leitura.Yaw,
UltimoCalculo = KinectService.Leitura.UltimoCalculo,
UltimoComandoRespondido = KinectService.Leitura.Momento,
};
SalvarLog(T_Code.Knt.ToString(), logKnt, false);
string Caminho = Variaveis.CaminhoOperacoes + Variaveis.OperacaoEmAndamento.ID + "/" + T_Code.Knt.ToString();
if (!Directory.Exists(Caminho))
{
Directory.CreateDirectory(Caminho);
}
string rgb = Caminho + "/rgb_" + Variaveis.OperacaoEmAndamento.idxLog + ".jpg";
string heat = Caminho + "/heat_" + Variaveis.OperacaoEmAndamento.idxLog + ".jpg";
lock (KinectService._lockBitmapRGB)
{
FuncoesGlobais.SalvarImagemComprimida(KinectService.bitmapRGB, rgb, 75L, 512, 512);
}
lock (KinectService._lockBitmapHeat)
{
FuncoesGlobais.SalvarImagemComprimida(KinectService.bitmapHeat, heat, 30L);
}
}
#endregion
#region FORMULARIO
public void AbrirForm()
{
if (Variaveis.OperacaoEmAndamento.OperacaoLiberada)
{
frmOperacao =
Modo == ModoOperacao.Manual ? new frmOperacaoManual() :
Modo == ModoOperacao.MapaGPS ? new frmOperacaoMapaGPS() :
new Form();
frmOperacao.Show();
}
else
{
MessageBox.Show(Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada, "Conexão de módulos pendentes", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
public string TextoFormOperacao(string ModoNome)
{
var statusAtual = Variaveis.OperacaoEmAndamento.StatusAtual;
if (statusAtual == StatusOperacao.Parametrizando)
{
return "Operação " + ModoNome + " - Parametrização";
}
else if (statusAtual == StatusOperacao.Aguardando)
{
return "Operação " + ModoNome + " - Iniciando em " + (Variaveis.OperacaoEmAndamento.TempoAguardando.AddSeconds(Variaveis.OperacaoEmAndamento.TempoIniciarOperacao) - DateTime.Now).TotalSeconds.ToString("0") + " segundo" + ((Variaveis.OperacaoEmAndamento.TempoAguardando.AddSeconds(Variaveis.OperacaoEmAndamento.TempoIniciarOperacao) - DateTime.Now).TotalSeconds < 1 ? "" : "s") + "...";
}
else if (statusAtual == StatusOperacao.Concluido)
{
return "Operação " + ModoNome + " - Concluída";
}
else if (statusAtual == StatusOperacao.EmAndamento)
{
return "Operação " + ModoNome + " - Em andamento";
}
else
{
return "Operação " + ModoNome;
}
}
#endregion
#region CODIGOS DE FALHAS
public ulong RetornaCodigoFalha()
{
ulong Cod = 0x00;
var _modsMandatorios = Variaveis.OperacaoEmAndamento.ModulosMandatorios.Where(x => x.Mandatorio).ToList();
var _parametrosMandatorios = Variaveis.OperacaoEmAndamento.ParametrosMandatorios;
var _sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
var _dispMVD = Variaveis.OperacaoEmAndamento.DispMvd;
var _dispATU = Variaveis.OperacaoEmAndamento.DispAtu;
var _dispSEN = Variaveis.OperacaoEmAndamento.DispSen;
bool _emergencia = Variaveis.OperacaoEmAndamento.Emergencia;
bool _operacaoIniciada = Variaveis.OperacaoEmAndamento.Iniciado;
bool _operacaoLiberada = Variaveis.OperacaoEmAndamento.OperacaoLiberada;
(bool _modulosConectados, List<T_Code> modsComFalha) = Variaveis.OperacaoEmAndamento.ModulosConectados;
bool _camerasSoloConectadas =
!_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.CameraSolo) ||
_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.CameraSolo && !x.Mandatorio) ||
(_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.CameraSolo && x.Mandatorio) &&
Variaveis.OperacaoEmAndamento.CamerasSolo.Count(y => y.Iniciada) == Variaveis.OperacaoEmAndamento.QuantidadeCamerasSolo);
bool _sonarConectado =
!_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Sonar) ||
_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Sonar && !x.Mandatorio) ||
(_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Sonar && x.Mandatorio) &&
(_sensoriamento?.Sonar != null && _sensoriamento.Sonar.Iniciado));
bool _mapaIniciado =
!_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Mapa) ||
_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Mapa && !x.Mandatorio) ||
(_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Mapa && x.Mandatorio) &&
Variaveis.OperacaoEmAndamento.Mapa.mapaService.Carregado);
bool _joystickConectado =
!_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Joystick) ||
_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Joystick && !x.Mandatorio) ||
(_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Joystick && x.Mandatorio) &&
GeneralJoystick.JoystickConectado != null);
(bool _atuOperante, List<string> atuModsFalha) = _dispATU == null ? (false, new List<string>()) : _dispATU.Dados.StatusModulosATU();
(bool _senOperante, List<string> senModsFalha) = _dispSEN == null ? (false, new List<string>()) : _dispSEN.Dados.StatusModulosSEN();
(bool _dirOperante, List<string> dirModsFalha) = _dispMVD == null ? (false, new List<string>()) : _dispMVD.Dados.StatusModulosDIR(Variaveis.OperacaoEmAndamento.Controle.TipoMovimento);
(bool _movEsqOperante, List<string> movEsqModsFalha) = _dispMVD == null ? (false, new List<string>()) : _dispMVD.Dados.StatusModulosMOV(Direcao.Esquerda);
(bool _movDirOperante, List<string> movDirModsFalha) = _dispMVD == null ? (false, new List<string>()) : _dispMVD.Dados.StatusModulosMOV(Direcao.Direita);
bool _nivelBateriaEstavel =
!_modsMandatorios.Any(x => x.Dispositivo == T_Code.Pzm) ||
(_modsMandatorios.Any(x => x.Dispositivo == T_Code.Pzm) &&
!modsComFalha.Any(x => x == T_Code.Pzm) &&
(_sensoriamento?.Bateria?.PorcentagemBateria ?? 0) > VariaveisEquipamento.PercentualTensaoBateriaMin);
var _sensorMassa = _dispATU == null ? null : _dispATU.Dados.Sensores.FirstOrDefault(x => x.Componente == S_Code.sMAS);
bool _nivelReservatorioEstavel =
!_modsMandatorios.Any(x => x.Dispositivo == T_Code.Atu) ||
(_modsMandatorios.Any(x => x.Dispositivo == T_Code.Atu) &&
_sensorMassa != null &&
!modsComFalha.Any(x => x == T_Code.Atu) &&
!atuModsFalha.Contains(_sensorMassa.ID) &&
_dispATU.Dados.PercentualReservatorio > VariaveisEquipamento.PercentualReservatorioMin);
var _sensorPressao = _dispATU == null ? null : _dispATU.Dados.Sensores.FirstOrDefault(x => x.Componente == S_Code.sPRS);
bool _pressaoLinhaEstavel =
!_modsMandatorios.Any(x => x.Dispositivo == T_Code.Atu) ||
(_modsMandatorios.Any(x => x.Dispositivo == T_Code.Atu) &&
_sensorPressao != null &&
!modsComFalha.Any(x => x == T_Code.Atu) &&
!atuModsFalha.Contains(_sensorPressao.ID) &&
_dispATU.Dados.PressaoLinha >= (Variaveis.OperacaoEmAndamento.Controle.PressaoLinha *
VariaveisEquipamento.PercentualToleranciaPressaoLinha) &&
_dispATU.Dados.PressaoLinha <= (Variaveis.OperacaoEmAndamento.Controle.PressaoLinha *
(1 + VariaveisEquipamento.PercentualToleranciaPressaoLinha)));
// Verificação de condições operacionais
if (_emergencia)
Cod |= 0x01; // Bit 0: Emergência ativada
if (!_operacaoIniciada)
Cod |= 0x02; // Bit 1: Operação não iniciada
if (!_operacaoLiberada)
Cod |= 0x04; // Bit 2: Operação não liberada
// Verificação de conexões dos módulos principais
if (!_modulosConectados)
Cod |= 0x08; // Bit 3: Módulos desconectados
if (!_camerasSoloConectadas)
Cod |= 0x10; // Bit 4: Câmeras de solo não conectadas
if (!_sonarConectado)
Cod |= 0x20; // Bit 5: Sonar não conectado
if (!_mapaIniciado)
Cod |= 0x40; // Bit 6: Mapa não iniciado
if (!_joystickConectado)
Cod |= 0x80; // Bit 7: Joystick não conectado
// Verificação de estado operacional de módulos principais
if (!_atuOperante)
Cod |= 0x100; // Bit 8: Atuador inoperante
if (!_senOperante)
Cod |= 0x200; // Bit 9: Sensoriamento inoperante
if (!_dirOperante)
Cod |= 0x400; // Bit 10: Direcional inoperante
if (!_movEsqOperante)
Cod |= 0x800; // Bit 11: Movimentação Esquerda inoperante
if (!_movDirOperante)
Cod |= 0x1000; // Bit 12: Movimentação Direita inoperante
// Verificação de falhas específicas em `modsComFalha`
foreach (var modFalha in modsComFalha ?? new List<T_Code>())
{
switch (modFalha)
{
case T_Code.Mov:
Cod |= 0x2000; // Bit 13: Falha no Módulo de Movimento
break;
case T_Code.Dir:
Cod |= 0x4000; // Bit 14: Falha no Módulo de Direção
break;
case T_Code.Sen:
Cod |= 0x8000; // Bit 15: Falha no Módulo de Sensores
break;
case T_Code.Atu:
Cod |= 0x10000; // Bit 16: Falha no Módulo ATU
break;
case T_Code.Gps:
Cod |= 0x20000; // Bit 17: Falha no Módulo GPS
break;
case T_Code.Pzm:
Cod |= 0x40000; // Bit 18: Falha no Módulo PZM
break;
case T_Code.Lra:
Cod |= 0x80000; // Bit 19: Falha no Módulo LRA
break;
case T_Code.Wit:
Cod |= 0x100000; // Bit 20: Falha no Módulo WIT
break;
case T_Code.Bld:
Cod |= 0x200000; // Bit 21: Falha no Módulo BLDC
break;
case T_Code.Mvd:
Cod |= 0x400000; // Bit 22: Falha no Módulo MVD
break;
case T_Code.Mbs:
Cod |= 0x800000; // Bit 23: Falha no Módulo MBS
break;
case T_Code.Mks:
Cod |= 0x1000000; // Bit 24: Falha no Módulo MKS
break;
case T_Code.Cam:
Cod |= 0x2000000; // Bit 25: Falha no Módulo de Câmera
break;
case T_Code.Snr:
Cod |= 0x4000000; // Bit 26: Falha no Módulo Sonar
break;
case T_Code.A05:
Cod |= 0x8000000; // Bit 27: Falha no Módulo A05
break;
}
}
// Verificação de `atuModsFalha`
foreach (var falha in atuModsFalha ?? new List<string>())
{
switch (falha)
{
case "B01":
Cod |= 0x10000000; // Bit 28: Falha no atuador B01
break;
case "B02":
Cod |= 0x20000000; // Bit 29: Falha no atuador B02
break;
case "B03":
Cod |= 0x40000000; // Bit 30: Falha no atuador B03
break;
case "B04":
Cod |= 0x80000000; // Bit 31: Falha no atuador B04
break;
case "BOMBA":
Cod |= 0x100000000; // Bit 32: Falha na BOMBA
break;
case "FLXLN":
Cod |= 0x200000000; // Bit 33: Falha no atuador FLXLN
break;
case "MASRS":
Cod |= 0x400000000; // Bit 34: Falha no atuador MASRS
break;
case "PRSLN":
Cod |= 0x800000000; // Bit 35: Falha no atuador PRSLN
break;
}
}
// Verificação de `senModsFalha`
foreach (var falha in senModsFalha ?? new List<string>())
{
switch (falha)
{
case "LEDMN":
Cod |= 0x1000000000; // Bit 36: Falha no LED MN
break;
case "LEDAT":
Cod |= 0x2000000000; // Bit 37: Falha no LED AT
break;
case "LEDOP":
Cod |= 0x4000000000; // Bit 38: Falha no LED OP
break;
case "TMVET":
Cod |= 0x8000000000; // Bit 39: Falha no TMV Esquerda Traseira
break;
case "TMVEF":
Cod |= 0x10000000000; // Bit 40: Falha no TMV Esquerda Frontal
break;
case "TMVDT":
Cod |= 0x20000000000; // Bit 41: Falha no TMV Direita Traseira
break;
case "TMVDF":
Cod |= 0x40000000000; // Bit 42: Falha no TMV Direita Frontal
break;
case "AB5V":
Cod |= 0x80000000000; // Bit 43: Falha no sensor AB 5V
break;
case "AB12V":
Cod |= 0x100000000000; // Bit 44: Falha no sensor AB 12V
break;
case "TBAT":
Cod |= 0x200000000000; // Bit 45: Falha na Temperatura da Bateria
break;
case "RLLRA":
Cod |= 0x400000000000; // Bit 46: Falha no sensor RLLRA
break;
case "FRO_ET":
Cod |= 0x800000000000; // Bit 47: Falha no sensor FRO Esquerda Traseira
break;
case "FRO_EF":
Cod |= 0x1000000000000; // Bit 48: Falha no sensor FRO Esquerda Frontal
break;
case "FRO_DT":
Cod |= 0x2000000000000; // Bit 49: Falha no sensor FRO Direita Traseira
break;
case "FRO_DF":
Cod |= 0x4000000000000; // Bit 50: Falha no sensor FRO Direita Frontal
break;
}
}
// Verificação de `dirModsFalha`
foreach (var falha in dirModsFalha ?? new List<string>())
{
switch (falha)
{
case "ET":
Cod |= 0x8000000000000; // Bit 51: Falha na direção Esquerda Traseira
break;
case "EF":
Cod |= 0x10000000000000; // Bit 52: Falha na direção Esquerda Frontal
break;
case "DT":
Cod |= 0x20000000000000; // Bit 53: Falha na direção Direita Traseira
break;
case "DF":
Cod |= 0x40000000000000; // Bit 54: Falha na direção Direita Frontal
break;
}
}
// Verificação de `movEsqModsFalha`
foreach (var falha in movEsqModsFalha ?? new List<string>())
{
switch (falha)
{
case "ET":
Cod |= 0x80000000000000; // Bit 55: Falha no motor Esquerda Traseira
break;
case "EF":
Cod |= 0x100000000000000; // Bit 56: Falha no motor Esquerda Frontal
break;
}
}
// Verificação de `movDirModsFalha`
foreach (var falha in movDirModsFalha ?? new List<string>())
{
switch (falha)
{
case "DT":
Cod |= 0x200000000000000; // Bit 57: Falha no motor Direita Traseira
break;
case "DF":
Cod |= 0x400000000000000; // Bit 58: Falha no motor Direita Frontal
break;
}
}
// Verificação de condições de bateria e reservatório
if (!_nivelBateriaEstavel)
Cod |= 0x800000000000000; // Bit 59: Nível da bateria abaixo do mínimo
if (!_nivelReservatorioEstavel)
Cod |= 0x1000000000000000; // Bit 60: Nível do reservatório abaixo do mínimo
if (!_pressaoLinhaEstavel)
Cod |= 0x2000000000000000; // Bit 61: Pressão da linha fora dos parâmetros
return Cod;
}
public static string DescricaoCodigoFalha(ulong codigo)
{
Dictionary<string, List<string>> erros = new Dictionary<string, List<string>>()
{
{ "Equipamento", new List<string>() },
{ "Parâmetros", new List<string>() },
{ "Módulos", new List<string>() },
{ "Atuador", new List<string>() },
{ "Direcional", new List<string>() },
{ "Movimentação", new List<string>() },
{ "Sensoriamento", new List<string>() },
{ "Operação", new List<string>() },
};
// Verificação de condições operacionais
if ((codigo & 0x01) != 0)
erros["Equipamento"].Add("Emergência ativado.");
if ((codigo & 0x02) != 0)
erros["Operação"].Add("Operação não iniciada.");
if ((codigo & 0x04) != 0)
erros["Operação"].Add("Operação não liberada.");
// Verificação de conexões dos módulos principais
if ((codigo & 0x08) != 0)
erros["Módulos"].Add("Um ou mais módulos principais desconectados.");
if ((codigo & 0x10) != 0)
erros["Parâmetros"].Add("Uma ou mais câmeras de solo não conectadas.");
if ((codigo & 0x20) != 0)
erros["Parâmetros"].Add("Sonar Frontal não conectado.");
if ((codigo & 0x40) != 0)
erros["Parâmetros"].Add("Mapa da operação não caregado.");
if ((codigo & 0x80) != 0)
erros["Parâmetros"].Add("Joystick não conectado.");
// Verificação de estado operacional de módulos principais
if ((codigo & 0x100) != 0)
erros["Módulos"].Add("Atuador inoperante.");
if ((codigo & 0x200) != 0)
erros["Módulos"].Add("Sensoriamento inoperante.");
if ((codigo & 0x400) != 0)
erros["Módulos"].Add("Direcional inoperante.");
if ((codigo & 0x800) != 0)
erros["Módulos"].Add("Movimentação Esquerdo inoperante.");
if ((codigo & 0x1000) != 0)
erros["Módulos"].Add("Movimentação Direito inoperante.");
// Verificação de falhas específicas em `modsComFalha`
if ((codigo & 0x2000) != 0)
erros["Módulos"].Add("Falha no Módulo de Movimentação.");
if ((codigo & 0x4000) != 0)
erros["Módulos"].Add("Falha no Módulo de Direcional.");
if ((codigo & 0x8000) != 0)
erros["Módulos"].Add("Falha no Módulo de Sensoriamento.");
if ((codigo & 0x10000) != 0)
erros["Módulos"].Add("Falha no Módulo de Atuador.");
if ((codigo & 0x20000) != 0)
erros["Módulos"].Add("Falha no Módulo de GPS.");
if ((codigo & 0x40000) != 0)
erros["Módulos"].Add("Falha no Módulo de Monitoramento de Bateria.");
if ((codigo & 0x80000) != 0)
erros["Módulos"].Add("Falha no Módulo de Comunicação.");
if ((codigo & 0x100000) != 0)
erros["Módulos"].Add("Falha no Módulo de Orientação.");
if ((codigo & 0x200000) != 0)
erros["Módulos"].Add("Falha no Módulo de Movimentação BLD.");
if ((codigo & 0x400000) != 0)
erros["Módulos"].Add("Falha no Módulo de Movimentação Unificada.");
if ((codigo & 0x800000) != 0)
erros["Módulos"].Add("Falha no Módulo de Modbus.");
if ((codigo & 0x1000000) != 0)
erros["Módulos"].Add("Falha no Módulo de Direcional MKS.");
if ((codigo & 0x2000000) != 0)
erros["Módulos"].Add("Falha no Módulo de Câmeras.");
if ((codigo & 0x4000000) != 0)
erros["Módulos"].Add("Falha no Módulo de Sonar Frontal.");
if ((codigo & 0x8000000) != 0)
erros["Módulos"].Add("Falha no Módulo de Ultrassom.");
// Verificação de `atuModsFalha`
if ((codigo & 0x10000000) != 0)
erros["Atuador"].Add("Falha no atuador Bico Pulverizador B01.");
if ((codigo & 0x20000000) != 0)
erros["Atuador"].Add("Falha no atuador Bico Pulverizador B02.");
if ((codigo & 0x40000000) != 0)
erros["Atuador"].Add("Falha no atuador Bico Pulverizador B03.");
if ((codigo & 0x80000000) != 0)
erros["Atuador"].Add("Falha no atuador Bico Pulverizador B04.");
if ((codigo & 0x100000000) != 0)
erros["Atuador"].Add("Falha na Bomba Pressurizadora.");
if ((codigo & 0x200000000) != 0)
erros["Atuador"].Add("Falha no sensor de Fluxo/Vazão.");
if ((codigo & 0x400000000) != 0)
erros["Atuador"].Add("Falha no sensor de Massa/Volume.");
if ((codigo & 0x800000000) != 0)
erros["Atuador"].Add("Falha no sensor de Pressão da linha.");
// Verificação de `senModsFalha`
if ((codigo & 0x1000000000) != 0)
erros["Sensoriamento"].Add("Falha no Sinaleiro Modo Manual.");
if ((codigo & 0x2000000000) != 0)
erros["Sensoriamento"].Add("Falha no Sinaleiro Modo Automático.");
if ((codigo & 0x4000000000) != 0)
erros["Sensoriamento"].Add("Falha no Sinaleiro Status da Operação.");
if ((codigo & 0x8000000000) != 0)
erros["Sensoriamento"].Add("Falha no sensor de Temperatura Motor Esquerdo Traseira.");
if ((codigo & 0x10000000000) != 0)
erros["Sensoriamento"].Add("Falha no sensor de Temperatura Motor Esquerdo Frontal.");
if ((codigo & 0x20000000000) != 0)
erros["Sensoriamento"].Add("Falha no sensor de Temperatura Motor Direito Traseira.");
if ((codigo & 0x40000000000) != 0)
erros["Sensoriamento"].Add("Falha no sensor de Temperatura Motor Direito Frontal.");
if ((codigo & 0x80000000000) != 0)
erros["Sensoriamento"].Add("Falha no sensor de Tensão e Corrente no barramento 5V.");
if ((codigo & 0x100000000000) != 0)
erros["Sensoriamento"].Add("Falha no sensor de Tensão e Corrente no barramento 12V.");
if ((codigo & 0x200000000000) != 0)
erros["Sensoriamento"].Add("Falha no sensor de Temperatura da Bateria.");
if ((codigo & 0x400000000000) != 0)
erros["Sensoriamento"].Add("Falha no Relé controlador do módulo de Comunicação.");
if ((codigo & 0x800000000000) != 0)
erros["Sensoriamento"].Add("Falha no sistema de freio Esquerdo Traseira.");
if ((codigo & 0x1000000000000) != 0)
erros["Sensoriamento"].Add("Falha no sistema de freio Esquerdo Frontal.");
if ((codigo & 0x2000000000000) != 0)
erros["Sensoriamento"].Add("Falha no sistema de freio Direito Traseira.");
if ((codigo & 0x4000000000000) != 0)
erros["Sensoriamento"].Add("Falha no sistema de freio Direito Frontal.");
// Verificação de `dirModsFalha`
if ((codigo & 0x8000000000000) != 0)
erros["Direcional"].Add("Falha no Motor Direcional Esquerdo Traseira.");
if ((codigo & 0x10000000000000) != 0)
erros["Direcional"].Add("Falha no Motor Direcional Esquerdo Frontal.");
if ((codigo & 0x20000000000000) != 0)
erros["Direcional"].Add("Falha no Motor Direcional Direito Traseira.");
if ((codigo & 0x40000000000000) != 0)
erros["Direcional"].Add("Falha no Motor Direcional Direito Frontal.");
// Verificação de `movEsqModsFalha`
if ((codigo & 0x80000000000000) != 0)
erros["Movimentação"].Add("Falha no Motor Movimentação Esquerdo Traseira.");
if ((codigo & 0x100000000000000) != 0)
erros["Movimentação"].Add("Falha no Motor Movimentação Esquerdo Frontal.");
// Verificação de `movDirModsFalha`
if ((codigo & 0x200000000000000) != 0)
erros["Movimentação"].Add("Falha no Motor Movimentação Direito Traseira.");
if ((codigo & 0x400000000000000) != 0)
erros["Movimentação"].Add("Falha no Motor Movimentação Direito Frontal.");
// Verificação de condições de bateria e reservatório
if ((codigo & 0x800000000000000) != 0)
erros["Operação"].Add("Nível da bateria abaixo do mínimo.");
if ((codigo & 0x1000000000000000) != 0)
erros["Operação"].Add("Nível do reservatório abaixo do mínimo.");
if ((codigo & 0x2000000000000000) != 0)
erros["Operação"].Add("Pressão da linha fora dos parâmetros.");
// Retorna a lista de erros como uma string única
var resultado = new StringBuilder();
foreach (var categoria in erros)
{
if (categoria.Value.Count > 0)
{
resultado.AppendLine($"{categoria.Key}:");
resultado.AppendLine(string.Join(", ", categoria.Value));
}
}
return resultado.Length > 0 ? resultado.ToString() : "Nenhuma falha detectada.";
}
public static void PopularTreeView(TreeView treeView, ulong codigoFalhas)
{
treeView.Font = new Font("Consolas", 10);
// Limpar o TreeView antes de adicionar novos nós
treeView.Nodes.Clear();
// Obtenha a descrição das falhas com base no código atual
string descricao = DescricaoCodigoFalha(codigoFalhas);
// Quebra a descrição em linhas, separando os tópicos e subitens
string[] linhas = descricao.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
TreeNode topicoAtual = null;
// Iterar sobre as linhas geradas pela descrição
foreach (string linha in linhas)
{
// Identificar se é um novo tópico (assumimos que tem dois pontos ':' no fim)
if (linha.EndsWith(":"))
{
// Criar um novo nó principal para o tópico
topicoAtual = new TreeNode(linha.TrimEnd(':'));
treeView.Nodes.Add(topicoAtual);
}
else if (topicoAtual != null && !string.IsNullOrWhiteSpace(linha))
{
// Adicionar sub-nós (falhas específicas) ao tópico atual
string[] topicos = linha.Split(new[] { ',' }, StringSplitOptions.None);
topicoAtual.Nodes.AddRange(topicos.Select(x => new TreeNode(x.Trim())).ToArray());
}
}
// Expandir todos os nós para melhor visualização
treeView.ExpandAll();
}
#endregion
}
public class OperacaoControleModel
{
public int RPM_Max { get; set; } = 100;
public int RPM_Min { get; set; } = 20;
public double Angulo_Max { get; set; } = 30;
public double Angulo_Min { get; set; } = -30;
public double VelocidadeMP { get; set; } = 50;
public double Angulo { get; set; } = 0;
public int RPM_SP
{
get
{
return Convert.ToInt32(VariaveisEquipamento.RPM_Max_Roda * (PercentualVelocidadeSP / 100.0));
}
}
public int RPM_Motor
{
get
{
return Convert.ToInt32(RPM_SP * VariaveisEquipamento.RelacaoRPM);
}
}
public double PercentualVelocidadeSP { get; set; } = 0.0;
public double PercentualVelocidadeMin
{
get
{
return FuncoesMatematicas.Map(RPM_Min, 0, VariaveisEquipamento.RPM_Max_Roda, 0, 100);
}
}
public double PercentualVelocidadeMax
{
get
{
return FuncoesMatematicas.Map(RPM_Max, 0, VariaveisEquipamento.RPM_Max_Roda, 0, 100);
}
}
public Direcao Direcao { get; set; } = Direcao.Parado;
private TipoMovimentoDirecional _tipoMovimento;
public TipoMovimentoDirecional TipoMovimento
{
get
{
return _tipoMovimento;
}
set
{
var DispMvd = Variaveis.OperacaoEmAndamento.DispMvd;
if (DispMvd != null)
{
if (value != _tipoMovimento)
{
switch (value)
{
case TipoMovimentoDirecional.RodasDianteiras:
DispMvd.Dados.Modulos.ForEach(x =>
{
x.MovMotor.Comandar = true;
x.DirMotor.Comandar = x.Modulo_ID.Contains("F");
});
break;
case TipoMovimentoDirecional.RodasTraseiras:
DispMvd.Dados.Modulos.ForEach(x =>
{
x.MovMotor.Comandar = true;
x.DirMotor.Comandar = x.Modulo_ID.Contains("T");
});
break;
default:
DispMvd.Dados.Modulos.ForEach(x =>
{
x.MovMotor.Comandar = true;
x.DirMotor.Comandar = true;
});
break;
}
}
}
_tipoMovimento = value;
}
}
public double PercentualInicioPulverizacao { get; set; } = 0.3;
public List<AtuadorBicoModel> BicosAtuados { get; set; } = new List<AtuadorBicoModel>();
public int TempoAtuacao { get; set; } = 200;
public double PressaoLinha { get; set; } = 85;
public List<OperacaoControleTipoModel> TiposControle { get; set; }
public bool PulverizadorAutomatico { get; set; } = true;
public bool SegmentacaoSemantica { get; set; } = false;
public bool SonarAtivado { get; set; } = false;
public bool SonarDesvioAutomatico { get; set; } = false;
public TiposControladorDirecional TipoControleDirecional { get; set; } = TiposControladorDirecional.PID;
public PIDModel PIDdirecional { get; set; } = new PIDModel();
public KalmanFilter FiltroVelocidade { get; set; } = new KalmanFilter();
public MPCController ControladorMPC { get; set; } = new MPCController();
public OperacaoControleModel Clone()
{
return new OperacaoControleModel()
{
Angulo = Angulo,
Angulo_Max = Angulo_Max,
Angulo_Min = Angulo_Min,
BicosAtuados = new List<AtuadorBicoModel>(BicosAtuados),
Direcao = Direcao,
PercentualInicioPulverizacao = PercentualInicioPulverizacao,
PercentualVelocidadeSP = PercentualVelocidadeSP,
PIDdirecional = PIDdirecional.Clone(),
FiltroVelocidade = FiltroVelocidade.Clone(),
ControladorMPC = ControladorMPC.Clone(),
_tipoMovimento = _tipoMovimento,
PressaoLinha = PressaoLinha,
PulverizadorAutomatico = PulverizadorAutomatico,
RPM_Max = RPM_Max,
RPM_Min = RPM_Min,
SegmentacaoSemantica = SegmentacaoSemantica,
SonarAtivado = SonarAtivado,
SonarDesvioAutomatico = SonarDesvioAutomatico,
TempoAtuacao = TempoAtuacao,
TipoControleDirecional = TipoControleDirecional,
TipoMovimento = TipoMovimento,
TiposControle = new List<OperacaoControleTipoModel>(TiposControle),
VelocidadeMP = VelocidadeMP
};
}
}
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 Direcao UltimaDirecao { get; set; } = Direcao.Parado;
}
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 bool Liberado
{
get
{
bool _liberado = true;
if (!Mandatorio || !Utilizar) return _liberado;
var _DispMvd = Variaveis.OperacaoEmAndamento.DispMvd;
switch (Dispositivo)
{
case T_Code.Mov:
{
(bool _EsqOperante, List<string> _EsqModsInoperantes) = _DispMvd?.Dados?.StatusModulosMOV(Direcao.Esquerda) ?? (true, new List<string>());
(bool _DirOperante, List<string> _DirModsInoperantes) = _DispMvd?.Dados?.StatusModulosMOV(Direcao.Direita) ?? (true, new List<string>());
_liberado = _EsqOperante && _DirOperante;
break;
}
case T_Code.Dir:
{
(bool _MksOperante, List<string> _MksModsInoperantes) = _DispMvd?.Dados?.StatusModulosDIR(Variaveis.OperacaoEmAndamento.Controle.TipoMovimento) ?? (true, new List<string>());
_liberado = _MksOperante;
break;
}
case T_Code.Atu:
{
(bool _AtuOperante, List<string> _AtuModsInoperantes) = Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.StatusModulosATU() ?? (true, new List<string>());
_liberado = _AtuOperante;
break;
}
case T_Code.Sen:
{
(bool _SenOperante, List<string> _SenModsInoperantes) = Variaveis.OperacaoEmAndamento.DispSen?.Dados?.StatusModulosSEN() ?? (true, new List<string>());
_liberado = _SenOperante;
break;
}
case T_Code.Gps:
{
_liberado = (Variaveis.OperacaoEmAndamento.Sensoriamento.Gps?.PrecisaoCm ?? 0) < GPSService.PrecisaoMinimaCm;
break;
}
}
return Conectado && _liberado;
}
}
}
public class OperacaoParametrosMandatoriosModel
{
public ParametrosOperacao Parametro { get; set; }
public bool Mandatorio { get; set; }
public bool Utilizar { get; set; }
public bool Liberado
{
get
{
bool _liberado = true;
if (!Mandatorio || !Utilizar) return _liberado;
bool opIniciada = Variaveis.OperacaoEmAndamento.Iniciado;
switch (Parametro)
{
case ParametrosOperacao.CameraSolo:
{
_liberado = Variaveis.OperacaoEmAndamento.CamerasSolo.Count(x => opIniciada ? x.Iniciada : true) >= Variaveis.OperacaoEmAndamento.QuantidadeCamerasSolo;
break;
}
case ParametrosOperacao.Sonar:
{
var sonar = Variaveis.OperacaoEmAndamento.CameraCaminho;
if (opIniciada)
{
_liberado = sonar?.Iniciada ?? false;
}
else
{
_liberado = (sonar?.camera?.cameraIndex ?? -1) > -1;
}
break;
}
case ParametrosOperacao.Mapa:
{
_liberado = Variaveis.OperacaoEmAndamento.Mapa?.RuasPercorrer?.Any() ?? false;
break;
}
case ParametrosOperacao.Joystick:
{
_liberado = GeneralJoystick.JoystickConectado != null;
break;
}
case ParametrosOperacao.LoRa:
{
_liberado = Variaveis.LoraService?.Iniciado ?? false;
break;
}
}
return _liberado;
}
}
}
public class OperacaoControleBaseModel
{
public DateTime Momento { get; set; }
public Keys Tecla { get; set; }
public T_Code Dispositivo { get; set; }
public double PercentualVelocidadeSP { get; set; }
public double AnguloMP { get; set; }
public double VelocidadeMP { get; set; }
public bool Emergencia { get; set; }
public TipoMovimentoDirecional TipoMovimento { get; set; }
}
public class OperacaoDadosModel
{
public string id { get; set; }
public string operacao { get; set; }
public string gps { get; set; }
public string dir { get; set; }
public string mov { get; set; }
public string atu { get; set; }
public string sen { get; set; }
public string pzm { get; set; }
public string snr { get; set; }
public string a05 { get; set; }
public string cam_caminho { get; set; }
public List<string> cam_solo { get; set; }
}
public class OperacaoSensoriamentoLogModel
{
public DateTime Momento { get; set; }
public ulong CodigoFalha { get; set; }
public bool OperacaoLiberada { get; set; }
public StatusOperacao StatusOperacao { get; set; } = StatusOperacao.Parado;
public DateTime DataInicio { get; set; }
public DateTime DataFim { get; set; }
public double TempoDecorridoSeg { get; set; }
public DateTime TempoDecorrido
{
get
{
return new DateTime().AddSeconds(TempoDecorridoSeg);
}
}
public OperacaoSensoriamentoLogImuModel IMU { get; set; }
public OperacaoSensoriamentoLogAtuModel Atuador { get; set; }
public OperacaoSensoriamentoLogMvdModel Movimentacao { get; set; }
public OperacaoSensoriamentoLogBateriaModel Bateria { get; set; }
public OperacaoSensoriamentoLogTrajetoriaModel Trajetoria { get; set; }
public GPSModel Gps { get; set; }
public PerformanceModel DadosPerformance { get; set; } = new PerformanceModel();
public OperacaoControleModel Controle { get; set; }
public SonarCamModel Sonar { get; set; }
public void AtualizarDados()
{
var _Trajetoria = Variaveis.OperacaoEmAndamento.Trajetoria;
var _OpMapaGPS = Variaveis.OperacaoEmAndamento.OpMapaGPS;
var _DispMvd = Variaveis.OperacaoEmAndamento.DispMvd;
var _DispAtu = Variaveis.OperacaoEmAndamento.DispAtu;
var _DispSen = Variaveis.OperacaoEmAndamento.DispSen;
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
_DispMvd?.Dados?.Modulos?.ForEach(x => x.AtualizarSensoresMotor());
Variaveis.OperacaoEmAndamento.AtualizarModulosConectados();
Variaveis.OperacaoEmAndamento.AtualizarOperacaoLiberada();
Variaveis.OperacaoEmAndamento.AtualizarStatusAtual();
Variaveis.OperacaoEmAndamento.DadosPerformance.AtualizarDadosPerformance();
// Soma total de atuações para todas as ervas de todos os bicos
int totalAtuacoes = _OpMapaGPS.Sensoriamento.AtuacoesPorBico
.Sum(dict => dict.Values.Sum());
// Evitar divisão por zero
double HerbicidaPorErva = totalAtuacoes > 0
? _DispAtu.Dados.VolumeVazaoML / totalAtuacoes
: 0.0;
var sIMU = _DispSen?.Dados?.DadosLeitura?.SensoresIMU?.FirstOrDefault();
var dadosIMU = sIMU != null ? new OperacaoSensoriamentoLogImuModel()
{
Iniciado = sIMU.Iniciado,
InclinacaoLateral = sIMU.Roll,
InclinacaoFrontal = sIMU.Pitch,
Rotacao = sIMU.Yaw,
RotacaoCorrigida = sIMU.YawFixed,
Altitude = sIMU.Altitude,
Pressao = sIMU.Pressao,
Temperatura = sIMU.Temperatura
} : new OperacaoSensoriamentoLogImuModel();
var dadosAtuador = _DispAtu != null ? new OperacaoSensoriamentoLogAtuModel()
{
HerbicidaConsumido = _DispAtu.Dados.VolumeVazaoML,
PercentualErvasTerreno = _DispAtu.Dados.PercentualErvasTerreno,
HerbicidaPorErva = HerbicidaPorErva,
ErvasNoRadar = Variaveis.OperacaoEmAndamento.CamerasSolo.Sum(x => x.ErvasNoRadar),
ErvasIdentificadas = new List<Dictionary<string, int>>(_OpMapaGPS.Sensoriamento.AtuacoesPorBico),
PercentualReservatorio = FuncoesMatematicas.Clamp(_DispAtu.Dados.PercentualReservatorio, 0, 100),
VolumeReservatorio = _DispAtu.Dados.VolumeReservatorio,
PressaoLinha = _DispAtu.Dados.PressaoLinha,
VazaoInstantanea = _DispAtu.Dados.VazaoFluxoMLpSInstantanea,
VazaoMedia = _DispAtu.Dados.VazaoFluxoMLpSMedia,
LeituraPotenciaBomba = FuncoesMatematicas.Clamp(_DispAtu.Dados.BombaPressurizadora.LeituraPotencia, 0, 100),
VolumeVazaoMl = _DispAtu.Dados.VolumeVazaoML
} : new OperacaoSensoriamentoLogAtuModel();
var dadosMovimentacao = _DispMvd != null ? new OperacaoSensoriamentoLogMvdModel()
{
VelocidadeMedia = _DispMvd.Dados.VelocidadeMedia,
RPMMedio = _DispMvd.Dados.Modulos.Where(x => x.MovMotor.Inicializado).DefaultIfEmpty()?.Average(x => x?.MovMotor?.RPM_Roda ?? 0) ?? 0,
TempoMovimentoSegs = _DispMvd.Dados.TempoEmAtividade,
Dir_Status = _DispMvd.Dados.StatusModulosDIR(_Controle.TipoMovimento),
MovEsq_Status = _DispMvd.Dados.StatusModulosMOV(Direcao.Esquerda),
MovDir_Status = _DispMvd.Dados.StatusModulosMOV(Direcao.Direita)
} : new OperacaoSensoriamentoLogMvdModel();
var S36V = _DispSen?.Dados?.DadosLeitura?.SensoresCorrente?.FirstOrDefault(x => x.ID == "AB36V");
var dadosBateria = S36V != null ? new OperacaoSensoriamentoLogBateriaModel()
{
Iniciado = S36V?.Iniciado ?? false,
_dt = S36V?._dt ?? 0,
PorcentagemBateria = FuncoesMatematicas.Clamp(_DispSen.Dados.ContadorCarga.PercentualBateria, 0, 100),
BateriaConsumida = FuncoesMatematicas.Clamp(_DispSen.Dados.ContadorCarga.PercentualConsumido, 0, 100),
TempoEstimadoRestanteMinutos = _DispSen.Dados.ContadorCarga.TempoEstimadoMinutos,
CorrenteInstantanea = (S36V?.Current ?? 0) / 1000.0,
TensaoInstantanea = S36V?.BusVoltage ?? 0,
PotenciaInstantanea = S36V?.Power ?? 0,
PotenciaAcumulada = S36V?.Energy ?? 0
} : new OperacaoSensoriamentoLogBateriaModel();
var dadosTrajetoria = new OperacaoSensoriamentoLogTrajetoriaModel()
{
StatusCarro = _Trajetoria?.StatusAtual ?? StatusCarroMapa.Parado,
DistanciaDireita = _Trajetoria?.DistanciaDireita ?? 0,
DistanciaEsquerda = _Trajetoria?.DistanciaEsquerda ?? 0,
ProgressoTrajeto = FuncoesMatematicas.Clamp(_Trajetoria?.PercentualTrajetoria ?? 0, 0, 100),
CorredorAtual = _Trajetoria?.CorredorAtual?.Clone(false) ?? new CorredorTrajetoriaModel(),
DirecaoCaminho = _Trajetoria?.DirecaoCaminho ?? DirecaoCarroRua.Parado,
AnguloCaminho = _Trajetoria?.AnguloCaminho ?? 0,
AnguloMedioCorredor = _Trajetoria?.AnguloMedioCorredor ?? 0,
DistanciaTotal = _Trajetoria?.DistanciaTotal ?? 0,
DistanciaPercorrida = _Trajetoria?.DistanciaPercorrida ?? 0,
DistanciaRestante = _Trajetoria?.DistanciaRestante ?? 0,
NaMargemDoCorredor = _Trajetoria?.NaMargemDoCorredor ?? false,
ManobrandoEntreRuas = _Trajetoria?.ManobrandoEntreRuas ?? false,
TempoEstimadoRestante = _Trajetoria?.TempoEstimadoRestante ?? "",
TempoEstimadoOperacao = _Trajetoria?.TempoEstimadoOperacao ?? "",
ProximoPonto = _Trajetoria?.ProximoPonto?.Clone() ?? new PontoTrajetoriaModel(TipoPontoRua.PosicaoRobo),
PontoMaisProximo = _Trajetoria?.PontoMaisProximo?.Clone() ?? new PontoTrajetoriaModel(TipoPontoRua.PosicaoRobo),
PontoAtual = _Trajetoria?.PontoAtual?.Clone() ?? new PontoTrajetoriaModel(TipoPontoRua.PosicaoRobo),
ErroLateralAngular = _Trajetoria?.ErroLateralAngular ?? 0,
ErroOrientacaoAngular = _Trajetoria?.ErroOrientacaoAngular ?? 0,
ErroOrientacaoAngularCombinado = _Trajetoria?.ErroOrientacaoAngularCombinado ?? 0,
ErroOrientacaoAngularCaminho = _Trajetoria?.ErroOrientacaoAngularCaminho ?? 0,
ErroOrientacaoAngularProximoPonto = _Trajetoria?.ErroOrientacaoAngularProximoPonto ?? 0
};
var dadosGps = GPSService.UltimaLeitura.Clone();
var dadosSonar = Variaveis.OperacaoEmAndamento.CameraCaminho?.Sonar?.Clone();
if (dadosSonar == null)
{
dadosSonar = new SonarCamModel();
dadosSonar.DetectarObstaculos(null);
}
var dadosControle = _Controle.Clone();
var dadosPerformance = Variaveis.OperacaoEmAndamento.DadosPerformance.Clone();
OperacaoSensoriamentoLogModel dadosAtualizados = new OperacaoSensoriamentoLogModel()
{
Momento = DateTime.Now,
CodigoFalha = Variaveis.OperacaoEmAndamento.RetornaCodigoFalha(),
OperacaoLiberada = Variaveis.OperacaoEmAndamento.OperacaoLiberada,
StatusOperacao = Variaveis.OperacaoEmAndamento.StatusAtual,
DataInicio = Variaveis.OperacaoEmAndamento.DataInicio,
DataFim = Variaveis.OperacaoEmAndamento.DataFim,
TempoDecorridoSeg = Variaveis.OperacaoEmAndamento.TempoDecorridoSegs,
IMU = dadosIMU,
Atuador = dadosAtuador,
Movimentacao = dadosMovimentacao,
Bateria = dadosBateria,
Trajetoria = dadosTrajetoria,
Gps = dadosGps,
Sonar = dadosSonar,
Controle = dadosControle,
DadosPerformance = dadosPerformance
};
Variaveis.OperacaoEmAndamento.Sensoriamento = dadosAtualizados;
}
public OperacaoSensoriamentoLogModel Clone(bool comSonar = false)
{
return new OperacaoSensoriamentoLogModel()
{
Momento = Momento,
CodigoFalha = CodigoFalha,
OperacaoLiberada = OperacaoLiberada,
StatusOperacao = StatusOperacao,
DataInicio = DataInicio,
DataFim = DataFim,
TempoDecorridoSeg = TempoDecorridoSeg,
Atuador = Atuador.Clone(),
Movimentacao = Movimentacao.Clone(),
Bateria = Bateria.Clone(),
Trajetoria = Trajetoria.Clone(),
Gps = Gps.Clone(),
Sonar = comSonar ? Sonar.Clone() : null,
Controle = Controle.Clone(),
DadosPerformance = DadosPerformance.Clone(),
};
}
}
public class OperacaoSensoriamentoLogImuModel
{
public bool Iniciado { get; set; }
public double InclinacaoLateral { get; set; }
public double InclinacaoFrontal { get; set; }
public double Rotacao { get; set; }
public double RotacaoCorrigida { get; set; }
public double Temperatura { get; set; }
public double Pressao { get; set; }
public double Altitude { get; set; }
}
public class OperacaoSensoriamentoLogAtuModel
{
public double HerbicidaConsumido { get; set;}
public double PercentualErvasTerreno { get; set; }
public double HerbicidaPorErva { get; set; }
public int ErvasNoRadar { get; set; }
public double PercentualReservatorio { get; set; }
public double VolumeReservatorio { get; set; }
public double PressaoLinha { get; set; }
public double VazaoInstantanea { get; set; }
public double VazaoMedia { get; set; }
public double LeituraPotenciaBomba { get; set; }
public double VolumeVazaoMl { get; set; }
public List<Dictionary<string, int>> ErvasIdentificadas { get; set; }
public int QtdErvasIdentificadas
{
get
{
int atuacoes = 0;
foreach (var bico in ErvasIdentificadas)
{
atuacoes += bico.Sum(x => x.Value);
}
return atuacoes;
}
}
public OperacaoSensoriamentoLogAtuModel Clone()
{
return new OperacaoSensoriamentoLogAtuModel()
{
ErvasIdentificadas = new List<Dictionary<string, int>>(ErvasIdentificadas),
ErvasNoRadar = ErvasNoRadar,
HerbicidaConsumido = HerbicidaConsumido,
HerbicidaPorErva = HerbicidaPorErva,
PercentualErvasTerreno = PercentualErvasTerreno,
PercentualReservatorio = PercentualReservatorio,
VolumeReservatorio = VolumeReservatorio,
PressaoLinha = PressaoLinha,
VazaoInstantanea = VazaoInstantanea,
VazaoMedia = VazaoMedia,
LeituraPotenciaBomba = LeituraPotenciaBomba,
VolumeVazaoMl = VolumeVazaoMl
};
}
}
public class OperacaoSensoriamentoLogMvdModel
{
public double VelocidadeMedia { get; set; }
public double RPMMedio { get; set; }
public double TempoMovimentoSegs { get; set; }
public DateTime TempoMovimento
{
get
{
return new DateTime().AddSeconds(TempoMovimentoSegs);
}
}
public (bool, List<string>) Dir_Status { get; set; }
public (bool, List<string>) MovEsq_Status { get; set; }
public (bool, List<string>) MovDir_Status { get; set; }
public OperacaoSensoriamentoLogMvdModel Clone()
{
return new OperacaoSensoriamentoLogMvdModel()
{
VelocidadeMedia = VelocidadeMedia,
RPMMedio = RPMMedio,
TempoMovimentoSegs = TempoMovimentoSegs,
Dir_Status = Dir_Status,
MovEsq_Status = MovEsq_Status,
MovDir_Status = MovDir_Status,
};
}
}
public class OperacaoSensoriamentoLogBateriaModel
{
public bool Iniciado { get; set; }
public double _dt { get; set; }
public double PorcentagemBateria { get; set; }
public double BateriaConsumida { get; set; }
public double CorrenteInstantanea { get; set; }
public double TensaoInstantanea { get; set; }
public double PotenciaInstantanea { get; set; }
public double PotenciaAcumulada { get; set; }
public double TempoEstimadoRestanteMinutos { get; set; }
public OperacaoSensoriamentoLogBateriaModel Clone()
{
return new OperacaoSensoriamentoLogBateriaModel()
{
_dt = _dt,
BateriaConsumida = BateriaConsumida,
PorcentagemBateria = PorcentagemBateria,
CorrenteInstantanea = CorrenteInstantanea,
TensaoInstantanea = TensaoInstantanea,
PotenciaInstantanea = PotenciaInstantanea,
PotenciaAcumulada = PotenciaAcumulada,
TempoEstimadoRestanteMinutos = TempoEstimadoRestanteMinutos
};
}
}
public class OperacaoSensoriamentoLogTrajetoriaModel
{
public StatusCarroMapa StatusCarro { get; set; }
public double ProgressoTrajeto { get; set; }
public double AnguloCaminho { get; set; }
public double AnguloMedioCorredor { get; set; }
public DirecaoCarroRua DirecaoCaminho { get; set; }
public CorredorTrajetoriaModel CorredorAtual { get; set; }
public double DistanciaEsquerda { get; set; }
public double DistanciaDireita { get; set; }
public double DistanciaTotal { get; set; }
public double DistanciaPercorrida { get; set; }
public double DistanciaRestante { get; set; }
public bool NaMargemDoCorredor { get; set; }
public bool ManobrandoEntreRuas { get; set; }
public string TempoEstimadoRestante { get; set; }
public string TempoEstimadoOperacao { get; set; }
public PontoTrajetoriaModel ProximoPonto { get; set; }
public PontoTrajetoriaModel PontoAtual { get; set; }
public PontoTrajetoriaModel PontoMaisProximo { get; set; }
public double ErroOrientacaoAngular { get; set; }
public double ErroOrientacaoAngularCombinado { get; set; }
public double ErroOrientacaoAngularCaminho { get; set; }
public double ErroOrientacaoAngularProximoPonto { get; set; }
public double ErroLateralAngular { get; set; }
public OperacaoSensoriamentoLogTrajetoriaModel Clone()
{
return new OperacaoSensoriamentoLogTrajetoriaModel()
{
StatusCarro = StatusCarro,
AnguloCaminho = AnguloCaminho,
AnguloMedioCorredor = AnguloMedioCorredor,
DirecaoCaminho = DirecaoCaminho,
DistanciaDireita = DistanciaDireita,
DistanciaEsquerda = DistanciaEsquerda,
CorredorAtual = CorredorAtual.Clone(false),
ProgressoTrajeto = ProgressoTrajeto,
DistanciaTotal = DistanciaTotal,
DistanciaPercorrida = DistanciaPercorrida,
DistanciaRestante = DistanciaRestante,
NaMargemDoCorredor = NaMargemDoCorredor,
ManobrandoEntreRuas = ManobrandoEntreRuas,
TempoEstimadoRestante = TempoEstimadoRestante,
TempoEstimadoOperacao = TempoEstimadoOperacao,
ErroLateralAngular = ErroLateralAngular,
ErroOrientacaoAngularCombinado = ErroOrientacaoAngularCombinado,
ErroOrientacaoAngular = ErroOrientacaoAngular,
ErroOrientacaoAngularCaminho = ErroOrientacaoAngularCaminho,
ErroOrientacaoAngularProximoPonto = ErroOrientacaoAngularProximoPonto,
ProximoPonto = ProximoPonto.Clone(),
PontoAtual = PontoAtual.Clone(),
PontoMaisProximo = PontoMaisProximo.Clone(),
};
}
}
public class PzmSensoriamentoLogModel
{
public DateTime Momento { get; set; }
public DateTime DataHora { get; set; }
public bool Inicializado { get; set; }
public double Tensao { get; set; }
public double Corrente { get; set; }
public double Potencia { get; set; }
public double Energia { get; set; }
public bool AlarmeTensaoMax { get; set; }
public bool AlarmeTensaoMin { get; set; }
public double CargaAtualAmp { get; set; }
public double CargaConsumidaAmp { get; set; }
public double CargaConsumidaPercentual { get; set; }
public DateTime UltimoComandoRespondido { get; set; }
}
public class DirSensoriamentoLogModel
{
public DateTime Momento { get; set; }
public string Modulo_ID { get; set; }
public bool Inicializado { get; set; }
public bool Controlar { get; set; }
public double Angulo_SP { get; set; }
public double Angulo { get; set; }
public Sentido Sentido_SP { get; set; }
public Sentido Sentido { get; set; }
public Sentido SentidoReal { get; set; }
public double Velocidade { get; set; }
public DateTime UltimoComandoRespondido { get; set; }
}
public class MovSensoriamentoLogModel
{
public DateTime Momento { get; set; }
public string Modulo_ID { get; set; }
public bool Inicializado { get; set; }
public double RPM_SP { get; set; }
public double RPM_Motor { get; set; }
public double RPM_Roda { get; set; }
public double Velocidade { get; set; }
public Sentido Sentido_SP { get; set; }
public Sentido Sentido { get; set; }
public double Temperatura { get; set; }
public double TemperaturaDriver { get; set; }
public double Corrente_Motor { get; set; }
public double Corrente_Barramento { get; set; }
public double Tensao { get; set; }
public double Potencia { get; set; }
public double CicloTrabalho { get; set; }
public OidCodigoErro CodAlarme { get; set; }
public bool AlarmeSensores { get; set; }
public bool AlarmeComando { get; set; }
public bool EmFreio { get; set; }
public bool Ativado { get; set; }
public DateTime UltimoComandoRespondido { get; set; }
}
public class AtuSensoriamentoLogModel
{
public DateTime Momento { get; set; }
public bool Inicializado { get; set; }
public int QualidadeWifi { get; set; }
public int LatenciaLoop { get; set; }
public double MassaReservatorio { get; set; }
public double PressaoLinha_SP { get; set; }
public double PressaoLinha { get; set; }
public double VolumeReservatorio { get; set; }
public double PercentualReservatorio { get; set; }
public double PotenciaBomba { get; set; }
public bool BombaLigada { get; set; }
public double VazaoFluxoMLpSInstantanea { get; set; }
public double VazaoFluxoMLpSMedia { get; set; }
public double VolumeVazaoML { get; set; }
public int QuantidadeBicos { get; set; }
public double TempoPulverizadorAtuado { get; set; }
public List<AtuBicoSensoriamentoLogModel> Bicos { get; set; }
public DateTime UltimoComandoRespondido { get; set; }
}
public class AtuBicoSensoriamentoLogModel
{
public string ID { get; set; }
public int Posicao { get; set; }
public bool Atuado { get; set; }
public bool Comandar { get; set; }
public bool Inicializado { get; set; }
public bool StatusBico { get; set; }
public double MediaNivelFluxo { get; set; }
public int Atuacoes { get; set; }
public double TempoAtuado { get; set; }
}
public class CamSoloSensoriamentoLogModel
{
public DateTime Momento { get; set; }
public CameraCoordenadasFrameModel Leitura { get; set; }
}
public class CamCaminhoSensoriamentoLogModel
{
public DateTime Momento { get; set; }
public Dictionary<string, Color> ClassMap { get; set; }
public List<System.Drawing.Point> PontosExtremos { get; set; }
public double Angulo { get; set; }
public double AnguloEsquerdo { get; set; }
public double AnguloDireito { get; set; }
public CameraDeepLabV3PlusModel Leitura { get; set; }
public bool Inicializado
{
get
{
return Leitura?.device_data?.Is_Pipeline_Running ?? false;
}
}
public DateTime UltimaMensagemRecebida { get; set; }
}
}