ajustado novo contrato de dados para logs e parametros runtime, ainda em teste

This commit is contained in:
Diego Freitas 2026-06-26 17:00:49 -03:00
parent f3cca4c54f
commit ab0d5966b2
75 changed files with 4507 additions and 5105 deletions

View File

@ -15,7 +15,7 @@ namespace AgroBase.Forms
{
public partial class frmAtuCamera : Form
{
private CameraSoloModel cameraSolo = new CameraSoloModel();
//private CameraSoloModel cameraSolo = new CameraSoloModel();
private AsyncTaskTimerModel tmrLeitura;
public frmAtuCamera()
@ -25,21 +25,21 @@ namespace AgroBase.Forms
private void frmCamera_Load(object sender, EventArgs e)
{
cameraSolo = new CameraSoloModel()
{
Nome = "T",
Posicao = CameraWorkerService.CamerasSolo.Count(),
ArquivoLeitura = "ervas_T.json",
browser = null,
camera = new CameraService(),
DeviceID = "",
combo = cmbCameras,
MaxLeituras = 10,
VideoPorta = "", //(VariaveisPortas.CameraSolo + Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo.Count()).ToString(),
VideoUrl = "green_objects_T",
MqttTopico = "green_objects_T",
panel = pnlCamera,
};
//cameraSolo = new CameraSoloModel()
//{
// Nome = "T",
// Posicao = CameraWorkerService.CamerasSolo.Count(),
// ArquivoLeitura = "ervas_T.json",
// browser = null,
// camera = new CameraService(),
// DeviceID = "",
// combo = cmbCameras,
// MaxLeituras = 10,
// VideoPorta = "", //(VariaveisPortas.CameraSolo + Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo.Count()).ToString(),
// VideoUrl = "green_objects_T",
// MqttTopico = "green_objects_T",
// panel = pnlCamera,
//};
AtualizaListaCameras();
}
@ -47,8 +47,8 @@ namespace AgroBase.Forms
{
try
{
cameraSolo.camera.pythonProcess?.Kill();
Variaveis.MqttServiceLocal.UnsubscribeAsync(cameraSolo.camera._mqttTopico).ConfigureAwait(false);
//cameraSolo.camera.pythonProcess?.Kill();
//Variaveis.MqttServiceLocal.UnsubscribeAsync(cameraSolo.camera._mqttTopico).ConfigureAwait(false);
}
catch (Exception ex)
{
@ -77,7 +77,7 @@ namespace AgroBase.Forms
else
{
btnSalvar.Text = "Editar";
cameraSolo.camera.cameraIndex = cmbCameras.SelectedIndex;
//cameraSolo.camera.cameraIndex = cmbCameras.SelectedIndex;
}
btnIniciar.Enabled = btnSalvar.Text == "Editar" && cmbCameras.SelectedIndex > 0;
cmbCameras.Enabled = btnSalvar.Text == "Salvar";
@ -88,94 +88,94 @@ namespace AgroBase.Forms
VersaoArquivoModel ArquivoVersao = VersionamentoService.ArquivoModeloWeedDetector;
string CamNome = "Cam_Solo_0";
CameraSoloModel CameraSolo = new CameraSoloModel()
{
ID = "S0",
Nome = CamNome,
Posicao = 0,
ArquivoLeitura = "ervas_" + CamNome + ".json",
browser = null,
camera = new CameraService(),
DeviceID = "123",
combo = new ComboBox(),
MaxLeituras = 1,
VideoPorta = "", // (VariaveisPortas.CameraSolo + 0).ToString(),
VideoUrl = "green_objects_" + CamNome,
MqttTopico = "green_objects_" + CamNome,
};
CameraSolo.panel = pnlCamera;
CameraSolo.camera.cameraIndex = 1;
IniciarCameraSolo(CameraSolo);
//CameraSoloModel CameraSolo = new CameraSoloModel()
//{
// ID = "S0",
// Nome = CamNome,
// Posicao = 0,
// ArquivoLeitura = "ervas_" + CamNome + ".json",
// browser = null,
// camera = new CameraService(),
// DeviceID = "123",
// combo = new ComboBox(),
// MaxLeituras = 1,
// VideoPorta = "", // (VariaveisPortas.CameraSolo + 0).ToString(),
// VideoUrl = "green_objects_" + CamNome,
// MqttTopico = "green_objects_" + CamNome,
//};
//CameraSolo.panel = pnlCamera;
//CameraSolo.camera.cameraIndex = 1;
//IniciarCameraSolo(CameraSolo);
tmrLeitura = new AsyncTaskTimerModel("tmrLeitura", tmrLeitura_Tick, 200);
tmrLeitura.Start();
}
public void IniciarCameraSolo(CameraSoloModel CameraSolo)
{
CameraSolo.DesligarCamera();
if (CameraSolo.camera.cameraIndex > 0)
{
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) =>
{
if (Mensagem.Momento > CameraSolo.camera.IniciadoEm && Mensagem.Mensagem == "OK")
{
CameraSolo.camera.ProntoEm = Mensagem.Momento;
if (CameraSolo.browser == 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 IniciarCameraSolo(CameraSoloModel CameraSolo)
//{
// CameraSolo.DesligarCamera();
//
// if (CameraSolo.camera.cameraIndex > 0)
// {
// 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) =>
// {
// if (Mensagem.Momento > CameraSolo.camera.IniciadoEm && Mensagem.Mensagem == "OK")
// {
// CameraSolo.camera.ProntoEm = Mensagem.Momento;
//
// if (CameraSolo.browser == 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!");
// }
//}
private void AtualizaListaCameras()
{
cameraSolo.camera.cameraIndex = cmbCameras.SelectedIndex > 0 ? cmbCameras.SelectedIndex : 0;
//cameraSolo.camera.cameraIndex = cmbCameras.SelectedIndex > 0 ? cmbCameras.SelectedIndex : 0;
cmbCameras.Items.Clear();
cmbCameras.Items.AddRange(CameraService.ObterListaCameras().Keys.ToArray());
cmbCameras.Items.AddRange(CameraWorkerService.ListaCameras.Select(x => x.mx_id).ToArray());
if (cmbCameras.Items.Count == 1)
{
cameraSolo.camera.cameraIndex = 0;
//cameraSolo.camera.cameraIndex = 0;
}
cmbCameras.SelectedIndex = cameraSolo.camera.cameraIndex;
//cmbCameras.SelectedIndex = cameraSolo.camera.cameraIndex;
}
private void ListarObjetosDetectados()
@ -184,27 +184,27 @@ namespace AgroBase.Forms
int i = 0;
//var coordenadas = cameraService.AferirDadosCamera<CameraCoordenadasModel>();
var MqttTopico = Variaveis.MqttServiceLocal.Topicos.FirstOrDefault(x => x.Topico == cameraSolo.MqttTopico);
if (MqttTopico == null)
{
return;
}
//var MqttTopico = Variaveis.MqttServiceLocal.Topicos.FirstOrDefault(x => x.Topico == cameraSolo.MqttTopico);
//
//if (MqttTopico == null)
//{
// return;
//}
CameraCoordenadasFrameModel leitura = null;
List<MqttTopicosMensagensModel> msgs = new List<MqttTopicosMensagensModel>(MqttTopico.Mensagens);
var Mensagem = msgs.LastOrDefault(x => x.Momento > cameraSolo.camera.IniciadoEm);
if (msgs.Count() > 1 && Mensagem != null)
{
try
{
leitura = JsonConvert.DeserializeObject<CameraCoordenadasFrameModel>(Mensagem.Mensagem);
}
catch
{
}
}
//List<MqttTopicosMensagensModel> msgs = new List<MqttTopicosMensagensModel>(MqttTopico.Mensagens);
//var Mensagem = msgs.LastOrDefault(x => x.Momento > cameraSolo.camera.IniciadoEm);
//if (msgs.Count() > 1 && Mensagem != null)
//{
// try
// {
// leitura = JsonConvert.DeserializeObject<CameraCoordenadasFrameModel>(Mensagem.Mensagem);
// }
// catch
// {
//
// }
//}
if (leitura != null)
{

View File

@ -246,10 +246,10 @@ namespace AgroBase.Forms.IHM
private async void cmbComunicacao_SelectedIndexChanged(object sender, EventArgs e)
{
if (Variaveis.LoraService.Iniciado)
{
await AtualizarParametrosLoRa();
}
//if (Variaveis.LoraService.Iniciado)
//{
// await AtualizarParametrosLoRa();
//}
}
#endregion

View File

@ -236,7 +236,7 @@ namespace AgroBase.Forms.IHM
PreencherDadosDiagnosticoSinaleiros(Diagnosticos.FirstOrDefault(x => x.Modulo == T_Code.Sen));
PreencherDadosDiagnosticoReles(Diagnosticos.FirstOrDefault(x => x.Modulo == T_Code.Mks));
PreencherDadosTabelaResultado(dgResultados);
OperacaoModel.PopularTreeView(tvwFalhas, HealthWorkerService.ModulosSaude);
OperacaoModel.PopularTreeView(tvwFalhas, Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorSaude.ModulosSaude);
}
private async Task<bool> IniciarDiagnostico(int idx)
@ -245,7 +245,7 @@ namespace AgroBase.Forms.IHM
if (idx == 9)
{
OperacaoModel.PopularTreeView(tvwFalhas, HealthWorkerService.ModulosSaude);
OperacaoModel.PopularTreeView(tvwFalhas, Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorSaude.ModulosSaude);
return true;
}
@ -1388,24 +1388,24 @@ namespace AgroBase.Forms.IHM
bool Conectado = SerialService.DispositivosMapeados.Any(x => x.Dispositivo == T_Code.Lra);
idx = PreencheDadosLinha(grid, Testes, idx, Conectado ? 1 : 0);
bool Inicializado = Variaveis.LoraService.Iniciado;
bool Inicializado = false; // Variaveis.LoraService.Iniciado;
idx = PreencheDadosLinha(grid, Testes, idx, Inicializado ? 1 : 0);
bool sucesso = false;
if (Inicializado)
{
(bool _sucesso, LoRaParametrosModel parametros) = await Variaveis.LoraService.RequisitarParametrosModulo();
sucesso = _sucesso;
//(bool _sucesso, LoRaParametrosModel parametros) = await Variaveis.LoraService.RequisitarParametrosModulo();
//sucesso = _sucesso;
}
bool Parametrizado = Inicializado && sucesso && Variaveis.LoraService.ParametrosGet != null;
bool Parametrizado = false; // Inicializado && sucesso && Variaveis.LoraService.ParametrosGet != null;
idx = PreencheDadosLinha(grid, Testes, idx, Parametrizado ? 1 : 0);
bool MensagemEnviada = false;
if (Inicializado)
{
//int msgEnviadasAnterior = LoRaBaseService.MensagensEnviadas;
Variaveis.LoraService.EnviarDadosParaBase();
//Variaveis.LoraService.EnviarDadosParaBase();
await Task.Delay(2000);
MensagemEnviada = true; //LoRaBaseService.MensagensEnviadas > msgEnviadasAnterior;
}
@ -1506,7 +1506,7 @@ namespace AgroBase.Forms.IHM
var grid = Diagnostico.grid;
var Testes = Diagnostico.Testes;
List<string> CamerasIDs = CameraService.ObterListaCameras().Values.ToList();
List<string> CamerasIDs = CameraWorkerService.ListaCameras.Select(x => x.mx_id).ToList();
string IDcamRua = CameraWorkerService.CameraCaminho.Id;//.Replace("\\", "#").ToLower();

View File

@ -61,7 +61,8 @@ namespace AgroBase.Forms.IHM
FuncoesGlobais.DefinirEventosPicBtn(picFechar, "", async () =>
{
if (Variaveis.OperacaoEmAndamento.Iniciado && !Variaveis.OperacaoEmAndamento.Finalizando)
var op = Variaveis.OperacaoEmAndamento;
if (op.Sensoriamento.Operacao.OperacaoIniciada && !op.Sensoriamento.Operacao.Finalizando)
{
var res = CustomDialog.ShowDialog(
"Interromper Operação",
@ -75,8 +76,8 @@ namespace AgroBase.Forms.IHM
);
if (res == DialogResult.Yes)
{
Task.Run(async () => await Variaveis.OperacaoEmAndamento.FinalizarOperacao());
if (Variaveis.OperacaoEmAndamento.Parametros?.Modo == Enums.ModoOperacao.Manual)
Task.Run(async () => await op.FinalizarOperacao());
if (op.Parametros?.Modo == ModoOperacao.Manual)
{
this.Close();
}
@ -84,7 +85,7 @@ namespace AgroBase.Forms.IHM
}
else
{
if (Variaveis.OperacaoEmAndamento.StatusAtual == Enums.StatusOperacao.Parametrizando)
if (op.Sensoriamento.Operacao.StatusOperacaoAtual == StatusOperacao.Parametrizando)
{
this.Hide();
}
@ -98,18 +99,19 @@ namespace AgroBase.Forms.IHM
private void frmDialogoMapa_Load(object sender, EventArgs e)
{
var op = Variaveis.OperacaoEmAndamento;
tmrLeitura?.Dispose();
tmrLeitura = new AsyncTaskTimerModel("tmrLeitura", tmrLeitura_Tick, 500, this);
tmrLeitura.Start();
if (Variaveis.OperacaoEmAndamento.Mapa.pnlMapa == null)
if (op.Mapa.pnlMapa == null)
{
Variaveis.OperacaoEmAndamento.Mapa = new MapasModel()
op.Mapa = new MapasModel()
{
pnlMapa = pnlMapa,
lblMapa = lblMapaCarregado
};
Variaveis.OperacaoEmAndamento.Mapa.CarregarMapaGPS();
op.Mapa.CarregarMapaGPS();
}
}
@ -136,8 +138,9 @@ namespace AgroBase.Forms.IHM
public void AtualizarMapaDinamico()
{
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
var _Trajetoria = Variaveis.OperacaoEmAndamento.Trajetoria;
var op = Variaveis.OperacaoEmAndamento;
var _Sensoriamento = op.Sensoriamento;
var _Trajetoria = op.Trajetoria;
if (_Trajetoria != null && _Trajetoria.CorredorAtual != null)
{
@ -148,9 +151,9 @@ namespace AgroBase.Forms.IHM
_Sensoriamento.Gps,
_Trajetoria._TrajetoriaDinamica,
_Trajetoria.CorredorAtual.Pontos,
Variaveis.OperacaoEmAndamento.GPSTrajetoria,
op.GPSTrajetoria,
_Trajetoria.RuasPlantacao,
_Sensoriamento.Controle.SimulacaoMPC
op.Controle.SimulacaoMPC
);
}
}
@ -160,25 +163,26 @@ namespace AgroBase.Forms.IHM
pnlOrientacao.Invalidate();
pnlInclinacao.Invalidate();
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
var op = Variaveis.OperacaoEmAndamento;
var _Sensoriamento = op.Sensoriamento;
lblUltimaLeituraSolo.Text = "Última Leitura Solo: " + _Sensoriamento.OperadorErvas.UltimaMensagem.ToString("HH:mm:ss.fff");
lblUltimaLeituraCaminho.Text = "Última Leitura Caminho: " + _Sensoriamento.OperadorVisual.UltimaMensagem.ToString("HH:mm:ss.fff");
lblPerformance.Text = _Sensoriamento.DadosPerformance.PerformanceStr;
lblMapaCarregado.Text = "Operação: " + Variaveis.OperacaoEmAndamento.Descricao;
lblMapaCarregado.Text = "Operação: " + op.Descricao;
txtModoOperacao.Text = (Variaveis.OperacaoEmAndamento.Parametros?.Modo ?? ModoOperacao.NaoDefinido).ToString();
bool opLiberada = _Sensoriamento.OperacaoLiberada;
txtModoOperacao.Text = (op.Parametros?.Modo ?? ModoOperacao.NaoDefinido).ToString();
bool opLiberada = _Sensoriamento.Operacao.OperacaoLiberada;
txtOperacaoLiberada.Text = opLiberada ? "Sim" : "Não";
txtOperacaoLiberada.ForeColor = opLiberada ? Color.Black : Color.Red;
btnCodFalha.Text = CodigoFalha.ToString("0.000");
txtStatusAtual.Text = _Sensoriamento.StatusOperacao.ToString();
txtIniciadoEm.Text = _Sensoriamento.DataInicio == DateTime.MinValue ? "Aguardando" : _Sensoriamento.DataInicio.ToString("dd/MM HH:mm:ss");
txtConcluidoEm.Text = _Sensoriamento.DataFim == DateTime.MinValue ? "-" : _Sensoriamento.DataFim.ToString("dd/MM HH:mm:ss");
txtStatusAtual.Text = _Sensoriamento.Operacao.StatusOperacaoAtual.ToString();
txtIniciadoEm.Text = _Sensoriamento.Operacao.DataInicio == DateTime.MinValue ? "Aguardando" : _Sensoriamento.Operacao.DataInicio.ToString("dd/MM HH:mm:ss");
txtConcluidoEm.Text = _Sensoriamento.Operacao.DataFim == DateTime.MinValue ? "-" : _Sensoriamento.Operacao.DataFim.ToString("dd/MM HH:mm:ss");
txtDistanciaPercorrida.Text = _Sensoriamento.Trajetoria.DistanciaPercorrida.ToString("0.00") + " m";
txtTempoOperacao.Text = _Sensoriamento.TempoDecorrido.ToString("HH:mm:ss");
txtLatenciaControle.Text = _Sensoriamento.Controle.Latencia.ToString();
txtTempoOperacao.Text = _Sensoriamento.Operacao.TempoDecorrido.ToString("HH:mm:ss");
txtLatenciaControle.Text = op.Controle.Latencia.ToString();
txtHerbicidaAplicado.Text = _Sensoriamento.Atuador.HerbicidaConsumido.ToString("0.000") + " L";
txtBateriaConsumida.Text = _Sensoriamento.Bateria.PercentualBateriaConsumida.ToString("0.00") + " %";
@ -197,38 +201,38 @@ namespace AgroBase.Forms.IHM
lblCorrecaoGPS.Text = (_Sensoriamento.Gps.Ntrip_ativado ? "N " : "B ") + _Sensoriamento.Gps.IdadeCorrecao + ": " + _Sensoriamento.Gps.QualidadeFix.ToString();
lblPrecisaoGPS.Text = $"Precisão: {_Sensoriamento.Gps.PrecisaoCm.ToString("0.00")} cm";
bool automatico = Variaveis.OperacaoEmAndamento.Parametros?.ControleAutomatico ?? false;
bool automatico = op.Parametros?.ControleAutomatico ?? false;
cmbModoControle.Enabled = !automatico;
tkbVelocidade.Enabled = !automatico;
tkbAnguloDirecional.Enabled = !automatico;
pnlFreio.Enabled = !automatico;
if (automatico)
{
cmbModoControle.SelectedIndex = (int)_Sensoriamento.Controle.TipoMovimento;
cmbModoControle.SelectedIndex = (int)op.Controle.TipoMovimento;
tkbVelocidade.Value = Convert.ToInt32(_Sensoriamento.Controle.PercentualVelocidadeSP);
tkbVelocidade.Value = Convert.ToInt32(op.Controle.PercentualVelocidadeSP);
tkbAnguloDirecional.Minimum = 0;
tkbAnguloDirecional.Maximum = Convert.ToInt32(Variaveis.OperacaoEmAndamento.Parametros.Controle.DirAnguloMaximo);
tkbAnguloDirecional.Value = Math.Abs(Convert.ToInt32(_Sensoriamento.Controle.Angulo));
tkbAnguloDirecional.Maximum = Convert.ToInt32(op.Parametros.Controle.DirAnguloMaximo);
tkbAnguloDirecional.Value = Math.Abs(Convert.ToInt32(op.Controle.Angulo));
}
txtDistanciasEsqDir.Text = _Sensoriamento.Trajetoria.DistanciaEsquerda.ToString("0.00") + " / " + _Sensoriamento.Trajetoria.DistanciaDireita.ToString("0.00") + " (" + _Sensoriamento.Controle.ErroLateral.ToString("0.00" + ")");
txtDistanciasEsqDir.Text = _Sensoriamento.Trajetoria.DistanciaEsquerda.ToString("0.00") + " / " + _Sensoriamento.Trajetoria.DistanciaDireita.ToString("0.00") + " (" + op.Controle.ErroLateral.ToString("0.00" + ")");
txtDentroCorredor.Text = _Sensoriamento.Trajetoria.CorredorAtual.Dentro ? "Sim" : "Não";
txtMargemCorredor.Text = _Sensoriamento.Trajetoria.NaMargemDoCorredor ? "Sim" : "Não";
txtStatusCarro.Text = _Sensoriamento.Trajetoria.StatusCarro.ToString();
txtInclinacao.Text = _Sensoriamento.IMU.RollSeguro.ToString("0.00") + "/" + _Sensoriamento.IMU.PitchSeguro.ToString("0.00");
var ModET = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.FirstOrDefault(x => x.Modulo_ID == "ET");
var ModET = op.DispMvd.Dados.Modulos.FirstOrDefault(x => x.Modulo_ID == "ET");
txtET.Text = (ModET?.MovMotor?.Corrente_Motor ?? 0).ToString("0.00");
lblET.ForeColor = (ModET?.Conectado ?? false) ? Color.Green : Color.Red;
var ModDT = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.FirstOrDefault(x => x.Modulo_ID == "DT");
var ModDT = op.DispMvd.Dados.Modulos.FirstOrDefault(x => x.Modulo_ID == "DT");
txtDT.Text = (ModDT?.MovMotor?.Corrente_Motor ?? 0).ToString("0.00");
lblDT.ForeColor = (ModDT?.Conectado ?? false) ? Color.Green : Color.Red;
var ModEF = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.FirstOrDefault(x => x.Modulo_ID == "EF");
var ModEF = op.DispMvd.Dados.Modulos.FirstOrDefault(x => x.Modulo_ID == "EF");
txtEF.Text = (ModEF?.MovMotor?.Corrente_Motor ?? 0).ToString("0.00");
lblEF.ForeColor = (ModEF?.Conectado ?? false) ? Color.Green : Color.Red;
var ModDF = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.FirstOrDefault(x => x.Modulo_ID == "DF");
var ModDF = op.DispMvd.Dados.Modulos.FirstOrDefault(x => x.Modulo_ID == "DF");
txtDF.Text = (ModDF?.MovMotor?.Corrente_Motor ?? 0).ToString("0.00");
lblDF.ForeColor = (ModDF?.Conectado ?? false) ? Color.Green : Color.Red;
@ -291,19 +295,21 @@ namespace AgroBase.Forms.IHM
private void pnlOrientacao_Paint(object sender, PaintEventArgs e)
{
var op = Variaveis.OperacaoEmAndamento;
try
{
double angulo = Variaveis.OperacaoEmAndamento.Sensoriamento?.Gps?.AnguloCarroDefinido ?? 0;
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90, (float)(Variaveis.OperacaoEmAndamento.Sensoriamento?.Trajetoria?.AnguloCaminho ?? 0));
double angulo = op.Sensoriamento?.Gps?.AnguloCarroDefinido ?? 0;
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90, (float)(op.Sensoriamento?.Trajetoria?.AnguloCaminho ?? 0));
}
catch { }
}
private void pnlInclinacao_Paint(object sender, PaintEventArgs e)
{
var op = Variaveis.OperacaoEmAndamento;
try
{
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)(Variaveis.OperacaoEmAndamento.Controle.Angulo), 90);
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)(op.Controle.Angulo), 90);
}
catch { }
}
@ -326,14 +332,16 @@ namespace AgroBase.Forms.IHM
private void AtualizarElementosModoManual()
{
var op = Variaveis.OperacaoEmAndamento;
cmbModoControle.Enabled = false;
tkbAnguloDirecional.Enabled = false;
tkbVelocidade.Enabled = false;
pnlJoystick.Visible = false;
tabControl1.TabPages.Remove(tabControle);
var pControle = Variaveis.OperacaoEmAndamento.Parametros.Controle;
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
var pControle = op.Parametros.Controle;
var _Controle = op.Controle;
cmbModoControle.SelectedIndex = (int)_Controle.TipoMovimento;
chbFrenagemAutomatica.Checked = pControle.FrenagemAutomaticaAoParar;
nudVelSemErvas.Value = (int)pControle.MovVelocidadeSErvasPercent;
@ -473,6 +481,8 @@ namespace AgroBase.Forms.IHM
private void SendMovementCommand(int deltaX, int deltaY)
{
var op = Variaveis.OperacaoEmAndamento;
Keys MovKey = Keys.Escape;
if (deltaY < -10) MovKey = Keys.Up;
else if (deltaY > 10) MovKey = Keys.Down;
@ -488,7 +498,7 @@ namespace AgroBase.Forms.IHM
Console.WriteLine($"Movimento: MovKey={MovKey}");
//GeneralJoystick.EnviaComandoMotor(MovKey, Enums.T_Code.Mov);
var comando = GeneralJoystick.DeParaComandos.FirstOrDefault(x => x.key == MovKey);
GeneralJoystick.ProcessarDadosControle(comando.botaoJoy, false, valorDesejado: Variaveis.OperacaoEmAndamento.Parametros.Controle.MovVelocidadeCErvasPercent);
GeneralJoystick.ProcessarDadosControle(comando.botaoJoy, false, valorDesejado: op.Parametros.Controle.MovVelocidadeCErvasPercent);
prevMovKey = MovKey; // Atualiza o estado anterior
}
@ -499,7 +509,7 @@ namespace AgroBase.Forms.IHM
Console.WriteLine($"Direção: DirKey={DirKey}");
//GeneralJoystick.EnviaComandoMotor(DirKey, Enums.T_Code.Dir);
var comando = GeneralJoystick.DeParaComandos.FirstOrDefault(x => x.key == DirKey);
GeneralJoystick.ProcessarDadosControle(comando.botaoJoy, false, valorDesejado: Variaveis.OperacaoEmAndamento.Parametros.Controle.DirAnguloMaximo);
GeneralJoystick.ProcessarDadosControle(comando.botaoJoy, false, valorDesejado: op.Parametros.Controle.DirAnguloMaximo);
prevDirKey = DirKey; // Atualiza o estado anterior
}
}
@ -526,7 +536,8 @@ namespace AgroBase.Forms.IHM
// Iniciar o arraste
private void BrakePanel_MouseDown(object sender, MouseEventArgs e)
{
if (Variaveis.OperacaoEmAndamento.Parametros?.Modo != Enums.ModoOperacao.Manual)
var op = Variaveis.OperacaoEmAndamento;
if (op.Parametros?.Modo != Enums.ModoOperacao.Manual)
{
return;
}
@ -540,7 +551,8 @@ namespace AgroBase.Forms.IHM
// Movimentar o botão de freio
private void BrakePanel_MouseMove(object sender, MouseEventArgs e)
{
if (Variaveis.OperacaoEmAndamento.Parametros?.Modo != Enums.ModoOperacao.Manual)
var op = Variaveis.OperacaoEmAndamento;
if (op.Parametros?.Modo != Enums.ModoOperacao.Manual)
{
return;
}
@ -582,7 +594,8 @@ namespace AgroBase.Forms.IHM
// Soltar o botão de freio
private void BrakePanel_MouseUp(object sender, MouseEventArgs e)
{
if (Variaveis.OperacaoEmAndamento.Parametros?.Modo != Enums.ModoOperacao.Manual)
var op = Variaveis.OperacaoEmAndamento;
if (op.Parametros?.Modo != Enums.ModoOperacao.Manual)
{
return;
}
@ -634,7 +647,7 @@ namespace AgroBase.Forms.IHM
private void btnCodFalha_Click(object sender, EventArgs e)
{
string DescricaoFalha = Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada;
string DescricaoFalha = Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.ErroOperacaoLiberada;
CustomDialog.ShowDialog(
"Código de Falha",
$"{DescricaoFalha}",
@ -670,14 +683,16 @@ namespace AgroBase.Forms.IHM
private void AtualizarListaModulos(bool forceRebuild = false)
{
var op = Variaveis.OperacaoEmAndamento;
if (_inRefresh) return;
_inRefresh = true;
try
{
// 1) Pega o estado atual do seu sistema
var src = Variaveis.OperacaoEmAndamento.Parametros.ModulosMandatorios;
var saude = HealthWorkerService.ModulosSaude;
var src = op.Parametros.ModulosMandatorios;
var saude = op.Sensoriamento.OperadorSaude.ModulosSaude;
// 2) Constrói snapshot
var novos = new List<ModuloUIItem>(src.Count);
@ -795,6 +810,7 @@ namespace AgroBase.Forms.IHM
private void clbModulos_ItemCheck(object sender, ItemCheckEventArgs e)
{
var op = Variaveis.OperacaoEmAndamento;
if (_inRefresh) return; // evita loop quando sincronizamos via código
var idx = e.Index;
@ -808,7 +824,7 @@ namespace AgroBase.Forms.IHM
// escreve de volta na fonte oficial
var disp = _modulosUI[idx].Disp;
var alvo = Variaveis.OperacaoEmAndamento.Parametros.ModulosMandatorios.FirstOrDefault(m => m.Dispositivo.Equals(disp));
var alvo = op.Parametros.ModulosMandatorios.FirstOrDefault(m => m.Dispositivo.Equals(disp));
if (alvo != null)
{
if (alvo.Utilizar && alvo.Mandatorio && !novoUtilizar)
@ -843,14 +859,15 @@ namespace AgroBase.Forms.IHM
private void btnPausarOperacao_Click(object sender, EventArgs e)
{
if (!Variaveis.OperacaoEmAndamento.Pausa)
var op = Variaveis.OperacaoEmAndamento;
if (!op.Sensoriamento.Operacao.Pausa)
{
Variaveis.OperacaoEmAndamento.Pausa = true;
op.Sensoriamento.Operacao.Pausa = true;
btnPausarOperacao.Text = "Retomar";
}
else
{
Variaveis.OperacaoEmAndamento.Pausa = false;
op.Sensoriamento.Operacao.Pausa = false;
btnPausarOperacao.Text = "Pausar";
}
}
@ -862,6 +879,7 @@ namespace AgroBase.Forms.IHM
private void btnSalvarParametros_Click(object sender, EventArgs e)
{
var op = Variaveis.OperacaoEmAndamento;
var res = CustomDialog.ShowDialog(
"Salvar parâmetros da operação",
"Deseja aplicar os novos parâmetros para operação atual?",
@ -872,7 +890,7 @@ namespace AgroBase.Forms.IHM
{ ("Não", DialogResult.No), () => { } },
}
);
var pControle = Variaveis.OperacaoEmAndamento.Parametros.Controle;
var pControle = op.Parametros.Controle;
if (res == DialogResult.Yes)
{
pControle.FrenagemAutomaticaAoParar = chbFrenagemAutomatica.Checked;

View File

@ -45,7 +45,7 @@ namespace AgroBase.Forms.IHM
FuncoesGlobais.DefinirEventosPicBtn(picManual, "Erro ao carregar modo de controle manual!", async () =>
{
OperacaoModel.CarregarParametrosOperacaoPadrao(ModoOperacao.Manual, true);
if (Variaveis.OperacaoEmAndamento.OperacaoLiberada)
if (Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoLiberada)
{
frmDialogoMapa frm = new frmDialogoMapa();
frm.Show();
@ -55,7 +55,7 @@ namespace AgroBase.Forms.IHM
{
CustomDialog.ShowDialog(
"Iniciar Operação Manual",
$"{Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada ?? ""}",
$"{Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.ErroOperacaoLiberada ?? ""}",
MessageBoxIcon.Error,
new Dictionary<(string, dynamic), Action>()
{
@ -194,7 +194,7 @@ namespace AgroBase.Forms.IHM
{
var Modulo = SerialService.DispositivosMapeados.FirstOrDefault(x => x.Dispositivo == T_Code.Snr);
bool modDesconectado = Modulo == null || Modulo.Status == StatusModulo.Desconectado;
var saudeImu = HealthWorkerService.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo);
var saudeImu = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorSaude.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo);
var CameraCaminho = CameraWorkerService.CameraCaminho;
lbl.ForeColor =
modDesconectado || saudeImu == null ? Color.Black
@ -208,8 +208,8 @@ namespace AgroBase.Forms.IHM
{
var Modulo = SerialService.DispositivosMapeados.FirstOrDefault(x => x.Dispositivo == T_Code.Snr);
bool modDesconectado = Modulo == null || Modulo.Status == StatusModulo.Desconectado;
var saudeLra = HealthWorkerService.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo);
var lora = Variaveis.LoraService;
var saudeLra = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorSaude.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo);
dynamic lora = null; // Variaveis.LoraService;
lbl.ForeColor =
lora == null || !(Variaveis.OperacaoEmAndamento.DispSen?.Dados?.Conectado ?? false)
? Color.Black
@ -309,7 +309,7 @@ namespace AgroBase.Forms.IHM
lblIA.Text = "IA: " + (VariaveisOperacao.Operadores.Conectado ? "Conectado" : "Desconectado");
lblIA.ForeColor = VariaveisOperacao.Operadores.Conectado ? Color.Green : Color.Red;
bool opLiberada = Variaveis.OperacaoEmAndamento.OperacaoLiberada;
bool opLiberada = Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoLiberada;
lblOperacaoLiberada.Text = "Operação Liberada: " + (opLiberada ? "Sim" : "Não");
lblOperacaoLiberada.ForeColor = opLiberada ? Color.Green : Color.Red;
@ -320,7 +320,7 @@ namespace AgroBase.Forms.IHM
private void LblCodigoFalha_Click(object sender, EventArgs e)
{
string DescricaoFalha = Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada;
string DescricaoFalha = Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.ErroOperacaoLiberada;
CustomDialog.ShowDialog(
"Código de Falha",
$"{DescricaoFalha}",
@ -340,7 +340,7 @@ namespace AgroBase.Forms.IHM
var Modulo = SerialService.DispositivosMapeados.FirstOrDefault(x => x.Dispositivo == Dispositivo && (x.Mod_ID == Mod_ID || x.Mod_ID == null));
var saudeGeral = HealthWorkerService.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo);
var saudeGeral = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorSaude.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo);
ManagerWorkerMessageResponseModulosPendentesSaudeModel saudeIndividual = null;
switch (Dispositivo)
{

View File

@ -48,7 +48,7 @@ namespace AgroBase.Forms.Operacoes
});
FuncoesGlobais.DefinirEventosPicBtn(picIniciar, "Erro ao iniciar operação!", async () =>
{
if (Variaveis.OperacaoEmAndamento.OperacaoLiberada)
if (Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoLiberada)
{
var res = CustomDialog.ShowDialog(
"Iniciar Operação",
@ -71,7 +71,7 @@ namespace AgroBase.Forms.Operacoes
{
CustomDialog.ShowDialog(
"Conexão de módulos pendentes",
$"{Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada}",
$"{Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.ErroOperacaoLiberada}",
MessageBoxIcon.Warning,
new Dictionary<(string, dynamic), Action>()
{
@ -350,7 +350,7 @@ namespace AgroBase.Forms.Operacoes
AtualizarOpLiberada();
CustomDialog.ShowDialog(
"Status",
Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada,
Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.ErroOperacaoLiberada,
MessageBoxIcon.Information,
new Dictionary<(string, dynamic), Action>()
{
@ -361,8 +361,8 @@ namespace AgroBase.Forms.Operacoes
private void AtualizarOpLiberada()
{
lblStatusOperacao.Text = "LIBERADO: " + (Variaveis.OperacaoEmAndamento.OperacaoLiberada ? "SIM" : "NÃO");
lblStatusOperacao.ForeColor = Variaveis.OperacaoEmAndamento.OperacaoLiberada ? Color.DarkGreen : Color.DarkRed;
lblStatusOperacao.Text = "LIBERADO: " + (Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoLiberada ? "SIM" : "NÃO");
lblStatusOperacao.ForeColor = Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoLiberada ? Color.DarkGreen : Color.DarkRed;
}
}

View File

@ -1,5 +1,6 @@
using AgroBase.Models;
using AgroBase.Services;
using AgroBase.Services.Operadores;
using Microsoft.Web.WebView2.WinForms;
using Newtonsoft.Json;
using System;
@ -27,7 +28,7 @@ namespace AgroBase.Forms.Movimentacao
};
private CameraService cameraService = new CameraService();
//private CameraService cameraService = new CameraService();
private WebView2 browser = null;
private Timer tmrLeitura;
@ -65,8 +66,8 @@ namespace AgroBase.Forms.Movimentacao
try
{
tmrLeitura.Stop();
Variaveis.MqttServiceLocal.UnsubscribeAsync(cameraService._mqttTopico).GetAwaiter().GetResult();
cameraService.pythonProcess.Kill();
//Variaveis.MqttServiceLocal.UnsubscribeAsync(cameraService._mqttTopico).GetAwaiter().GetResult();
//cameraService.pythonProcess.Kill();
}
catch (Exception ex)
{
@ -238,7 +239,7 @@ namespace AgroBase.Forms.Movimentacao
if (browser == null)
{
browser = new WebView2();
browser.Source = new Uri(cameraService.URLcamera[0]);
//browser.Source = new Uri(cameraService.URLcamera[0]);
this.pnlCamera.Controls.Add(browser);
browser.Dock = DockStyle.Fill;
}
@ -273,7 +274,7 @@ namespace AgroBase.Forms.Movimentacao
else
{
btnSalvar.Text = "Editar";
cameraService.cameraIndex = cmbCameras.SelectedIndex;
//cameraService.cameraIndex = cmbCameras.SelectedIndex;
}
btnIniciar.Enabled = btnSalvar.Text == "Editar" && cmbCameras.SelectedIndex > 0;
cmbCameras.Enabled = btnSalvar.Text == "Salvar";
@ -306,14 +307,14 @@ namespace AgroBase.Forms.Movimentacao
private void AtualizaListaCameras()
{
cameraService.cameraIndex = cmbCameras.SelectedIndex > 0 ? cmbCameras.SelectedIndex : 0;
//cameraService.cameraIndex = cmbCameras.SelectedIndex > 0 ? cmbCameras.SelectedIndex : 0;
cmbCameras.Items.Clear();
cmbCameras.Items.AddRange(CameraService.ObterListaCameras().Keys.ToArray());
cmbCameras.Items.AddRange(CameraWorkerService.ListaCameras.Select(x => x.mx_id).ToArray());
if (cmbCameras.Items.Count == 1)
{
cameraService.cameraIndex = 0;
//cameraService.cameraIndex = 0;
}
cmbCameras.SelectedIndex = cameraService.cameraIndex;
//cmbCameras.SelectedIndex = cameraService.cameraIndex;
}

View File

@ -132,7 +132,7 @@ namespace AgroBase.Forms.Operacoes
});
// Verifica se a operação está liberada
if (Variaveis.OperacaoEmAndamento.OperacaoLiberada)
if (Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoLiberada)
{
// Inicia a operação de forma assíncrona
Task.Run(async () => await Variaveis.OperacaoEmAndamento.IniciarOperacao());
@ -149,7 +149,7 @@ namespace AgroBase.Forms.Operacoes
// Mostra a mensagem de erro na thread principal
btnIniciarOperacao.Invoke((MethodInvoker)delegate
{
MessageBox.Show(Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada, "Aviso", MessageBoxButtons.OK, MessageBoxIcon.Error);
MessageBox.Show(Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.ErroOperacaoLiberada, "Aviso", MessageBoxButtons.OK, MessageBoxIcon.Error);
btnIniciarOperacao.Text = "Iniciar Operação";
btnIniciarOperacao.Enabled = true;
});
@ -186,8 +186,8 @@ namespace AgroBase.Forms.Operacoes
lblTensao.Text = _Sensoriamento.Bateria.TensaoInstantanea.ToString("0.00") + " v";
lblCorrente.Text = _Sensoriamento.Bateria.CorrenteInstantanea.ToString("0.00") + " A";
lblRPM.Text = _Sensoriamento.Movimentacao.RPMMedio.ToString("0") + " rpm";
lblVelocidade.Text = (_Sensoriamento.Movimentacao.VelocidadeMedia * 3.6).ToString("0.00");
lblRPM.Text = _Sensoriamento.Movimentacao.RPMRodaMedio.ToString("0") + " rpm";
lblVelocidade.Text = (_Sensoriamento.Movimentacao.VelocidadeMediaMs * 3.6).ToString("0.00");
lblPressao.Text = $"{(_Sensoriamento.Atuador.PressaoLinha):F0} psi";
lblPressaoBomba.Text = $"{(_Sensoriamento.Atuador.PressaoAtualBomba):F0} psi";
lblVazaoInstantanea.Text = $"{(_Sensoriamento.Atuador.VazaoFluxoMLpSInstantaneaCorrigida):F0} ml/s";
@ -557,9 +557,9 @@ namespace AgroBase.Forms.Operacoes
var _Atuador = _Sensoriamento?.Atuador;
var _IMU = _Sensoriamento?.IMU;
gridDados.Rows[0].Cells[1].Value = _Sensoriamento.TempoDecorrido.ToString("HH:mm:ss");
gridDados.Rows[1].Cells[1].Value = (_Movimentacao?.TempoMovimento ?? DateTime.Now).ToString("HH:mm:ss");
gridDados.Rows[2].Cells[1].Value = (_Movimentacao?.VelocidadeMedia ?? 0 * 3.6).ToString("0.00");
gridDados.Rows[0].Cells[1].Value = _Sensoriamento.Operacao.TempoDecorrido.ToString("HH:mm:ss");
gridDados.Rows[1].Cells[1].Value = (FuncoesGlobais.TimestampToDate(_Movimentacao?.TempoMovimentoSegs ?? 0));
gridDados.Rows[2].Cells[1].Value = (_Movimentacao?.VelocidadeMediaMs ?? 0 * 3.6).ToString("0.00");
gridDados.Rows[3].Cells[1].Value = (_Sensoriamento.Trajetoria?.DistanciaPercorrida ?? 0).ToString("0.00");
gridDados.Rows[4].Cells[1].Value = ((_Bateria?.PercentualBateria ?? 0).ToString("0.00"));
gridDados.Rows[5].Cells[1].Value = ((_Bateria?.TensaoInstantanea ?? 0).ToString("0.00"));
@ -735,7 +735,7 @@ namespace AgroBase.Forms.Operacoes
AtuadorFuncoesGerais.DesenharAtuadores(
pnlAtuadores,
e,
Atuador.BicosPulverizadores.Select(x => new AtuBicoSensoriamentoLogModel()
Atuador.BicosPulverizadores.Select(x => new AtuadorBicoLogModel()
{
ID = x.ID,
Atuacoes = x.Atuacoes,

View File

@ -78,7 +78,7 @@ namespace AgroBase.Forms.Operacoes
lblUltimaLeituraRua.Text = "Ultima Leitura Rua: " + FuncoesGlobais.TimestampToDate(Variaveis.OperacaoEmAndamento.CameraCaminho.Leitura.timestamp);*/
btnCarregarMapa.Enabled = !Variaveis.OperacaoEmAndamento.Iniciado;
btnCarregarMapa.Enabled = !Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoIniciada;
this.Text = Variaveis.OperacaoEmAndamento.TextoFormOperacao("Mapa GPS");
@ -86,8 +86,8 @@ namespace AgroBase.Forms.Operacoes
//lblDistanciaDireita.Text = "Distancia da Direita: " + Variaveis.OperacaoEmAndamento.Sensoriamento.DistanciaDireita.ToString("0.00") + " cm";
lblDistanciaPercorrida.Text = "Distancia Percorrida: " + _Sensoriamento.Trajetoria.DistanciaPercorrida.ToString("0.00") + " m";
lblTempoOperacao.Text = "Tempo de Operação: " + _Sensoriamento.TempoDecorrido.ToString("HH:mm:ss");
lblVelocidadeMedia.Text = "Velocidade Média: " + _Sensoriamento.Movimentacao.VelocidadeMedia.ToString("0.00") + " km/h";
lblTempoOperacao.Text = "Tempo de Operação: " + _Sensoriamento.Operacao.TempoDecorrido.ToString("HH:mm:ss");
lblVelocidadeMedia.Text = "Velocidade Média: " + _Sensoriamento.Movimentacao.VelocidadeMediaMs.ToString("0.00") + " km/h";
//lblErvasIdentificadas.Text = "Ervas Identificadas: " + _Sensoriamento.Atuador.QtdErvasIdentificadas.ToString("000");
lblHerbicidaAplicado.Text = "Herbicida Aplicado: " + _Sensoriamento.Atuador.HerbicidaConsumido.ToString("0.000") + " L";
lblHerbicidaPorErva.Text = "Herbicida por Erva: " + _Sensoriamento.Atuador.HerbicidaPorErva.ToString("0.000") + " mL";
@ -107,7 +107,7 @@ namespace AgroBase.Forms.Operacoes
lblPerformance.Text = _Sensoriamento.DadosPerformance.PerformanceStr;
if (!Variaveis.OperacaoEmAndamento.Iniciado && btnIniciarOperacao.Text == "Finalizar Operação")
if (!Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoIniciada && btnIniciarOperacao.Text == "Finalizar Operação")
{
AtualizaComponentesOperacao();
}
@ -143,7 +143,7 @@ namespace AgroBase.Forms.Operacoes
}
else
{
if (Variaveis.OperacaoEmAndamento.OperacaoLiberada && Variaveis.OperacaoEmAndamento.Trajetoria.DistanciaTotal > 0 && Variaveis.OperacaoEmAndamento.Mapa.RuasPercorrer.Any())
if (Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoLiberada && Variaveis.OperacaoEmAndamento.Trajetoria.DistanciaTotal > 0 && Variaveis.OperacaoEmAndamento.Mapa.RuasPercorrer.Any())
{
//Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombaPressurizadora.PressaoSP = Convert.ToDouble(nudPressaoSP.Value);
await Variaveis.OperacaoEmAndamento.IniciarOperacao();
@ -159,7 +159,7 @@ namespace AgroBase.Forms.Operacoes
private void AtualizaComponentesOperacao()
{
btnIniciarOperacao.Text = !Variaveis.OperacaoEmAndamento.Iniciado ? "Iniciar Operação" : "Finalizar Operação";
btnIniciarOperacao.Text = !Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoIniciada ? "Iniciar Operação" : "Finalizar Operação";
}
#endregion
@ -169,7 +169,7 @@ namespace AgroBase.Forms.Operacoes
private void pnlAtuadores_Paint(object sender, PaintEventArgs e)
{
var Atuador = Variaveis.OperacaoEmAndamento.DispAtu.Dados;
AtuadorFuncoesGerais.DesenharAtuadores(pnlAtuadores, e, Atuador.BicosPulverizadores.Select(x => new AtuBicoSensoriamentoLogModel()
AtuadorFuncoesGerais.DesenharAtuadores(pnlAtuadores, e, Atuador.BicosPulverizadores.Select(x => new AtuadorBicoLogModel()
{
ID = x.ID,
Atuacoes = x.Atuacoes,

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
using AgroBase.Models;
using AgroBase.Services;
using AgroBase.Services.Operadores;
using Microsoft.Web.WebView2.WinForms;
using Newtonsoft.Json;
using System;
@ -10,7 +11,7 @@ namespace AgroBase.Forms.Sensoriamento
{
public partial class frmSenCamera : Form
{
private CameraService cameraService = new CameraService();
//private CameraService cameraService = new CameraService();
private WebView2 browser = null;
private Timer tmrLeitura;
@ -34,8 +35,8 @@ namespace AgroBase.Forms.Sensoriamento
{
try
{
Variaveis.MqttServiceLocal.UnsubscribeAsync(cameraService._mqttTopico).GetAwaiter().GetResult();
cameraService.pythonProcess?.Kill();
//`Variaveis.MqttServiceLocal.UnsubscribeAsync(cameraService._mqttTopico).GetAwaiter().GetResult();
//`cameraService.pythonProcess?.Kill();
}
catch (Exception ex)
{
@ -63,7 +64,7 @@ namespace AgroBase.Forms.Sensoriamento
else
{
btnSalvar.Text = "Editar";
cameraService.cameraIndex = cmbCameras.SelectedIndex;
//cameraService.cameraIndex = cmbCameras.SelectedIndex;
}
btnIniciar.Enabled = btnSalvar.Text == "Editar" && cmbCameras.SelectedIndex > 0;
cmbCameras.Enabled = btnSalvar.Text == "Salvar";
@ -96,14 +97,14 @@ namespace AgroBase.Forms.Sensoriamento
private void AtualizaListaCameras()
{
cameraService.cameraIndex = cmbCameras.SelectedIndex > 0 ? cmbCameras.SelectedIndex : 0;
//cameraService.cameraIndex = cmbCameras.SelectedIndex > 0 ? cmbCameras.SelectedIndex : 0;
cmbCameras.Items.Clear();
cmbCameras.Items.AddRange(CameraService.ObterListaCameras().Keys.ToArray());
cmbCameras.Items.AddRange(CameraWorkerService.ListaCameras.Select(x => x.mx_id).ToArray());
if (cmbCameras.Items.Count == 1)
{
cameraService.cameraIndex = 0;
//cameraService.cameraIndex = 0;
}
cmbCameras.SelectedIndex = cameraService.cameraIndex;
//cmbCameras.SelectedIndex = cameraService.cameraIndex;
}
private void ListarObjetosDetectados()
@ -111,7 +112,7 @@ namespace AgroBase.Forms.Sensoriamento
if (browser == null)
{
browser = new WebView2();
browser.Source = new Uri(cameraService.URLcamera[0]);
//browser.Source = new Uri(cameraService.URLcamera[0]);
this.pnlCamera.Controls.Add(browser);
browser.Dock = DockStyle.Fill;
}
@ -121,18 +122,18 @@ namespace AgroBase.Forms.Sensoriamento
var MqttTopico = Variaveis.MqttServiceLocal.Topicos.FirstOrDefault(x => x.Topico == VideoUrl);
CameraCoordenadasFrameModel leitura = null;
var Mensagem = MqttTopico.Mensagens.LastOrDefault(x => x.Momento > cameraService.IniciadoEm);
if (Mensagem != null)
{
try
{
leitura = JsonConvert.DeserializeObject<CameraCoordenadasFrameModel>(Mensagem.Mensagem);
}
catch
{
}
}
//var Mensagem = MqttTopico.Mensagens.LastOrDefault(x => x.Momento > cameraService.IniciadoEm);
//if (Mensagem != null)
//{
// try
// {
// leitura = JsonConvert.DeserializeObject<CameraCoordenadasFrameModel>(Mensagem.Mensagem);
// }
// catch
// {
//
// }
//}
/*foreach (var leitura in leituras)
{

View File

@ -67,7 +67,7 @@ namespace AgroBase.Forms.Sensoriamento
private void AtualizarCameras()
{
Cameras = CameraService.ObterListaCameras();
//Cameras = CameraWorkerService.ListaCameras.Select(x => x.mx_id);
cmbCaminho.Items.Clear();
cmbCaminho.Items.AddRange(Cameras.Values.ToArray());
string IDrua = CameraWorkerService.CameraCaminho.Id;

View File

@ -70,7 +70,7 @@ namespace AgroBase.Forms
private void frmSimulacaoMapaGPS_FormClosing(object sender, FormClosingEventArgs e)
{
tmrLeitura?.Dispose();
Variaveis.OperacaoEmAndamento.Iniciado = false;
Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoIniciada = false;
}
DateTime t0 = DateTime.Now;
@ -115,6 +115,7 @@ namespace AgroBase.Forms
return;
AtualizandoTela = true;
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
var _Trajetoria = Variaveis.OperacaoEmAndamento.Trajetoria;
@ -124,9 +125,9 @@ namespace AgroBase.Forms
return;
}
lblStatusOperacao.Text = $"Operação: {_Sensoriamento.StatusOperacao}";
if (_Sensoriamento.StatusOperacao == StatusOperacao.Aguardando) lblStatusOperacao.Text += $" ({_Sensoriamento.TempoAguardandoSeg:0})";
lblTipoMovimento.Text = (_Sensoriamento.Controle?.TipoMovimento ?? TipoMovimentoDirecional.Diagnostico).ToString();
lblStatusOperacao.Text = $"Operação: {_Sensoriamento.Operacao.StatusOperacaoAtual}";
if (_Sensoriamento.Operacao.StatusOperacaoAtual == StatusOperacao.Aguardando) lblStatusOperacao.Text += $" ({_Sensoriamento.Operacao.TempoAguardandoSeg:0})";
lblTipoMovimento.Text = (_Controle?.TipoMovimento ?? TipoMovimentoDirecional.Diagnostico).ToString();
if (_Trajetoria == null)
{
@ -148,7 +149,7 @@ namespace AgroBase.Forms
lblDistanciaOperacao.Text = $"Distância Operação: {_Sensoriamento.Trajetoria.DistanciaPercorrida:F2} m de {_Sensoriamento.Trajetoria.DistanciaTotal:F2} m";
lblDistanciaFinal.Text = $"Distância Restante: {_Sensoriamento.Trajetoria.DistanciaRestante:F2} m";
//lblDistanciaLateral.Text = $"Esq: {_Sensoriamento.Trajetoria.DistanciaEsquerda:F2} m - Dir: {_Sensoriamento.Trajetoria.DistanciaDireita:F2} m {Variaveis.OperacaoEmAndamento.Controle.ErroLateral:F2} m";
lblDistanciaLateral.Text = $"h: {h:F2} m, p: {_Sensoriamento.Controle.SimulacaoMPC.Count}, s: {_Sensoriamento.Controle.DebugCustoMpc.Count}";
lblDistanciaLateral.Text = $"h: {h:F2} m, p: {_Controle.SimulacaoMPC.Count}, s: {_Controle.DebugCustoMpc.Count}";
lblRua.Text = $"Corredor: " + (_Sensoriamento.Trajetoria.CorredorAtual.Dentro ? "Dentro" : "Fora");
lblMargem.Text = $"Margem: " + (_Sensoriamento.Trajetoria.NaMargemDoCorredor ? "Sim" : "Não");
lblProximoPonto.Text = $"Próximo Ponto: {_Sensoriamento.Trajetoria.ProximoPonto.idxPonto}";
@ -156,7 +157,7 @@ namespace AgroBase.Forms
lblDistProx.Text = $"Distância Próximo Ponto: {_Sensoriamento.Trajetoria.ProximoPonto.DistanciaTrajeto:F2} m";
lblDistAnt.Text = $"Distância Ponto Anterior: {_Sensoriamento.Trajetoria.PontoMaisProximo.DistanciaTrajeto:F2} m";
lblTempoRestante.Text = $"Tempo Restante: {_Sensoriamento.Trajetoria.TempoEstimadoRestante}";
lblTempoOperacao.Text = $"Tempo: " + _Sensoriamento.TempoDecorrido.ToString("HH:mm:ss") + $" de {_Sensoriamento.Trajetoria.TempoEstimadoOperacao}";
lblTempoOperacao.Text = $"Tempo: " + _Sensoriamento.Operacao.TempoDecorrido.ToString("HH:mm:ss") + $" de {_Sensoriamento.Trajetoria.TempoEstimadoOperacao}";
lblPercentualRua.Text = $"Rua: {_Sensoriamento.Trajetoria.CorredorAtual.Progresso:F2}%";
lblPercentualOperacao.Text = $"Operação: {_Sensoriamento.Trajetoria.ProgressoTrajeto:F2}%";
@ -165,9 +166,9 @@ namespace AgroBase.Forms
pnlAnguloControle.Invalidate();
pnlOrientacaoCarro.Invalidate();
if (_Sensoriamento.Controle.SimulacaoMPC != null)
if (_Controle.SimulacaoMPC != null)
{
simulacao = _Sensoriamento.Controle.SimulacaoMPC;
simulacao = _Controle.SimulacaoMPC;
}
else
{
@ -190,7 +191,7 @@ namespace AgroBase.Forms
}
if (!Variaveis.OperacaoEmAndamento.Iniciado)
if (!Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoIniciada)
{
if (btnIniciarSimulacao.Text.Contains("Parar"))
{
@ -280,7 +281,7 @@ namespace AgroBase.Forms
double anguloControle = 0.0;
TipoMovimentoDirecional tipoMovimento = Variaveis.OperacaoEmAndamento.Controle.TipoMovimento;
double veloccidade = (Variaveis.OperacaoEmAndamento.StatusAtual == StatusOperacao.Concluido || Variaveis.OperacaoEmAndamento.StatusAtual == StatusOperacao.Aguardando) ? 0 : velocidadeCarroMs;
double veloccidade = (Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.StatusOperacaoAtual == StatusOperacao.Concluido || Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.StatusOperacaoAtual == StatusOperacao.Aguardando) ? 0 : velocidadeCarroMs;
var tipoControle = Variaveis.OperacaoEmAndamento.Parametros.Controle.DirTipoMovimento;
@ -374,13 +375,13 @@ namespace AgroBase.Forms
return;
}
if (!Variaveis.OperacaoEmAndamento.Iniciado && !parar)
if (!Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoIniciada && !parar)
{
Variaveis.OperacaoEmAndamento.IniciarSimulacao();
}
btnIniciarSimulacao.Text = Variaveis.OperacaoEmAndamento.Iniciado ? "Parar Simulação" : "Iniciar Simulação";
if (Variaveis.OperacaoEmAndamento.Iniciado)
btnIniciarSimulacao.Text = Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoIniciada ? "Parar Simulação" : "Iniciar Simulação";
if (Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoIniciada)
{
GPSService.PenultimaLeitura.Latitude = GPSService.UltimaLeitura.Latitude;
GPSService.PenultimaLeitura.Longitude = GPSService.UltimaLeitura.Longitude;
@ -569,7 +570,7 @@ namespace AgroBase.Forms
Heartbeat = GPSService.UltimaLeitura.Heartbeat,
OrientacaoReal = double.Parse(txtAnguloGPS.Text.Replace(".", ",")),
};
GPSService.EnviarCoordenadasParaMapa(VariaveisOperacao.PosicaoBase.Latitude, VariaveisOperacao.PosicaoBase.Longitude, VariaveisOperacao.PosicaoBase.AnguloCarroDefinido, false, Variaveis.LoraBaseParametros.address);
GPSService.EnviarCoordenadasParaMapa(VariaveisOperacao.PosicaoBase.Latitude, VariaveisOperacao.PosicaoBase.Longitude, VariaveisOperacao.PosicaoBase.AnguloCarroDefinido, false, 0x01);
}
private void btnLiberarCorredor_Click(object sender, EventArgs e)

View File

@ -107,13 +107,15 @@ namespace AgroBase.Forms
return;
}
if (!Variaveis.OperacaoEmAndamento.Iniciado && !parar)
bool iniciado = Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoIniciada;
if (!iniciado && !parar)
{
Variaveis.OperacaoEmAndamento.IniciarTreinamento();
}
btnIniciarSimulacao.Text = Variaveis.OperacaoEmAndamento.Iniciado ? "Parar Treinamento" : "Iniciar Treinamento";
if (Variaveis.OperacaoEmAndamento.Iniciado)
btnIniciarSimulacao.Text = iniciado ? "Parar Treinamento" : "Iniciar Treinamento";
if (iniciado)
{
GPSService.PenultimaLeitura.Latitude = GPSService.UltimaLeitura.Latitude;
GPSService.PenultimaLeitura.Longitude = GPSService.UltimaLeitura.Longitude;
@ -129,7 +131,7 @@ namespace AgroBase.Forms
StatusCarro = _robotState.Current_State.Status;
lblStatusOperacao.Text = "Operação: " + Enum.GetName(typeof(StatusOperacao), Variaveis.OperacaoEmAndamento.StatusAtual);
lblStatusOperacao.Text = "Operação: " + Enum.GetName(typeof(StatusOperacao), Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.StatusOperacaoAtual);
lblStatus.Text = "Carro: " + Enum.GetName(typeof(StatusCarroMapa), StatusCarro);
lblDirecao.Text = "Direção: " + Enum.GetName(typeof(DirecaoCarroRua), Variaveis.OperacaoEmAndamento.Trajetoria?.DirecaoCaminho ?? DirecaoCarroRua.Parado);
lblDistanciaOperacao.Text = "Distância Operação: " + (Variaveis.OperacaoEmAndamento.Trajetoria?.DistanciaTotal ?? 0).ToString("00.00") + " m";
@ -145,7 +147,7 @@ namespace AgroBase.Forms
lblTempoEstimado.Text = "Tempo Estimado: " + Variaveis.OperacaoEmAndamento.Trajetoria?.TempoEstimadoRestante ?? "";
if (Variaveis.OperacaoEmAndamento.Iniciado)
if (Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoIniciada)
{
pnlOrientacaoTrajeto.Invalidate();
pnlAnguloControle.Invalidate();

View File

@ -78,7 +78,7 @@ namespace AgroBase.Forms
lblGPSDetalhes.Text = $"{Gps.QualidadeFix} - {Gps.PrecisaoCm:F2} cm";
}
lblPerformance.Text = Variaveis.OperacaoEmAndamento.DadosPerformance.PerformanceStr;
lblPerformance.Text = Variaveis.OperacaoEmAndamento.Sensoriamento.DadosPerformance.PerformanceStr;
lblSen_Latencia.Text = $"Latencia de Loop: {Variaveis.OperacaoEmAndamento.DispSen.Dados?.DadosLeitura?.LatenciaLoop ?? 0} ms";

View File

@ -1,5 +1,4 @@
using AgroBase.Models;
using AgroBase.Services.Operadores;
using System;
using System.Windows.Forms;
@ -19,7 +18,7 @@ namespace AgroBase.Forms
private void btnAtualizar_Click(object sender, EventArgs e)
{
OperacaoModel.PopularTreeView(tvwFalhas, HealthWorkerService.ModulosSaude);
OperacaoModel.PopularTreeView(tvwFalhas, Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorSaude.ModulosSaude);
}
}
}

View File

@ -70,14 +70,14 @@ namespace AgroBase.Forms
if (GPSService.Iniciado)
{
int ID = Convert.ToInt32(Variaveis.IsAgroMonitor ? LoRaBaseService.parametrosModel.address : Variaveis.LoraService.ParametrosSet.address);
int ID = 0x02; // Convert.ToInt32(Variaveis.IsAgroMonitor ? LoRaBaseService.parametrosModel.address : Variaveis.LoraService.ParametrosSet.address);
GPSService.EnviarCoordenadasParaMapa(Gps.Latitude, Gps.Longitude, Gps.AnguloCarroDefinido, true, ID);
}
if (Variaveis.LoraService.Iniciado && Variaveis.LoraService._ultimoRxDados > DateTime.UtcNow.AddSeconds(-60))
if (VariaveisOperacao.PosicaoBase.Inicializado && VariaveisOperacao.PosicaoBase.UltimoComandoRespondido > DateTime.UtcNow.AddSeconds(-60))
{
var GpsBase = VariaveisOperacao.PosicaoBase;
GPSService.EnviarCoordenadasParaMapa(GpsBase.Latitude, GpsBase.Longitude, GpsBase.AnguloCarroDefinido, false, Variaveis.LoraBaseParametros.address);
GPSService.EnviarCoordenadasParaMapa(GpsBase.Latitude, GpsBase.Longitude, GpsBase.AnguloCarroDefinido, false, 0x01);
}
}

View File

@ -49,7 +49,7 @@ namespace AgroBase.Forms
}
else
{
(sucesso, par) = await Variaveis.LoraService?.RequisitarParametrosModulo();
//(sucesso, par) = await Variaveis.LoraService?.RequisitarParametrosModulo();
}
if (!sucesso)
@ -96,19 +96,19 @@ namespace AgroBase.Forms
}
else
{
var MensagemDisponivel = Variaveis.LoraService.MensagensRecebidasAvulsas.FirstOrDefault(x => !x.Lido);
if (MensagemDisponivel != null)
{
MensagemDisponivel.Lido = true;
AtualizarConsole(MensagemDisponivel.Remetente, MensagemDisponivel.Destinatario, MensagemDisponivel.Mensagem);
}
//var MensagemDisponivel = Variaveis.LoraService.MensagensRecebidasAvulsas.FirstOrDefault(x => !x.Lido);
//if (MensagemDisponivel != null)
//{
// MensagemDisponivel.Lido = true;
// AtualizarConsole(MensagemDisponivel.Remetente, MensagemDisponivel.Destinatario, MensagemDisponivel.Mensagem);
//}
}
}
private void AtualizarDadosTela()
{
bool loraConectado = Variaveis.IsAgroMonitor ? LoRaBaseService.Iniciado : Variaveis.LoraService.Iniciado;
bool loraConectado = false; // Variaveis.IsAgroMonitor ? LoRaBaseService.Iniciado : Variaveis.LoraService.Iniciado;
cmbPorta.Items.Clear();
cmbPorta.Items.AddRange(SerialPort.GetPortNames().ToArray());
@ -158,7 +158,7 @@ namespace AgroBase.Forms
}
else
{
(Sucesso, par) = await Variaveis.LoraService?.RedefinirParametros(Parametros);
//(Sucesso, par) = await Variaveis.LoraService?.RedefinirParametros(Parametros);
}
if (Sucesso)
{
@ -208,7 +208,7 @@ namespace AgroBase.Forms
}
else
{
Variaveis.LoraService.EnviarDadosLoRaViaCAN(payload.ToArray());
//Variaveis.LoraService.EnviarDadosLoRaViaCAN(payload.ToArray());
}
MessageBox.Show("Dados enviados com sucesso: " + FuncoesGlobais.ConverterComandoBytesParaTexto(payload.ToArray()));

View File

@ -91,11 +91,11 @@ namespace AgroBase.Forms
ID = x.ID,
Funcoes = x.Funcoes
}));
Dispositivos.Add(new DispositivoDataModel()
{
ID = Variaveis.LoraService.ID,
Funcoes = Variaveis.LoraService.Funcoes
});
//Dispositivos.Add(new DispositivoDataModel()
//{
// ID = Variaveis.LoraService.ID,
// Funcoes = Variaveis.LoraService.Funcoes
//});
break;
}
case T_Code.Atu:

View File

@ -96,6 +96,8 @@ namespace AgroBase
private async Task tmrLoopDispositivos_Tick()
{
var op = Variaveis.OperacaoEmAndamento;
AtualizaDadosGerais();
lblStripMqtt.Text = "MQTT: " + (Variaveis.MqttServiceLocal.StatusConexao() ? "Conectado" : "Desconectado");
@ -103,8 +105,8 @@ namespace AgroBase
lblStripPython.Text = "IA: " + (VariaveisOperacao.Operadores.Conectado ? "Conectado" : "Desconectado");
lblStripPython.ForeColor = VariaveisOperacao.Operadores.Conectado ? Color.Green : Color.Red;
lblStripOperacaoLiberada.Text = "Operação Liberada: " + (Variaveis.OperacaoEmAndamento.OperacaoLiberada ? "Sim" : "Não");
lblStripOperacaoLiberada.ForeColor = Variaveis.OperacaoEmAndamento.OperacaoLiberada ? Color.Green : Color.Red;
lblStripOperacaoLiberada.Text = "Operação Liberada: " + (op.Sensoriamento.Operacao.OperacaoLiberada ? "Sim" : "Não");
lblStripOperacaoLiberada.ForeColor = op.Sensoriamento.Operacao.OperacaoLiberada ? Color.Green : Color.Red;
Variaveis.DebugMode = chbDebugMode.Checked;
}
@ -211,19 +213,21 @@ namespace AgroBase
private void btnIniciarOperacao_Click(object sender, EventArgs e)
{
if (Variaveis.OperacaoEmAndamento.Iniciado)
var op = Variaveis.OperacaoEmAndamento;
if (op.Sensoriamento.Operacao.OperacaoIniciada)
{
Task.Run(async () => await Variaveis.OperacaoEmAndamento.FinalizarOperacao());
Task.Run(async () => await op.FinalizarOperacao());
btnIniciarOperacao.Text = "Abrir Operação";
cmbModoOperacao.Enabled = true;
}
else
{
Variaveis.OperacaoEmAndamento.AbrirForm();
op.AbrirForm();
}
lblStripOperacaoStatus.Text = Variaveis.OperacaoEmAndamento.Iniciado ? "Iniciado" : "Não iniciado";
lblStripOperacaoStatus.Text = op.Sensoriamento.Operacao.OperacaoIniciada ? "Iniciado" : "Não iniciado";
}
private void btnConfigurarOperacao_Click(object sender, EventArgs e)
@ -397,7 +401,7 @@ namespace AgroBase
private void btnLoRaConfig_Click(object sender, EventArgs e)
{
if (Variaveis.LoraService.Iniciado)
if (false)//(Variaveis.LoraService.Iniciado)
{
frmLoraConfig frm = new frmLoraConfig();
frm.Show();
@ -473,7 +477,7 @@ namespace AgroBase
private void lblStripOperacaoLiberada_Click(object sender, EventArgs e)
{
MessageBox.Show($"{Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada}", "Status da Operacao", MessageBoxButtons.OK, MessageBoxIcon.Information);
MessageBox.Show($"{Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.ErroOperacaoLiberada}", "Status da Operacao", MessageBoxButtons.OK, MessageBoxIcon.Information);
}

View File

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static AgroBase.Models.Enums;
using static AgroBase.Models.Enums;
namespace AgroBase.Models
{

View File

@ -1,294 +0,0 @@
using AgroBase.Services;
using Microsoft.Web.WebView2.WinForms;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AgroBase.Models
{
public class CameraCaminhoModel
{
public Bitmap bitmapSegmentado;
public string ID { get; set; }
public string Nome { get; set; }
public int Posicao { get; set; }
public bool Iniciada { get; set; } = false;
public CameraService camera { get; set; }
public WebView2 browserRgb { get; set; }
public Panel panelRgb { get; set; }
public WebView2 browserHeatmap { get; set; }
public Panel panelHeatmap { get; set; }
public ComboBox combo { get; set; }
public string ArquivoLeitura { get; set; }
public int MaxLeituras { get; set; }
public string VideoPorta { get; set; }
public string VideoRgbUrl { get; set; }
public string VideoHeatmapUrl { get; set; }
public string DeviceID { get; set; }
public string MqttTopico { get; set; } = "street_detector";
public Dictionary<string, Color> ClassMap = new Dictionary<string, Color>()
{
{ "background", Color.Black },
{ "rua", Color.DarkRed },
{ "cana", Color.DarkGreen },
{ "ceu", Color.Gold },
};
public CameraDeepLabV3PlusModel Leitura { get; set; } = new CameraDeepLabV3PlusModel();
public List<Point> PontosExtremos { get; set; } = new List<Point>();
public double Angulo { get; set; }
public double AnguloEsquerdo { get; set; }
public double AnguloDireito { get; set; }
public DateTime UltimaMensagemRecebida { get; set; } = DateTime.MinValue;
public DateTime UltimaMensagemProcessada { get; set; } = DateTime.MinValue;
public SonarCamModel Sonar { get; set; } = new SonarCamModel();
public void DesligarCamera()
{
try
{
Iniciada = false;
Variaveis.MqttServiceLocal.Topicos.Remove(camera._mqttTopico);
if (panelRgb != null)
{
panelRgb.Controls.Remove(browserRgb);
}
browserRgb = null;
Task.Run(async () => await Variaveis.MqttServiceLocal.UnsubscribeAsync(camera._mqttTopico));
lock (camera.processLock)
{
if (camera.pythonProcess != null)
{
camera.pythonProcess.Kill();
camera.pythonProcess = null;
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public static List<Point> DefinirPontosExtremos(List<Point> PontosCamera)
{
if (!PontosCamera.Any())
{
return new List<Point>();
}
List<Point> Pontos = new List<Point>()
{
new Point(9999, -1), // Ponto 0 - Mais a esquerda e abaixo
new Point(9999, -1), // Ponto 1 - Mais a esquerda e abaixo, e esquerda > Ponto0.X
new Point(9999, 9999), // Ponto 2 - Mais a esquerda e acima
new Point(-1, 9999), // Ponto 3 - Mais a direita e acima
new Point(-1, -1), // Ponto 4 - Mais a direita e abaixo, e direita < Ponto5.X
new Point(-1, -1), // Ponto 5 - Mais a direita e abaixo
};
foreach (var Ponto in PontosCamera)
{
// Ponto 0 - Mais a esquerda e abaixo
if (Ponto.X < Pontos[0].X)
{
Pontos[0] = new Point() { X = Ponto.X, Y = Ponto.Y };
}
// Ponto 5 - Mais a direita e abaixo
if (Ponto.X > Pontos[5].X)
{
Pontos[5] = new Point() { X = Ponto.X, Y = Ponto.Y };
}
}
var Ponto0 = PontosCamera.Where(Ponto => Ponto.X == Pontos[0].X).OrderByDescending(Ponto => Ponto.Y).First();
Pontos[0] = Ponto0;
var Ponto5 = PontosCamera.Where(Ponto => Ponto.X == Pontos[5].X).OrderByDescending(Ponto => Ponto.Y).First();
Pontos[5] = Ponto5;
foreach (var Ponto in PontosCamera)
{
// Ponto 1 - Mais a esquerda e abaixo, e esquerda > Ponto0.X
if (Ponto.X < Pontos[1].X && Ponto.X > Ponto0.X)
{
Pontos[1] = new Point() { X = Ponto.X, Y = Ponto.Y };
}
// Ponto 4 Mais a direita e abaixo, e direita < Ponto5.X
if (Ponto.X > Pontos[4].X && Ponto.X < Ponto5.X)
{
Pontos[4] = new Point() { X = Ponto.X, Y = Ponto.Y };
}
}
var Ponto1 = PontosCamera.Where(Ponto => Ponto.X == Pontos[1].X).OrderByDescending(Ponto => Ponto.Y).First();
Pontos[1] = Ponto1;
var Ponto4 = PontosCamera.Where(Ponto => Ponto.X == Pontos[4].X).OrderByDescending(Ponto => Ponto.Y).First();
Pontos[4] = Ponto4;
int Y_min = PontosCamera.OrderBy(Ponto => Ponto.Y).First().Y;
foreach (var Ponto in PontosCamera.Where(x => x.Y == Y_min))
{
// Ponto 2 - Mais a esquerda e acima
if (Ponto.X < Pontos[2].X)
{
Pontos[2] = new Point() { X = Ponto.X, Y = Ponto.Y };
}
// Ponto 3 - Mais a direita e acima
if (Ponto.X > Pontos[3].X)
{
Pontos[3] = new Point() { X = Ponto.X, Y = Ponto.Y };
}
}
return Pontos;
}
// 🔹 Gera um mapa de calor corretamente escalado
public Bitmap GenerateHeatmapBitmap()
{
double MaxDepth = 10000;
var depth_data = Leitura.depth_data;
if (depth_data == null || depth_data.Count == 0)
{
return null;
//throw new InvalidOperationException("Dados de profundidade inválidos.");
}
int height = depth_data.Count;
int width = depth_data[0].Count;
Bitmap heatmap = new Bitmap(width, height);
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
int depth = depth_data[y][x];
// 🔹 Normaliza a profundidade entre 0 (vermelho, perto) e 10.000 mm (azul, longe)
int normalized = (int)FuncoesMatematicas.Clamp(255 - ((depth * 255) / MaxDepth), 0, 255);
Color color = ApplyJetColormap(normalized);
heatmap.SetPixel(x, y, color);
}
}
return heatmap;
}
// 🔹 Função para converter um valor normalizado (0-255) para um colormap "Jet" correto
private Color ApplyJetColormap(int value)
{
double normalized = value / 255.0;
int r = (int)(FuncoesMatematicas.Clamp(255 * Math.Max(0, Math.Min(1, 1.5 - Math.Abs(normalized * 2 - 1.5))), 0, 255));
int g = (int)(FuncoesMatematicas.Clamp(255 * Math.Max(0, Math.Min(1, 1.5 - Math.Abs(normalized * 2 - 1.0))), 0, 255));
int b = (int)(FuncoesMatematicas.Clamp(255 * Math.Max(0, Math.Min(1, 1.5 - Math.Abs(normalized * 2 - 0.5))), 0, 255));
return Color.FromArgb(r, g, b);
}
}
public class GridMap
{
public int x_max { get; set; }
public int y_max { get; set; }
public Subdivisoes subdivisoes_cima { get; set; }
public Subdivisoes subdivisoes_chao { get; set; }
}
public class Subdivisoes
{
public int num_linhas { get; set; }
public int num_colunas { get; set; }
public List<Celula> celulas { get; set; }
}
public class Celula
{
public int linha { get; set; }
public int coluna { get; set; }
public int x { get; set; }
public int y { get; set; }
public int largura { get; set; }
public int altura { get; set; }
public double profundidade_calibragem { get; set; }
public double profundidade_media { get; set; }
public double dif_profundidade
{
get
{
return profundidade_media - profundidade_calibragem;
}
}
public Color cor
{
get
{
double margem = 200;
if (dif_profundidade < margem)
{
return Color.Red;
}
else if (dif_profundidade > margem)
{
return Color.Gold;
}
return Color.Transparent;
}
}
}
public class GridDrawer
{
public static GridMap LoadJson(string json)
{
return JsonConvert.DeserializeObject<GridMap>(json);
}
public static Bitmap DrawGridOnBitmap(GridMap gridMap, Bitmap image)
{
Bitmap output = new Bitmap(image);
using (Graphics g = Graphics.FromImage(output))
{
foreach (var celula in gridMap.subdivisoes_chao.celulas)
{
using (Brush brush = new SolidBrush(Color.FromArgb(100, celula.cor))) // 100 = opacidade
{
g.FillRectangle(brush, celula.x, celula.y, celula.largura, celula.altura);
}
g.DrawRectangle(Pens.White, celula.x, celula.y, celula.largura, celula.altura);
}
foreach (var celula in gridMap.subdivisoes_cima.celulas)
{
using (Brush brush = new SolidBrush(Color.FromArgb(100, celula.cor)))
{
g.FillRectangle(brush, celula.x, celula.y, celula.largura, celula.altura);
}
g.DrawRectangle(Pens.White, celula.x, celula.y, celula.largura, celula.altura);
}
}
return output;
}
}
}

View File

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
namespace AgroBase.Models

View File

@ -1,70 +0,0 @@
using AgroBase.Services;
using Microsoft.Web.WebView2.WinForms;
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AgroBase.Models
{
public class CameraSoloModel
{
public CameraSoloModel()
{
}
public void DesligarCamera()
{
try
{
Iniciada = false;
Variaveis.MqttServiceLocal.Topicos.Remove(camera._mqttTopico);
if (panel != null)
{
panel.Controls.Remove(browser);
}
browser = null;
Task.Run(async () => await Variaveis.MqttServiceLocal.UnsubscribeAsync(camera._mqttTopico));
lock (camera.processLock)
{
if (camera.pythonProcess != null)
{
camera.pythonProcess.Kill();
camera.pythonProcess = null;
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public string ID { get; set; }
public string Nome { get; set; }
public int Posicao { get; set; }
public bool Iniciada { get; set; } = false;
public CameraService camera { get; set; } = new CameraService();
public WebView2 browser { get; set; }
public Panel panel { get;set; }
public ComboBox combo { get;set; }
public string ArquivoLeitura { get; set; }
public int MaxLeituras { get; set; }
public string VideoPorta { get; set; }
public string VideoUrl { get; set; }
public string MqttTopico { get; set; } = "weed_detector";
public string DeviceID { get; set; }
public CameraCoordenadasFrameModel Leitura { get; set; } = new CameraCoordenadasFrameModel();
public int ErvasNoRadar { get; set; }
public DateTime UltimaMensagemRecebida { get; set; } = DateTime.MinValue;
public DateTime UltimaMensagemProcessada { get; set; } = DateTime.MinValue;
}
}

View File

@ -1,5 +1,4 @@
using AgroBase.Services;
using System;
using System;
using System.Collections.Generic;
using System.Linq;

View File

@ -1,5 +1,4 @@
using AgroBase.Services.Operadores;
using System;
using System;
using System.Linq;
using static AgroBase.Models.Enums;
@ -38,11 +37,12 @@ namespace AgroBase.Models
public void AtualizarDados()
{
Status = HealthWorkerService.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo)?.status ?? StatusModulo.Desconectado;
Saude = HealthWorkerService.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo)?.saude ?? 0;
var saude = Variaveis.OperacaoEmAndamento.Sensoriamento?.OperadorSaude?.ModulosSaude;
Status = saude.FirstOrDefault(x => x.modulo == Dispositivo)?.status ?? StatusModulo.Desconectado;
Saude = saude.FirstOrDefault(x => x.modulo == Dispositivo)?.saude ?? 0;
var motivos = HealthWorkerService.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo)?.motivos ?? new System.Collections.Generic.List<string>();
var cond_op = HealthWorkerService.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo)?.condicoes_operacionais?.Select(x => x.descricao) ?? new System.Collections.Generic.List<string>();
var motivos = saude.FirstOrDefault(x => x.modulo == Dispositivo)?.motivos ?? new System.Collections.Generic.List<string>();
var cond_op = saude.FirstOrDefault(x => x.modulo == Dispositivo)?.condicoes_operacionais?.Select(x => x.descricao) ?? new System.Collections.Generic.List<string>();
string motivos_str = string.Join(", ", motivos);
string cond_op_str = string.Join(", ", cond_op);
Erros = motivos_str + (motivos.Any() && cond_op.Any() ? ", " : "") + cond_op_str;

View File

@ -31,7 +31,6 @@ namespace AgroBase.Models
public double Distancia { get; set; }
public double OrientacaoMovimento { get; set; }
public int NumeroSatelites { get; set; }
//public CanCommandFreqModel<int> NumeroSatelites { get; set; } = new CanCommandFreqModel<int>();
public double PrecisaoHorizontal { get; set; }
public double CursoVerdadeiro { get; set; }
public double OrientacaoReal { get; set; }

View File

@ -3,7 +3,6 @@ using AgroBase.Models;
using AgroBase.Models.Modules;
using AgroBase.Services;
using SharpDX.DirectInput;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Data;
@ -20,7 +19,6 @@ namespace AgroBase
public static int MargemAnalogico = 100;
public static int MaximoAnalogico = 65534;
public static List<ComandosDispositivo> Comandos = new List<ComandosDispositivo>() { };
public static List<DeParaComandos> DeParaComandos = new List<DeParaComandos>()
{
new DeParaComandos() { key = Keys.Left, botaoJoy = BotoesJoystick.SEsquerda, direcao = Direcao.Esquerda, Dispositivo = T_Code.Dir, PararAoSoltar = true },
@ -55,10 +53,6 @@ namespace AgroBase
public static bool Pressionado = false;
public static List<IDispositivosService> DispCon;
//public static int RPM { get; set; } = 60;
//public static double Angulo { get; set; } = 20;
//public static int Velocidade { get; set; } = 50;
public static AsyncTaskTimerModel tmrJoystick;
public static void IniciarRotinas()
@ -553,14 +547,16 @@ namespace AgroBase
private static void EnviarComandoMotorAtualizado(DeParaComandos Comando, string ID = "", bool ForcarComando = false)
{
var op = Variaveis.OperacaoEmAndamento;
bool bloqueioAutomatico =
(Variaveis.OperacaoEmAndamento.Parametros.Controle.MovimentoAutomatico && Comando.Dispositivo == T_Code.Mov) ||
(Variaveis.OperacaoEmAndamento.Parametros.Controle.DirecionalAutomatico && Comando.Dispositivo == T_Code.Dir);
(op.Parametros.Controle.MovimentoAutomatico && Comando.Dispositivo == T_Code.Mov) ||
(op.Parametros.Controle.DirecionalAutomatico && Comando.Dispositivo == T_Code.Dir);
bool bloqueioOperacional =
Variaveis.OperacaoEmAndamento.Calibrando ||
!Variaveis.OperacaoEmAndamento.OperacaoLiberada ||
!Variaveis.OperacaoEmAndamento.Iniciado;
op.Sensoriamento.Operacao.Calibrando ||
!op.Sensoriamento.Operacao.OperacaoLiberada ||
!op.Sensoriamento.Operacao.OperacaoIniciada;
bool deveInterromper =
bloqueioAutomatico ||
@ -569,8 +565,8 @@ namespace AgroBase
if (deveInterromper) return;
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
if (Comando.direcao.HasValue)
var _Controle = op.Controle;
if (Comando.direcao.HasValue && _Controle.TiposControle.Any(x => x.Tipo == Comando.Dispositivo))
_Controle.TiposControle.FirstOrDefault(x => x.Tipo == Comando.Dispositivo).DirecaoAtual = Comando.direcao.Value;
for (int i = 0; i < 1; i++)
@ -580,38 +576,41 @@ namespace AgroBase
case T_Code.Mov:
_Controle.PercentualVelocidadeSP = Comando.ValorAplicar;
_Controle.EmFreio = Comando.EstadoAplicar;
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(ForcarComando, new List<T_Code>() { Comando.Dispositivo });
op.AtualizarDadosControle(ForcarComando, new List<T_Code>() { Comando.Dispositivo });
break;
case T_Code.Dir:
if (MovimentosCombinados.Contains(Variaveis.OperacaoEmAndamento.Controle.TipoMovimento))
if (MovimentosCombinados.Contains(_Controle.TipoMovimento))
{
Task.Run(async () => await Variaveis.OperacaoEmAndamento.DispMvd.Dados.ExecutarMovimentoDirecionalCombinado(Comando.direcao.Value));
Task.Run(async () => await op.DispMvd.Dados.ExecutarMovimentoDirecionalCombinado(Comando.direcao.Value));
}
else if (Comando.direcao == Direcao.Referenciar)
{
List<string> modsControlar = (!string.IsNullOrEmpty(ID)) ? new List<string>() { ID } : null;
Task.Run(async () => await Variaveis.OperacaoEmAndamento.DispMvd.Dados.RealizarReferenciamentoDirecional(ModsReferenciar: modsControlar));
Task.Run(async () => await op.DispMvd.Dados.RealizarReferenciamentoDirecional(ModsReferenciar: modsControlar));
}
else
{
_Controle.Angulo = Comando.ValorAplicar;
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(ForcarComando, new List<T_Code>() { Comando.Dispositivo });
op.AtualizarDadosControle(ForcarComando, new List<T_Code>() { Comando.Dispositivo });
}
break;
}
}
AtualizaConsole(_Controle.TiposControle.FirstOrDefault(x => x.Tipo == Comando.Dispositivo).DirecaoAtual.ToString());
if (_Controle.TiposControle.Any(x => x.Tipo == Comando.Dispositivo))
AtualizaConsole(_Controle.TiposControle.FirstOrDefault(x => x.Tipo == Comando.Dispositivo).DirecaoAtual.ToString());
}
public static void EnviarComandoAtuadorAtualizado(DeParaComandos Comando, bool ForcarComando = false)
{
bool bloqueioAutomatico = Variaveis.OperacaoEmAndamento.Parametros.Controle.PulverizadorAutomatico;
var op = Variaveis.OperacaoEmAndamento;
bool bloqueioAutomatico = op.Parametros.Controle.PulverizadorAutomatico;
bool bloqueioOperacional =
Variaveis.OperacaoEmAndamento.Calibrando ||
!Variaveis.OperacaoEmAndamento.OperacaoLiberada ||
!Variaveis.OperacaoEmAndamento.Iniciado;
op.Sensoriamento.Operacao.Calibrando ||
!op.Sensoriamento.Operacao.OperacaoLiberada ||
!op.Sensoriamento.Operacao.OperacaoIniciada;
bool deveInterromper =
bloqueioAutomatico ||
@ -619,11 +618,11 @@ namespace AgroBase
if (deveInterromper) return;
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
var _Controle = op.Controle;
var tipoControle = _Controle?.TiposControle?.FirstOrDefault(x => x?.Tipo == Comando.Dispositivo);
var bico = Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.BicosPulverizadores?.FirstOrDefault(x => x.ID == Comando.IDcontrolar);
var bomba = Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.BombasPressurizadoras?.FirstOrDefault(x => x.ID == Comando.IDcontrolar);
var bico = op.DispAtu?.Dados?.BicosPulverizadores?.FirstOrDefault(x => x.ID == Comando.IDcontrolar);
var bomba = op.DispAtu?.Dados?.BombasPressurizadoras?.FirstOrDefault(x => x.ID == Comando.IDcontrolar);
S_Code comp = bico?.Componente ?? bomba?.Componente ?? S_Code.sVZO;
for (int i = 0; i < 1; i++)
@ -632,214 +631,18 @@ namespace AgroBase
}
}
public static void EnviaComandoMotor(Keys Tecla, T_Code Disp = T_Code.Vzo, string ID = null, BotoesJoystick botao = BotoesJoystick.Vazio, bool ForcarComando = false)
{
// Verifica se deve interromper o fluxo
// interrompe se nao estiver diagnosticando, nao forca o envio, e se o modo for manual vai verificar o status da operacao e do sonar, pois automatico faz esse controle em outro lugar
bool deveInterromper =
!Forms.IHM.frmDiagnosticos.Diagnosticando && !ForcarComando &&
(
Variaveis.OperacaoEmAndamento.Parametros?.Modo == ModoOperacao.Manual && (
Variaveis.OperacaoEmAndamento.Calibrando ||
!Variaveis.OperacaoEmAndamento.OperacaoLiberada ||
!Variaveis.OperacaoEmAndamento.Iniciado ||
!VerificaComandoValidoSonar(Tecla)
)
);
if (deveInterromper)
{
return;
}
ComandosDispositivo Comando = new ComandosDispositivo()
{
Momento = DateTime.Now,
Comando = Tecla,
IDcontrolar = DeParaComandos.FirstOrDefault(x => x.key == Tecla)?.IDcontrolar ?? "",
};
Direcao DirecaoAtual = Direcao.Parado;
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
var tipoControle = _Controle?.TiposControle?.FirstOrDefault(x => x?.Tipo == Comando.Dispositivo);
// Cancelar Comando Anterior
if (Comando.Comando == Keys.Escape)
{
var ComandosDisp = Disp == T_Code.Vzo ? Comandos : Comandos.Where(x => x.Dispositivo == Disp).ToList();
if (ComandosDisp.Any())
{
if (Disp == T_Code.Vzo)
{
Comando.Dispositivo = ComandosDisp[ComandosDisp.Count - 1].Dispositivo;
Comando.IDcontrolar = ComandosDisp[ComandosDisp.Count - 1].IDcontrolar;
}
else
{
Comando.Dispositivo = Disp;
Comando.IDcontrolar = !string.IsNullOrEmpty(ID) ? ID : ComandosDisp[ComandosDisp.Count - 1].IDcontrolar;
}
DirecaoAtual = Direcao.Parado;
switch (botao)
{
case BotoesJoystick.Bolinha:
_Controle.EmFreio = false;
break;
}
Pressionado = true;
}
}
// Controle de Velocidade (MOV RPM SP)
else if (Comando.Comando == Keys.Add)
{
Comando.Dispositivo = T_Code.Mov;
DirecaoAtual = tipoControle?.UltimaDirecao ?? Direcao.Parado;
int s = Math.Sign(_Controle.PercentualVelocidadeSP);
var p = (Math.Abs(_Controle.PercentualVelocidadeSP) + 1) * s;
_Controle.PercentualVelocidadeSP = p;
Pressionado = true;
}
else if (Comando.Comando == Keys.Subtract)
{
Comando.Dispositivo = T_Code.Mov;
DirecaoAtual = tipoControle?.UltimaDirecao ?? Direcao.Parado;
int s = Math.Sign(_Controle.PercentualVelocidadeSP);
var p = (Math.Abs(_Controle.PercentualVelocidadeSP) - 1) * s;
_Controle.PercentualVelocidadeSP = p;
Pressionado = true;
}
// Controle Direcao dos Motores BLDC (MOV)
else if (Comando.Comando == Keys.Up) // && UltimaDirecao != Direcao.Frente
{
Comando.Dispositivo = T_Code.Mov;
DirecaoAtual = Direcao.Frente;
Pressionado = true;
}
else if (Comando.Comando == Keys.Down) // && UltimaDirecao != Direcao.Tras
{
Comando.Dispositivo = T_Code.Mov;
DirecaoAtual = Direcao.Tras;
Pressionado = true;
}
else if (Comando.Comando == Keys.Space && UltimaDirecao != Direcao.EmFreio)
{
Comando.Dispositivo = T_Code.Mov;
DirecaoAtual = Direcao.EmFreio;
_Controle.EmFreio = true;
Pressionado = true;
}
// Controle de Rotação dos Motores de Passo (DIR)
else if (Comando.Comando == Keys.Left) // && UltimaDirecao != Direcao.Esquerda
{
Comando.Dispositivo = T_Code.Dir;
DirecaoAtual = Direcao.Esquerda;
Pressionado = true;
}
else if (Comando.Comando == Keys.Right) // && UltimaDirecao != Direcao.Direita
{
Comando.Dispositivo = T_Code.Dir;
DirecaoAtual = Direcao.Direita;
Pressionado = true;
}
else if (Comando.Comando == Keys.R)
{
Comando.Dispositivo = T_Code.Dir;
DirecaoAtual = Direcao.Referenciar;
Pressionado = true;
}
// Controle dos Bicos Pulverizadores (ATU)
else if ((Comando.Comando == Keys.D1 || Comando.Comando == Keys.D2 || Comando.Comando == Keys.D3 || Comando.Comando == Keys.D4) && (Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.BicosPulverizadores?.Any(x => x?.ID == Comando.IDcontrolar && !(x?.ComandoAtuar ?? false)) ?? false))
{
Comando.Dispositivo = T_Code.Atu;
Pressionado = true;
}
// Soltar o Botão
else
{
Pressionado = false;
}
if (Pressionado)
{
Comandos.Add(Comando);
for (int i = 0; i < 1; i++)
{
switch (Comando.Dispositivo)
{
case T_Code.Mov:
{
//Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.ForEach(x => x.MovMotor.EnviarComandoControle(DirecaoAtual));
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(ForcarComando, new List<T_Code>() { Comando.Dispositivo });
break;
}
case T_Code.Dir:
{
List<string> modsControlar = null;
if (!string.IsNullOrEmpty(ID))
modsControlar = new List<string>() { ID };
if (MovimentosCombinados.Contains(Variaveis.OperacaoEmAndamento.Controle.TipoMovimento))
{
Task.Run(async () => await Variaveis.OperacaoEmAndamento.DispMvd.Dados.ExecutarMovimentoDirecionalCombinado(DirecaoAtual));
}
else if (DirecaoAtual == Direcao.Referenciar)
{
Task.Run(async () => await Variaveis.OperacaoEmAndamento.DispMvd.Dados.RealizarReferenciamentoDirecional(ModsReferenciar: modsControlar));
}
else
{
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(ForcarComando, new List<T_Code>() { Comando.Dispositivo });
//foreach (var mod in Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos)
//{
// if (modsControlar == null || modsControlar.Contains(mod.DirMotor.Mod_ID))
// {
// mod.DirMotor.EnviarComandoControle(DirecaoAtual);
//
// if (mod.MovMotor.CompensacaoNecessaria)
// {
// Direcao ultimaDirecaoMov = Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Mov)?.UltimaDirecao ?? Direcao.Parado;
// mod.MovMotor.EnviarComandoControle(ultimaDirecaoMov);
// }
// }
//};
}
break;
}
case T_Code.Atu:
{
EnviarComandoAtuador(S_Code.sBIC, Comando.IDcontrolar, Status: Comando.Comando == Keys.Escape ? false : true);
break;
}
}
//Controle = Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == Comando.Dispositivo);
//if (Controle != null)
//{
// Controle.UltimaDirecao = DirecaoAtual;
//}
}
UltimaDirecao = DirecaoAtual;
AtualizaConsole(Enum.GetName(typeof(Direcao), UltimaDirecao));
}
}
public static void EnviarComandoAtuador(S_Code Componente, string ID, bool? Status = null, List<double?> Valores = null, CanMessagePosicaoDados Comando = CanMessagePosicaoDados.Command1, bool Forcar = false)
{
var DispAtu = Variaveis.OperacaoEmAndamento.DispAtu;
var op = Variaveis.OperacaoEmAndamento;
var DispAtu = op.DispAtu;
if (!DispAtu.Dados.Conectado)
return;
if (!Forcar)
{
if (!Variaveis.OperacaoEmAndamento.Iniciado) return;
bool componente_em_uso = Variaveis.OperacaoEmAndamento.Parametros.ModulosMandatorios.Any(x => x.Dispositivo == T_Code.Atu && (x.ComponentesEmUso?.ContainsKey(ID) ?? false) && x.ComponentesEmUso[ID].Item2);
if (!op.Sensoriamento.Operacao.OperacaoIniciada) return;
bool componente_em_uso = op.Parametros.ModulosMandatorios.Any(x => x.Dispositivo == T_Code.Atu && (x.ComponentesEmUso?.ContainsKey(ID) ?? false) && x.ComponentesEmUso[ID].Item2);
if (!componente_em_uso && (Status ?? false)) return; // Impede execucao de comandos que liguem componentes quando estiver marcado para nao utilizar
}
@ -895,13 +698,15 @@ namespace AgroBase
public static void EnviarComandoSensoriamento(S_Code Componente, string ID, dynamic Status) //, bool Forcar = false
{
var DispSen = Variaveis.OperacaoEmAndamento.DispSen;
var op = Variaveis.OperacaoEmAndamento;
var DispSen = op.DispSen;
if (!DispSen.Dados.Conectado)
return;
if (false) // !Forcar
{
bool componente_em_uso = Variaveis.OperacaoEmAndamento.Parametros.ModulosMandatorios.Any(x => x.Dispositivo == T_Code.Sen && (x.ComponentesEmUso?.ContainsKey(ID) ?? false) && x.ComponentesEmUso[ID].Item2);
bool componente_em_uso = op.Parametros.ModulosMandatorios.Any(x => x.Dispositivo == T_Code.Sen && (x.ComponentesEmUso?.ContainsKey(ID) ?? false) && x.ComponentesEmUso[ID].Item2);
if (!componente_em_uso)
{
// Impede execucao de comandos que liguem componentes quando estiver marcado para nao utilizar
@ -987,14 +792,6 @@ namespace AgroBase
}
public class ComandosDispositivo
{
public DateTime Momento { get; set; }
public Keys Comando { get; set; }
public T_Code Dispositivo { get; set; }
public string IDcontrolar { get; set; }
}
public class DeParaComandos
{
public BotoesJoystick botaoJoy { get; set; }
@ -1009,11 +806,13 @@ namespace AgroBase
public void CalcularValor(bool solto, double? valorJoy = null, double? valorDesejado = null)
{
var op = Variaveis.OperacaoEmAndamento;
double centro = 32767.0;
double deadzone = 3000.0;
var pControle = Variaveis.OperacaoEmAndamento.Parametros.Controle;
var controle = Variaveis.OperacaoEmAndamento.Controle;
var pControle = op.Parametros.Controle;
var controle = op.Controle;
if (pControle == null || controle == null) return;

View File

@ -146,7 +146,7 @@ namespace AgroBase.Models
}
catch (Exception ex)
{
Console.WriteLine($"Erro ao atualizar dados do grafico: {ex.Message}");
Variaveis.MostrarLog($"[GraficoInterativoModel.AtualizarDados] Erro ao atualizar dados do grafico: {ex.Message}");
}
}

View File

@ -92,6 +92,8 @@ public class MPCController
public async Task<MPCComandoModel> Compute(double _lat, double _long, double _theta, double _velocidadeMs)
{
var op = Variaveis.OperacaoEmAndamento;
DateTime EnviadoEm = DateTime.Now;
double taxaHz = GPSService.TaxaAmostragemHz; // ex: 10 Hz
@ -101,7 +103,7 @@ public class MPCController
_dt = (EnviadoEm - _ultimaAtualizacao).TotalSeconds;
double dtCalc = Math.Max(tempoMinimo, Math.Min(tempoMaximo, _dt));
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
var _Sensoriamento = op.Sensoriamento;
var dadosEnvio = new
{
@ -112,8 +114,8 @@ public class MPCController
dt = dtCalc,
comando_anterior = new
{
angulo = _Sensoriamento.Controle.Angulo,
tipo = _Sensoriamento.Controle.TipoMovimento,
angulo = op.Controle.Angulo,
tipo = op.Controle.TipoMovimento,
},
contexto = new
{

View File

@ -24,10 +24,12 @@ public class MPCControllerAprimorado
public MPCControllerAprimorado()
{
this.maxAnguloDirecao = Variaveis.OperacaoEmAndamento.Parametros?.Controle?.DirAnguloMaximo ?? 30.0;
var op = Variaveis.OperacaoEmAndamento;
this.maxAnguloDirecao = op.Parametros?.Controle?.DirAnguloMaximo ?? 30.0;
this.maxAngulo4Rodas = this.maxAnguloDirecao * 0.8;
this.velocidadeMin = Variaveis.OperacaoEmAndamento.Parametros?.Controle?.MovVelocidadeCErvasPercent ?? 20.0;
this.velocidadeMax = Variaveis.OperacaoEmAndamento.Parametros?.Controle?.MovVelocidadeSErvasPercent ?? 100.0;
this.velocidadeMin = op.Parametros?.Controle?.MovVelocidadeCErvasPercent ?? 20.0;
this.velocidadeMax = op.Parametros?.Controle?.MovVelocidadeSErvasPercent ?? 100.0;
}
public (double anguloControle, Enums.TipoMovimentoDirecional modo) CalcularControle(GPSModel posicalAtual, double velocidadeAtual, List<GPSModel> proximaTrajetoria, Enums.TipoMovimentoDirecional[] modosPermitidos)
@ -93,6 +95,8 @@ public class MPCControllerAprimorado
private double SimularTrajetoriaComReavaliacao(GPSModel posicaoInicial, List<GPSModel> trajeto, double anguloInicial, double anguloControleInicial, Enums.TipoMovimentoDirecional modoInicial, double velocidadeMs, double dt)
{
var op = Variaveis.OperacaoEmAndamento;
double custoTotal = 0;
GPSModel posAtual = posicaoInicial;
double anguloAtual = anguloInicial;
@ -126,14 +130,14 @@ public class MPCControllerAprimorado
double erroOri = Math.Abs(GPSUtils.CalcularDiferencaAngulo(novaPos.OrientacaoReal, orientacaoAlvo));
(GPSModel ponto, int idx) = GPSUtils.PontoMaisProximoTrechoComIndice(posAtual, trajeto);
int idxNovoPonto = Variaveis.OperacaoEmAndamento.Trajetoria.PontoAtual.idxPonto + idx;
PontoTrajetoriaModel pontoAtual = Variaveis.OperacaoEmAndamento.Trajetoria._TrajetoriaFixa[idxNovoPonto].Clone();
int idxNovoPonto = op.Trajetoria.PontoAtual.idxPonto + idx;
PontoTrajetoriaModel pontoAtual = op.Trajetoria._TrajetoriaFixa[idxNovoPonto].Clone();
int idxRuaEsquerda = Variaveis.OperacaoEmAndamento.Trajetoria._Corredores[pontoAtual.idxCorredor].idxRuaEsquerda;
double distEsq = Variaveis.OperacaoEmAndamento.Trajetoria.CalcularDistanciaLateral(true, posAtual, idxRuaEsquerda, pontoAtual.Direcao);
int idxRuaEsquerda = op.Trajetoria._Corredores[pontoAtual.idxCorredor].idxRuaEsquerda;
double distEsq = op.Trajetoria.CalcularDistanciaLateral(true, posAtual, idxRuaEsquerda, pontoAtual.Direcao);
int idxRuaDireita = Variaveis.OperacaoEmAndamento.Trajetoria._Corredores[pontoAtual.idxCorredor].idxRuaDireita;
double distDir = Variaveis.OperacaoEmAndamento.Trajetoria.CalcularDistanciaLateral(false, posAtual, idxRuaDireita, pontoAtual.Direcao);
int idxRuaDireita = op.Trajetoria._Corredores[pontoAtual.idxCorredor].idxRuaDireita;
double distDir = op.Trajetoria.CalcularDistanciaLateral(false, posAtual, idxRuaDireita, pontoAtual.Direcao);
double erroLat = Math.Abs(distEsq - distDir);

View File

@ -248,7 +248,7 @@ namespace AgroBase.Models
}
catch (Exception ex)
{
Console.WriteLine("Erro ao atualizar mapa dinamico: " + ex.Message);
Variaveis.MostrarLog("[MapaDinamicoModel.PnlZoomMapa_Paint] Erro ao atualizar mapa dinamico: " + ex.Message);
}
}
@ -329,7 +329,7 @@ namespace AgroBase.Models
}
catch (Exception ex)
{
Console.WriteLine("Erro ao atualizar mapa dinamico: " + ex.Message);
Variaveis.MostrarLog("[MapaDinamicoModel.PnlZoomMapa_Paint] Erro ao atualizar mapa dinamico: " + ex.Message);
}
}

View File

@ -151,7 +151,7 @@ namespace AgroBase.Models
}
catch (InvalidOperationException ex)
{
Console.WriteLine($"Erro ao verificar o estado do processo: {ex.Message}");
Variaveis.MostrarLog($"[MapasModel.tmrCarregamento_Tick] Erro ao verificar o estado do processo: {ex.Message}");
picLoading.Visible = false;
tmrCarregamento.Dispose();
}
@ -215,8 +215,9 @@ namespace AgroBase.Models
if (TrajetoriaMapa.Any())
{
Variaveis.OperacaoEmAndamento.Trajetoria = new TrajetoriaMapaOperacaoModel(TrajetoriaMapa);
Variaveis.OperacaoEmAndamento.Trajetoria.ProjetarTrajetoriaFixa();
var op = Variaveis.OperacaoEmAndamento;
op.Trajetoria = new TrajetoriaMapaOperacaoModel(TrajetoriaMapa);
op.Trajetoria.ProjetarTrajetoriaFixa();
}
}

View File

@ -1,5 +1,4 @@
using AgroBase.Services;
using AgroBase.Services.Operadores;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
@ -41,7 +40,7 @@ namespace AgroBase.Models.Modules
{
get
{
return HealthWorkerService.ModulosSaude.Any(x => x.modulo == Dispositivo && x.status == StatusModulo.Operante);
return Variaveis.OperacaoEmAndamento.Sensoriamento?.OperadorSaude?.ModulosSaude?.Any(x => x.modulo == Dispositivo && x.status == StatusModulo.Operante) ?? false;
}
}
public bool AtuPronto { get; set; } = false;
@ -335,80 +334,53 @@ namespace AgroBase.Models.Modules
public void AtualizarMetricasOperacao()
{
var op = Variaveis.OperacaoEmAndamento;
lock (_metricasLock)
{
long agoraTicks =
Stopwatch.GetTimestamp();
long agoraTicks = Stopwatch.GetTimestamp();
DateTime agora = DateTime.Now;
DateTime agora =
DateTime.Now;
bool operacaoConcluida =
Variaveis.OperacaoEmAndamento
.Sensoriamento != null &&
Variaveis.OperacaoEmAndamento
.Sensoriamento
.StatusOperacao ==
StatusOperacao.Concluido;
bool operacaoAtiva =
Variaveis.OperacaoEmAndamento.Iniciado &&
!operacaoConcluida;
bool operacaoConcluida = op.Sensoriamento?.Operacao?.StatusOperacaoAtual == StatusOperacao.Concluido;
bool operacaoAtiva = op.Sensoriamento?.Operacao?.OperacaoIniciada == true && !operacaoConcluida;
bool atuadorComTelemetriaRecente =
DadosLeitura != null &&
DadosLeitura.UltimoComandoRespondido != DateTime.MinValue &&
DadosLeitura
.UltimoComandoRespondido
.AddMilliseconds(TempoLimiteConexao) > agora;
DadosLeitura.UltimoComandoRespondido.AddMilliseconds(TempoLimiteConexao) > agora;
bool atuadorTemEstrutura =
(BicosPulverizadores?.Count ?? 0) > 0;
bool atuadorTemEstrutura = (BicosPulverizadores?.Count ?? 0) > 0;
bool atuadorDisponivel =
operacaoAtiva &&
atuadorTemEstrutura &&
atuadorComTelemetriaRecente;
bool pulverizadorAutomatico =
Variaveis.OperacaoEmAndamento
.Parametros?
.Controle?
.PulverizadorAutomatico
?? false;
bool pulverizadorAutomatico = op.Parametros?.Controle?.PulverizadorAutomatico ?? false;
/*
* Bicos são contabilizados pelo comando de alta resolução.
* O retorno CAN permanece sendo telemetria e diagnóstico.
*/
var bicosAtivosAgora =
atuadorDisponivel
? BicosPulverizadores
.Where(b =>
b != null &&
b.Inicializado &&
b.Comandar &&
b.ComandoAtuar)
.Select(b => b.ID_Num)
.ToHashSet()
: new HashSet<int>();
var bicosAtivosAgora = atuadorDisponivel
? BicosPulverizadores
.Where(b =>
b != null &&
b.Inicializado &&
b.Comandar &&
b.ComandoAtuar)
.Select(b => b.ID_Num)
.ToHashSet()
: new HashSet<int>();
/*
* O mesmo estado usado nas métricas governa
* abertura e fechamento dos trechos.
*/
foreach (var bico in
BicosPulverizadores ??
new List<AtuadorBicoModel>())
foreach (var bico in BicosPulverizadores ?? new List<AtuadorBicoModel>())
{
bool atuandoComandado =
bicosAtivosAgora.Contains(
bico.ID_Num
);
bico.AtualizarEstadoTrecho(
atuandoComandado
);
bool atuandoComandado = bicosAtivosAgora.Contains(bico.ID_Num);
bico.AtualizarEstadoTrecho(atuandoComandado);
}
/*
@ -432,54 +404,28 @@ namespace AgroBase.Models.Modules
.ToHashSet()
: new HashSet<int>();
double vazaoAtualMLs =
operacaoAtiva
? ObterVazaoAtualConfiavelMLs(
agora
)
: 0.0;
double tempoMovimentoAtualSeg =
Variaveis.OperacaoEmAndamento
.Sensoriamento?
.Movimentacao?
.TempoMovimentoSegs
?? 0.0;
double vazaoAtualMLs = operacaoAtiva ? ObterVazaoAtualConfiavelMLs(agora) : 0.0;
double tempoMovimentoAtualSeg = op.Sensoriamento?.Movimentacao?.TempoMovimentoSegs ?? 0.0;
if (_ultimoTickMetricas != 0)
{
double dt =
(agoraTicks -
_ultimoTickMetricas) /
(double)Stopwatch.Frequency;
double dt = (agoraTicks - _ultimoTickMetricas) / (double)Stopwatch.Frequency;
if (dt > 0 && dt <= IntervaloMaximoIntegracaoSeg)
{
double deltaMovimentoSeg = 0;
if (tempoMovimentoAtualSeg >=
_tempoMovimentoAnteriorSeg)
if (tempoMovimentoAtualSeg >= _tempoMovimentoAnteriorSeg)
{
deltaMovimentoSeg =
tempoMovimentoAtualSeg -
_tempoMovimentoAnteriorSeg;
deltaMovimentoSeg = tempoMovimentoAtualSeg - _tempoMovimentoAnteriorSeg;
}
/*
* O tempo em movimento não pode exceder
* o tempo físico do intervalo integrado.
*/
deltaMovimentoSeg =
FuncoesMatematicas.Clamp(
deltaMovimentoSeg,
0.0,
dt
);
IntegrarIntervaloAnterior(
dt,
deltaMovimentoSeg
);
deltaMovimentoSeg = FuncoesMatematicas.Clamp(deltaMovimentoSeg, 0.0, dt);
IntegrarIntervaloAnterior(dt, deltaMovimentoSeg);
}
else
{
@ -492,7 +438,7 @@ namespace AgroBase.Models.Modules
if (dt > IntervaloMaximoIntegracaoSeg)
{
Variaveis.MostrarLog("[ATU/METRICAS] Integração ignorada por dt alto: " + dt.ToString("0.000") + "s");
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Alerta, 50, "[ATU/METRICAS] Integração ignorada por dt alto: " + dt.ToString("0.000") + "s");
op.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Alerta, 50, "[ATU/METRICAS] Integração ignorada por dt alto: " + dt.ToString("0.000") + "s");
}
}
}
@ -501,20 +447,12 @@ namespace AgroBase.Models.Modules
* Contagem de atuações das bombas por borda
* do comando efetivo OFF -> ON.
*/
foreach (var bomba in
BombasPressurizadoras ??
new List<AtuadorBombaModel>())
foreach (var bomba in BombasPressurizadoras ?? new List<AtuadorBombaModel>())
{
bool estavaLigada =
_bombasAtivasIntervaloAnterior
.Contains(bomba.ID_Num);
bool estavaLigada = _bombasAtivasIntervaloAnterior.Contains(bomba.ID_Num);
bool estaLigada = bombasAtivasAgora.Contains(bomba.ID_Num);
bool estaLigada =
bombasAtivasAgora
.Contains(bomba.ID_Num);
if (!estavaLigada &&
estaLigada)
if (!estavaLigada && estaLigada)
{
bomba.Atuacoes++;
}
@ -524,43 +462,27 @@ namespace AgroBase.Models.Modules
* Atualiza o snapshot que representará
* o próximo intervalo.
*/
_ultimoTickMetricas =
agoraTicks;
_ultimoTickMetricas = agoraTicks;
_tempoMovimentoAnteriorSeg = tempoMovimentoAtualSeg;
_bicosAtivosIntervaloAnterior = bicosAtivosAgora;
_bombasAtivasIntervaloAnterior = bombasAtivasAgora;
_tempoMovimentoAnteriorSeg =
tempoMovimentoAtualSeg;
_potenciaBombasIntervaloAnterior = (BombasPressurizadoras ??
new List<AtuadorBombaModel>())
.ToDictionary(
b => b.ID_Num,
b =>
ObterPotenciaAtualConfiavelPct(
b,
agora
)
);
_bicosAtivosIntervaloAnterior =
bicosAtivosAgora;
_vazaoIntervaloAnteriorMLs = vazaoAtualMLs;
_bombasAtivasIntervaloAnterior =
bombasAtivasAgora;
AtualizarVazoesInstantaneas(bicosAtivosAgora, vazaoAtualMLs);
_potenciaBombasIntervaloAnterior =
(BombasPressurizadoras ??
new List<AtuadorBombaModel>())
.ToDictionary(
b => b.ID_Num,
b =>
ObterPotenciaAtualConfiavelPct(
b,
agora
)
);
_vazaoIntervaloAnteriorMLs =
vazaoAtualMLs;
AtualizarVazoesInstantaneas(
bicosAtivosAgora,
vazaoAtualMLs
);
VazaoMediaMLs =
TempoAtuado > 0
? VolumeVazadoML /
TempoAtuado
: 0;
VazaoMediaMLs = TempoAtuado > 0 ? VolumeVazadoML / TempoAtuado : 0;
AtualizaPercentualErvas();
}
@ -568,13 +490,12 @@ namespace AgroBase.Models.Modules
private void IntegrarIntervaloAnterior(double dt, double tempoMovimentoIntervaloSeg)
{
var bicosDoIntervalo =
(BicosPulverizadores ??
new List<AtuadorBicoModel>())
.Where(b =>
_bicosAtivosIntervaloAnterior
.Contains(b.ID_Num))
.ToList();
var bicosDoIntervalo = (BicosPulverizadores ??
new List<AtuadorBicoModel>())
.Where(b =>
_bicosAtivosIntervaloAnterior
.Contains(b.ID_Num))
.ToList();
/*
* Tempo geral de pulverização:
@ -585,32 +506,22 @@ namespace AgroBase.Models.Modules
{
TempoAtuado += dt;
foreach (var bico in
bicosDoIntervalo)
foreach (var bico in bicosDoIntervalo)
{
bico.TempoAtuado += dt;
bico.TempoAtuadoEmMovimento +=
tempoMovimentoIntervaloSeg;
bico.TempoAtuadoEmMovimento += tempoMovimentoIntervaloSeg;
}
double vazaoTotalMLs =
Math.Max(
0,
_vazaoIntervaloAnteriorMLs
);
double vazaoTotalMLs = Math.Max(0, _vazaoIntervaloAnteriorMLs);
if (vazaoTotalMLs > 0)
{
double volumeIntervaloML =
vazaoTotalMLs * dt;
double volumeIntervaloML = vazaoTotalMLs * dt;
VolumeVazadoML +=
volumeIntervaloML;
VolumeVazadoML += volumeIntervaloML;
double volumePorBicoML =
volumeIntervaloML /
bicosDoIntervalo.Count;
double volumePorBicoML = volumeIntervaloML / bicosDoIntervalo.Count;
foreach (var bico in bicosDoIntervalo)
{
@ -624,14 +535,9 @@ namespace AgroBase.Models.Modules
* não existe fluxo. O tempo continua crescendo,
* logo a média operacional deve diminuir.
*/
foreach (var bico in
bicosDoIntervalo)
foreach (var bico in bicosDoIntervalo)
{
bico.VazaoMediaMLs =
bico.TempoAtuado > 0
? bico.VolumeVazadoML /
bico.TempoAtuado
: 0;
bico.VazaoMediaMLs = bico.TempoAtuado > 0 ? bico.VolumeVazadoML / bico.TempoAtuado : 0;
}
}
@ -640,32 +546,27 @@ namespace AgroBase.Models.Modules
* TempoAtuado é baseado no comando efetivo.
* TempoComPotencia usa telemetria CAN recente.
*/
foreach (var bomba in
BombasPressurizadoras ??
new List<AtuadorBombaModel>())
foreach (var bomba in BombasPressurizadoras ?? new List<AtuadorBombaModel>())
{
if (!_bombasAtivasIntervaloAnterior
.Contains(bomba.ID_Num))
if (!_bombasAtivasIntervaloAnterior.Contains(bomba.ID_Num))
{
continue;
}
bomba.TempoAtuado += dt;
double potencia =
_potenciaBombasIntervaloAnterior
.TryGetValue(
bomba.ID_Num,
out double valorPotencia)
? valorPotencia
: 0;
double potencia = _potenciaBombasIntervaloAnterior
.TryGetValue(
bomba.ID_Num,
out double valorPotencia)
? valorPotencia
: 0;
if (potencia > 0)
{
bomba.TempoComPotencia += dt;
bomba.PotenciaAcumuladaPctSeg +=
potencia * dt;
bomba.PotenciaAcumuladaPctSeg += potencia * dt;
}
/*
@ -673,11 +574,7 @@ namespace AgroBase.Models.Modules
* o denominador deve ser o período com
* potência efetivamente observada.
*/
bomba.PotenciaMediaAtiva =
bomba.TempoComPotencia > 0
? bomba.PotenciaAcumuladaPctSeg /
bomba.TempoComPotencia
: 0;
bomba.PotenciaMediaAtiva = bomba.TempoComPotencia > 0 ? bomba.PotenciaAcumuladaPctSeg / bomba.TempoComPotencia : 0;
}
}
@ -704,23 +601,16 @@ namespace AgroBase.Models.Modules
private void AtualizaPercentualErvas()
{
double tempoMovimentoSeg =
Variaveis.OperacaoEmAndamento
.Sensoriamento?
.Movimentacao?
.TempoMovimentoSegs
?? 0;
var op = Variaveis.OperacaoEmAndamento;
var bicosConsiderados =
BicosPulverizadores?
.Where(b =>
b != null &&
b.Comandar)
.ToList()
?? new List<AtuadorBicoModel>();
double tempoMovimentoSeg = op.Sensoriamento?.Movimentacao?.TempoMovimentoSegs ?? 0;
if (tempoMovimentoSeg <= 0 ||
bicosConsiderados.Count == 0)
var bicosConsiderados = BicosPulverizadores?
.Where(b => b != null && b.Comandar)
.ToList()
?? new List<AtuadorBicoModel>();
if (tempoMovimentoSeg <= 0 || bicosConsiderados.Count == 0)
{
PercentualErvasTerreno = 0;
return;
@ -730,38 +620,19 @@ namespace AgroBase.Models.Modules
* Soma somente atuação ocorrida enquanto
* o rover acumulava tempo de movimento.
*/
double somaBicoSegEmMovimento =
bicosConsiderados.Sum(
b => b.TempoAtuadoEmMovimento
);
double somaBicoSegEmMovimento = bicosConsiderados.Sum(b => b.TempoAtuadoEmMovimento);
/*
* Capacidade total:
* tempo de movimento x quantidade de regiões/bicos.
*/
double capacidadeTotalBicoSeg =
tempoMovimentoSeg *
bicosConsiderados.Count;
double capacidadeTotalBicoSeg = tempoMovimentoSeg * bicosConsiderados.Count;
double percentual =
capacidadeTotalBicoSeg > 0
? somaBicoSegEmMovimento /
capacidadeTotalBicoSeg *
100.0
: 0;
double percentual = capacidadeTotalBicoSeg > 0 ? somaBicoSegEmMovimento / capacidadeTotalBicoSeg * 100.0 : 0;
percentual =
FuncoesMatematicas.Clamp(
percentual,
0.0,
100.0
);
percentual = FuncoesMatematicas.Clamp(percentual, 0.0, 100.0);
PercentualErvasTerreno =
Math.Round(
percentual,
2
);
PercentualErvasTerreno = Math.Round(percentual, 2);
}
private void ZerarVazoesInstantaneas()
@ -1215,8 +1086,8 @@ namespace AgroBase.Models.Modules
{
Modo = ModoControleBomba.PID,
PotenciaMinPID = 40,
Kp = 6.0,
Ki = 0.2,
Kp = 1.10,
Ki = 0.12,
Kd = 0.0,
}
},
@ -1434,12 +1305,10 @@ namespace AgroBase.Models.Modules
private void PrepararAtuadorParaOperacao(AtuadorModel Dados, bool resetarComandos)
{
var op = Variaveis.OperacaoEmAndamento;
var dadosAtuador = Dados;
var controle =
Variaveis
.OperacaoEmAndamento
.Parametros?
.Controle;
var controle = op.Parametros?.Controle;
if (dadosAtuador == null || controle == null)
return;
@ -1478,16 +1347,13 @@ namespace AgroBase.Models.Modules
public void SincronizarBombaPressurizadoraAutomatica(bool forcar = false)
{
var operacao = Variaveis.OperacaoEmAndamento;
var op = Variaveis.OperacaoEmAndamento;
var controle =
operacao?
.Parametros?
.Controle;
var controle = op?.Parametros?.Controle;
var bomba = BombaPressurizadora;
if (operacao == null || controle == null || bomba == null || !bomba.Inicializado)
if (op == null || controle == null || bomba == null || !bomba.Inicializado)
return;
bool pulverizadorAutomatico = controle.PulverizadorAutomatico;
@ -1495,14 +1361,14 @@ namespace AgroBase.Models.Modules
if (!pulverizadorAutomatico)
return;
bool operacaoConcluida = operacao.Sensoriamento?.StatusOperacao == StatusOperacao.Concluido;
bool operacaoConcluida = op.Sensoriamento?.Operacao?.StatusOperacaoAtual == StatusOperacao.Concluido;
bool atuacaoPermitida =
operacao.Iniciado &&
!operacao.Finalizando &&
!operacao.Emergencia &&
op.Sensoriamento.Operacao.OperacaoIniciada &&
!op.Sensoriamento.Operacao.Finalizando &&
!op.Sensoriamento.Operacao.Emergencia &&
!operacaoConcluida &&
!operacao.Pausa;
!op.Sensoriamento.Operacao.Pausa;
/*
* Reaplica setpoints sempre antes de sincronizar.
@ -1522,45 +1388,19 @@ namespace AgroBase.Models.Modules
*/
bomba.ComandoAtuar = statusDesejado;
double potenciaEfetiva =
statusDesejado
? bomba.PotenciaSP
: 0;
double potenciaEfetiva = statusDesejado ? bomba.PotenciaSP : 0;
double pressaoEfetiva =
bomba.Sensor_ID_Num > -1
? (
statusDesejado
? bomba.PressaoSP
: 0
)
: bomba.PressaoSP;
double pressaoEfetiva = bomba.Sensor_ID_Num > -1 ? (statusDesejado ? bomba.PressaoSP : 0) : bomba.PressaoSP;
Estado estadoDesejado =
statusDesejado
? Estado.Ligado
: Estado.Desligado;
Estado estadoDesejado = statusDesejado ? Estado.Ligado : Estado.Desligado;
bool estadoDivergente =
estadoDesejado != bomba._EstadoLeitura;
bool estadoDivergente = estadoDesejado != bomba._EstadoLeitura;
bool potenciaDivergente =
Math.Abs(
bomba._PotenciaSP -
potenciaEfetiva
) > 1.0;
bool potenciaDivergente = Math.Abs(bomba._PotenciaSP - potenciaEfetiva) > 1.0;
bool pressaoDivergente =
bomba.Sensor_ID_Num > -1 &&
Math.Abs(
bomba._PressaoSP -
pressaoEfetiva
) > 0.05;
bool pressaoDivergente = bomba.Sensor_ID_Num > -1 && Math.Abs(bomba._PressaoSP - pressaoEfetiva) > 0.05;
if (forcar ||
estadoDivergente ||
potenciaDivergente ||
pressaoDivergente)
if (forcar || estadoDivergente || potenciaDivergente || pressaoDivergente)
{
EnviarComandoFisicoBomba(
bomba,
@ -1573,22 +1413,24 @@ namespace AgroBase.Models.Modules
public async Task<bool> VerificaDispositivoConectado()
{
var op = Variaveis.OperacaoEmAndamento;
if (!CanManager.CanService.IsConnected) return false;
if (Variaveis.OperacaoEmAndamento.DispAtu == null) return false;
if (op.DispAtu == null) return false;
CanManager.CanService.RegistrarHandler(_EnderecoCAN_Rx, _AtuHandler);
RequisitarDadosDescoberta();
DateTime Inicio = DateTime.Now;
bool Respondido() => Variaveis.OperacaoEmAndamento.DispAtu.Dados.DadosLeitura.UltimoComandoRespondido > Inicio;
bool Respondido() => op.DispAtu.Dados.DadosLeitura.UltimoComandoRespondido > Inicio;
await FuncoesGlobais.AguardarCondicaoAsync(Respondido, 500, 50);
if (Conectado)
{
DefinirDispositivo();
Variaveis.OperacaoEmAndamento.DispAtu?.EnviarProtocolosConfiguracao();
op.DispAtu?.EnviarProtocolosConfiguracao();
}
return Conectado;
@ -1596,6 +1438,8 @@ namespace AgroBase.Models.Modules
private void DefinirDispositivo()
{
var op = Variaveis.OperacaoEmAndamento;
if (!SerialService.DispositivosMapeados.Any(x => x.Dispositivo == Dispositivo && x.Mod_ID == Modulo_ID))
{
SerialService.DispositivosMapeados.Add(new DispositivoDetalhesModel()
@ -1606,8 +1450,8 @@ namespace AgroBase.Models.Modules
Mod_ID = Modulo_ID
});
Variaveis.OperacaoEmAndamento.ModsCalibragem[Dispositivo] = new Dictionary<string, bool>();
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Conectado, 0, "Dispositivo conectado");
op.Sensoriamento.Operacao.ModsCalibragem[Dispositivo] = new Dictionary<string, bool>();
op.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Conectado, 0, "Dispositivo conectado");
}
}
@ -1760,13 +1604,15 @@ namespace AgroBase.Models.Modules
public async Task tmrRegistrador_Tick()
{
var op = Variaveis.OperacaoEmAndamento;
if (Variaveis.Fechando) return;
tmrRegistrador.SetInterval(_TaxaAmostragem);
if (SerialService.DispositivosMapeados.Any(x => x.Dispositivo == T_Code.Atu) && (_VezesLeituraReconexao >= _TempoReconexaoComponentes))
if (SerialService.DispositivosMapeados.Any(x => x.Dispositivo == Dispositivo) && (_VezesLeituraReconexao >= _TempoReconexaoComponentes))
{
Variaveis.OperacaoEmAndamento.DispAtu?.EnviarProtocolosConfiguracao();
op.DispAtu?.EnviarProtocolosConfiguracao();
_VezesLeituraReconexao = 0;
}
@ -1792,23 +1638,16 @@ namespace AgroBase.Models.Modules
if (Variaveis.Fechando)
return;
var operacao = Variaveis.OperacaoEmAndamento;
var op = Variaveis.OperacaoEmAndamento;
if (operacao?.DispAtu?.Dados?.Conectado != true)
if (op?.DispAtu?.Dados?.Conectado != true)
return;
bool operacaoConcluida =
operacao.Sensoriamento?.StatusOperacao ==
StatusOperacao.Concluido;
bool operacaoConcluida = op.Sensoriamento?.Operacao?.StatusOperacaoAtual == StatusOperacao.Concluido;
bool pulverizadorAutomatico =
operacao.Parametros?
.Controle?
.PulverizadorAutomatico
?? false;
bool pulverizadorAutomatico = op.Parametros?.Controle?.PulverizadorAutomatico ?? false;
bool calibrando =
operacao.Calibrando;
bool calibrando = op.Sensoriamento?.Operacao?.Calibrando == true;
/*
* Bloqueios absolutos.
@ -1818,9 +1657,9 @@ namespace AgroBase.Models.Modules
* operação ter sido encerrada.
*/
bool bloqueioGeral =
!operacao.Iniciado ||
operacao.Finalizando ||
operacao.Emergencia ||
!op.Sensoriamento.Operacao.OperacaoIniciada ||
op.Sensoriamento.Operacao.Finalizando ||
op.Sensoriamento.Operacao.Emergencia ||
operacaoConcluida;
/*
@ -1828,12 +1667,7 @@ namespace AgroBase.Models.Modules
* Portanto, a pausa somente bloqueia atuação fora
* da calibração.
*/
bool atuacaoPermitida =
!bloqueioGeral &&
(
!operacao.Pausa ||
calibrando
);
bool atuacaoPermitida = !bloqueioGeral && (!op.Sensoriamento.Operacao.Pausa || calibrando);
/*
* BICOS
@ -1843,21 +1677,10 @@ namespace AgroBase.Models.Modules
*
* Este método apenas calcula o comando físico.
*/
foreach (
var bico in
BicosPulverizadores
.Where(x =>
x != null &&
x.Inicializado)
)
foreach (var bico in BicosPulverizadores.Where(x => x != null && x.Inicializado))
{
bool comandoSolicitado =
bico.Comandar &&
bico.ComandoAtuar;
bool statusDesejado =
comandoSolicitado &&
atuacaoPermitida;
bool comandoSolicitado = bico.Comandar && bico.ComandoAtuar;
bool statusDesejado = comandoSolicitado && atuacaoPermitida;
/*
* Fora da calibração, a pulverização automática
@ -1866,43 +1689,24 @@ namespace AgroBase.Models.Modules
* Durante a calibração, permite o pulso de teste
* explicitamente solicitado pelo método de calibração.
*/
if (
pulverizadorAutomatico &&
!calibrando
)
if (pulverizadorAutomatico && !calibrando)
{
statusDesejado &=
ContadorCarga.PulverizadorLiberado;
statusDesejado &= ContadorCarga.PulverizadorLiberado;
}
Estado estadoDesejado =
statusDesejado
? Estado.Ligado
: Estado.Desligado;
Estado estadoDesejado = statusDesejado ? Estado.Ligado : Estado.Desligado;
double anguloDesejado =
statusDesejado
? bico.AnguloControle
: bico.AnguloNeutro;
double anguloDesejado = statusDesejado ? bico.AnguloControle : bico.AnguloNeutro;
bool estadoDivergente =
estadoDesejado !=
bico._EstadoLeitura;
bool estadoDivergente = estadoDesejado != bico._EstadoLeitura;
/*
* Verifica o ângulo também quando desligado,
* para garantir o retorno à posição neutra.
*/
bool anguloDivergente =
Math.Abs(
anguloDesejado -
bico._AnguloBicoLeitura
) > 1.0;
bool anguloDivergente = Math.Abs(anguloDesejado - bico._AnguloBicoLeitura) > 1.0;
if (
estadoDivergente ||
anguloDivergente
)
if (estadoDivergente || anguloDivergente)
{
EnviarComandoFisicoBico(
bico,
@ -1915,21 +1719,11 @@ namespace AgroBase.Models.Modules
/*
* BOMBAS
*/
foreach (
var bomba in
BombasPressurizadoras
.Where(x =>
x != null &&
x.Inicializado)
)
foreach (var bomba in BombasPressurizadoras.Where(x => x != null && x.Inicializado))
{
bool ehBombaPrincipal =
bomba.ID ==
BombaPressurizadora?.ID;
bool ehBombaPrincipal = bomba.ID == BombaPressurizadora?.ID;
bool comandoSolicitado =
bomba.Comandar &&
bomba.ComandoAtuar;
bool comandoSolicitado = bomba.Comandar && bomba.ComandoAtuar;
bool statusDesejado;
@ -1942,9 +1736,7 @@ namespace AgroBase.Models.Modules
*/
if (calibrando)
{
statusDesejado =
comandoSolicitado &&
atuacaoPermitida;
statusDesejado = comandoSolicitado && atuacaoPermitida;
}
/*
* Fora da calibração, a bomba principal automática
@ -1955,10 +1747,7 @@ namespace AgroBase.Models.Modules
*/
else if (ehBombaPrincipal && pulverizadorAutomatico)
{
statusDesejado =
bomba.Comandar &&
atuacaoPermitida &&
ContadorCarga.PulverizadorLiberado;
statusDesejado = bomba.Comandar && atuacaoPermitida && ContadorCarga.PulverizadorLiberado;
/*
* Mantém o modelo coerente com o comando automático.
@ -1975,15 +1764,10 @@ namespace AgroBase.Models.Modules
*/
else
{
statusDesejado =
comandoSolicitado &&
atuacaoPermitida;
statusDesejado = comandoSolicitado && atuacaoPermitida;
}
Estado estadoDesejado =
statusDesejado
? Estado.Ligado
: Estado.Desligado;
Estado estadoDesejado = statusDesejado ? Estado.Ligado : Estado.Desligado;
/*
* Valores efetivamente enviados ao hardware.
@ -1991,19 +1775,13 @@ namespace AgroBase.Models.Modules
* Os setpoints armazenados no modelo não são
* alterados quando existir um bloqueio temporário.
*/
double potenciaEfetiva =
statusDesejado
? bomba.PotenciaSP
: 0;
double potenciaEfetiva = statusDesejado ? bomba.PotenciaSP : 0;
double pressaoEfetiva;
if (bomba.Sensor_ID_Num > -1)
{
pressaoEfetiva =
statusDesejado
? bomba.PressaoSP
: 0;
pressaoEfetiva = statusDesejado ? bomba.PressaoSP : 0;
}
else
{
@ -2011,32 +1789,16 @@ namespace AgroBase.Models.Modules
* Mantém -1 como marcador de bomba sem
* sensor de pressão, como o agitador.
*/
pressaoEfetiva =
bomba.PressaoSP;
pressaoEfetiva = bomba.PressaoSP;
}
bool estadoDivergente =
estadoDesejado !=
bomba._EstadoLeitura;
bool estadoDivergente = estadoDesejado != bomba._EstadoLeitura;
bool potenciaDivergente =
Math.Abs(
bomba._PotenciaSP -
potenciaEfetiva
) > 1.0;
bool potenciaDivergente = Math.Abs(bomba._PotenciaSP - potenciaEfetiva) > 1.0;
bool pressaoDivergente =
bomba.Sensor_ID_Num > -1 &&
Math.Abs(
bomba._PressaoSP -
pressaoEfetiva
) > 0.05;
bool pressaoDivergente = bomba.Sensor_ID_Num > -1 && Math.Abs(bomba._PressaoSP - pressaoEfetiva) > 0.05;
if (
estadoDivergente ||
potenciaDivergente ||
pressaoDivergente
)
if (estadoDivergente || potenciaDivergente || pressaoDivergente)
{
EnviarComandoFisicoBomba(
bomba,
@ -2127,7 +1889,9 @@ namespace AgroBase.Models.Modules
private async Task<bool> RealizarTestesIniciais(bool forcar)
{
var calAtu = Variaveis.OperacaoEmAndamento.ModsCalibragem[Dispositivo];
var op = Variaveis.OperacaoEmAndamento;
var calAtu = op.Sensoriamento.Operacao.ModsCalibragem[Dispositivo];
// Ligar bomba
foreach (var Bomba in BombasPressurizadoras.Where(x => x.Comandar))
@ -2141,29 +1905,29 @@ namespace AgroBase.Models.Modules
if (!Bomba.Inicializado || ContadorCarga.PercentualAtual < VariaveisEquipamento.PercentualReservatorioMin)
{
Variaveis.MostrarLog($"[AtuadorModel] [RealizarTestesIniciais] Bomba não iniciada ou nível do reservatório baixo, não irá ligar a bomba {Bomba.ID}");
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Alerta, 50, $"Bomba não iniciada ou nível do reservatório baixo, não irá ligar a bomba {Bomba.ID}", id: Bomba.ID);
op.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Alerta, 50, $"Bomba não iniciada ou nível do reservatório baixo, não irá ligar a bomba {Bomba.ID}", id: Bomba.ID);
continue;
}
Bomba.PotenciaSP = 100;
if (Bomba.ID == BombaPressurizadora.ID)
{
Bomba.Controle.Modo = Variaveis.OperacaoEmAndamento.Parametros.Controle.AtuModoControle;
Bomba.PressaoSP = Variaveis.OperacaoEmAndamento.Parametros.Controle.AtuPressaoLinha;
Bomba.Controle.Modo = op.Parametros.Controle.AtuModoControle;
Bomba.PressaoSP = op.Parametros.Controle.AtuPressaoLinha;
GeneralJoystick.EnviarComandoAtuador(Bomba.Componente, Bomba.ID, Status: true, Valores: new List<double?>() { (int)Bomba.Controle.Modo, Bomba.Controle.PotenciaMinPID, Bomba.Controle.Kp, Bomba.Controle.Ki, Bomba.Controle.Kd }, Comando: CanMessagePosicaoDados.Command2, Forcar: true);
GeneralJoystick.EnviarComandoAtuador(Bomba.Componente, Bomba.ID, Status: true, Valores: new List<double?>() { Bomba.PotenciaSP, Bomba.PressaoSP }, Comando: CanMessagePosicaoDados.Command1, Forcar: true);
}
else
{
Bomba.PressaoSP = -1;
bool ligar = Variaveis.OperacaoEmAndamento.Parametros.Controle.AtuAgitadorModo != ModoAgitadorCalda.SemAgitacao;
bool ligar = op.Parametros.Controle.AtuAgitadorModo != ModoAgitadorCalda.SemAgitacao;
GeneralJoystick.EnviarComandoAtuador(Bomba.Componente, Bomba.ID, Status: ligar, Valores: new List<double?>() { Bomba.PotenciaSP, Bomba.PressaoSP }, Comando: CanMessagePosicaoDados.Command1, Forcar: true);
}
if (Bomba.Sensor_ID_Num == -1)
{
Variaveis.MostrarLog($"[AtuadorModel] [RealizarTestesIniciais] Bomba {Bomba.ID} não possui um sensor de pressão, será controlada mecanicamente pelo pressostato");
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Alerta, 50, $"Bomba {Bomba.ID} não possui um sensor de pressão, será controlada mecanicamente pelo pressostato", id: Bomba.ID);
op.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Alerta, 50, $"Bomba {Bomba.ID} não possui um sensor de pressão, será controlada mecanicamente pelo pressostato", id: Bomba.ID);
calAtu[Bomba.ID] = true;
continue;
}
@ -2227,22 +1991,24 @@ namespace AgroBase.Models.Modules
public List<Task> RealizarCalibragemAsync(bool forcar)
{
var op = Variaveis.OperacaoEmAndamento;
List<Task> tasks = new List<Task>();
var DispAtu = Variaveis.OperacaoEmAndamento.DispAtu;
var DispAtu = op.DispAtu;
if (DispAtu != null)
{
tasks.Add(DispAtu.Dados.RealizarTestesIniciais(forcar).ContinueWith(t => {
if (t.IsFaulted)
{
Variaveis.MostrarLog($"[AtuadorModel] [RealizarCalibragemAsync] Erro no referenciamento do módulo {Modulo_ID}: {t.Exception?.InnerException?.Message}");
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Falha, 0, $"Erro no referenciamento do módulo {Modulo_ID}: {t.Exception?.InnerException?.Message}");
op.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Falha, 0, $"Erro no referenciamento do módulo {Modulo_ID}: {t.Exception?.InnerException?.Message}");
}
if (t.IsCompleted)
{
var calAtu = Variaveis.OperacaoEmAndamento.ModsCalibragem[Dispositivo];
var calAtu = op.Sensoriamento.Operacao.ModsCalibragem[Dispositivo];
var v = calAtu.Select(x => $"{x.Key} " + (x.Value ? "Sim" : "Não"));
Variaveis.MostrarLog($"[AtuadorModel] [RealizarCalibragemAsync] Task de referenciamento do módulo {Modulo_ID} finalizada: " + string.Join(", ", v));
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Operante, 100, $"Task de referenciamento do módulo {Modulo_ID} finalizada: " + string.Join(", ", v));
op.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Operante, 100, $"Task de referenciamento do módulo {Modulo_ID} finalizada: " + string.Join(", ", v));
}
}));
@ -2437,7 +2203,8 @@ namespace AgroBase.Models.Modules
}
}
public void ReiniciarHistoricoAtuacao(bool limparTrechos = true) {
public void ReiniciarHistoricoAtuacao(bool limparTrechos = true)
{
lock (_trechosLock)
{
_trechoAtivo = null;
@ -2712,7 +2479,7 @@ namespace AgroBase.Models.Modules
public class AtuadorFuncoesGerais
{
public static void DesenharAtuadores(object sender, PaintEventArgs e, List<AtuBicoSensoriamentoLogModel> Bicos, bool BombaLigada, double PressaoLinha, double TempoBombaAtuada)
public static void DesenharAtuadores(object sender, PaintEventArgs e, List<AtuadorBicoLogModel> Bicos, bool BombaLigada, double PressaoLinha, double TempoBombaAtuada)
{
Panel myPanel = (Panel)sender;

View File

@ -289,11 +289,13 @@ namespace AgroBase.Models.Modules
public void EnviarComandoControle(Direcao Direcao)
{
var _Simulando = Variaveis.OperacaoEmAndamento.Simulando;
var op = Variaveis.OperacaoEmAndamento;
var _Simulando = op.Simulando;
if ((Inicializado && (Comandar || !AtingiuAnguloSP)) || _Simulando)
{
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
var _Controle = op.Controle;
int AnguloTipoMovimento = VariaveisEquipamento.AnguloMovimento[_Controle.TipoMovimento];
if (!Comandar)
@ -332,7 +334,7 @@ namespace AgroBase.Models.Modules
if (Comandar)
{
Variaveis.OperacaoEmAndamento.SimulacaoAnguloControle = Variaveis.OperacaoEmAndamento.Controle.Angulo;
op.SimulacaoAnguloControle = op.Controle.Angulo;
//Console.WriteLine($"[{Mod_ID}] Angulo Atualizado para {Variaveis.OperacaoEmAndamento.SimulacaoAnguloControle}");
}
@ -353,6 +355,8 @@ namespace AgroBase.Models.Modules
public async Task ReferenciaMotor()
{
var op = Variaveis.OperacaoEmAndamento;
if (Referenciando || !Inicializado) return;
Referenciando = true;
@ -376,12 +380,12 @@ namespace AgroBase.Models.Modules
{
await SetZero();
Variaveis.MostrarLog($"[DirecionalModel] [ReferenciaMotor] [DIR {Mod_ID}] - Referenciamento Concluído!");
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(T_Code.Dir, StatusModulo.Operante, 100, $"Referenciamento Concluído!", id: Mod_ID);
op.Sensoriamento.InserirLog(T_Code.Dir, StatusModulo.Operante, 100, $"Referenciamento Concluído!", id: Mod_ID);
}
else
{
Variaveis.MostrarLog($"[DirecionalModel] [ReferenciaMotor] [DIR {Mod_ID}] - Referenciamento Falhou!");
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(T_Code.Dir, StatusModulo.Falha, 0, $"Referenciamento Falhou!", id: Mod_ID);
op.Sensoriamento.InserirLog(T_Code.Dir, StatusModulo.Falha, 0, $"Referenciamento Falhou!", id: Mod_ID);
}
Referenciando = false;

View File

@ -10,6 +10,8 @@ namespace AgroBase.Models.Modules
{
public class ModuloIMUModel
{
public DateTime Momento { get; set; }
// ============================================================
// Estado geral
// ============================================================

View File

@ -205,7 +205,9 @@ namespace AgroBase.Models.Modules
{
if (ComandoLigado)
{
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
var op = Variaveis.OperacaoEmAndamento;
var _Controle = op.Controle;
var _ControleDir = _Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Dir);
bool movimentoCompensado =
@ -213,7 +215,7 @@ namespace AgroBase.Models.Modules
(_Controle.TipoMovimento == TipoMovimentoDirecional.RodasDianteiras && Mod_ID.Contains("F")) ||
(_Controle.TipoMovimento == TipoMovimentoDirecional.RodasTraseiras && Mod_ID.Contains("T"));
bool emCurva = _ControleDir.UltimaDirecao != Direcao.Parado;
double anguloDir = Math.Abs(Variaveis.OperacaoEmAndamento.DispMvd?.Dados?.Modulos?.FirstOrDefault(x => x.Modulo_ID == Mod_ID)?.DirMotor?.Angulo_SP ?? 0);
double anguloDir = Math.Abs(op.DispMvd?.Dados?.Modulos?.FirstOrDefault(x => x.Modulo_ID == Mod_ID)?.DirMotor?.Angulo_SP ?? 0);
bool direcionalAtuado = anguloDir > 0.0;
if (movimentoCompensado && emCurva && direcionalAtuado)
@ -261,7 +263,6 @@ namespace AgroBase.Models.Modules
public List<FuncoesPinout> Funcoes { get; set; }
public List<MvdMotorMOVSensorimanetoGrafico> LogGrafico { get; set; } = new List<MvdMotorMOVSensorimanetoGrafico>();
public List<AlarmeModel> Alarmes { get; set; } = new List<AlarmeModel>();
public MvdServoFreioModel ConfigFreio { get; set; }
@ -380,13 +381,15 @@ namespace AgroBase.Models.Modules
public void EnviarComandoControle(Direcao DirecaoAtual)
{
var simulando = Variaveis.OperacaoEmAndamento.Simulando || Variaveis.OperacaoEmAndamento.Treinando;
var op = Variaveis.OperacaoEmAndamento;
var simulando = op.Simulando || op.Treinando;
bool Freado = DirecaoAtual == Direcao.EmFreio;
if ((Comandar && Inicializado) || simulando)
{
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
var _Controle = op.Controle;
if (AlarmeSensores || AlarmeMotor)
{
@ -404,7 +407,7 @@ namespace AgroBase.Models.Modules
RPM_SP = Math.Abs(RpmCorrigido);
FatorCompensacaoCurvasAnterior = FatorCompensacaoCurvas;
Variaveis.OperacaoEmAndamento.SimulacaoRpmControle = _Controle.PercentualVelocidadeSP;
op.SimulacaoRpmControle = _Controle.PercentualVelocidadeSP;
//Console.WriteLine($"RPM Atualizado para {Variaveis.OperacaoEmAndamento.SimulacaoRpmControle}");
switch (DirecaoAtual)
@ -517,7 +520,7 @@ namespace AgroBase.Models.Modules
public int DelayEnvio { get; set; } = 500;
public SensorServoModel Servo => Variaveis.OperacaoEmAndamento.DispSen?.Dados?.Servos?.FirstOrDefault(x => x.Inicializado && x.ID.Contains(Mod_ID));
private double VelocidadeAtual => FuncoesMatematicas.CalculaVelocidadePercentualMs(Variaveis.OperacaoEmAndamento.Sensoriamento?.Movimentacao?.VelocidadeMedia ?? 0);
private double VelocidadeAtual => FuncoesMatematicas.CalculaVelocidadePercentualMs(Variaveis.OperacaoEmAndamento.Sensoriamento?.Movimentacao?.VelocidadeMediaMs ?? 0);
private bool StatusControleEmFreio => Variaveis.OperacaoEmAndamento.DispMvd?.Dados?.Modulos?.FirstOrDefault(x => x.Modulo_ID == Mod_ID)?.MovMotor?.Leitura?.Freado ?? false;
private int? AnguloLido => (int?)Servo?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.ServoAnguloLeitura)?.atual?.valor;
@ -671,9 +674,11 @@ namespace AgroBase.Models.Modules
public static void AtualizarDados()
{
var ctrl = Variaveis.OperacaoEmAndamento?.Controle;
var disp = Variaveis.OperacaoEmAndamento?.DispMvd?.Dados?.Modulos;
if (Variaveis.OperacaoEmAndamento.StatusAtual != StatusOperacao.EmAndamento || ctrl == null || disp == null || !MovimentosCompensar.Contains(ctrl.TipoMovimento))
var op = Variaveis.OperacaoEmAndamento;
var ctrl = op.Controle;
var disp = op.DispMvd?.Dados?.Modulos;
if (op.Sensoriamento?.Operacao?.StatusOperacaoAtual != StatusOperacao.EmAndamento || ctrl == null || disp == null || !MovimentosCompensar.Contains(ctrl.TipoMovimento))
{
compensacoes = (disp ?? Enumerable.Empty<ModuloMvdModel>()).ToDictionary(x => x.Modulo_ID, x => 1.0);
return;

View File

@ -212,14 +212,15 @@ namespace AgroBase.Models.Modules
public async Task tmrRegistrador_Tick()
{
var op = Variaveis.OperacaoEmAndamento;
tmrRegistrador.SetInterval(_TaxaAmostragem);
if (!Variaveis.OperacaoEmAndamento.Simulando)
if (!op.Simulando)
{
VelocidadeMedia = FuncoesMatematicas.ConverteKmhParaMs(Modulos.Where(x => x.Conectado && x.MovMotor.ComandoLigado).DefaultIfEmpty().Average(x => x?.MovMotor?.VelocidadeInstantanea ?? 0));
}
var UltimaDirecao = Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Mov)?.UltimaDirecao ?? Direcao.Parado;
var UltimaDirecao = op.Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Mov)?.UltimaDirecao ?? Direcao.Parado;
if (UltimaDirecao != Direcao.Parado)
{
//double tempo = _TaxaAmostragem / 1000.0;
@ -242,16 +243,16 @@ namespace AgroBase.Models.Modules
private static readonly TimeSpan IntervaloLogMov = TimeSpan.FromSeconds(1);
private async Task tmrRegistradorMOV_Tick()
{
var op = Variaveis.OperacaoEmAndamento;
if (Variaveis.Fechando)
return;
DateTime agora = DateTime.Now;
if (!OIDCanService.Iniciado &&
SerialService.DispositivosMapeados.Any(x => x.Dispositivo == T_Code.Mov))
if (!OIDCanService.Iniciado && SerialService.DispositivosMapeados.Any(x => x.Dispositivo == T_Code.Mov))
{
foreach (var leitura in OIDCanService.DadosLeitura
.Where(x => x.UltimoComandoRecebido.AddSeconds(10) < agora))
foreach (var leitura in OIDCanService.DadosLeitura.Where(x => x.UltimoComandoRecebido.AddSeconds(10) < agora))
{
OIDCanService.RequisitarDado(
leitura.EnderecoTx,
@ -264,22 +265,14 @@ namespace AgroBase.Models.Modules
return;
}
bool deveEnviarControle =
_ultimoEnvioControleMov == DateTime.MinValue ||
agora - _ultimoEnvioControleMov >= IntervaloControleMov;
bool deveEnviarControle = _ultimoEnvioControleMov == DateTime.MinValue || agora - _ultimoEnvioControleMov >= IntervaloControleMov;
bool deveRegistrarLog =
_ultimoRegistroLogMov == DateTime.MinValue ||
agora - _ultimoRegistroLogMov >= IntervaloLogMov;
bool deveRegistrarLog = _ultimoRegistroLogMov == DateTime.MinValue || agora - _ultimoRegistroLogMov >= IntervaloLogMov;
bool enviouControle = false;
bool registrouLog = false;
var controleMov =
deveEnviarControle
? Variaveis.OperacaoEmAndamento.Controle.TiposControle?
.FirstOrDefault(x => x.Tipo == T_Code.Mov)
: null;
var controleMov = deveEnviarControle ? op.Controle.TiposControle?.FirstOrDefault(x => x.Tipo == T_Code.Mov) : null;
foreach (var modulo in Modulos)
{
@ -313,15 +306,14 @@ namespace AgroBase.Models.Modules
/*
* Essa leitura é local, pode deixar no tick.
*/
modulo.MovMotor.ConfigFreio.Leitura =
modulo.MovMotor.Leitura?.Freado ?? false;
modulo.MovMotor.ConfigFreio.Leitura = modulo.MovMotor.Leitura?.Freado ?? false;
/*
* Log só a cada 1s para não virar serragem de JSON.
*/
if (deveRegistrarLog)
{
Variaveis.OperacaoEmAndamento.DispMvd.Dados.RegistrarLogMov(modulo);
op.DispMvd.Dados.RegistrarLogMov(modulo);
registrouLog = true;
}
}
@ -343,6 +335,8 @@ namespace AgroBase.Models.Modules
private static readonly TimeSpan IntervaloSensoresExternosDir = TimeSpan.FromMilliseconds(500);
private async Task tmrRegistradorDIR_Tick()
{
var op = Variaveis.OperacaoEmAndamento;
if (Variaveis.Fechando)
return;
@ -368,22 +362,14 @@ namespace AgroBase.Models.Modules
return;
}
bool deveEnviarControle =
_ultimoEnvioControleDir == DateTime.MinValue ||
agora - _ultimoEnvioControleDir >= IntervaloControleDir;
bool deveEnviarControle = _ultimoEnvioControleDir == DateTime.MinValue || agora - _ultimoEnvioControleDir >= IntervaloControleDir;
bool deveRequisitarSensoresExternos =
_ultimoSensoresExternosDir == DateTime.MinValue ||
agora - _ultimoSensoresExternosDir >= IntervaloSensoresExternosDir;
bool deveRequisitarSensoresExternos = _ultimoSensoresExternosDir == DateTime.MinValue || agora - _ultimoSensoresExternosDir >= IntervaloSensoresExternosDir;
bool enviouControle = false;
bool requisitouSensoresExternos = false;
var controleDir =
deveEnviarControle
? Variaveis.OperacaoEmAndamento.Controle.TiposControle?
.FirstOrDefault(x => x.Tipo == T_Code.Dir)
: null;
var controleDir = deveEnviarControle ? op.Controle.TiposControle?.FirstOrDefault(x => x.Tipo == T_Code.Dir) : null;
foreach (var modulo in Modulos)
{
@ -417,10 +403,7 @@ namespace AgroBase.Models.Modules
* O MKS057DCanService já tem dedupe curto, mas ainda assim
* é melhor não transformar posição em metralhadora CAN.
*/
if (!MKS057DCanService.Referenciando &&
deveEnviarControle &&
controleDir != null &&
!modulo.DirMotor.AtingiuAnguloSP)
if (!MKS057DCanService.Referenciando && deveEnviarControle && controleDir != null && !modulo.DirMotor.AtingiuAnguloSP)
{
modulo.DirMotor.EnviarComandoControle(controleDir.UltimaDirecao);
enviouControle = true;
@ -463,6 +446,8 @@ namespace AgroBase.Models.Modules
public async Task ExecutarMovimentoDirecionalCombinado(Direcao DirecaoAtual)
{
var op = Variaveis.OperacaoEmAndamento;
if (DirecaoAtual == Direcao.Parado)
{
foreach (var Modulo in Modulos)
@ -473,7 +458,7 @@ namespace AgroBase.Models.Modules
await Task.Delay(1000);
}
switch (Variaveis.OperacaoEmAndamento.Controle.TipoMovimento)
switch (op.Controle.TipoMovimento)
{
case TipoMovimentoDirecional.RotacionarNoEixo:
case TipoMovimentoDirecional.MovimentoLateral:
@ -493,7 +478,7 @@ namespace AgroBase.Models.Modules
if (Sucesso && DirecaoAtual != Direcao.Parado)
{
Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP = 20;
op.Controle.PercentualVelocidadeSP = 20;
foreach (var Modulo in Modulos)
{
Modulo.MovMotor.EnviarComandoControle(
@ -513,9 +498,11 @@ namespace AgroBase.Models.Modules
{
if (!MKS057DCanService.Referenciando)
{
TipoMovimentoDirecional tipoControle = Variaveis.OperacaoEmAndamento.Controle.TipoMovimento;
var op = Variaveis.OperacaoEmAndamento;
Variaveis.OperacaoEmAndamento.Controle.TipoMovimento = TipoMovimentoDirecional.Diagnostico;
TipoMovimentoDirecional tipoControle = op.Controle.TipoMovimento;
op.Controle.TipoMovimento = TipoMovimentoDirecional.Diagnostico;
var ModsRef = Modulos.Where(x => x.DirMotor.Comandar && x.DirMotor.Inicializado && (ModsReferenciar != null ? ModsReferenciar.Contains(x.DirMotor.Mod_ID) : true)).ToList();
foreach (var Modulo in ModsRef)
{
@ -524,7 +511,7 @@ namespace AgroBase.Models.Modules
bool ReferenciamentoConcluido() => !MKS057DCanService.Referenciando;
await FuncoesGlobais.AguardarCondicaoAsync(ReferenciamentoConcluido, 2 * 1000 * 60, 1000);
Variaveis.OperacaoEmAndamento.Controle.TipoMovimento = tipoControle;
op.Controle.TipoMovimento = tipoControle;
}
return Modulos.All(x => x.DirMotor.Referenciado);
@ -532,11 +519,13 @@ namespace AgroBase.Models.Modules
public List<Task> RealizarCalibragemMovAsync(bool forcar)
{
var op = Variaveis.OperacaoEmAndamento;
List<Task> tasks = new List<Task>();
var DispMvd = Variaveis.OperacaoEmAndamento.DispMvd;
var DispMvd = op.DispMvd;
if (DispMvd != null)
{
var calMov = Variaveis.OperacaoEmAndamento.ModsCalibragem[T_Code.Mov];
var calMov = op.Sensoriamento.Operacao.ModsCalibragem[T_Code.Mov];
foreach (var mod in DispMvd.Dados.Modulos)
{
calMov.TryGetValue(mod.Modulo_ID, out var cal);
@ -551,11 +540,13 @@ namespace AgroBase.Models.Modules
public List<Task> RealizarCalibragemDirAsync(bool forcar)
{
var op = Variaveis.OperacaoEmAndamento;
List<Task> tasks = new List<Task>();
var DispMvd = Variaveis.OperacaoEmAndamento.DispMvd;
var DispMvd = op.DispMvd;
if (DispMvd != null)
{
var calDir = Variaveis.OperacaoEmAndamento.ModsCalibragem[T_Code.Dir];
var calDir = op.Sensoriamento.Operacao.ModsCalibragem[T_Code.Dir];
foreach (var mod in DispMvd.Dados.Modulos)
{
calDir.TryGetValue(mod.Modulo_ID, out var cal);
@ -567,7 +558,7 @@ namespace AgroBase.Models.Modules
if (DispMvd.Dados.Modulos.Any(x => x.DirMotor.Inicializado))
{
Variaveis.OperacaoEmAndamento.Controle.TipoMovimento = TipoMovimentoDirecional.Diagnostico;
op.Controle.TipoMovimento = TipoMovimentoDirecional.Diagnostico;
var ModsRef = Modulos.Where(x => x.DirMotor.Comandar).ToList(); // && x.DirMotor.Inicializado
foreach (var Modulo in ModsRef)
{
@ -576,12 +567,12 @@ namespace AgroBase.Models.Modules
if (t.IsFaulted)
{
Variaveis.MostrarLog($"[MovimentacaoUnificadaModel] [RealizarCalibragemDirAsync] Erro no referenciamento do módulo {Modulo.Modulo_ID}: {t.Exception?.InnerException?.Message}");
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Falha, 0, $"Erro no referenciamento do módulo {Modulo.Modulo_ID}: {t.Exception?.InnerException?.Message}");
op.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Falha, 0, $"Erro no referenciamento do módulo {Modulo.Modulo_ID}: {t.Exception?.InnerException?.Message}");
}
if (t.IsCompleted)
{
Variaveis.MostrarLog($"[MovimentacaoUnificadaModel] [RealizarCalibragemDirAsync] Referenciamento do módulo {Modulo.Modulo_ID} concluído com sucesso!");
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Operante, 100, $"Referenciamento do módulo {Modulo.Modulo_ID} concluído com sucesso!");
op.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Operante, 100, $"Referenciamento do módulo {Modulo.Modulo_ID} concluído com sucesso!");
calDir[Modulo.Modulo_ID] = true;
}
}));

View File

@ -6,10 +6,6 @@ using System.Threading.Tasks;
using static AgroBase.Models.Enums;
using System.Globalization;
using System.Data;
using static AgroBase.Services.LoRaEspService;
using AgroBase.Services.Operadores;
using System.Diagnostics;
using AgroBase.Models.Operadores;
namespace AgroBase.Models.Modules
{
@ -42,7 +38,7 @@ namespace AgroBase.Models.Modules
{
get
{
return HealthWorkerService.ModulosSaude.Any(x => x.modulo == Dispositivo && x.status == StatusModulo.Operante);
return Variaveis.OperacaoEmAndamento.Sensoriamento?.OperadorSaude?.ModulosSaude?.Any(x => x.modulo == Dispositivo && x.status == StatusModulo.Operante) ?? false;
}
}
public SensoriamentoMensagemJsonModel DadosLeitura { get; set; } = new SensoriamentoMensagemJsonModel();
@ -58,18 +54,6 @@ namespace AgroBase.Models.Modules
public List<SensorServoModel> Servos { get; set; }
public UltrasonicA05Configuracoes ConfiguracaoSensorUltrassom { get; set; }
private SenHandler _SenHandler = new SenHandler();
public LoRaEspService loRaService { get; set; } = new LoRaEspService();
public LoRaParametrosModel LoRaParametrosBase { get; set; } = new LoRaParametrosModel()
{
address = 0x01,
channel = 0x17,
tranMode = LoRaBaseService.CodigosTipoTransmissao["Fixed"],
baudRate = LoRaBaseService.CodigosBaudRates[9600],
airRate = LoRaBaseService.CodigosAirRates[2.4],
packetSize = LoRaBaseService.CodigosPacketSizes[200],
worCycle = LoRaBaseService.CodigosWorCycles[4000],
power = LoRaBaseService.CodigosPowers[22],
};
public CoulombCounterService ContadorCarga = new CoulombCounterService(VariaveisEquipamento.CorrenteMaximaBateria);
public CoolerControlService CoolerControl = new CoolerControlService();
public AsyncTaskTimerModel tmrRegistrador;
@ -1999,40 +1983,6 @@ namespace AgroBase.Models.Modules
}
},
},
loRaService = new LoRaEspService()
{
ID = "LoRa",
ID_Num = Variaveis.ID_Num_sLRA,
Componente = S_Code.sLRA,
Funcoes = new List<FuncoesPinout>()
{
FuncoesPinout.ENA,
FuncoesPinout.M0,
FuncoesPinout.M1,
FuncoesPinout.Aux,
FuncoesPinout.RX,
FuncoesPinout.TX
},
Conectado = false,
Configurado = false,
ParametrosSet = new LoRaParametrosModel()
{
address = 2,
airRate = 0,
baudRate = 96,
parity = 0,
packetSize = 192,
power = 0,
tranMode = 64,
worCycle = 3,
channelRssi = 0,
lbt = 0,
packetRssi = 0,
channel = 65,
key = 0
},
ParametrosGet = new LoRaParametrosModel()
},
};
return obj;
@ -2050,12 +2000,6 @@ namespace AgroBase.Models.Modules
{
x._AnguloControle = x.Incremental ? 0 : 180;
});
loRaService.Conectado = false;
loRaService.Configurado = false;
loRaService.ParametrosGet.UltimaLeitura = DateTime.MinValue;
loRaService.MensagensRecebidasAvulsas = new List<LoRaMensagemModel>();
VisualWorkerService.DadosLeitura.CameraFrames = new Dictionary<TipoFrameCamera, OAKCameraFrameModel>();
WeedWorkerService.DadosLeitura.CameraFrames = new Dictionary<TipoFrameCamera, OAKCameraFrameModel>();
ReiniciarLeituras(Dados);
}
@ -2094,22 +2038,24 @@ namespace AgroBase.Models.Modules
public async Task<bool> VerificaDispositivoConectado()
{
var op = Variaveis.OperacaoEmAndamento;
if (!CanManager.CanService.IsConnected) return false;
if (Variaveis.OperacaoEmAndamento.DispSen == null) return false;
if (op.DispSen == null) return false;
CanManager.CanService.RegistrarHandler(_EnderecoCAN_Rx, _SenHandler);
RequisitarDadosDescoberta();
DateTime Inicio = DateTime.Now;
bool Respondido() => Variaveis.OperacaoEmAndamento.DispSen.Dados.DadosLeitura.UltimoComandoRespondido > Inicio;
bool Respondido() => op.DispSen.Dados.DadosLeitura.UltimoComandoRespondido > Inicio;
await FuncoesGlobais.AguardarCondicaoAsync(Respondido, 500, 50);
if (Conectado)
{
DefinirDispositivo();
Variaveis.OperacaoEmAndamento.DispSen?.EnviarProtocolosConfiguracao();
op.DispSen?.EnviarProtocolosConfiguracao();
}
return Conectado;
@ -2117,6 +2063,8 @@ namespace AgroBase.Models.Modules
private void DefinirDispositivo()
{
var op = Variaveis.OperacaoEmAndamento;
if (!SerialService.DispositivosMapeados.Any(x => x.Dispositivo == DadosLeitura.Dispositivo && x.Mod_ID == Modulo_ID))
{
SerialService.DispositivosMapeados.Add(new DispositivoDetalhesModel()
@ -2127,8 +2075,8 @@ namespace AgroBase.Models.Modules
Mod_ID = Modulo_ID,
});
Variaveis.OperacaoEmAndamento.ModsCalibragem[Dispositivo] = new Dictionary<string, bool>();
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Conectado, 0, "Dispositivo conectado");
op.Sensoriamento.Operacao.ModsCalibragem[Dispositivo] = new Dictionary<string, bool>();
op.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Conectado, 0, "Dispositivo conectado");
}
}
@ -2184,13 +2132,6 @@ namespace AgroBase.Models.Modules
//var sensoresConfig = SensoresConfig(Conectar, configurarTodos);
//config.AddRange(sensoresConfig);
// Adicionar configurações do LoRa
if (Variaveis.OperacaoEmAndamento.Parametros.ModulosMandatorios.Any(x => x.Dispositivo == T_Code.Lra && x.Mandatorio && x.Utilizar) && (!loRaService.Conectado || !loRaService.Configurado || configurarTodos))
{
var loraConfig = loRaService.ProtocoloConfiguracao(Pinout, Conectar);
config.AddRange(loraConfig);
}
return config;
}
@ -2201,7 +2142,7 @@ namespace AgroBase.Models.Modules
(byte)(Conectar ? 1 : 0),
(byte)(_TaxaAmostragem / 1000),
(byte)(RequisitarDados ? 1 : 0),
LoRaParametrosBase.address
(byte)0x00, //LoRaParametrosBase.address
};
config1.AddRange(PinoutModel.PinoProtocolo(Pinout, Funcoes, false));
@ -2313,13 +2254,15 @@ namespace AgroBase.Models.Modules
public async Task tmrRegistrador_Tick()
{
var op = Variaveis.OperacaoEmAndamento;
if (Variaveis.Fechando) return;
tmrRegistrador.SetInterval(_TaxaAmostragem);
if (SerialService.DispositivosMapeados.Any(x => x.Dispositivo == T_Code.Sen) && (_VezesLeituraReconexao >= _TempoReconexaoComponentes))
{
Variaveis.OperacaoEmAndamento.DispSen?.EnviarProtocolosConfiguracao();
op.DispSen?.EnviarProtocolosConfiguracao();
_VezesLeituraReconexao = 0;
}
@ -2883,13 +2826,15 @@ namespace AgroBase.Models.Modules
public void ProcessarMensagem(CanMessage mensagem)
{
var op = Variaveis.OperacaoEmAndamento;
CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)mensagem.DataRx[0];
byte ID_Num = mensagem.DataRx[1];
var data = mensagem.DataRx;
S_Code componente = DetectarComponenteDoID_Num(ID_Num);
var Dados = Variaveis.OperacaoEmAndamento.DispSen.Dados;
var Dados = op.DispSen.Dados;
//Console.WriteLine($"[SEN] Componente={componente.ToString()}, ID_Num={ID_Num}, Posicao={posicao.ToString()}, Data={FuncoesGlobais.ConverterComandoBytesParaTexto(data)}");
@ -2915,139 +2860,139 @@ namespace AgroBase.Models.Modules
}
break;
}
case S_Code.sLRA:
{
var loraService = Dados.loRaService;
switch (posicao)
{
case CanMessagePosicaoDados.Status:
{
bool Conectado = data[2] == 1;
bool Configurado = data[3] == 1;
//Console.WriteLine($"[LRA] Resposta {ID_Num} recebida. Conectado={Conectado}, Configurado={Configurado}");
loraService.Conectado = Conectado;
loraService.Configurado = Configurado;
break;
}
case CanMessagePosicaoDados.Dados1:
{
byte address = data[2];
byte baudAndAirRate = data[3];
byte baud = (byte)(baudAndAirRate & 0b11100000);
byte airRate = (byte)((baudAndAirRate & 0b00011100) >> 2);
byte packetSizeAndPower = data[4];
byte packetSize = (byte)((packetSizeAndPower & 0b11000000));
byte power = (byte)(packetSizeAndPower & 0b00000011);
byte channel = data[5];
byte tranModeAndWorCycle = data[6];
byte tranMode = (byte)(tranModeAndWorCycle & 0b01000000);
byte worCycle = (byte)(tranModeAndWorCycle & 0b00000111);
//Console.WriteLine($"[LRA] Resposta {ID_Num} recebida. Address={address.ToString("X")}, BaudRate={baud.ToString("X")}, AirRate={airRate.ToString("X")}, PacketSize={packetSize.ToString("X")}, Power={power.ToString("X")}, Channel={channel.ToString("X")}, transMode={tranMode.ToString("X")}, WorCycle={worCycle.ToString("X")}");
loraService.ParametrosGet.address = address;
loraService.ParametrosGet.baudRate = baud;
loraService.ParametrosGet.airRate = airRate;
loraService.ParametrosGet.packetSize = packetSize;
loraService.ParametrosGet.power = power;
loraService.ParametrosGet.channel = channel;
loraService.ParametrosGet.worCycle = worCycle;
loraService.ParametrosGet.tranMode = tranMode;
loraService.ParametrosGet.UltimaLeitura = DateTime.Now;
break;
}
default:
{
DadosLoRaParse tipoDado = (DadosLoRaParse)posicao;
//Console.WriteLine($"[LRA] Dados recebidos ({tipoDado.ToString()}). " + string.Join(" ", data));
switch (tipoDado)
{
case DadosLoRaParse.ComandoControle:
{
BotoesJoystick tecla = (BotoesJoystick)data[2];
int percentualVelocidadeSp = data[3];
TipoMovimentoDirecional tipoMovimentoDirecional = (TipoMovimentoDirecional)data[4];
int anguloMp = data[5];
//int velocidadeMp = data[6];
T_Code dispositivo = (T_Code)data[6];
bool emergencia = data[7] == 1;
OperacaoComandoBaseModel Controle = new OperacaoComandoBaseModel()
{
Momento = DateTime.Now,
Tecla = tecla,
Controle = new OperacaoComandoBaseControleModel()
{
AnguloSP = anguloMp,
PercentualVelocidadeSP = percentualVelocidadeSp,
TipoMovimentoDirecional = tipoMovimentoDirecional,
},
Emergencia = emergencia,
Dispositivo = dispositivo
};
Variaveis.OperacaoEmAndamento.ExecutaComandoDaBase(Controle);
break;
}
case DadosLoRaParse.DadosLivre:
{
Console.WriteLine("[LRA] Dados livres LORA recebidos da base: " + FuncoesGlobais.ConverterComandoBytesParaTexto(data));
Variaveis.LoraService.MensagensRecebidasAvulsas.Add(new LoRaMensagemModel()
{
Lido = false,
Momento = DateTime.Now,
channel = Variaveis.LoraBaseParametros.channel,
Remetente = Variaveis.LoraBaseParametros.address,
Destinatario = Variaveis.LoraService.ParametrosGet.address,
Data = data,
Mensagem = string.Join("", data.Select(x => x.ToString("X")))
});
break;
}
case DadosLoRaParse.GpsQualidade:
{
bool iniciado = data[2] == 1;
TiposCorrecaoGPS qualidadeFix = (TiposCorrecaoGPS)data[3];
int numeroSatelites = data[4];
double precisao = LoRaSerializer.DescompactarDecimal(data, 5);
VariaveisOperacao.PosicaoBase.Inicializado = iniciado;
VariaveisOperacao.PosicaoBase.QualidadeFix = qualidadeFix;
VariaveisOperacao.PosicaoBase.NumeroSatelites = numeroSatelites;
VariaveisOperacao.PosicaoBase.PrecisaoHorizontal = precisao;
VariaveisOperacao.PosicaoBase.Momento = DateTime.Now;
break;
}
case DadosLoRaParse.GpsLatitude:
{
double _lat = LoRaSerializer.DescompactarCoordenada(data.Skip(2).ToArray());
VariaveisOperacao.PosicaoBase.Latitude = _lat;
VariaveisOperacao.PosicaoBase.Momento = DateTime.Now;
break;
}
case DadosLoRaParse.GpsLongitude:
{
double _long = LoRaSerializer.DescompactarCoordenada(data.Skip(2).ToArray());
VariaveisOperacao.PosicaoBase.Longitude = _long;
VariaveisOperacao.PosicaoBase.Momento = DateTime.Now;
break;
}
case DadosLoRaParse.GpsGerais:
{
double _altitude = LoRaSerializer.DescompactarDecimal(data, 2);
double _velocidade = LoRaSerializer.DescompactarDecimal(data, 4);
double _orientacao = LoRaSerializer.DescompactarDecimal(data, 6);
VariaveisOperacao.PosicaoBase.Altitude = _altitude;
VariaveisOperacao.PosicaoBase.Velocidade = _velocidade;
VariaveisOperacao.PosicaoBase.OrientacaoReal = _orientacao;
VariaveisOperacao.PosicaoBase.Momento = DateTime.Now;
break;
}
}
Variaveis.LoraService.UltimoRxDados = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
Variaveis.LoraService._ultimoRxDados = DateTime.UtcNow;
break;
}
}
break;
}
//case S_Code.sLRA:
// {
// var loraService = Dados.loRaService;
// switch (posicao)
// {
// case CanMessagePosicaoDados.Status:
// {
// bool Conectado = data[2] == 1;
// bool Configurado = data[3] == 1;
// //Console.WriteLine($"[LRA] Resposta {ID_Num} recebida. Conectado={Conectado}, Configurado={Configurado}");
// loraService.Conectado = Conectado;
// loraService.Configurado = Configurado;
// break;
// }
// case CanMessagePosicaoDados.Dados1:
// {
// byte address = data[2];
// byte baudAndAirRate = data[3];
// byte baud = (byte)(baudAndAirRate & 0b11100000);
// byte airRate = (byte)((baudAndAirRate & 0b00011100) >> 2);
// byte packetSizeAndPower = data[4];
// byte packetSize = (byte)((packetSizeAndPower & 0b11000000));
// byte power = (byte)(packetSizeAndPower & 0b00000011);
// byte channel = data[5];
// byte tranModeAndWorCycle = data[6];
// byte tranMode = (byte)(tranModeAndWorCycle & 0b01000000);
// byte worCycle = (byte)(tranModeAndWorCycle & 0b00000111);
// //Console.WriteLine($"[LRA] Resposta {ID_Num} recebida. Address={address.ToString("X")}, BaudRate={baud.ToString("X")}, AirRate={airRate.ToString("X")}, PacketSize={packetSize.ToString("X")}, Power={power.ToString("X")}, Channel={channel.ToString("X")}, transMode={tranMode.ToString("X")}, WorCycle={worCycle.ToString("X")}");
// loraService.ParametrosGet.address = address;
// loraService.ParametrosGet.baudRate = baud;
// loraService.ParametrosGet.airRate = airRate;
// loraService.ParametrosGet.packetSize = packetSize;
// loraService.ParametrosGet.power = power;
// loraService.ParametrosGet.channel = channel;
// loraService.ParametrosGet.worCycle = worCycle;
// loraService.ParametrosGet.tranMode = tranMode;
// loraService.ParametrosGet.UltimaLeitura = DateTime.Now;
// break;
// }
// default:
// {
// DadosLoRaParse tipoDado = (DadosLoRaParse)posicao;
// //Console.WriteLine($"[LRA] Dados recebidos ({tipoDado.ToString()}). " + string.Join(" ", data));
// switch (tipoDado)
// {
// case DadosLoRaParse.ComandoControle:
// {
// BotoesJoystick tecla = (BotoesJoystick)data[2];
// int percentualVelocidadeSp = data[3];
// TipoMovimentoDirecional tipoMovimentoDirecional = (TipoMovimentoDirecional)data[4];
// int anguloMp = data[5];
// //int velocidadeMp = data[6];
// T_Code dispositivo = (T_Code)data[6];
// bool emergencia = data[7] == 1;
//
// OperacaoComandoBaseModel Controle = new OperacaoComandoBaseModel()
// {
// Momento = DateTime.Now,
// Tecla = tecla,
// Controle = new OperacaoComandoBaseControleModel()
// {
// AnguloSP = anguloMp,
// PercentualVelocidadeSP = percentualVelocidadeSp,
// TipoMovimentoDirecional = tipoMovimentoDirecional,
// },
// Emergencia = emergencia,
// Dispositivo = dispositivo
// };
// op.ExecutaComandoDaBase(Controle);
// break;
// }
// case DadosLoRaParse.DadosLivre:
// {
// Console.WriteLine("[LRA] Dados livres LORA recebidos da base: " + FuncoesGlobais.ConverterComandoBytesParaTexto(data));
// Variaveis.LoraService.MensagensRecebidasAvulsas.Add(new LoRaMensagemModel()
// {
// Lido = false,
// Momento = DateTime.Now,
// channel = Variaveis.LoraBaseParametros.channel,
// Remetente = Variaveis.LoraBaseParametros.address,
// Destinatario = Variaveis.LoraService.ParametrosGet.address,
// Data = data,
// Mensagem = string.Join("", data.Select(x => x.ToString("X")))
// });
// break;
// }
// case DadosLoRaParse.GpsQualidade:
// {
// bool iniciado = data[2] == 1;
// TiposCorrecaoGPS qualidadeFix = (TiposCorrecaoGPS)data[3];
// int numeroSatelites = data[4];
// double precisao = LoRaSerializer.DescompactarDecimal(data, 5);
//
// VariaveisOperacao.PosicaoBase.Inicializado = iniciado;
// VariaveisOperacao.PosicaoBase.QualidadeFix = qualidadeFix;
// VariaveisOperacao.PosicaoBase.NumeroSatelites = numeroSatelites;
// VariaveisOperacao.PosicaoBase.PrecisaoHorizontal = precisao;
// VariaveisOperacao.PosicaoBase.Momento = DateTime.Now;
// break;
// }
// case DadosLoRaParse.GpsLatitude:
// {
// double _lat = LoRaSerializer.DescompactarCoordenada(data.Skip(2).ToArray());
// VariaveisOperacao.PosicaoBase.Latitude = _lat;
// VariaveisOperacao.PosicaoBase.Momento = DateTime.Now;
// break;
// }
// case DadosLoRaParse.GpsLongitude:
// {
// double _long = LoRaSerializer.DescompactarCoordenada(data.Skip(2).ToArray());
// VariaveisOperacao.PosicaoBase.Longitude = _long;
// VariaveisOperacao.PosicaoBase.Momento = DateTime.Now;
// break;
// }
// case DadosLoRaParse.GpsGerais:
// {
// double _altitude = LoRaSerializer.DescompactarDecimal(data, 2);
// double _velocidade = LoRaSerializer.DescompactarDecimal(data, 4);
// double _orientacao = LoRaSerializer.DescompactarDecimal(data, 6);
// VariaveisOperacao.PosicaoBase.Altitude = _altitude;
// VariaveisOperacao.PosicaoBase.Velocidade = _velocidade;
// VariaveisOperacao.PosicaoBase.OrientacaoReal = _orientacao;
// VariaveisOperacao.PosicaoBase.Momento = DateTime.Now;
// break;
// }
// }
// Variaveis.LoraService.UltimoRxDados = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
// Variaveis.LoraService._ultimoRxDados = DateTime.UtcNow;
// break;
// }
// }
// break;
// }
case S_Code.sTOD:
{
switch (posicao)
@ -3378,7 +3323,7 @@ namespace AgroBase.Models.Modules
Dados.DadosLeitura.UltimoComandoRespondido = DateTime.Now;
//Console.WriteLine("Ultimo comando respondido: " + Dados.DadosLeitura.UltimoComandoRespondido.ToString("HH:mm:ss.fff") + ", Conectado: " + Dados.Conectado);
Variaveis.OperacaoEmAndamento.DispMvd.Dados.AtualizarDadosSensoresExternos(componente, ID_Num);
op.DispMvd.Dados.AtualizarDadosSensoresExternos(componente, ID_Num);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -584,8 +584,8 @@ namespace AgroBase.Models.Operacoes
public OperacaoSensoriamentoLogImuModel Imu { get; set; }
public OperacaoParametrosDadosAtuadorModel Atuador { get; set; }
public OperacaoParametrosDadosSensoriamentoModel Sensoriamento { get; set; }
public OperacaoParametrosDadosMovimentacaoModel Movimentacao { get; set; }
public OperacaoParametrosDadosDirecionalModel Direcional { get; set; }
public MovimentacaoLogModel Movimentacao { get; set; }
public DirecionalLogModel Direcional { get; set; }
public OperacaoSensoriamentoLogBateriaModel Bateria { get; set; }
public CoolerControlDataModel Refrigeracao { get; set; }
@ -622,41 +622,37 @@ namespace AgroBase.Models.Operacoes
AtualizarImu(sen);
AtualizarAtuador(sen, dAtu);
AtualizarSensoriamento(dSen);
AtualizarMovimentacao(sen, dMvd);
AtualizarDirecional(sen, dMvd);
AtualizarMovimentacao(sen);
AtualizarDirecional(sen);
AtualizarGnss(sen);
AtualizarOutrosBlocos(sen);
AtualizarCameras();
AtualizarLogs(sen);
}
private void AtualizarOperacao(dynamic op)
private void AtualizarOperacao(OperacaoModel op)
{
var parametros = op?.Parametros;
Operacao = new OperacaoParametrosDadosOperacaoModel
{
Iniciada = op?.Iniciado ?? false,
Liberada = op?.OperacaoLiberada ?? false,
Status = op?.StatusAtual ?? StatusOperacao.Erro,
Iniciada = op?.Sensoriamento?.Operacao?.OperacaoIniciada ?? false,
Liberada = op?.Sensoriamento?.Operacao?.OperacaoLiberada ?? false,
Status = op?.Sensoriamento?.Operacao?.StatusOperacaoAtual ?? StatusOperacao.Erro,
Modo = parametros?.Modo ?? ModoOperacao.NaoDefinido,
ImpedimentoErro = op?.ErroOperacaoLiberada,
TempoAguardandoSegs = op?.TempoAguardandoSegs ?? 0,
TempoDecorridoSegs = op?.TempoDecorridoSegs ?? 0,
Emergencia = op?.Emergencia ?? false,
Pausa = op?.Pausa ?? false,
IniciadoEm = op?.DataInicio ?? DateTime.MinValue,
FinalizadoEm = op?.DataFim ?? DateTime.MinValue,
ModulosMandatorios = CloneList(
parametros?.ModulosMandatorios
),
ParametrosMandatorios = CloneList(
parametros?.ParametrosMandatorios
)
ImpedimentoErro = op?.Sensoriamento?.Operacao?.ErroOperacaoLiberada,
TempoAguardandoSegs = op?.Sensoriamento?.Operacao?.TempoAguardandoSeg ?? 0,
TempoDecorridoSegs = op?.Sensoriamento?.Operacao?.TempoDecorridoSeg ?? 0,
Emergencia = op?.Sensoriamento?.Operacao?.Emergencia ?? false,
Pausa = op?.Sensoriamento?.Operacao?.Pausa ?? false,
IniciadoEm = op?.Sensoriamento?.Operacao?.DataInicio ?? DateTime.MinValue,
FinalizadoEm = op?.Sensoriamento?.Operacao?.DataFim ?? DateTime.MinValue,
ModulosMandatorios = CloneList(parametros?.ModulosMandatorios),
ParametrosMandatorios = CloneList(parametros?.ParametrosMandatorios)
};
}
private void AtualizarTrajetoria(dynamic sen)
private void AtualizarTrajetoria(OperacaoSensoriamentoConjuntoModel sen)
{
var t = sen?.Trajetoria;
@ -664,8 +660,7 @@ namespace AgroBase.Models.Operacoes
{
Trajetoria = new OperacaoParametrosDadosTrajetoriaModel
{
AutonomiaCorredor =
new OperacaoParametrosDadosTrajetoriaAutonomiaCorredorModel()
AutonomiaCorredor = new OperacaoParametrosDadosTrajetoriaAutonomiaCorredorModel()
};
return;
}
@ -750,7 +745,7 @@ namespace AgroBase.Models.Operacoes
};
}
private void AtualizarControle(dynamic op)
private void AtualizarControle(OperacaoModel op)
{
var c = op?.Controle?.Clone();
@ -768,18 +763,13 @@ namespace AgroBase.Models.Operacoes
: new OperacaoParametrosDadosControleModel();
}
private void AtualizarSaude(dynamic sen)
private void AtualizarSaude(OperacaoSensoriamentoConjuntoModel sen)
{
ModulosSaude = CloneList(
sen?.ModulosSaude
);
DispositivosMapeados = CloneList(
sen?.DispositivosMapeados
);
ModulosSaude = CloneList(sen?.OperadorSaude?.ModulosSaude);
DispositivosMapeados = CloneList(sen?.Operacao?.DispositivosMapeados);
}
private void AtualizarImu(dynamic sen)
private void AtualizarImu(OperacaoSensoriamentoConjuntoModel sen)
{
Imu = new OperacaoSensoriamentoLogImuModel
{
@ -790,21 +780,13 @@ namespace AgroBase.Models.Operacoes
};
}
private void AtualizarAtuador(dynamic sen, dynamic dAtu)
private void AtualizarAtuador(OperacaoSensoriamentoConjuntoModel sen, AtuadorModel dAtu)
{
var atu = sen?.Atuador;
var bicosPulverizadores = ToDynamicList(
dAtu == null ? null : dAtu.BicosPulverizadores
);
var bombasPressurizadoras = ToDynamicList(
dAtu == null ? null : dAtu.BombasPressurizadoras
);
var sensoresAtuador = ToDynamicList(
dAtu == null ? null : dAtu.Sensores
);
var bicosPulverizadores = ToDynamicList(dAtu == null ? null : dAtu.BicosPulverizadores);
var bombasPressurizadoras = ToDynamicList(dAtu == null ? null : dAtu.BombasPressurizadoras);
var sensoresAtuador = ToDynamicList(dAtu == null ? null : dAtu.Sensores);
Atuador = new OperacaoParametrosDadosAtuadorModel
{
@ -813,34 +795,23 @@ namespace AgroBase.Models.Operacoes
AnguloBarraDireita = atu?.AnguloBarraDireita ?? 0,
AnguloBarraEsquerda = atu?.AnguloBarraEsquerda ?? 0,
CapacidadeReservatorio =
atu?.CapacidadeReservatorio ?? 0,
CapacidadeReservatorio = atu?.CapacidadeReservatorio ?? 0,
ErvasNoRadar = atu?.ErvasNoRadar ?? false,
DistanciaEstimadaRestanteMetros =
atu?.DistanciaEstimadaRestanteMetros ?? 0,
HerbicidaConsumidoMl =
atu?.HerbicidaConsumido ?? 0,
HerbicidaPorAtuacaoMl =
atu?.HerbicidaPorErva ?? 0,
DistanciaEstimadaRestanteMetros = atu?.DistanciaEstimadaRestanteMetros ?? 0,
HerbicidaConsumidoMl = atu?.HerbicidaConsumido ?? 0,
HerbicidaPorAtuacaoMl = atu?.HerbicidaPorErva ?? 0,
LPorMetro = atu?.LPorMetro ?? 0,
LPorMinuto = atu?.LPorMinuto ?? 0,
MassaReservatorioKg =
atu?.MassaReservatorio ?? 0,
VolumeReservatorioL =
atu?.VolumeReservatorio ?? 0,
VolumeVazaoMl = atu?.VolumeVazaoMl ?? 0,
VazaoMediaMLs = atu?.VazaoMedia ?? 0,
VazaoInstantaneaMLs =
atu?.VazaoInstantanea ?? 0,
TempoEstimadoRestanteMinutos =
atu?.TempoEstimadoRestanteMinutos ?? 0,
MassaReservatorioKg = atu?.MassaReservatorio ?? 0,
VolumeReservatorioL = atu?.VolumeReservatorio ?? 0,
VolumeVazaoMl = atu?.VolumeVazaoML ?? 0,
VazaoMediaMLs = atu?.VazaoFluxoMLpSMedia ?? 0,
VazaoInstantaneaMLs = atu?.VazaoFluxoMLpSInstantaneaCorrigida ?? 0,
TempoEstimadoRestanteMinutos = atu?.TempoEstimadoRestanteMinutos ?? 0,
QtdCamerasSolo = atu?.QtdCamerasSolo ?? 0,
PercentualErvasNoRadar =
atu?.PercentualErvasNoRadar ?? 0,
PercentualErvasTerreno =
atu?.PercentualErvasTerreno ?? 0,
PercentualReservatorio =
atu?.PercentualReservatorio ?? 0,
PercentualErvasNoRadar = atu?.PercentualErvasNoRadar ?? 0,
PercentualErvasTerreno = atu?.PercentualErvasTerreno ?? 0,
PercentualReservatorio = atu?.PercentualReservatorio ?? 0,
PressaoLinhaPsi = atu?.PressaoLinha ?? 0,
Bicos =
@ -918,7 +889,7 @@ namespace AgroBase.Models.Operacoes
};
}
private void AtualizarSensoriamento(dynamic dSen)
private void AtualizarSensoriamento(SensoriamentoModel dSen)
{
Sensoriamento = new OperacaoParametrosDadosSensoriamentoModel
{
@ -995,119 +966,17 @@ namespace AgroBase.Models.Operacoes
};
}
private void AtualizarMovimentacao(dynamic sen, dynamic dMvd)
private void AtualizarMovimentacao(OperacaoSensoriamentoConjuntoModel sen)
{
var modules = ToDynamicList(
dMvd == null ? null : dMvd.Modulos
);
var validMov =
((IEnumerable<dynamic>)modules)
.Where(x => x?.MovMotor != null)
.ToList();
Movimentacao = new OperacaoParametrosDadosMovimentacaoModel
{
VelocidadeMediaMs =
sen?.Movimentacao?.VelocidadeMedia ?? 0,
RPMMedio =
sen?.Movimentacao?.RPMMedio ?? 0,
TemperaturaMedia =
sen?.Movimentacao?.TemperaturaMedia ?? 0,
TempoMovimentoSegs =
sen?.Movimentacao?.TempoMovimentoSegs ?? 0,
DistanciaPercorridaParcial =
sen?.Movimentacao?.DistanciaPercorridaParcial ?? 0,
DistanciaPercorridaTotal =
sen?.Movimentacao?.DistanciaPercorridaTotal ?? 0,
Modulos =
validMov
.Select(x => new OperacaoSensoriamentoLogMovDadosModel
{
Mod_ID = x.MovMotor.Mod_ID,
ID = x.MovMotor._EnderecoCAN_Rx,
Iniciado = x.MovMotor.Inicializado,
Controlar = x.MovMotor.Comandar,
CicloTrabalho = x.MovMotor.CicloTrabalho,
Corrente_Barramento =
x.MovMotor.Corrente_Barramento,
Corrente_Motor =
x.MovMotor.Corrente_Motor,
Potencia = x.MovMotor.Potencia,
RPM_Motor = x.MovMotor.RPM_Motor,
RPM_Roda = x.MovMotor.RPM_Roda,
TemperaturaDriver =
x.MovMotor.TemperaturaDriver,
Tensao = x.MovMotor.Tensao,
VelocidadeInstantaneaMs =
x.MovMotor.VelocidadeInstantanea,
UltimoComandoRespondido =
x.MovMotor.Leitura?.UltimoComandoRecebido
?? DateTime.MinValue
})
.ToList(),
UltimoComandoRespondido =
validMov.Any()
? validMov.Max(x =>
x.MovMotor.Leitura?.UltimoComandoRecebido
?? DateTime.MinValue)
: DateTime.MinValue
};
Movimentacao = sen.Movimentacao?.Clone();
}
private void AtualizarDirecional(dynamic sen, dynamic dMvd)
private void AtualizarDirecional(OperacaoSensoriamentoConjuntoModel sen)
{
var modules = ToDynamicList(
dMvd == null ? null : dMvd.Modulos
);
var validDir =
((IEnumerable<dynamic>)modules)
.Where(x => x?.DirMotor != null)
.ToList();
Direcional = new OperacaoParametrosDadosDirecionalModel
{
AnguloMedio =
sen?.Direcional?.AnguloMedio ?? 0,
Modulos =
validDir
.Select(x => new DirSensoriamentoLogModel
{
Mod_ID = x.DirMotor.Mod_ID,
ID = x.DirMotor._EnderecoCAN_Rx,
Iniciado = x.DirMotor.Inicializado,
Controlar = x.DirMotor.Comandar,
AnguloDriver = x.DirMotor.AnguloDriver,
AnguloFolgaCompensar =
x.DirMotor.AnguloFolgaCompensar,
AnguloLeitura = x.DirMotor.AnguloLeitura,
AnguloReal = x.DirMotor.AnguloReal,
Angulo_SP = x.DirMotor.Angulo_SP,
FolgaMecanica = x.DirMotor.FolgaMecanica,
Sentido = x.DirMotor.Sentido,
SentidoReal = x.DirMotor.SentidoReal,
Sentido_SP = x.DirMotor.Sentido_SP,
Velocidade = x.DirMotor.Velocidade,
UltimoComandoRespondido =
x.DirMotor.Leitura?.UltimoComandoRecebido
?? DateTime.MinValue
})
.ToList(),
UltimoComandoRespondido =
validDir.Any()
? validDir.Max(x =>
x.DirMotor.Leitura?.UltimoComandoRecebido
?? DateTime.MinValue)
: DateTime.MinValue
};
Direcional = sen.Direcional?.Clone();
}
private void AtualizarGnss(dynamic sen)
private void AtualizarGnss(OperacaoSensoriamentoConjuntoModel sen)
{
var gps = sen?.Gps;
@ -1127,24 +996,19 @@ namespace AgroBase.Models.Operacoes
OrientacaoReal = gps?.OrientacaoReal ?? 0,
PrecisaoCm = gps?.PrecisaoCm ?? 0,
PrecisaoHorizontal = gps?.PrecisaoHorizontal ?? 0,
QualidadeFix =
gps?.QualidadeFix ?? TiposCorrecaoGPS.SemCorrecao,
QualidadeFix = gps?.QualidadeFix ?? TiposCorrecaoGPS.SemCorrecao,
Velocidade = gps?.Velocidade ?? 0,
UltimoComandoRespondido =
gps?.UltimoComandoRespondido ?? DateTime.MinValue
UltimoComandoRespondido = gps?.UltimoComandoRespondido ?? DateTime.MinValue
};
}
private void AtualizarOutrosBlocos(dynamic sen)
private void AtualizarOutrosBlocos(OperacaoSensoriamentoConjuntoModel sen)
{
Bateria = sen?.Bateria?.Clone();
Refrigeracao = sen?.CoolerControl?.Clone();
PerformanceNcp = sen?.DadosPerformance?.Clone();
LivoxLidar = sen?.LivoxLidar?.Clone();
OperadorVisual = VisualWorkerService
.DadosLeitura?
.Resumo?
.Clone();
OperadorVisual = sen?.OperadorVisual?.Resumo?.Clone();
}
private void AtualizarCameras()
@ -1154,14 +1018,14 @@ namespace AgroBase.Models.Operacoes
: new List<CameraWorkerItemModel>();
}
private void AtualizarLogs(dynamic sen)
private void AtualizarLogs(OperacaoSensoriamentoConjuntoModel sen)
{
DateTime corte = UltimoEnvioLog;
var logs = sen?.Logs;
Logs = logs != null
? ((IEnumerable<OperacaoSensoriamentoLogErrosModel>)logs)
? logs
.Where(x => x != null && x.Momento > corte)
.ToList()
: new List<OperacaoSensoriamentoLogErrosModel>();
@ -1185,8 +1049,8 @@ namespace AgroBase.Models.Operacoes
Imu = Imu?.Clone(),
Atuador = CloneAtuador(Atuador),
Sensoriamento = CloneSensoriamento(Sensoriamento),
Movimentacao = CloneMovimentacao(Movimentacao),
Direcional = CloneDirecional(Direcional),
Movimentacao = Movimentacao.Clone(),
Direcional = Direcional.Clone(),
Bateria = Bateria?.Clone(),
Refrigeracao = Refrigeracao?.Clone(),
@ -1204,8 +1068,7 @@ namespace AgroBase.Models.Operacoes
};
}
private static OperacaoParametrosDadosOperacaoModel CloneOperacao(
OperacaoParametrosDadosOperacaoModel src)
private static OperacaoParametrosDadosOperacaoModel CloneOperacao(OperacaoParametrosDadosOperacaoModel src)
{
if (src == null)
return null;
@ -1228,8 +1091,7 @@ namespace AgroBase.Models.Operacoes
};
}
private static OperacaoParametrosDadosAtuadorModel CloneAtuador(
OperacaoParametrosDadosAtuadorModel src)
private static OperacaoParametrosDadosAtuadorModel CloneAtuador(OperacaoParametrosDadosAtuadorModel src)
{
if (src == null)
return null;
@ -1270,8 +1132,7 @@ namespace AgroBase.Models.Operacoes
};
}
private static OperacaoParametrosDadosBicoModel CloneBico(
OperacaoParametrosDadosBicoModel src)
private static OperacaoParametrosDadosBicoModel CloneBico(OperacaoParametrosDadosBicoModel src)
{
if (src == null)
return null;
@ -1297,8 +1158,7 @@ namespace AgroBase.Models.Operacoes
};
}
private static OperacaoParametrosDadosBombaModel CloneBomba(
OperacaoParametrosDadosBombaModel src)
private static OperacaoParametrosDadosBombaModel CloneBomba(OperacaoParametrosDadosBombaModel src)
{
if (src == null)
return null;
@ -1320,8 +1180,7 @@ namespace AgroBase.Models.Operacoes
};
}
private static OperacaoParametrosDadosSensoriamentoModel
CloneSensoriamento(OperacaoParametrosDadosSensoriamentoModel src)
private static OperacaoParametrosDadosSensoriamentoModel CloneSensoriamento(OperacaoParametrosDadosSensoriamentoModel src)
{
if (src == null)
return null;
@ -1342,8 +1201,7 @@ namespace AgroBase.Models.Operacoes
};
}
private static OperacaoParametrosDadosSensorModel CloneSensor(
OperacaoParametrosDadosSensorModel src)
private static OperacaoParametrosDadosSensorModel CloneSensor(OperacaoParametrosDadosSensorModel src)
{
if (src == null)
return null;
@ -1361,8 +1219,7 @@ namespace AgroBase.Models.Operacoes
};
}
private static OperacaoParametrosDadosServoModel CloneServo(
OperacaoParametrosDadosServoModel src)
private static OperacaoParametrosDadosServoModel CloneServo(OperacaoParametrosDadosServoModel src)
{
if (src == null)
return null;
@ -1379,8 +1236,7 @@ namespace AgroBase.Models.Operacoes
};
}
private static OperacaoParametrosDadosReleModel CloneRele(
OperacaoParametrosDadosReleModel src)
private static OperacaoParametrosDadosReleModel CloneRele(OperacaoParametrosDadosReleModel src)
{
if (src == null)
return null;
@ -1396,8 +1252,7 @@ namespace AgroBase.Models.Operacoes
};
}
private static OperacaoParametrosDadosSinaleiroModel CloneSinaleiro(
OperacaoParametrosDadosSinaleiroModel src)
private static OperacaoParametrosDadosSinaleiroModel CloneSinaleiro(OperacaoParametrosDadosSinaleiroModel src)
{
if (src == null)
return null;
@ -1414,41 +1269,7 @@ namespace AgroBase.Models.Operacoes
};
}
private static OperacaoParametrosDadosMovimentacaoModel
CloneMovimentacao(OperacaoParametrosDadosMovimentacaoModel src)
{
if (src == null)
return null;
return new OperacaoParametrosDadosMovimentacaoModel
{
VelocidadeMediaMs = src.VelocidadeMediaMs,
RPMMedio = src.RPMMedio,
TempoMovimentoSegs = src.TempoMovimentoSegs,
DistanciaPercorridaTotal = src.DistanciaPercorridaTotal,
DistanciaPercorridaParcial = src.DistanciaPercorridaParcial,
TemperaturaMedia = src.TemperaturaMedia,
Modulos = CloneList(src.Modulos),
UltimoComandoRespondido = src.UltimoComandoRespondido
};
}
private static OperacaoParametrosDadosDirecionalModel CloneDirecional(
OperacaoParametrosDadosDirecionalModel src)
{
if (src == null)
return null;
return new OperacaoParametrosDadosDirecionalModel
{
AnguloMedio = src.AnguloMedio,
Modulos = CloneList(src.Modulos),
UltimoComandoRespondido = src.UltimoComandoRespondido
};
}
private static OperacaoParametrosDadosGNSSModel CloneGnss(
OperacaoParametrosDadosGNSSModel src)
private static OperacaoParametrosDadosGNSSModel CloneGnss(OperacaoParametrosDadosGNSSModel src)
{
if (src == null)
return null;
@ -1563,10 +1384,7 @@ namespace AgroBase.Models.Operacoes
return result;
}
private static double TryGetDouble(
object obj,
string property,
double fallback)
private static double TryGetDouble(object obj, string property, double fallback)
{
if (obj == null ||
string.IsNullOrWhiteSpace(property))
@ -1850,25 +1668,6 @@ namespace AgroBase.Models.Operacoes
public DateTime UltimoComandoRespondido { get; set; }
}
public class OperacaoParametrosDadosMovimentacaoModel
{
public double VelocidadeMediaMs { get; set; }
public double RPMMedio { get; set; }
public double TempoMovimentoSegs { get; set; }
public double DistanciaPercorridaTotal { get; set; }
public double DistanciaPercorridaParcial { get; set; }
public double TemperaturaMedia { get; set; }
public List<OperacaoSensoriamentoLogMovDadosModel> Modulos { get; set; }
public DateTime UltimoComandoRespondido { get; set; }
}
public class OperacaoParametrosDadosDirecionalModel
{
public double AnguloMedio { get; set; }
public List<DirSensoriamentoLogModel> Modulos { get; set; }
public DateTime UltimoComandoRespondido { get; set; }
}
public class OperacaoParametrosDadosSensoriamentoModel
{
public bool Iniciado { get; set; }

View File

@ -1,23 +1,29 @@
using System;
using System.Collections.Generic;
namespace AgroBase.Models.Operadores
{
public class HealthWorkerModel
{
public DateTime Momento { get; set; }
public bool Iniciado { get; set; }
public DateTime IniciadoEm { get; set; }
public bool Pronto { get; set; }
public DateTime ProntoEm { get; set; }
public DateTime UltimaMensagem { get; set; }
public List<ManagerWorkerMessageResponseModulosPendentesModel> ModulosSaude = new List<ManagerWorkerMessageResponseModulosPendentesModel>();
public HealthWorkerModel Clone()
{
return new HealthWorkerModel()
{
Momento = Momento,
Iniciado = Iniciado,
IniciadoEm = IniciadoEm,
Pronto = Pronto,
ProntoEm = ProntoEm,
ModulosSaude = new List<ManagerWorkerMessageResponseModulosPendentesModel>(ModulosSaude ?? new List<ManagerWorkerMessageResponseModulosPendentesModel>()),
};
}

View File

@ -12,7 +12,6 @@ namespace AgroBase.Models.Operadores
public bool Pronto { get; set; }
public DateTime ProntoEm { get; set; }
public DateTime UltimaMensagem { get; set; }
//public WorkerMessageModel<ManagerWorkerMessageResponseModel> Leitura { get; set; }
public ManagerWorkerModel Clone()
{
@ -32,7 +31,6 @@ namespace AgroBase.Models.Operadores
IniciadoEm = DateTime.MinValue;
Pronto = false;
ProntoEm = DateTime.MinValue;
//Leitura = new WorkerMessageModel<ManagerWorkerMessageResponseModel>();
}
}

View File

@ -9,6 +9,7 @@ namespace AgroBase.Models.Operadores
{
public class VisualWorkerModel
{
public DateTime Momento { get; set; }
public bool Iniciado { get; set; }
public DateTime IniciadoEm { get; set; }
public bool Pronto { get; set; }
@ -28,6 +29,7 @@ namespace AgroBase.Models.Operadores
{
return new VisualWorkerModel()
{
Momento = Momento,
Iniciado = Iniciado,
IniciadoEm = IniciadoEm,
Pronto = Pronto,
@ -207,7 +209,9 @@ namespace AgroBase.Models.Operadores
public void AtualizarStatusBloqueioManual(VisualWorkerModel Sonar, bool consideraEmMovimento)
{
if (!(Variaveis.OperacaoEmAndamento.Parametros?.Controle?.OakParadaPorObstaculo ?? false))
var op = Variaveis.OperacaoEmAndamento;
if (!(op.Parametros?.Controle?.OakParadaPorObstaculo ?? false))
{
_comandoParadaEnviado = false;
DeveParar = false;
@ -217,7 +221,7 @@ namespace AgroBase.Models.Operadores
else
{
List<Direcao> _direcoesInterromperMovimento = new List<Direcao> { Direcao.Frente }; //, Direcao.Tras
Direcao _ultimaDirecaoControle = Variaveis.OperacaoEmAndamento.Controle?.TiposControle?.FirstOrDefault(x => x?.Tipo == T_Code.Mov)?.UltimaDirecao ?? Direcao.Parado;
Direcao _ultimaDirecaoControle = op.Controle?.TiposControle?.FirstOrDefault(x => x?.Tipo == T_Code.Mov)?.UltimaDirecao ?? Direcao.Parado;
bool _carroEmMovimento = _direcoesInterromperMovimento.Contains(_ultimaDirecaoControle);
bool emMovimento = consideraEmMovimento ? _carroEmMovimento : true;
DeveParar = Sonar?.StatusValido == true && (ParadaDetectada || Modo == "stop");
@ -591,25 +595,15 @@ namespace AgroBase.Models.Operadores
public class VisualWorkerPerformanceModel
{
public double timestamp { get; set; }
public Dictionary<string, VisualWorkerPerformanceLoopModel> loops { get; set; }
= new Dictionary<string, VisualWorkerPerformanceLoopModel>();
public Dictionary<string, VisualWorkerPerformanceLoopModel> loops { get; set; } = new Dictionary<string, VisualWorkerPerformanceLoopModel>();
public JObject sync { get; set; } = new JObject();
public JObject camera_cache { get; set; } = new JObject();
public VisualWorkerPerformanceCacheModel visual_cache { get; set; }
= new VisualWorkerPerformanceCacheModel();
public VisualWorkerPerformancePublicacaoModel pub_debug { get; set; }
= new VisualWorkerPerformancePublicacaoModel();
public VisualWorkerPerformanceCacheModel visual_cache { get; set; } = new VisualWorkerPerformanceCacheModel();
public VisualWorkerPerformancePublicacaoModel pub_debug { get; set; } = new VisualWorkerPerformancePublicacaoModel();
public JObject contadores { get; set; } = new JObject();
[JsonExtensionData]
public IDictionary<string, JToken> Extra { get; set; }
= new Dictionary<string, JToken>();
public IDictionary<string, JToken> Extra { get; set; } = new Dictionary<string, JToken>();
public VisualWorkerPerformanceModel Clone()
{
@ -647,16 +641,12 @@ namespace AgroBase.Models.Operadores
public class VisualWorkerPerformanceLoopModel
{
public double fps_real { get; set; }
public JObject periodo_ms { get; set; } = new JObject();
public JObject latencia_ms { get; set; } = new JObject();
public Dictionary<string, JObject> metrics_ms { get; set; }
= new Dictionary<string, JObject>();
public Dictionary<string, JObject> metrics_ms { get; set; } = new Dictionary<string, JObject>();
[JsonExtensionData]
public IDictionary<string, JToken> Extra { get; set; }
= new Dictionary<string, JToken>();
public IDictionary<string, JToken> Extra { get; set; } = new Dictionary<string, JToken>();
public VisualWorkerPerformanceLoopModel Clone()
{

View File

@ -9,6 +9,7 @@ namespace AgroBase.Models.Operadores
{
public class WeedWorkerModel
{
public DateTime Momento { get; set; }
public bool Iniciado { get; set; }
public DateTime IniciadoEm { get; set; }
public bool Pronto { get; set; }
@ -27,25 +28,17 @@ namespace AgroBase.Models.Operadores
{
return new WeedWorkerModel
{
Momento = Momento,
Iniciado = Iniciado,
IniciadoEm = IniciadoEm,
Pronto = Pronto,
ProntoEm = ProntoEm,
UltimaMensagem = UltimaMensagem,
Imu = Imu?.Clone(),
Analise = Analise?.Clone()
?? new WeedWorkerAnaliseModel(),
MetricasAnalise = MetricasAnalise?.Clone()
?? new WeedWorkerAnaliseMetricasModel(),
Performance = Performance?.Clone()
?? new WeedWorkerPerformanceModel(),
Timestamps = Timestamps?.Clone()
?? new WeedWorkerRedisTimestampsModel()
Analise = Analise?.Clone() ?? new WeedWorkerAnaliseModel(),
MetricasAnalise = MetricasAnalise?.Clone() ?? new WeedWorkerAnaliseMetricasModel(),
Performance = Performance?.Clone() ?? new WeedWorkerPerformanceModel(),
Timestamps = Timestamps?.Clone() ?? new WeedWorkerRedisTimestampsModel(),
};
}
@ -59,8 +52,7 @@ namespace AgroBase.Models.Operadores
UltimaMensagem = DateTime.MinValue;
CameraFrames =
new Dictionary<TipoFrameCamera, OAKCameraFrameModel>();
CameraFrames = new Dictionary<TipoFrameCamera, OAKCameraFrameModel>();
Analise = new WeedWorkerAnaliseModel();
Imu = new OAKImuModel();
@ -89,19 +81,14 @@ namespace AgroBase.Models.Operadores
public class WeedWorkerAnaliseEnvelopeModel
{
public double ts_analise { get; set; }
public double fps_model { get; set; }
public double fps_inferencia { get; set; }
public double infer_ms { get; set; }
public double infer_gpu_ms { get; set; }
public WeedWorkerAnaliseModel analise { get; set; }
= new WeedWorkerAnaliseModel();
public WeedWorkerAnaliseModel analise { get; set; } = new WeedWorkerAnaliseModel();
[JsonExtensionData]
public IDictionary<string, JToken> Extra { get; set; }
= new Dictionary<string, JToken>();
public IDictionary<string, JToken> Extra { get; set; } = new Dictionary<string, JToken>();
public WeedWorkerAnaliseEnvelopeModel Clone()
{
@ -112,14 +99,8 @@ namespace AgroBase.Models.Operadores
fps_inferencia = fps_inferencia,
infer_ms = infer_ms,
infer_gpu_ms = infer_gpu_ms,
analise = analise?.Clone()
?? new WeedWorkerAnaliseModel(),
Extra = Extra?.ToDictionary(
x => x.Key,
x => x.Value?.DeepClone()
) ?? new Dictionary<string, JToken>()
analise = analise?.Clone() ?? new WeedWorkerAnaliseModel(),
Extra = Extra?.ToDictionary(x => x.Key, x => x.Value?.DeepClone()) ?? new Dictionary<string, JToken>()
};
}
}
@ -197,61 +178,36 @@ namespace AgroBase.Models.Operadores
public class WeedWorkerAnaliseEstatisticasBicosModel
{
public string motivo { get; set; }
public List<double> frac_erva_por_bico { get; set; }
= new List<double>();
public List<double> ema_frac_por_bico { get; set; }
= new List<double>();
public WeedWorkerAnaliseEstatisticasBicosFaixaModel faixa { get; set; }
= new WeedWorkerAnaliseEstatisticasBicosFaixaModel();
public List<double> larguras { get; set; }
= new List<double>();
public List<double> frac_erva_por_bico { get; set; } = new List<double>();
public List<double> ema_frac_por_bico { get; set; } = new List<double>();
public WeedWorkerAnaliseEstatisticasBicosFaixaModel faixa { get; set; } = new WeedWorkerAnaliseEstatisticasBicosFaixaModel();
public List<double> larguras { get; set; } = new List<double>();
public int shift_px { get; set; }
public double thr_on_eff { get; set; }
public double thr_off_eff { get; set; }
public List<int> on_cnt { get; set; }
= new List<int>();
public List<int> off_cnt { get; set; }
= new List<int>();
public List<bool> estado_bico { get; set; }
= new List<bool>();
public List<int> on_cnt { get; set; } = new List<int>();
public List<int> off_cnt { get; set; } = new List<int>();
public List<bool> estado_bico { get; set; } = new List<bool>();
[JsonExtensionData]
public IDictionary<string, JToken> Extra { get; set; }
= new Dictionary<string, JToken>();
public IDictionary<string, JToken> Extra { get; set; } = new Dictionary<string, JToken>();
public WeedWorkerAnaliseEstatisticasBicosModel Clone()
{
return new WeedWorkerAnaliseEstatisticasBicosModel
{
motivo = motivo,
frac_erva_por_bico =
new List<double>(frac_erva_por_bico ?? new List<double>()),
ema_frac_por_bico =
new List<double>(ema_frac_por_bico ?? new List<double>()),
faixa = faixa?.Clone()
?? new WeedWorkerAnaliseEstatisticasBicosFaixaModel(),
larguras =
new List<double>(larguras ?? new List<double>()),
frac_erva_por_bico = new List<double>(frac_erva_por_bico ?? new List<double>()),
ema_frac_por_bico = new List<double>(ema_frac_por_bico ?? new List<double>()),
faixa = faixa?.Clone() ?? new WeedWorkerAnaliseEstatisticasBicosFaixaModel(),
larguras = new List<double>(larguras ?? new List<double>()),
shift_px = shift_px,
thr_on_eff = thr_on_eff,
thr_off_eff = thr_off_eff,
on_cnt = new List<int>(on_cnt ?? new List<int>()),
off_cnt = new List<int>(off_cnt ?? new List<int>()),
estado_bico =
new List<bool>(estado_bico ?? new List<bool>()),
Extra = Extra?.ToDictionary(
x => x.Key,
x => x.Value?.DeepClone()
) ?? new Dictionary<string, JToken>()
estado_bico = new List<bool>(estado_bico ?? new List<bool>()),
Extra = Extra?.ToDictionary(x => x.Key, x => x.Value?.DeepClone()) ?? new Dictionary<string, JToken>()
};
}
}
@ -275,53 +231,26 @@ namespace AgroBase.Models.Operadores
public class WeedWorkerPerformanceModel
{
public double timestamp { get; set; }
public Dictionary<string, WeedWorkerPerformanceLoopModel> loops { get; set; }
= new Dictionary<string, WeedWorkerPerformanceLoopModel>();
public Dictionary<string, WeedWorkerPerformanceLoopModel> loops { get; set; } = new Dictionary<string, WeedWorkerPerformanceLoopModel>();
public JObject sync { get; set; } = new JObject();
public WeedWorkerPerformanceCacheModel weed_cache { get; set; }
= new WeedWorkerPerformanceCacheModel();
public WeedWorkerPerformancePublicacaoModel pub_debug { get; set; }
= new WeedWorkerPerformancePublicacaoModel();
public WeedWorkerPerformanceCacheModel weed_cache { get; set; } = new WeedWorkerPerformanceCacheModel();
public WeedWorkerPerformancePublicacaoModel pub_debug { get; set; } = new WeedWorkerPerformancePublicacaoModel();
public JObject contadores { get; set; } = new JObject();
[JsonExtensionData]
public IDictionary<string, JToken> Extra { get; set; }
= new Dictionary<string, JToken>();
public IDictionary<string, JToken> Extra { get; set; } = new Dictionary<string, JToken>();
public WeedWorkerPerformanceModel Clone()
{
return new WeedWorkerPerformanceModel
{
timestamp = timestamp,
loops = loops?.ToDictionary(
x => x.Key,
x => x.Value?.Clone()
) ?? new Dictionary<string, WeedWorkerPerformanceLoopModel>(),
sync = sync != null
? (JObject)sync.DeepClone()
: new JObject(),
weed_cache = weed_cache?.Clone()
?? new WeedWorkerPerformanceCacheModel(),
pub_debug = pub_debug?.Clone()
?? new WeedWorkerPerformancePublicacaoModel(),
contadores = contadores != null
? (JObject)contadores.DeepClone()
: new JObject(),
Extra = Extra?.ToDictionary(
x => x.Key,
x => x.Value?.DeepClone()
) ?? new Dictionary<string, JToken>()
loops = loops?.ToDictionary(x => x.Key, x => x.Value?.Clone()) ?? new Dictionary<string, WeedWorkerPerformanceLoopModel>(),
sync = sync != null ? (JObject)sync.DeepClone() : new JObject(),
weed_cache = weed_cache?.Clone() ?? new WeedWorkerPerformanceCacheModel(),
pub_debug = pub_debug?.Clone() ?? new WeedWorkerPerformancePublicacaoModel(),
contadores = contadores != null ? (JObject)contadores.DeepClone() : new JObject(),
Extra = Extra?.ToDictionary(x => x.Key, x => x.Value?.DeepClone()) ?? new Dictionary<string, JToken>()
};
}
}
@ -329,42 +258,21 @@ namespace AgroBase.Models.Operadores
public class WeedWorkerPerformanceLoopModel
{
public double fps_real { get; set; }
public JObject periodo_ms { get; set; } = new JObject();
public JObject latencia_ms { get; set; } = new JObject();
public Dictionary<string, JObject> metrics_ms { get; set; }
= new Dictionary<string, JObject>();
public Dictionary<string, JObject> metrics_ms { get; set; } = new Dictionary<string, JObject>();
[Newtonsoft.Json.JsonExtensionData]
public IDictionary<string, JToken> Extra { get; set; }
= new Dictionary<string, JToken>();
public IDictionary<string, JToken> Extra { get; set; } = new Dictionary<string, JToken>();
public WeedWorkerPerformanceLoopModel Clone()
{
return new WeedWorkerPerformanceLoopModel
{
fps_real = fps_real,
periodo_ms = periodo_ms != null
? (JObject)periodo_ms.DeepClone()
: new JObject(),
latencia_ms = latencia_ms != null
? (JObject)latencia_ms.DeepClone()
: new JObject(),
metrics_ms = metrics_ms?.ToDictionary(
x => x.Key,
x => x.Value != null
? (JObject)x.Value.DeepClone()
: new JObject()
) ?? new Dictionary<string, JObject>(),
Extra = Extra?.ToDictionary(
x => x.Key,
x => x.Value?.DeepClone()
) ?? new Dictionary<string, JToken>()
periodo_ms = periodo_ms != null ? (JObject)periodo_ms.DeepClone() : new JObject(),
latencia_ms = latencia_ms != null ? (JObject)latencia_ms.DeepClone() : new JObject(),
metrics_ms = metrics_ms?.ToDictionary(x => x.Key, x => x.Value != null ? (JObject)x.Value.DeepClone() : new JObject()) ?? new Dictionary<string, JObject>(),
Extra = Extra?.ToDictionary(x => x.Key, x => x.Value?.DeepClone()) ?? new Dictionary<string, JToken>()
};
}
}

View File

@ -1,7 +1,6 @@
using OpenHardwareMonitor.Hardware;
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
namespace AgroBase.Models

View File

@ -4,8 +4,6 @@ using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static AgroBase.Models.Enums;
@ -601,7 +599,7 @@ namespace AgroBase.Models
{
get
{
return DistanciaMedia / FuncoesMatematicas.ConverteKmhParaMs(Variaveis.OperacaoEmAndamento.Sensoriamento.Movimentacao.VelocidadeMedia);
return DistanciaMedia / FuncoesMatematicas.ConverteKmhParaMs(Variaveis.OperacaoEmAndamento.Sensoriamento.Movimentacao.VelocidadeMediaMs);
}
}
public double DeslocamentoNecessarioDesvio

View File

@ -38,11 +38,14 @@ namespace AgroBase.Models
public bool RetornandoBase { get; set; }
public AutonomiaCorredorModel AutonomiaCorredor { get; set; }
[JsonIgnore]
private GPSModel GPSPosicaoAtual => Variaveis.OperacaoEmAndamento.Sensoriamento?.Gps?.Clone();
[JsonProperty]
public double TempoEntreLeituras { get; private set; }
private void AtualizarTempoEntreLeituras()
{
DateTime leitura_gps = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps?.Momento ?? DateTime.MinValue;
DateTime leitura_gps = GPSPosicaoAtual?.Momento ?? DateTime.MinValue;
double t_min = (1.0 / GPSService.TaxaAmostragemHz);
double dt = (leitura_gps - UltimaAtualizacaoDados).TotalSeconds;
TempoEntreLeituras = Math.Min(t_min, dt);
@ -89,8 +92,8 @@ namespace AgroBase.Models
{
get
{
double distPP = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, PrimeiroPontoRuaMapa);
double distUP = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, UltimoPontoRuaMapa);
double distPP = GPSUtils.DistanciaEntrePontos(GPSPosicaoAtual, PrimeiroPontoRuaMapa);
double distUP = GPSUtils.DistanciaEntrePontos(GPSPosicaoAtual, UltimoPontoRuaMapa);
// 0 para mais próximo do primeiro ponto da rua (ENTRANDO)
// 1 para mais próximo do último ponto da rua (SAINDO)
@ -130,7 +133,7 @@ namespace AgroBase.Models
{
new PontoTrajetoriaModel(TipoPontoRua.PosicaoRobo)
{
Posicao = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps,
Posicao = GPSPosicaoAtual,
LarguraCorredor = 1.0,
idxCorredor = CorredorAtual?.Idx ?? 0,
Visitado = true
@ -233,7 +236,7 @@ namespace AgroBase.Models
private void AtualizarAnguloCaminho()
{
PontoTrajetoriaModel pontoComparar = PontoAtual.Aproximando ? PontoAtual : ProximoPonto != null ? ProximoPonto : PontoAtual;
AnguloCaminho = GPSUtils.CalcularOrientacao(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, pontoComparar.Posicao);
AnguloCaminho = GPSUtils.CalcularOrientacao(GPSPosicaoAtual, pontoComparar.Posicao);
}
[JsonProperty]
public double DistanciaEsquerda { get; private set; }
@ -241,8 +244,8 @@ namespace AgroBase.Models
public double DistanciaDireita { get; private set; }
private void AtualizarDistanciasLaterais()
{
DistanciaEsquerda = CalcularDistanciaLateral(true, Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, CorredorAtual?.idxRuaEsquerda ?? 0, PontoAtual?.Direcao ?? DirecaoCarroRua.Ida);
DistanciaDireita = CalcularDistanciaLateral(false, Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, CorredorAtual?.idxRuaDireita ?? 0, PontoAtual?.Direcao ?? DirecaoCarroRua.Ida);
DistanciaEsquerda = CalcularDistanciaLateral(true, GPSPosicaoAtual, CorredorAtual?.idxRuaEsquerda ?? 0, PontoAtual?.Direcao ?? DirecaoCarroRua.Ida);
DistanciaDireita = CalcularDistanciaLateral(false, GPSPosicaoAtual, CorredorAtual?.idxRuaDireita ?? 0, PontoAtual?.Direcao ?? DirecaoCarroRua.Ida);
}
public double CalcularDistanciaLateral(bool ladoEsquerdo, GPSModel posicaoAtual, int idxRua, DirecaoCarroRua direcaoAtual)
@ -435,7 +438,7 @@ namespace AgroBase.Models
{
if (CorredorAtual != null)
{
if ((RetornandoBase && CorredorAtual.Dentro) || (!RetornandoBase && Variaveis.OperacaoEmAndamento.StatusAtual == StatusOperacao.EmAndamento))
if ((RetornandoBase && CorredorAtual.Dentro) || (!RetornandoBase && Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.StatusOperacaoAtual == StatusOperacao.EmAndamento))
{
PontoAtual.AtualizarPropriedades();
if (!CorredorAtual.Dentro && ProximoPonto.DistanciaAtual > DistanciaManobraEntreRuas)
@ -506,18 +509,20 @@ namespace AgroBase.Models
public string TempoEstimadoRestante { get; private set; }
public void AtualizarTempoEstimado(double? velocidadeSemErvasMs = null, double? velocidadeComErvasMs = null)
{
var op = Variaveis.OperacaoEmAndamento;
if (!velocidadeSemErvasMs.HasValue)
{
velocidadeSemErvasMs = FuncoesMatematicas.CalculaVelocidadeMsPercentual(Variaveis.OperacaoEmAndamento.Parametros.Controle.MovVelocidadeSErvasPercent) * 0.8;
velocidadeSemErvasMs = FuncoesMatematicas.CalculaVelocidadeMsPercentual(op.Parametros.Controle.MovVelocidadeSErvasPercent) * 0.8;
}
if (!velocidadeComErvasMs.HasValue)
{
velocidadeComErvasMs = FuncoesMatematicas.CalculaVelocidadeMsPercentual(Variaveis.OperacaoEmAndamento.Parametros.Controle.MovVelocidadeCErvasPercent);
velocidadeComErvasMs = FuncoesMatematicas.CalculaVelocidadeMsPercentual(op.Parametros.Controle.MovVelocidadeCErvasPercent);
}
// Supondo que metade do percurso tem ervas e a outra metade não tem
double distanciaComErvas = DistanciaTotal * VariaveisOperacao.PercentualComErvas;
double distanciaSemErvas = DistanciaTotal * VariaveisOperacao.PercentualSemErvas;
double distanciaComErvas = DistanciaTotal * op.Sensoriamento.Atuador.PercentualErvasTerreno;
double distanciaSemErvas = DistanciaTotal * (100 - op.Sensoriamento.Atuador.PercentualErvasTerreno);
// Tempo em segundos para cada parte do percurso
double tempoSemErvas = velocidadeSemErvasMs.Value > 0 ? distanciaSemErvas / velocidadeSemErvasMs.Value : 0;
@ -536,8 +541,8 @@ namespace AgroBase.Models
double distanciaRestante = DistanciaRestante;
// Calcular a distância restante sem ervas e com ervas
double distanciaSemErvasRestante = distanciaRestante * VariaveisOperacao.PercentualSemErvas;
double distanciaComErvasRestante = distanciaRestante * VariaveisOperacao.PercentualComErvas;
double distanciaSemErvasRestante = distanciaRestante * (100 - op.Sensoriamento.Atuador.PercentualErvasTerreno);
double distanciaComErvasRestante = distanciaRestante * op.Sensoriamento.Atuador.PercentualErvasTerreno;
// Calcular o tempo restante para as áreas sem ervas e com ervas
double tempoRestanteSemErvas = distanciaSemErvasRestante / velocidadeSemErvasMs.Value;
@ -563,12 +568,12 @@ namespace AgroBase.Models
if (CorredorAtual.Idx > 0) return;
if (!CorredorAtual.Dentro) return;
GPSModel posicaoAtual = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.Clone();
var op = Variaveis.OperacaoEmAndamento;
if (PrimeiroPontoDentroMapa == null) PrimeiroPontoDentroMapa = posicaoAtual;
if (PrimeiroPontoDentroMapa == null) PrimeiroPontoDentroMapa = GPSPosicaoAtual;
var OpVisual = Variaveis.OperacaoEmAndamento.Sensoriamento?.OperadorVisual ?? new VisualWorkerModel();
StatusModulo OpVisualStatus = Variaveis.OperacaoEmAndamento.Sensoriamento.ModulosSaude.FirstOrDefault(x => x.modulo == T_Code.Snr)?.status ?? StatusModulo.Desconectado;
var OpVisual = op.Sensoriamento?.OperadorVisual ?? new VisualWorkerModel();
StatusModulo OpVisualStatus = op.Sensoriamento.OperadorSaude.ModulosSaude.FirstOrDefault(x => x.modulo == T_Code.Snr)?.status ?? StatusModulo.Desconectado;
if (OpVisualStatus != StatusModulo.Operante) return;
@ -576,7 +581,7 @@ namespace AgroBase.Models
bool CanaNoRadar = new List<StatusCarroMapa>() { StatusCarroMapa.EntrandoRua, StatusCarroMapa.CaminhandoRua, StatusCarroMapa.SaindoRua }.Contains(DadosSegmentacao.status_corredor);
if (!CanaNoRadar) return;
PrimeiroPontoDentroCana = posicaoAtual;
PrimeiroPontoDentroCana = GPSPosicaoAtual;
DistanciaErroMapaPlantacao = GPSUtils.DistanciaEntrePontos(PrimeiroPontoDentroMapa, PrimeiroPontoDentroCana);
}
@ -600,7 +605,9 @@ namespace AgroBase.Models
private void AtualizarErroCombinado()
{
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
var op = Variaveis.OperacaoEmAndamento;
var _Sensoriamento = op.Sensoriamento;
//double anguloCamera = _Sensoriamento.OperadorVisual.Leitura.obj?.segmentacao?.angulo_rua ?? 0;
double anguloCorredor = AnguloMedioCorredor;
@ -617,7 +624,7 @@ namespace AgroBase.Models
double curvaDaRua = GPSUtils.CalcularDiferencaAngulo(anguloProximoPonto, anguloCorredor);
// Peso do desalinhamento atual (prioriza alinhar o robô ao corredor)
double pesoAlinhamento = Math.Min(Math.Abs(desalinhamentoComRua) / Variaveis.OperacaoEmAndamento.Parametros.Controle.DirAnguloMaximo, 1.0); // Normaliza até 30°
double pesoAlinhamento = Math.Min(Math.Abs(desalinhamentoComRua) / op.Parametros.Controle.DirAnguloMaximo, 1.0); // Normaliza até 30°
// Peso do centro (prioriza ir pro ponto central do corredor)
double pesoCentro = 1.0 - pesoAlinhamento;
@ -756,7 +763,7 @@ namespace AgroBase.Models
private bool VerificaInicioOperacaoMeioRua(bool considerarStatus)
{
if (_TrajetoriaFixaDefinida && !VerificacaoInicialMeioRuaConcluida && ((considerarStatus && new List<StatusOperacao>() { StatusOperacao.Aguardando, StatusOperacao.EmAndamento }.Contains(Variaveis.OperacaoEmAndamento.StatusAtual)) || !considerarStatus))
if (_TrajetoriaFixaDefinida && !VerificacaoInicialMeioRuaConcluida && ((considerarStatus && new List<StatusOperacao>() { StatusOperacao.Aguardando, StatusOperacao.EmAndamento }.Contains(Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.StatusOperacaoAtual)) || !considerarStatus))
{
VerificacaoInicialMeioRuaConcluida = true;
(bool noCoredor, var idxPontoMaisProximo) = VerificaEquipamentoDentroCorredorMontado(_TrajetoriaFixa[0].Posicao);
@ -779,22 +786,23 @@ namespace AgroBase.Models
private void VerificaFimCorredorSegmentacao()
{
var op = Variaveis.OperacaoEmAndamento;
// Limiar de "margem" para considerar proximidade do fim
//double limiarDistanciaMargem = DistanciaErroMapaPlantacao > -1 ? DistanciaErroMapaPlantacao : 10.0;
double limiarDistanciaMargem = Variaveis.OperacaoEmAndamento.Parametros?.Controle?.AnteciparManobraCorredorM ?? 0;
double limiarDistanciaMargem = op.Parametros?.Controle?.AnteciparManobraCorredorM ?? 0;
if (limiarDistanciaMargem <= 0) return;
if (CorredorAtual == null) return;
if (CorredorAtual.DadosVisuais.JaAntecipado) return;
bool modoSimulador = false && Variaveis.OperacaoEmAndamento.Simulando;
bool modoSimulador = false && op.Simulando;
double distanciaCorredor = CorredorAtual.DistanciaTotal;
double distanciaRestanteCorredor = CorredorAtual.DistanciaRestante;
double distanciaUltimoPontoCorredor = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, CorredorAtual.Pontos.LastOrDefault().Posicao);
double distanciaUltimoPontoCorredor = GPSUtils.DistanciaEntrePontos(GPSPosicaoAtual, CorredorAtual.Pontos.LastOrDefault().Posicao);
var opVisual = Variaveis.OperacaoEmAndamento.Sensoriamento?.OperadorVisual ?? new VisualWorkerModel();
StatusModulo opVisualStatus = Variaveis.OperacaoEmAndamento.Sensoriamento.ModulosSaude.FirstOrDefault(x => x.modulo == T_Code.Snr)?.status ?? StatusModulo.Desconectado;
var opVisual = op.Sensoriamento?.OperadorVisual ?? new VisualWorkerModel();
StatusModulo opVisualStatus = op.Sensoriamento.OperadorSaude.ModulosSaude.FirstOrDefault(x => x.modulo == T_Code.Snr)?.status ?? StatusModulo.Desconectado;
var dadosSegmentacao = opVisual.Analises?.segmentacao ?? new VisualWorkerMessageSegmentacaoSemanticaModel();
// Se não tem visual operante, não está no modoSimulador ou o corredor eh curto demais, não faz nada
@ -919,12 +927,12 @@ namespace AgroBase.Models
// acha o ponto mais próximo do corredor seguinte
var pc = _Corredores[CorredorAtual.Idx + 1];
(GPSModel pp, double distanciaAtual) = GPSUtils.CalcularPontoMaisProximoTrajetoria(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, pc.Pontos.Select(x => x.Posicao).ToList());
(GPSModel pp, double distanciaAtual) = GPSUtils.CalcularPontoMaisProximoTrajetoria(GPSPosicaoAtual, pc.Pontos.Select(x => x.Posicao).ToList());
var _pp = pc.Pontos.FirstOrDefault(x => Math.Abs(x.Posicao.Latitude - pp.Latitude) < 1e-8 && Math.Abs(x.Posicao.Longitude - pp.Longitude) < 1e-8);
double anguloControle = CorredorAtual.idxRuaDireita > CorredorAtual.idxRuaEsquerda ? -AnguloAberturaCurva : AnguloAberturaCurva;
double anguloDesvio = PontoAtual.Orientacao + anguloControle;
double fd = FuncoesMatematicas.Map(Variaveis.OperacaoEmAndamento.Sensoriamento.Controle.PercentualVelocidadeSP, 10, 100, 0.7, 2.5);
double fd = FuncoesMatematicas.Map(op.Controle.PercentualVelocidadeSP, 10, 100, 0.7, 2.5);
var pontoDesvio = GPSUtils.GerarPontoDeslocado(pls.Posicao, anguloDesvio, DistanciaProjecaoRua * fd);
@ -968,7 +976,7 @@ namespace AgroBase.Models
ReindexarTrajetoriaFixa();
Variaveis.OperacaoEmAndamento.Sensoriamento.AtualizarDados();
op.Sensoriamento.AtualizarDados();
HealthWorkerService.AtualizarDadosOperacao(true);
}
}
@ -986,14 +994,16 @@ namespace AgroBase.Models
public void LoopAtualizaDados()
{
if (!(Variaveis.OperacaoEmAndamento.Parametros?.ControleAutomatico ?? false))
var op = Variaveis.OperacaoEmAndamento;
if (!(op.Parametros?.ControleAutomatico ?? false))
return;
AtualizarPropriedadesPontosTrajetoria();
AtualizarDadosTrajetoria();
//Variaveis.OperacaoEmAndamento.AtualizaInformacoesControleOperacao();
//op.AtualizaInformacoesControleOperacao();
//RedisService.Publish(CmdKey.ManagerWorkerRx, JsonConvert.SerializeObject(new { cmd = ManagerWorkerCommandType.AtualizarDadosControle }));
@ -1002,7 +1012,9 @@ namespace AgroBase.Models
private void AtualizarDadosControleRedis()
{
if (!Variaveis.OperacaoEmAndamento.Iniciado)
var op = Variaveis.OperacaoEmAndamento;
if (!op.Sensoriamento.Operacao.OperacaoIniciada)
return;
int min_ticks_sem_resposta = 500;
@ -1027,7 +1039,7 @@ namespace AgroBase.Models
DateTime agora = DateTime.Now;
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
var _Controle = op.Controle;
bool heartbeatMudou =
novoComando != null &&
@ -1083,9 +1095,9 @@ namespace AgroBase.Models
{
if (_Controle.ticks_sem_resposta.AddMilliseconds(max_ticks_sem_resposta) < agora)
{
if (Variaveis.OperacaoEmAndamento?.Sensoriamento?.Controle?.RPM_SP > 0)
if (op.Controle?.RPM_SP > 0)
{
Variaveis.OperacaoEmAndamento.Sensoriamento?.InserirLog(T_Code.Npc, StatusModulo.Falha, 0, "Muito tempo sem receber novo comando do Manager Worker! Parando Movimento!");
op.Sensoriamento?.InserirLog(T_Code.Npc, StatusModulo.Falha, 0, "Muito tempo sem receber novo comando do Manager Worker! Parando Movimento!");
Variaveis.MostrarLog("Muito tempo sem receber novo comando do Manager Worker! Parando Movimento!");
RedisService.AtualizarCampos(
CtxKey.DadosControle,
@ -1095,13 +1107,13 @@ namespace AgroBase.Models
}
else if (_Controle.ticks_sem_resposta.AddMilliseconds(min_ticks_sem_resposta) < agora)
{
if (Variaveis.OperacaoEmAndamento?.Sensoriamento?.Controle?.RPM_SP > Variaveis.OperacaoEmAndamento.Parametros.Controle.MovVelocidadeCErvasPercent)
if (op.Controle?.RPM_SP > op.Parametros.Controle.MovVelocidadeCErvasPercent)
{
Variaveis.OperacaoEmAndamento.Sensoriamento?.InserirLog(T_Code.Npc, StatusModulo.Alerta, 80, "Muito tempo sem receber novo comando do Manager Worker! Reduzindo Velocidade!");
op.Sensoriamento?.InserirLog(T_Code.Npc, StatusModulo.Alerta, 80, "Muito tempo sem receber novo comando do Manager Worker! Reduzindo Velocidade!");
Variaveis.MostrarLog("Muito tempo sem receber novo comando do Manager Worker! Reduzindo Velocidade!");
RedisService.AtualizarCampos(
CtxKey.DadosControle,
("velocidade_sp", Variaveis.OperacaoEmAndamento.Parametros.Controle.MovVelocidadeCErvasPercent)
("velocidade_sp", op.Parametros.Controle.MovVelocidadeCErvasPercent)
);
}
}
@ -1348,7 +1360,7 @@ namespace AgroBase.Models
idxCorredor = 0,
idxPonto = 0,
idxPontoCorredor = 0,
Posicao = posicaoRobo ?? Variaveis.OperacaoEmAndamento.Sensoriamento.Gps,
Posicao = posicaoRobo ?? GPSPosicaoAtual,
Orientacao = 0,
Direcao = direcaoAtual,
Visitado = true,
@ -1657,15 +1669,13 @@ namespace AgroBase.Models
public void AjustarTrajetoriaParaDesvio(Obstaculo obstaculo)
{
GPSModel posicaoAtual = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps;
double distanciaObstaculo = ((double)obstaculo.DistanciaMedia_mm / 1000);
double larguraObstaculo = ((double)obstaculo.Largura_mm / 1000);
double anguloCaminho = AnguloCaminho;
double anguloDesvioInicial = anguloCaminho + obstaculo.AnguloParaDesvio;
double anguloDesvioFinal = anguloCaminho - obstaculo.AnguloParaDesvio;
GPSModel ponto1 = GPSUtils.GerarPontoDeslocado(posicaoAtual, anguloDesvioInicial, distanciaObstaculo);
GPSModel ponto1 = GPSUtils.GerarPontoDeslocado(GPSPosicaoAtual, anguloDesvioInicial, distanciaObstaculo);
GPSModel ponto2 = GPSUtils.GerarPontoDeslocado(ponto1, anguloCaminho, larguraObstaculo);
GPSModel ponto3 = GPSUtils.GerarPontoDeslocado(ponto2, anguloDesvioFinal, distanciaObstaculo);
List<PontoTrajetoriaModel> lista = new List<PontoTrajetoriaModel>()
@ -1789,7 +1799,7 @@ namespace AgroBase.Models
idxCorredor = 0,
idxPonto = 0,
idxPontoCorredor = 0,
Posicao = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps,
Posicao = GPSPosicaoAtual,
Visitado = true,
LarguraCorredor = 1.0
});
@ -1829,6 +1839,8 @@ namespace AgroBase.Models
private void AtualizarDadosOperacaoParaRetorno()
{
var op = Variaveis.OperacaoEmAndamento;
AutonomiaCorredor.Parar();
AtualizarDadosTrajetoria();
@ -1836,12 +1848,12 @@ namespace AgroBase.Models
LoopAtualizaDados();
var _p = OperacaoModel.CarregarParametrosOperacaoPadrao(ModoOperacao.RetornoBase, false);
Variaveis.OperacaoEmAndamento.Parametros = _p;
op.Parametros = _p;
if (!Variaveis.OperacaoEmAndamento.Iniciado)
if (!op.Sensoriamento.Operacao.OperacaoIniciada)
{
Variaveis.OperacaoEmAndamento.Iniciado = true;
Variaveis.OperacaoEmAndamento.Simulando = !GPSService.Iniciado;
op.Sensoriamento.Operacao.OperacaoIniciada = true;
op.Simulando = !GPSService.Iniciado;
}
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
@ -1851,7 +1863,7 @@ namespace AgroBase.Models
{
var pontos = new List<GPSModel>();
GPSModel posicaoAtual = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps;
GPSModel posicaoAtual = GPSPosicaoAtual;
double distancia = GPSUtils.DistanciaEntrePontos(posicaoAtual, baseGps);
if (distancia < 5)
@ -2642,20 +2654,22 @@ namespace AgroBase.Models
private void AtualizarDistanciaTrajeto()
{
if (!Variaveis.OperacaoEmAndamento.Trajetoria._TrajetoriaFixaDefinida)
var op = Variaveis.OperacaoEmAndamento;
if (!op.Trajetoria._TrajetoriaFixaDefinida)
{
return;
}
var pontoAtual = Variaveis.OperacaoEmAndamento.Trajetoria.PontoAtual;
var pontoAtual = op.Trajetoria.PontoAtual;
int idxPontoAtual = pontoAtual.idxPonto + 1;
int qtdPontos = Math.Abs(idxPonto - idxPontoAtual) + 1; // Sempre positivo
if (qtdPontos == 1)
{
//DistanciaTrajeto = pontoAtual.Aproximando ? pontoAtual.DistanciaAtual : -pontoAtual.DistanciaAtual;
//DistanciaTrajeto = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Trajetoria._TrajetoriaDinamica.First().Posicao, Posicao);
DistanciaTrajeto = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Trajetoria._TrajetoriaFixa.Where(x => !x.Visitado).First().Posicao, Posicao);
//DistanciaTrajeto = GPSUtils.DistanciaEntrePontos(op.Trajetoria._TrajetoriaDinamica.First().Posicao, Posicao);
DistanciaTrajeto = GPSUtils.DistanciaEntrePontos(op.Trajetoria._TrajetoriaFixa.Where(x => !x.Visitado).First().Posicao, Posicao);
return;
}
@ -2664,7 +2678,7 @@ namespace AgroBase.Models
int idxFim = Math.Max(idxPontoAtual, idxPonto);
// ✅ Pega os pontos corretos, independentemente de direção
List<GPSModel> trecho = Variaveis.OperacaoEmAndamento.Trajetoria._TrajetoriaFixa
List<GPSModel> trecho = op.Trajetoria._TrajetoriaFixa
.Skip(idxInicio)
.Take(qtdPontos)
.ToList()
@ -2829,8 +2843,10 @@ namespace AgroBase.Models
return;
}
var op = Variaveis.OperacaoEmAndamento;
// Valida índice do corredor
if (Variaveis.OperacaoEmAndamento.Trajetoria?._Corredores?.Count <= idxCorredor)
if (op.Trajetoria?._Corredores?.Count <= idxCorredor)
return;
// Se já registrou esse corredor como liberado e travado/feito, não recalcula
@ -2844,10 +2860,10 @@ namespace AgroBase.Models
bool solicitouLiberacaoHumana = bateria_liberada || reservatorio_liberado;
// Carrega distâncias e contadores
double distanciaCorredor = Variaveis.OperacaoEmAndamento.Trajetoria._Corredores[idxCorredor]?.DistanciaTotal ?? 0;
double distanciaCorredor = op.Trajetoria._Corredores[idxCorredor]?.DistanciaTotal ?? 0;
var _Bateria = Variaveis.OperacaoEmAndamento.DispSen?.Dados?.ContadorCarga;
var _Reservatorio = Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.ContadorCarga;
var _Bateria = op.DispSen?.Dados?.ContadorCarga;
var _Reservatorio = op.DispAtu?.Dados?.ContadorCarga;
DistanciaCorredor_m = distanciaCorredor;
DistanciaSeguraBateria_m = _Bateria?.DistanciaEstimadaRestante_m ?? 0;
@ -2857,7 +2873,7 @@ namespace AgroBase.Models
bool herbOk = HerbicidaSuficiente && (_Reservatorio?.Iniciado ?? false);
bool exigirPulverizacaoTotal =
Variaveis.OperacaoEmAndamento.Parametros?.ModulosMandatorios?.Any(x => x.Dispositivo == T_Code.Atu && x.Mandatorio && x.Utilizar) ?? false;
op.Parametros?.ModulosMandatorios?.Any(x => x.Dispositivo == T_Code.Atu && x.Mandatorio && x.Utilizar) ?? false;
// ==========================
// 1) Calcula status "base" (sem considerar trava)
@ -3037,7 +3053,7 @@ namespace AgroBase.Models
if (CorredoresLiberados[idxCorredor].Liberado == false && liberadoFinal)
{
CorredoresLiberados[idxCorredor] = res;
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(T_Code.Trj, liberadoFinal ? StatusModulo.Operante : StatusModulo.Alerta, liberadoFinal ? 100 : 0, $"Corredor {idxCorredor + 1} liberado pelo operador");
op.Sensoriamento.InserirLog(T_Code.Trj, liberadoFinal ? StatusModulo.Operante : StatusModulo.Alerta, liberadoFinal ? 100 : 0, $"Corredor {idxCorredor + 1} liberado pelo operador");
}
else
{
@ -3048,7 +3064,7 @@ namespace AgroBase.Models
else
{
CorredoresLiberados.Add(idxCorredor, res);
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(T_Code.Trj, liberadoFinal ? StatusModulo.Operante : StatusModulo.Alerta, liberadoFinal ? 100 : 0, $"{motivoFinal}");
op.Sensoriamento.InserirLog(T_Code.Trj, liberadoFinal ? StatusModulo.Operante : StatusModulo.Alerta, liberadoFinal ? 100 : 0, $"{motivoFinal}");
}
// Atualiza estado exposto

View File

@ -91,20 +91,20 @@ namespace AgroBase.Models
private static readonly SemaphoreSlim _mqttLifecycleLock = new SemaphoreSlim(1, 1);
private static AsyncTaskTimerModel _tmrMqttLinkMonitor;
private static int _mqttCriticalConnectedState = -1;
public static LoRaEspService LoraService
{
get
{
return OperacaoEmAndamento.DispSen?.Dados?.loRaService;
}
}
public static LoRaParametrosModel LoraBaseParametros
{
get
{
return OperacaoEmAndamento.DispSen?.Dados?.LoRaParametrosBase;
}
}
//public static LoRaEspService LoraService
//{
// get
// {
// return OperacaoEmAndamento.DispSen?.Dados?.loRaService;
// }
//}
//public static LoRaParametrosModel LoraBaseParametros
//{
// get
// {
// return OperacaoEmAndamento.DispSen?.Dados?.LoRaParametrosBase;
// }
//}
public static string FaixaIPwifi { get; set; } = "192.168.100";
public static string FaixaIPethernet { get; set; } = "192.168.105";
public static string IP_Host { get; set; } = FaixaIPwifi + ".105";
@ -688,7 +688,7 @@ namespace AgroBase.Models
}
}
Variaveis.OperacaoEmAndamento.ExecutaComandoDaBase(controle);
OperacaoEmAndamento?.ExecutaComandoDaBase(controle);
}
// ===== FAILSAFE: só considera comando de controle válido (não heartbeat) =====
@ -1263,28 +1263,6 @@ namespace AgroBase.Models
public static class VariaveisOperacao
{
public static double TempoManobra { get; set; } = 10;
public static double PercentualComErvas
{
get
{
if (!Variaveis.IsAgroMonitor && Variaveis.OperacaoEmAndamento.DispAtu != null)
{
return (Variaveis.OperacaoEmAndamento.Sensoriamento.Atuador?.PercentualErvasTerreno ?? 0) / 100.0;
}
return 0.3;
}
}
public static double PercentualSemErvas
{
get
{
if (!Variaveis.IsAgroMonitor && Variaveis.OperacaoEmAndamento.DispAtu != null)
{
return (100.0 - (Variaveis.OperacaoEmAndamento.Sensoriamento.Atuador?.PercentualErvasTerreno ?? 0)) / 100.0;
}
return 0.7;
}
}
private static readonly object _posicaoBaseLock = new object();
private static GPSModel _posicaoBase = new GPSModel();

View File

@ -73,7 +73,7 @@ namespace AgroBase.Services
Texto = "Calibrando módulos. Mantenha distância.";
break;
case StatusOperacao.Aguardando:
Texto = $"Atenção: início em {SegundosFmt(Variaveis.OperacaoEmAndamento.TempoAguardandoSegs)}.";
Texto = $"Atenção: início em {SegundosFmt(Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.TempoAguardandoSeg)}.";
break;
case StatusOperacao.EmAndamento:
Texto = "Operação em andamento.";
@ -100,7 +100,7 @@ namespace AgroBase.Services
string TextoParado()
{
string motivo = Variaveis.OperacaoEmAndamento?.ErroOperacaoLiberada;
string motivo = Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.ErroOperacaoLiberada;
motivo = string.IsNullOrWhiteSpace(motivo) ? "motivo não informado" : motivo;
return $"Operação interrompida: {motivo}. Intervenção necessária.";
}

View File

@ -1150,7 +1150,7 @@ namespace AgroBase.Services
UltimoErroCriticoMotivo = motivo;
MostrarLog($"Erro crítico: {motivo}");
var saude = Variaveis.OperacaoEmAndamento.Sensoriamento.ModulosSaude.FirstOrDefault(x => x.modulo == T_Code.Can);
var saude = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorSaude.ModulosSaude.FirstOrDefault(x => x.modulo == T_Code.Can);
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(T_Code.Can, saude?.status ?? StatusModulo.Desconectado, saude?.saude ?? 0, $"Erro crítico: {motivo}");
}

View File

@ -855,7 +855,7 @@ namespace AgroBase.Services
UltimoErroCriticoMotivo = motivo;
MostrarLog($"Erro crítico: {motivo}");
var saude = Variaveis.OperacaoEmAndamento.Sensoriamento.ModulosSaude.FirstOrDefault(x => x.modulo == T_Code.Can);
var saude = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorSaude.ModulosSaude.FirstOrDefault(x => x.modulo == T_Code.Can);
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(T_Code.Can, saude?.status ?? StatusModulo.Desconectado, saude?.saude ?? 0, $"Erro crítico: {motivo}");
}

View File

@ -1,115 +0,0 @@
using AForge.Video.DirectShow;
using AgroBase.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Management;
using System.Threading.Tasks;
using static MqttService;
namespace AgroBase.Services
{
public class CameraService
{
public static Dictionary<string, string> CamerasConectadas = new Dictionary<string, string>();
public Process pythonProcess;
public readonly object processLock = new object();
public DateTime? IniciadoEm = null;
public DateTime? ProntoEm = null;
public DateTime? FinalizadoEm = null;
public MqttTopicosModel _mqttTopico;
private string Endereco = "localhost";
public string ArquivoLeitura = "leitura.json";
public int cameraIndex = 0;
private double conf_threshold = 0.5;
private double nms_threshold = 0.4;
public List<string> URLcamera = new List<string>();
public bool InverterDadosLeitura = false;
public void IniciarCamera(string Script, string[] Argumentos, string FlaskPorta, List<string> FlaskUrl, string MqttTopico, Func<MqttTopicosMensagensModel, Task> mqttCallback = null)
{
Task.Run(async () =>
{
_mqttTopico = await Variaveis.MqttServiceLocal.AdicionarNovoTopico(MqttTopico, true, 2, mqttCallback);
lock (processLock)
{
pythonProcess = new Process();
pythonProcess = PythonService.RunScript(Script, Argumentos);
}
IniciadoEm = DateTime.Now;
foreach (string url in FlaskUrl)
{
string _url = "http://" + Endereco + ":" + FlaskPorta + "/" + url +
"?conf_threshold=" + conf_threshold.ToString().Replace(",", ".") +
"&nms_threshold=" + nms_threshold.ToString().Replace(",", ".") +
"&camera_index=" + cameraIndex;
URLcamera.Add(_url);
Console.WriteLine(_url);
}
});
}
private void PythonProcess_Exited(object sender, EventArgs e)
{
FinalizadoEm = DateTime.Now;
}
public static Dictionary<string, string> AtualizaListaCameras()
{
try
{
CamerasConectadas.Clear();
CamerasConectadas.Add("Sem vídeo", "Sem video");
using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE (PNPClass = 'Camera')")) // PNPClass = 'Image' OR PNPClass = 'Camera')
{
int i = 0;
foreach (var device in searcher.Get())
{
string cameraDesc = i.ToString() + " - " + device["Caption"].ToString();
CamerasConectadas.Add(cameraDesc, device["DeviceID"].ToString());
i++;
}
}
}
catch (ApplicationException)
{
}
return CamerasConectadas;
}
public static Dictionary<string, string> ObterListaCameras()
{
var cameras = new Dictionary<string, string>();
try
{
FilterInfoCollection videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
cameras.Add("Sem vídeo", "Sem video");
int index = 0;
foreach (FilterInfo device in videoDevices)
{
string cameraDesc = $"{index} - {device.Name}";
cameras.Add(cameraDesc, device.MonikerString);
index++;
}
}
catch (Exception ex)
{
Console.WriteLine($"Erro ao listar câmeras: {ex.Message}");
}
return cameras;
}
}
}

View File

@ -1275,7 +1275,7 @@ namespace AgroBase.Services
UltimoErroCriticoMotivo = motivo;
MostrarLog($"Erro crítico: {motivo}");
var saude = Variaveis.OperacaoEmAndamento.Sensoriamento.ModulosSaude.FirstOrDefault(x => x.modulo == T_Code.Can);
var saude = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorSaude.ModulosSaude.FirstOrDefault(x => x.modulo == T_Code.Can);
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(T_Code.Can, saude?.status ?? StatusModulo.Desconectado, saude?.saude ?? 0, $"Erro crítico: {motivo}");
}

View File

@ -282,7 +282,7 @@ namespace AgroBase.Services
if (_dt <= 0 || _dt > 10)
{
Console.WriteLine($"[COULOMB COUNTER] dt inválido: {_dt:F3}s");
Variaveis.MostrarLog($"[COULOMB COUNTER] dt inválido: {_dt:F3}s");
AtualizarCargaAtualPeloSocOuIntegrador();
AtualizarAutonomia(distanciaTotalMetrosAtual);
return;

View File

@ -11,83 +11,65 @@ namespace AgroBase.Services
{
public class DalyBMSService
{
public static DalyBmsModel DadosLeitura { get; set; } =
new DalyBmsModel();
public static DalyBmsModel DadosLeitura { get; set; } = new DalyBmsModel();
private static T_Code Dispositivo { get; set; } =
T_Code.Bat;
private static T_Code Dispositivo { get; set; } = T_Code.Bat;
public static BatHandler _BatHandler { get; set; } =
new BatHandler();
public static BatHandler _BatHandler { get; set; } = new BatHandler();
private static readonly object _sync =
new object();
private static readonly object _sync = new object();
private static readonly object _handlerLock =
new object();
private static readonly object _handlerLock = new object();
private static bool _handlersRegistrados;
private static readonly TimeSpan TempoRespostaRecente =
TimeSpan.FromSeconds(12);
private static readonly TimeSpan TempoRespostaRecente = TimeSpan.FromSeconds(12);
private static readonly TimeSpan TempoRemoverMapeamento =
TimeSpan.FromSeconds(60);
private static readonly TimeSpan TempoRemoverMapeamento = TimeSpan.FromSeconds(60);
private static readonly TimeSpan IntervaloMinimoEntreRequests =
TimeSpan.FromMilliseconds(250);
private static readonly TimeSpan IntervaloMinimoEntreRequests = TimeSpan.FromMilliseconds(250);
private static readonly TimeSpan IntervaloDescoberta =
TimeSpan.FromSeconds(3);
private static readonly TimeSpan IntervaloDescoberta = TimeSpan.FromSeconds(3);
private static readonly Dictionary<BatFuncCode, TimeSpan>
IntervalosPorFuncao =
new Dictionary<BatFuncCode, TimeSpan>
{
/*
* Polling rápido, dados realmente úteis para runtime.
*/
{ BatFuncCode.SOC, TimeSpan.FromSeconds(1) },
private static readonly Dictionary<BatFuncCode, TimeSpan> IntervalosPorFuncao = new Dictionary<BatFuncCode, TimeSpan>
{
/*
* Polling rápido, dados realmente úteis para runtime.
*/
{ BatFuncCode.SOC, TimeSpan.FromSeconds(1) },
/*
* Estado geral/MOS não precisa bater a cada ciclo.
*/
{ BatFuncCode.CargaDescargaMOS, TimeSpan.FromSeconds(3) },
{ BatFuncCode.StatusInformacao, TimeSpan.FromSeconds(3) },
/*
* Estado geral/MOS não precisa bater a cada ciclo.
*/
{ BatFuncCode.CargaDescargaMOS, TimeSpan.FromSeconds(3) },
{ BatFuncCode.StatusInformacao, TimeSpan.FromSeconds(3) },
/*
* Max/min são leves.
*/
{ BatFuncCode.TensaoMaxMin, TimeSpan.FromSeconds(5) },
{ BatFuncCode.TemperaturaMaxMin, TimeSpan.FromSeconds(5) },
/*
* Max/min são leves.
*/
{ BatFuncCode.TensaoMaxMin, TimeSpan.FromSeconds(5) },
{ BatFuncCode.TemperaturaMaxMin, TimeSpan.FromSeconds(5) },
/*
* Alarmes e balanceamento.
*/
{ BatFuncCode.StatusFalhaBateria, TimeSpan.FromSeconds(8) },
{ BatFuncCode.StatusBalanceamentoCelula, TimeSpan.FromSeconds(15) },
/*
* Alarmes e balanceamento.
*/
{ BatFuncCode.StatusFalhaBateria, TimeSpan.FromSeconds(8) },
{ BatFuncCode.StatusBalanceamentoCelula, TimeSpan.FromSeconds(15) },
/*
* Dados multi-frame. Pedir devagar para não saturar o Daly.
* 0x95 pode responder até 16 frames.
* 0x96 pode responder até 3 frames.
*/
{ BatFuncCode.TensaoCelula, TimeSpan.FromSeconds(20) },
{ BatFuncCode.TemperaturaCelula, TimeSpan.FromSeconds(20) },
};
/*
* Dados multi-frame. Pedir devagar para não saturar o Daly.
* 0x95 pode responder até 16 frames.
* 0x96 pode responder até 3 frames.
*/
{ BatFuncCode.TensaoCelula, TimeSpan.FromSeconds(20) },
{ BatFuncCode.TemperaturaCelula, TimeSpan.FromSeconds(20) },
};
private static readonly Dictionary<BatFuncCode, DateTime>
_ultimoPedido =
Enum
.GetValues(typeof(BatFuncCode))
.Cast<BatFuncCode>()
.ToDictionary(x => x, x => DateTime.MinValue);
private static readonly Dictionary<BatFuncCode, DateTime> _ultimoPedido = Enum.GetValues(typeof(BatFuncCode)).Cast<BatFuncCode>().ToDictionary(x => x, x => DateTime.MinValue);
private static DateTime _ultimaTentativaDescoberta =
DateTime.MinValue;
private static DateTime _ultimaTentativaDescoberta = DateTime.MinValue;
private static DateTime _ultimoEnvioCan =
DateTime.MinValue;
private static DateTime _ultimoEnvioCan = DateTime.MinValue;
/*
* Mantém prioridade determinística.
@ -125,10 +107,7 @@ namespace AgroBase.Services
{
get
{
return
SerialService
.DispositivosMapeados
.Any(x => x.Dispositivo == Dispositivo);
return SerialService.DispositivosMapeados.Any(x => x.Dispositivo == Dispositivo);
}
}
@ -159,15 +138,9 @@ namespace AgroBase.Services
EnviarComandoDescoberta();
bool Respondido() =>
DadosLeitura.UltimoComandoRecebido > inicio;
bool Respondido() => DadosLeitura.UltimoComandoRecebido > inicio;
await FuncoesGlobais
.AguardarCondicaoAsync(
Respondido,
1200,
50
);
await FuncoesGlobais.AguardarCondicaoAsync(Respondido, 1200, 50);
if (Respondido())
DefinirDispositivo();
@ -192,8 +165,7 @@ namespace AgroBase.Services
*/
if (!DispositivoMapeado)
{
if (agora - _ultimaTentativaDescoberta >=
IntervaloDescoberta)
if (agora - _ultimaTentativaDescoberta >= IntervaloDescoberta)
{
_ultimaTentativaDescoberta = agora;
EnviarComandoDescoberta();
@ -218,64 +190,44 @@ namespace AgroBase.Services
return;
}
if (agora - _ultimoEnvioCan <
IntervaloMinimoEntreRequests)
if (agora - _ultimoEnvioCan < IntervaloMinimoEntreRequests)
{
return;
}
BatFuncCode? proximo =
EscolherProximoDadoParaRequisitar(agora);
BatFuncCode? proximo = EscolherProximoDadoParaRequisitar(agora);
if (!proximo.HasValue)
return;
bool contabilizarTimeout =
DeveContabilizarTimeoutHealth(proximo.Value);
bool contabilizarTimeout = DeveContabilizarTimeoutHealth(proximo.Value);
RequisitarDado(
proximo.Value,
contabilizarTimeout
);
RequisitarDado(proximo.Value, contabilizarTimeout);
_ultimoPedido[proximo.Value] = agora;
_ultimoEnvioCan = agora;
}
catch (Exception ex)
{
Console.WriteLine(
"[DalyBMSService] Erro em AtualizarDados: " +
ex.Message
);
Variaveis.MostrarLog("[DalyBMSService.AtualizarDados] Erro em AtualizarDados: " + ex.Message);
}
}
private static BatFuncCode? EscolherProximoDadoParaRequisitar(
DateTime agora)
private static BatFuncCode? EscolherProximoDadoParaRequisitar(DateTime agora)
{
for (int tentativa = 0;
tentativa < OrdemPolling.Length;
tentativa++)
for (int tentativa = 0; tentativa < OrdemPolling.Length; tentativa++)
{
int index =
(_cursorPolling + tentativa) %
OrdemPolling.Length;
int index = (_cursorPolling + tentativa) % OrdemPolling.Length;
BatFuncCode codigo =
OrdemPolling[index];
BatFuncCode codigo = OrdemPolling[index];
TimeSpan intervalo =
IntervalosPorFuncao[codigo];
TimeSpan intervalo = IntervalosPorFuncao[codigo];
DateTime ultimo =
_ultimoPedido[codigo];
DateTime ultimo = _ultimoPedido[codigo];
if (ultimo == DateTime.MinValue ||
agora - ultimo >= intervalo)
if (ultimo == DateTime.MinValue || agora - ultimo >= intervalo)
{
_cursorPolling =
(index + 1) %
OrdemPolling.Length;
_cursorPolling = (index + 1) % OrdemPolling.Length;
return codigo;
}
@ -284,8 +236,7 @@ namespace AgroBase.Services
return null;
}
private static bool DeveContabilizarTimeoutHealth(
BatFuncCode dado)
private static bool DeveContabilizarTimeoutHealth(BatFuncCode dado)
{
/*
* Apenas requests leves e críticos entram na saúde CAN.
@ -305,18 +256,9 @@ namespace AgroBase.Services
if (_handlersRegistrados)
return;
foreach (BatFuncCode f in Enum.GetValues(
typeof(BatFuncCode)))
foreach (BatFuncCode f in Enum.GetValues(typeof(BatFuncCode)))
{
CanManager
.CanService
.RegistrarHandler(
CanManager
.ConverterIdCan(
MakeResponseID(f)
),
_BatHandler
);
CanManager.CanService.RegistrarHandler(CanManager.ConverterIdCan(MakeResponseID(f)), _BatHandler);
}
_handlersRegistrados = true;
@ -331,26 +273,19 @@ namespace AgroBase.Services
if (DadosLeitura == null)
return;
SerialService
.DispositivosMapeados
.Add(
new DispositivoDetalhesModel
{
Dispositivo = Dispositivo,
Endereco = CanManager.CanService._portName,
Versao = "1"
}
);
SerialService.DispositivosMapeados.Add(
new DispositivoDetalhesModel
{
Dispositivo = Dispositivo,
Endereco = CanManager.CanService._portName,
Versao = "1"
}
);
}
private static void RemoverMapeamento()
{
var d =
SerialService
.DispositivosMapeados
.FirstOrDefault(
x => x.Dispositivo == Dispositivo
);
var d = SerialService.DispositivosMapeados.FirstOrDefault(x => x.Dispositivo == Dispositivo);
if (d != null)
SerialService.DispositivosMapeados.Remove(d);
@ -360,22 +295,19 @@ namespace AgroBase.Services
private static void EnviarComandoDescoberta()
{
BatFuncCode dado =
BatFuncCode.SOC;
BatFuncCode dado = BatFuncCode.SOC;
CanManager
.CanService
.AdicionarMensagemNaFila(
Dispositivo,
MakeRequestID(dado),
MakeResponseID(dado),
(byte)dado,
(byte)dado,
payload: new byte[8],
get: true,
contabilizarTimeoutHealth: false,
mensagemDescoberta: true
);
CanManager.CanService.AdicionarMensagemNaFila(
Dispositivo,
MakeRequestID(dado),
MakeResponseID(dado),
(byte)dado,
(byte)dado,
payload: new byte[8],
get: true,
contabilizarTimeoutHealth: false,
mensagemDescoberta: true
);
}
private static void EnviarComando(

View File

@ -2161,43 +2161,24 @@ namespace AgroBase.Services
public static void AtualizarCoordenadasGPS()
{
PenultimaLeitura.Ntrip_ativado =
UltimaLeitura.Ntrip_ativado;
var op = Variaveis.OperacaoEmAndamento;
PenultimaLeitura.Heartbeat =
UltimaLeitura.Heartbeat;
PenultimaLeitura.Ntrip_ativado = UltimaLeitura.Ntrip_ativado;
PenultimaLeitura.Heartbeat = UltimaLeitura.Heartbeat;
PenultimaLeitura.LeverArmFrontal = UltimaLeitura.LeverArmFrontal;
PenultimaLeitura.LeverArmLateral = UltimaLeitura.LeverArmLateral;
UltimaLeitura.Ntrip_ativado = CorrecaoRTK_Ntrip;
PenultimaLeitura.LeverArmFrontal =
UltimaLeitura.LeverArmFrontal;
PenultimaLeitura.LeverArmLateral =
UltimaLeitura.LeverArmLateral;
UltimaLeitura.Ntrip_ativado =
CorrecaoRTK_Ntrip;
UltimaLeitura.Heartbeat =
(UltimaLeitura.Heartbeat + 1) % 10;
UltimaLeitura.LeverArmFrontal =
LeverArm != null
? LeverArm.FrontalTotalCm
: 0;
UltimaLeitura.LeverArmLateral =
LeverArm != null
? LeverArm.LateralTotalCm
: 0;
UltimaLeitura.Heartbeat = (UltimaLeitura.Heartbeat + 1) % 10;
UltimaLeitura.LeverArmFrontal = LeverArm != null ? LeverArm.FrontalTotalCm : 0;
UltimaLeitura.LeverArmLateral = LeverArm != null ? LeverArm.LateralTotalCm : 0;
if (Variaveis.IsAgroMonitor)
return;
UltimasLeituras.Add(
UltimaLeitura.Clone()
);
UltimasLeituras.Add(UltimaLeitura.Clone());
while (UltimasLeituras.Count >
Math.Max(1, TaxaAmostragemHz))
while (UltimasLeituras.Count > Math.Max(1, TaxaAmostragemHz))
{
UltimasLeituras.RemoveAt(0);
}
@ -2205,102 +2186,61 @@ namespace AgroBase.Services
DefinirOrientacaoMovimento();
AtualizaDadosRedis();
if (Variaveis.OperacaoEmAndamento.Iniciado)
if (op.Sensoriamento.Operacao.OperacaoIniciada)
{
var trajetoria =
Variaveis.OperacaoEmAndamento.Trajetoria;
var gpsTrajetoria =
Variaveis.OperacaoEmAndamento
.GPSTrajetoria;
GPSModel novaLeitura =
UltimaLeitura.Clone();
var trajetoria = op.Trajetoria;
var gpsTrajetoria = op.GPSTrajetoria;
GPSModel novaLeitura = UltimaLeitura.Clone();
gpsTrajetoria.Add(novaLeitura);
if (gpsTrajetoria.Count > 1)
{
int ultimo =
gpsTrajetoria.Count - 1;
int ultimo = gpsTrajetoria.Count - 1;
int penultimo = ultimo - 1;
double distancia =
GPSUtils.DistanciaEntrePontos(
gpsTrajetoria[ultimo],
gpsTrajetoria[penultimo]
);
double distancia = GPSUtils.DistanciaEntrePontos(gpsTrajetoria[ultimo], gpsTrajetoria[penultimo]);
if (trajetoria != null)
trajetoria.AtualizarDistanciaPercorrida(
distancia
);
trajetoria.AtualizarDistanciaPercorrida(distancia);
}
var bicos =
Variaveis.OperacaoEmAndamento
.DispAtu?
.Dados?
.BicosPulverizadores;
var bicos = op.DispAtu?.Dados?.BicosPulverizadores;
if (bicos != null)
{
foreach (var bico in bicos)
{
if (!bico.Inicializado ||
!bico.Comandar ||
!bico.ComandoAtuar)
if (!bico.Inicializado || !bico.Comandar || !bico.ComandoAtuar)
{
continue;
}
bico.AdicionarPontoTrechoAtivo(
UltimaLeitura.Latitude,
UltimaLeitura.Longitude
);
bico.AdicionarPontoTrechoAtivo(UltimaLeitura.Latitude, UltimaLeitura.Longitude);
}
}
}
if (Variaveis.OperacaoEmAndamento.Trajetoria != null)
if (op.Trajetoria != null)
{
Variaveis.OperacaoEmAndamento
.Trajetoria
.LoopAtualizaDados();
op.Trajetoria.LoopAtualizaDados();
}
AtualizarTrajetoriaDinamica();
int enderecoEquipamento = Convert.ToInt32(
Variaveis.LoraService?
.ParametrosGet?
.address ??
Variaveis.LoraService?
.ParametrosSet?
.address ??
0x00
);
int enderecoEquipamento = 1;
EnviarCoordenadasParaMapa(
UltimaLeitura.Latitude,
UltimaLeitura.Longitude,
UltimaLeitura.AnguloCarroDefinido,
Variaveis.OperacaoEmAndamento.Iniciado,
op.Sensoriamento.Operacao.OperacaoIniciada,
enderecoEquipamento
);
if ((Variaveis.LoraService?.Iniciado ?? false) &&
(Variaveis.LoraService?._ultimoRxDados ??
DateTime.MinValue) >
DateTime.UtcNow.AddSeconds(-60))
GPSModel posicaoBase = VariaveisOperacao.ObterPosicaoBaseSnapshot();
if ((posicaoBase?.UltimoComandoRespondido ?? DateTime.MinValue) > DateTime.UtcNow.AddSeconds(-60))
{
byte enderecoBase =
Variaveis.LoraBaseParametros.address;
GPSModel posicaoBase =
VariaveisOperacao
.ObterPosicaoBaseSnapshot();
int enderecoBase = 0;
EnviarCoordenadasParaMapa(
posicaoBase.Latitude,
@ -2311,17 +2251,10 @@ namespace AgroBase.Services
);
}
PenultimaLeitura.Inicializado =
UltimaLeitura.Inicializado;
PenultimaLeitura.Inicializado = UltimaLeitura.Inicializado;
UltimaLeitura.Inicializado = Iniciado;
if (CorrecaoRTK_Ntrip &&
GetAgeMs(
Interlocked.Read(
ref _lastRtcmWrittenMono
)
) > TempoMin_Ntrip * 1000.0)
if (CorrecaoRTK_Ntrip && GetAgeMs(Interlocked.Read(ref _lastRtcmWrittenMono)) > TempoMin_Ntrip * 1000.0)
{
_ = IniciarNtripAsync();
}
@ -2331,61 +2264,40 @@ namespace AgroBase.Services
// PUBLICAÇÃO LOCAL LATEST-ONLY
// ============================================================
public static void EnviarCoordenadasParaMapa(
double Latitude,
double Longitude,
double Orientacao,
bool EmFoco,
int ID)
public static void EnviarCoordenadasParaMapa(double Latitude, double Longitude, double Orientacao, bool EmFoco, int ID)
{
var coordenadas = new
{
latitude = Latitude,
longitude = Longitude,
orientacao =
GPSUtils.NormalizarAngulo(
Orientacao - 180.0
),
orientacao = GPSUtils.NormalizarAngulo(Orientacao - 180.0),
id = ID,
foco = EmFoco
};
QueueLocalPublication(
MapasVariaveisModel.TopicoCoordenadasGPS,
JsonConvert.SerializeObject(coordenadas)
);
QueueLocalPublication(MapasVariaveisModel.TopicoCoordenadasGPS, JsonConvert.SerializeObject(coordenadas));
}
public static void AtualizarTrajetoriaDinamica()
{
var dinamica =
Variaveis.OperacaoEmAndamento
.Trajetoria?
._TrajetoriaDinamica;
var op = Variaveis.OperacaoEmAndamento;
var dinamica = op.Trajetoria?._TrajetoriaDinamica;
if (!(dinamica?.Any() ?? false))
return;
var trajetoria = Variaveis
.OperacaoEmAndamento
.Trajetoria
.TrajetoriaDinamica
.Select(x => new
{
latitude = x.Latitude,
longitude = x.Longitude
})
.ToArray();
var trajetoria = op.Trajetoria.TrajetoriaDinamica.Select(x => new
{
latitude = x.Latitude,
longitude = x.Longitude
})
.ToArray();
QueueLocalPublication(
MapasVariaveisModel
.TopicoTrajetoriaDinamica,
JsonConvert.SerializeObject(trajetoria)
);
QueueLocalPublication(MapasVariaveisModel.TopicoTrajetoriaDinamica, JsonConvert.SerializeObject(trajetoria));
}
public static void AtualizarRuasSelecionadas(
List<string> RuasSelecionadas)
public static void AtualizarRuasSelecionadas(List<string> RuasSelecionadas)
{
/*
* Preserva o formato legado produzido anteriormente.
@ -2405,9 +2317,7 @@ namespace AgroBase.Services
);
}
private static void QueueLocalPublication(
string topic,
string payload)
private static void QueueLocalPublication(string topic, string payload)
{
if (string.IsNullOrWhiteSpace(topic))
return;
@ -2424,8 +2334,7 @@ namespace AgroBase.Services
catch (SemaphoreFullException) { }
}
private static async Task LocalPublisherLoopAsync(
CancellationToken cancellationToken)
private static async Task LocalPublisherLoopAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
@ -2605,51 +2514,38 @@ namespace AgroBase.Services
public static void DefinirAnguloCarro()
{
var op = Variaveis.OperacaoEmAndamento;
double anguloFinal;
bool imuIniciado =
Variaveis.OperacaoEmAndamento
.Sensoriamento?
.IMU?
.Iniciado ?? false;
bool imuIniciado = op.Sensoriamento?.IMU?.Iniciado ?? false;
bool gpsIniciado = Iniciado;
bool headingValido =
PossuiHeadingValido(UltimaLeitura);
bool headingValido = PossuiHeadingValido(UltimaLeitura);
if (Variaveis.OperacaoEmAndamento.Simulando)
if (op.Simulando)
{
anguloFinal =
UltimaLeitura.OrientacaoReal;
anguloFinal = UltimaLeitura.OrientacaoReal;
}
else if (gpsIniciado && headingValido)
{
anguloFinal =
UltimaLeitura.OrientacaoReal;
anguloFinal = UltimaLeitura.OrientacaoReal;
}
else if (gpsIniciado &&
UltimaLeitura.Distancia > 0.25)
else if (gpsIniciado && UltimaLeitura.Distancia > 0.25)
{
anguloFinal =
UltimaLeitura.OrientacaoMovimento;
anguloFinal = UltimaLeitura.OrientacaoMovimento;
}
else if (imuIniciado)
{
anguloFinal =
Variaveis.OperacaoEmAndamento
.Sensoriamento
.IMU
.YawSeguro;
anguloFinal = op.Sensoriamento.IMU.YawSeguro;
}
else
{
anguloFinal =
UltimaLeitura.AnguloCarroDefinido;
anguloFinal = UltimaLeitura.AnguloCarroDefinido;
}
UltimaLeitura.AnguloCarroDefinido =
anguloFinal;
UltimaLeitura.AnguloCarroDefinido = anguloFinal;
}
public static double FundirHeadingComMovimento(
@ -2810,10 +2706,7 @@ namespace AgroBase.Services
{
lock (_stateLock)
{
posicaoAtual =
historicoPosicao.Count > 0
? historicoPosicao.Peek().Clone()
: UltimaLeitura.Clone();
posicaoAtual = historicoPosicao.Count > 0 ? historicoPosicao.Peek().Clone() : UltimaLeitura.Clone();
}
}
else
@ -2821,37 +2714,18 @@ namespace AgroBase.Services
posicaoAtual = GetSnapshot();
}
bool rtkValido =
posicaoAtual.IdadeCorrecao >= 0 &&
posicaoAtual.IdadeCorrecao <
rtk_timeout &&
bool rtkValido = posicaoAtual.IdadeCorrecao >= 0 && posicaoAtual.IdadeCorrecao < rtk_timeout &&
(
posicaoAtual.QualidadeFix ==
TiposCorrecaoGPS.RTKFixo ||
posicaoAtual.QualidadeFix ==
TiposCorrecaoGPS.RTKFlutuante ||
posicaoAtual.QualidadeFix ==
TiposCorrecaoGPS.DGPS
posicaoAtual.QualidadeFix == TiposCorrecaoGPS.RTKFixo ||
posicaoAtual.QualidadeFix == TiposCorrecaoGPS.RTKFlutuante ||
posicaoAtual.QualidadeFix == TiposCorrecaoGPS.DGPS
);
string statusOrientacao =
(posicaoAtual.TipoOrientacao ??
string.Empty)
.Trim()
.ToUpperInvariant();
string statusOrientacao = (posicaoAtual.TipoOrientacao ?? string.Empty).Trim().ToUpperInvariant();
double valorOrientacao = posicaoAtual.OrientacaoReal;
bool orientacaoValida = statusOrientacao == "A" && !double.IsNaN(valorOrientacao) && !double.IsInfinity(valorOrientacao) && valorOrientacao >= 0.0 && valorOrientacao < 360.0;
double valorOrientacao =
posicaoAtual.OrientacaoReal;
bool orientacaoValida =
statusOrientacao == "A" &&
!double.IsNaN(valorOrientacao) &&
!double.IsInfinity(valorOrientacao) &&
valorOrientacao >= 0.0 &&
valorOrientacao < 360.0;
GpsTransportMetrics metrics =
GetTransportMetrics();
GpsTransportMetrics metrics = GetTransportMetrics();
RedisService.AtualizarCampos(
RedisService.ModKey(T_Code.Gps),
@ -2869,78 +2743,54 @@ namespace AgroBase.Services
("nSatelites", posicaoAtual.NumeroSatelites),
("age", posicaoAtual.IdadeCorrecao),
("freq.posicao",
posicaoAtual.TimestampPos.frequencia),
("freq.orientacao",
posicaoAtual.TimestampOri.frequencia),
("freq.posicao", posicaoAtual.TimestampPos.frequencia),
("freq.orientacao", posicaoAtual.TimestampOri.frequencia),
("latency.posicao",
posicaoAtual.TimestampPos.dt),
("latency.orientacao",
posicaoAtual.TimestampOri.dt),
("latency.posicao", posicaoAtual.TimestampPos.dt),
("latency.orientacao", posicaoAtual.TimestampOri.dt),
("timestamp.posicao",
posicaoAtual.TimestampPos.valor),
("timestamp.orientacao",
posicaoAtual.TimestampOri.valor),
("timestamp.posicao", posicaoAtual.TimestampPos.valor),
("timestamp.orientacao", posicaoAtual.TimestampOri.valor),
("orientacao.status",
statusOrientacao),
("orientacao.valida",
orientacaoValida),
("orientacao.valor",
valorOrientacao),
("orientacao.status", statusOrientacao),
("orientacao.valida", orientacaoValida),
("orientacao.valor", valorOrientacao),
("heartbeat",
posicaoAtual.Heartbeat),
("heartbeat", posicaoAtual.Heartbeat),
("rtcm.received",
metrics.RtcmReceived),
("rtcm.written",
metrics.RtcmWritten),
("rtcm.queue_depth",
metrics.RtcmQueueDepth),
("rtcm.last_rx_age_ms",
metrics.LastRtcmReceivedAgeMs),
("rtcm.last_write_age_ms",
metrics.LastRtcmWrittenAgeMs),
("rtcm.drop_stale",
metrics.RtcmDroppedStale),
("rtcm.write_errors",
metrics.RtcmWriteErrors)
("rtcm.received", metrics.RtcmReceived),
("rtcm.written", metrics.RtcmWritten),
("rtcm.queue_depth", metrics.RtcmQueueDepth),
("rtcm.last_rx_age_ms", metrics.LastRtcmReceivedAgeMs),
("rtcm.last_write_age_ms", metrics.LastRtcmWrittenAgeMs),
("rtcm.drop_stale", metrics.RtcmDroppedStale),
("rtcm.write_errors", metrics.RtcmWriteErrors)
);
CorrecaoRTK_Ntrip = RedisService.GetField<bool>(RedisService.ModKey(T_Code.Gps), "correcao_ntrip", false);
}
catch (Exception ex)
{
RecordError(
"[GPSService.AtualizaDadosRedis] " +
ex.Message
);
RecordError("[GPSService.AtualizaDadosRedis] " + ex.Message);
try
{
Variaveis.OperacaoEmAndamento
.Sensoriamento
.InserirLog(
T_Code.Gps,
StatusModulo.Falha,
0,
"Erro ao salvar dados do GPS no Redis: " +
ex.Message
);
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(
T_Code.Gps,
StatusModulo.Falha,
0,
"Erro ao salvar dados do GPS no Redis: " + ex.Message
);
}
catch { }
}
}
public static void AtualizarAtrasoPosicoes(
int errosConsiderar = 0)
public static void AtualizarAtrasoPosicoes(int errosConsiderar = 0)
{
lock (_stateLock)
{
historicoPosicao.Enqueue(
UltimaLeitura.Clone()
);
historicoPosicao.Enqueue(UltimaLeitura.Clone());
while (historicoPosicao.Count > 1 &&
(

View File

@ -599,9 +599,9 @@ namespace AgroBase.Services
public void AtualizarAgitadorCalda(ModoAgitadorCalda modo)
{
var operacao = Variaveis.OperacaoEmAndamento;
var op = Variaveis.OperacaoEmAndamento;
if (operacao?.Calibrando == true)
if (op.Sensoriamento.Operacao.Calibrando == true)
{
/*
* Durante a calibração, RealizarTestesIniciais()
@ -611,12 +611,12 @@ namespace AgroBase.Services
}
var agitador =
operacao?.DispAtu?.Dados?.AgitadorDeCalda;
op?.DispAtu?.Dados?.AgitadorDeCalda;
if (!(agitador?.Inicializado ?? false))
return;
var controle = operacao.Parametros?.Controle;
var controle = op.Parametros?.Controle;
if (controle == null)
{
@ -626,18 +626,16 @@ namespace AgroBase.Services
return;
}
bool operacaoConcluida =
operacao.Sensoriamento?.StatusOperacao ==
StatusOperacao.Concluido;
bool operacaoConcluida = op.Sensoriamento?.Operacao?.StatusOperacaoAtual == StatusOperacao.Concluido;
bool operacaoAtiva =
operacao.Iniciado &&
!operacao.Pausa &&
op.Sensoriamento.Operacao.OperacaoIniciada &&
!op.Sensoriamento.Operacao.Pausa &&
!operacaoConcluida &&
PulverizadorLiberado;
bool bicosAtuando =
operacao.DispAtu?.Dados?.BicosPulverizadores?
op.DispAtu?.Dados?.BicosPulverizadores?
.Any(x =>
x.Comandar &&
x.ComandoAtuar)

View File

@ -315,7 +315,7 @@ namespace AgroBase.Services
private static async Task tmrLeitura_Tick()
{
bool usoNaoNecessario = !Iniciado || (picRGB == null && !Variaveis.OperacaoEmAndamento.Iniciado);
bool usoNaoNecessario = !Iniciado || (picRGB == null && !Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoIniciada);
tmrLeitura.SetInterval(usoNaoNecessario ? 1000 : 200);
if (usoNaoNecessario)
@ -624,7 +624,7 @@ namespace AgroBase.Services
public static Bitmap ExibirObstaculos(Bitmap bitmap, List<Subdivisao> subdivisoes, List<Obstaculo> obstaculos, bool ExibirTexto = false)
{
if (bitmap == null || (!false && Variaveis.OperacaoEmAndamento.Iniciado))
if (bitmap == null || (!false && Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoIniciada))
{
return bitmap;
}

View File

@ -53,7 +53,7 @@ namespace AgroBase.Services
List<byte> config2 = new List<byte>
{
Variaveis.LoraBaseParametros?.address ?? 0x01,
0x01, //Variaveis.LoraBaseParametros?.address ?? 0x01,
ParametrosSet.address,
ParametrosSet.baudAndAirRate,
ParametrosSet.packetSizeAndPower,
@ -139,16 +139,16 @@ namespace AgroBase.Services
// --- ENVIO (ideal: agregue em 1-2 frames) ---
var s = Variaveis.OperacaoEmAndamento.Sensoriamento;
foreach (var dado in LoRaSerializer.SerializeGPS(s.Gps))
Variaveis.LoraService?.EnviarDadosLoRaViaCAN(dado);
//foreach (var dado in LoRaSerializer.SerializeGPS(s.Gps))
// Variaveis.LoraService?.EnviarDadosLoRaViaCAN(dado);
foreach (var dado in LoRaSerializer.SerializeOperacao(s))
Variaveis.LoraService?.EnviarDadosLoRaViaCAN(dado);
//foreach (var dado in LoRaSerializer.SerializeOperacao(s))
// Variaveis.LoraService?.EnviarDadosLoRaViaCAN(dado);
foreach (var dado in LoRaSerializer.SerializeSensores(s))
Variaveis.LoraService?.EnviarDadosLoRaViaCAN(dado);
//foreach (var dado in LoRaSerializer.SerializeSensores(s))
// Variaveis.LoraService?.EnviarDadosLoRaViaCAN(dado);
Variaveis.LoraService?.EnviarDadosLoRaViaCAN(LoRaSerializer.SerializeControleAtual(s.Controle));
//Variaveis.LoraService?.EnviarDadosLoRaViaCAN(LoRaSerializer.SerializeControleAtual(s.Controle));
}

View File

@ -301,11 +301,11 @@ namespace AgroBase.Services
return dados.ToArray();
}
public static List<byte[]> SerializeOperacao(OperacaoSensoriamentoLogModel sensoriamento)
public static List<byte[]> SerializeOperacao(OperacaoSensoriamentoConjuntoModel sensoriamento)
{
List<byte> _operacao = new List<byte>();
_operacao.AddRange(CanPrefix(DadosLoRaParse.DadosOperacao));
_operacao.Add((byte)(sensoriamento.StatusOperacao)); // 1 byte
_operacao.Add((byte)(sensoriamento.Operacao.StatusOperacaoAtual)); // 1 byte
_operacao.Add((byte)sensoriamento.Trajetoria.StatusCarro); // 1 byte
_operacao.Add((byte)Convert.ToInt32(sensoriamento.Trajetoria.PercentualOperacao)); // 1 byte
_operacao.Add((byte)Convert.ToInt32(sensoriamento.Trajetoria.PercentualRuaAtual)); // 1 byte
@ -317,15 +317,15 @@ namespace AgroBase.Services
};
}
public static List<byte[]> SerializeSensores(OperacaoSensoriamentoLogModel sensoriamento)
public static List<byte[]> SerializeSensores(OperacaoSensoriamentoConjuntoModel sensoriamento)
{
List<byte> _sensores = new List<byte>();
_sensores.AddRange(CanPrefix(DadosLoRaParse.DadosSensores));
_sensores.Add((byte)Convert.ToInt32(sensoriamento.Bateria.PercentualBateria)); // 1 byte
_sensores.Add((byte)Convert.ToInt32(sensoriamento.Movimentacao.TemperaturaMedia)); // 1 byte
_sensores.Add((byte)Convert.ToInt32(sensoriamento.Movimentacao.TemperaturaMedia)); // 1 byte
_sensores.Add((byte)Convert.ToInt32(sensoriamento.Movimentacao.TemperaturaMotorMedia)); // 1 byte
_sensores.Add((byte)Convert.ToInt32(sensoriamento.Movimentacao.TemperaturaDriverMedia)); // 1 byte
_sensores.Add((byte)Convert.ToInt32(sensoriamento.Trajetoria.AnguloCaminho)); // 1 byte
_sensores.Add((byte)Convert.ToInt32(sensoriamento.Movimentacao.VelocidadeMedia)); // 1 byte
_sensores.Add((byte)Convert.ToInt32(sensoriamento.Movimentacao.VelocidadeMediaMs)); // 1 byte
List<byte> _pulverizador = new List<byte>();
_pulverizador.AddRange(CanPrefix(DadosLoRaParse.DadosPulverizador));

View File

@ -418,15 +418,11 @@ namespace AgroBase.Services
private static void DefinirDispositivo(List<string> modIds)
{
var op = Variaveis.OperacaoEmAndamento;
foreach (var modId in modIds)
{
var modulo =
Variaveis
.OperacaoEmAndamento
.DispMvd
.Dados
.Modulos
.FirstOrDefault(x => x.Modulo_ID == modId);
var modulo = op.DispMvd.Dados.Modulos.FirstOrDefault(x => x.Modulo_ID == modId);
if (modulo?.DirMotor == null)
continue;
@ -453,19 +449,16 @@ namespace AgroBase.Services
Mod_ID = modId,
});
Variaveis.OperacaoEmAndamento.ModsCalibragem.TryGetValue(T_Code.Dir, out var m);
op.Sensoriamento.Operacao.ModsCalibragem.TryGetValue(T_Code.Dir, out var m);
if (m == null)
{
Variaveis.OperacaoEmAndamento.ModsCalibragem.Add(
T_Code.Dir,
new Dictionary<string, bool>()
);
op.Sensoriamento.Operacao.ModsCalibragem.Add(T_Code.Dir, new Dictionary<string, bool>());
}
Variaveis.OperacaoEmAndamento.ModsCalibragem[T_Code.Dir][modId] = false;
op.Sensoriamento.Operacao.ModsCalibragem[T_Code.Dir][modId] = false;
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(
op.Sensoriamento.InserirLog(
T_Code.Dir,
StatusModulo.Conectado,
0,

View File

@ -13,11 +13,9 @@ namespace AgroBase.Services
{
public static List<OIDModel> DadosLeitura = new List<OIDModel>();
private static T_Code Dispositivo { get; set; } =
T_Code.Oid;
private static T_Code Dispositivo { get; set; } = T_Code.Oid;
private static OidHandler _OidHandler { get; set; } =
new OidHandler();
private static OidHandler _OidHandler { get; set; } = new OidHandler();
private static AsyncTaskTimerModel tmrHeartbeat;
@ -401,18 +399,13 @@ namespace AgroBase.Services
private static void DefinirDispositivo(List<string> modIds)
{
var op = Variaveis.OperacaoEmAndamento;
GarantirTimerHeartbeat();
foreach (var modId in modIds)
{
var modulo =
Variaveis
.OperacaoEmAndamento
.DispMvd
.Dados
.Modulos
.FirstOrDefault(x => x.Modulo_ID == modId)?
.MovMotor;
var modulo = op.DispMvd.Dados.Modulos.FirstOrDefault(x => x.Modulo_ID == modId)?.MovMotor;
if (modulo == null)
continue;
@ -422,17 +415,12 @@ namespace AgroBase.Services
modulo._EnderecoCAN_Rx
);
var leitura =
DadosLeitura.FirstOrDefault(
x => x.EnderecoTx == modulo._EnderecoCAN_Tx
);
var leitura = DadosLeitura.FirstOrDefault(x => x.EnderecoTx == modulo._EnderecoCAN_Tx);
if (leitura != null && !leitura.Configurado)
ConfigurarDriver(modulo);
if (!SerialService.DispositivosMapeados.Any(
x => x.Dispositivo == T_Code.Mov &&
x.Mod_ID == modId))
if (!SerialService.DispositivosMapeados.Any(x => x.Dispositivo == T_Code.Mov && x.Mod_ID == modId))
{
SerialService.DispositivosMapeados.Add(
new DispositivoDetalhesModel
@ -444,38 +432,22 @@ namespace AgroBase.Services
}
);
Variaveis.OperacaoEmAndamento.ModsCalibragem
.TryGetValue(T_Code.Mov, out var m);
op.Sensoriamento.Operacao.ModsCalibragem.TryGetValue(T_Code.Mov, out var m);
if (m == null)
{
Variaveis.OperacaoEmAndamento.ModsCalibragem
.Add(
T_Code.Mov,
new Dictionary<string, bool>()
);
op.Sensoriamento.Operacao.ModsCalibragem.Add(T_Code.Mov, new Dictionary<string, bool>());
}
Variaveis.OperacaoEmAndamento
.ModsCalibragem[T_Code.Mov][modId] = false;
Variaveis.OperacaoEmAndamento
.Sensoriamento
.InserirLog(
T_Code.Mov,
StatusModulo.Conectado,
0,
"Dispositivo conectado",
modId
);
op.Sensoriamento.Operacao.ModsCalibragem[T_Code.Mov][modId] = false;
op.Sensoriamento.InserirLog(T_Code.Mov, StatusModulo.Conectado, 0, "Dispositivo conectado", modId);
}
}
}
private static void GarantirTimerHeartbeat()
{
if (tmrHeartbeat != null &&
(tmrHeartbeat.IsRunning))
if (tmrHeartbeat != null && (tmrHeartbeat.IsRunning))
{
return;
}

View File

@ -29,8 +29,7 @@ namespace AgroBase.Services.Operadores
}
};
private static List<CameraWorkerItemModel> CamerasConectadas =
CriarListaVaziaComPlaceholder();
private static List<CameraWorkerItemModel> CamerasConectadas = CriarListaVaziaComPlaceholder();
private static DateTime _ultimoRefreshUtc = DateTime.MinValue;
private static bool _refreshEmAndamento;
@ -39,10 +38,9 @@ namespace AgroBase.Services.Operadores
* Pode chamar AtualizarDadosCameras() em tmrLeitura_Tick sem medo.
* Se o tick estiver em 100 ms, este throttle evita martelar Redis.
*/
private static readonly TimeSpan IntervaloMinimoRefresh =
TimeSpan.FromMilliseconds(500);
private static readonly TimeSpan IntervaloMinimoRefresh = TimeSpan.FromMilliseconds(500);
private bool DebugMode = true;
private bool DebugMode = false;
public static List<CameraWorkerItemModel> ListaCameras
{
@ -59,10 +57,7 @@ namespace AgroBase.Services.Operadores
{
get
{
CameraWorkerItemModel item =
ListaCameras.FirstOrDefault(
x => x.dispositivo == T_Code.Snr
);
CameraWorkerItemModel item = ListaCameras.FirstOrDefault(x => x.dispositivo == T_Code.Snr);
return item?.ToOAK();
}
@ -126,11 +121,7 @@ namespace AgroBase.Services.Operadores
if (string.IsNullOrWhiteSpace(mensagem))
return;
var comando =
JsonConvert.DeserializeObject<ComandoRedis>(
mensagem,
_jsonSettings
);
var comando = JsonConvert.DeserializeObject<ComandoRedis>(mensagem, _jsonSettings);
if (comando == null)
return;
@ -152,10 +143,7 @@ namespace AgroBase.Services.Operadores
}
catch (Exception ex)
{
MostrarLog(
"Erro ao deserializar resposta: " +
ex.Message
);
MostrarLog("Erro ao deserializar resposta: " + ex.Message);
}
finally
{
@ -165,10 +153,7 @@ namespace AgroBase.Services.Operadores
public void AtualizarSaude()
{
Saude =
OperadoresModels.AtualizarSaude(
CtxKey.DadosCameraWorker
);
Saude = OperadoresModels.AtualizarSaude(CtxKey.DadosCameraWorker);
}
/// <summary>
@ -193,8 +178,7 @@ namespace AgroBase.Services.Operadores
{
DateTime agoraUtc = DateTime.UtcNow;
if (!forcar &&
agoraUtc - _ultimoRefreshUtc < IntervaloMinimoRefresh)
if (!forcar && agoraUtc - _ultimoRefreshUtc < IntervaloMinimoRefresh)
{
return;
}
@ -204,9 +188,7 @@ namespace AgroBase.Services.Operadores
if (_refreshEmAndamento)
return;
if (!forcar &&
DateTime.UtcNow - _ultimoRefreshUtc <
IntervaloMinimoRefresh)
if (!forcar && DateTime.UtcNow - _ultimoRefreshUtc < IntervaloMinimoRefresh)
{
return;
}
@ -216,8 +198,7 @@ namespace AgroBase.Services.Operadores
try
{
List<CameraWorkerItemModel> novaLista =
LerCamerasDoRedis();
List<CameraWorkerItemModel> novaLista = LerCamerasDoRedis();
lock (_cameraLock)
{
@ -227,10 +208,7 @@ namespace AgroBase.Services.Operadores
}
catch (Exception ex)
{
Console.WriteLine(
"[CameraWorkerService] Erro ao atualizar câmeras: " +
ex.Message
);
Variaveis.MostrarLog("[CameraWorkerService.AtualizarDadosCameras] Erro ao atualizar câmeras: " + ex.Message);
}
finally
{
@ -324,16 +302,12 @@ namespace AgroBase.Services.Operadores
return resultado;
}
private static CameraWorkerItemModel LerCameraDoRedis(
string redisIdOuMxId)
private static CameraWorkerItemModel LerCameraDoRedis(string redisIdOuMxId)
{
if (string.IsNullOrWhiteSpace(redisIdOuMxId))
return null;
string cameraStr =
RedisService.Get(
RedisService.CamKey(redisIdOuMxId)
);
string cameraStr = RedisService.Get(RedisService.CamKey(redisIdOuMxId));
if (string.IsNullOrWhiteSpace(cameraStr))
return null;
@ -342,64 +316,42 @@ namespace AgroBase.Services.Operadores
try
{
camera =
JsonConvert.DeserializeObject<CameraWorkerItemModel>(
cameraStr,
_jsonSettings
);
camera = JsonConvert.DeserializeObject<CameraWorkerItemModel>(cameraStr, _jsonSettings);
}
catch (Exception ex)
{
Console.WriteLine(
"[CameraWorkerService] Falha ao ler câmera " +
redisIdOuMxId + ": " + ex.Message
);
Variaveis.MostrarLog("[CameraWorkerService.LerCameraDoRedis] Falha ao ler câmera " + redisIdOuMxId + ": " + ex.Message);
Console.WriteLine(
"[CameraWorkerService] JSON câmera: " +
cameraStr
);
Variaveis.MostrarLog("[CameraWorkerService.LerCameraDoRedis] JSON câmera: " + cameraStr);
return null;
}
if (camera == null ||
string.IsNullOrWhiteSpace(camera.mx_id))
if (camera == null || string.IsNullOrWhiteSpace(camera.mx_id))
{
return null;
}
string imuStr =
RedisService.Get(
RedisService.CamImuKey(camera.mx_id)
);
string imuStr = RedisService.Get(RedisService.CamImuKey(camera.mx_id));
if (!string.IsNullOrWhiteSpace(imuStr))
{
try
{
var imu =
JsonConvert.DeserializeObject<OAKImuModel>(
imuStr,
_jsonSettings
);
var imu = JsonConvert.DeserializeObject<OAKImuModel>(imuStr, _jsonSettings);
camera.imu = imu?.dados;
}
catch (Exception ex)
{
Console.WriteLine(
"[CameraWorkerService] Falha ao ler IMU da câmera " +
camera.mx_id + ": " + ex.Message
);
Variaveis.MostrarLog("[CameraWorkerService.LerCameraDoRedis] Falha ao ler IMU da câmera " + camera.mx_id + ": " + ex.Message);
}
}
return camera;
}
private static List<CameraWorkerItemModel>
CriarListaVaziaComPlaceholder()
private static List<CameraWorkerItemModel> CriarListaVaziaComPlaceholder()
{
return new List<CameraWorkerItemModel>
{
@ -411,23 +363,16 @@ namespace AgroBase.Services.Operadores
};
}
private static void OrdenarCamerasMantendoPlaceholder(
List<CameraWorkerItemModel> cameras)
private static void OrdenarCamerasMantendoPlaceholder(List<CameraWorkerItemModel> cameras)
{
if (cameras == null || cameras.Count <= 1)
return;
CameraWorkerItemModel placeholder =
cameras.FirstOrDefault(
x => x.dispositivo == T_Code.Vzo &&
x.modelo == "Sem Video"
);
CameraWorkerItemModel placeholder = cameras.FirstOrDefault(x => x.dispositivo == T_Code.Vzo && x.modelo == "Sem Video");
var reais =
cameras
.Where(x =>
!(x.dispositivo == T_Code.Vzo &&
x.modelo == "Sem Video"))
.Where(x => !(x.dispositivo == T_Code.Vzo && x.modelo == "Sem Video"))
.OrderBy(PrioridadeCamera)
.ThenBy(x => x.mx_id)
.ToList();

View File

@ -1,7 +1,6 @@
using AgroBase.Models;
using AgroBase.Models.Operadores;
using Newtonsoft.Json;
using OpenHardwareMonitor.Hardware;
using System;
using System.Collections.Generic;
using System.Linq;
@ -13,11 +12,10 @@ namespace AgroBase.Services.Operadores
{
public class HealthWorkerService : IWorkerModel
{
public HealthWorkerModel DadosLeitura = new HealthWorkerModel();
public static HealthWorkerModel DadosLeitura = new HealthWorkerModel();
public SaudeWorkerModel Saude { get; set; } = new SaudeWorkerModel();
public static List<ManagerWorkerMessageResponseModulosPendentesModel> ModulosSaude = new List<ManagerWorkerMessageResponseModulosPendentesModel>();
private bool DebugMode = true;
private bool DebugMode = false;
//private static bool AtualizandoRedis = false;
public void MostrarLog(string message, int limite = 500)
@ -96,17 +94,18 @@ namespace AgroBase.Services.Operadores
private static void AtualizarDadosContextoLocal()
{
var op = Variaveis.OperacaoEmAndamento;
try
{
RedisService.AtualizarCampos(
CtxKey.DadosOperacao,
("debug_mode", Variaveis.DebugMode),
("iniciado", Variaveis.OperacaoEmAndamento.Iniciado),
("finalizando", Variaveis.OperacaoEmAndamento.Finalizando),
("calibrando", Variaveis.OperacaoEmAndamento.Calibrando),
("simulando", Variaveis.OperacaoEmAndamento.Simulando),
("emergencia", Variaveis.OperacaoEmAndamento.Emergencia),
("pausa", Variaveis.OperacaoEmAndamento.Pausa)
("iniciado", op.Sensoriamento.Operacao?.OperacaoIniciada),
("finalizando", op.Sensoriamento.Operacao.Finalizando),
("calibrando", op.Sensoriamento.Operacao.Calibrando),
("simulando", op.Simulando),
("emergencia", op.Sensoriamento.Operacao.Emergencia),
("pausa", op.Sensoriamento.Operacao.Pausa)
);
}
catch (Exception ex)
@ -117,6 +116,8 @@ namespace AgroBase.Services.Operadores
public static void AtualizarDadosContexto()
{
var op = Variaveis.OperacaoEmAndamento;
try
{
//if (AtualizandoRedis)
@ -127,7 +128,7 @@ namespace AgroBase.Services.Operadores
AtualizarDadosModulos();
AtualizarDadosControleOperacao();
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
var _Sensoriamento = op.Sensoriamento;
if (_Sensoriamento == null)
{
@ -142,23 +143,18 @@ namespace AgroBase.Services.Operadores
pontoComparar.idxPonto < _t.QtdPontos - 1 ? pontoComparar.idxPonto + 1 :
pontoComparar.idxPonto) : 0;
double velocidadeMs = Variaveis.OperacaoEmAndamento.Simulando
? FuncoesMatematicas.CalculaVelocidadeMsPercentual(Variaveis.OperacaoEmAndamento.Controle.RPM_SP)
: (_Sensoriamento.Movimentacao?.VelocidadeMedia ?? 0.0);
double velocidadeMs = op.Simulando
? FuncoesMatematicas.CalculaVelocidadeMsPercentual(op.Controle.RPM_SP)
: (_Sensoriamento.Movimentacao?.VelocidadeMediaMs ?? 0.0);
double percentualVelSp = Variaveis.OperacaoEmAndamento.Controle?.PercentualVelocidadeSP ?? 0.0;
double rpmSp = Variaveis.OperacaoEmAndamento.Controle?.RPM_SP ?? 0.0;
double percentualVelSp = op.Controle?.PercentualVelocidadeSP ?? 0.0;
double rpmSp = op.Controle?.RPM_SP ?? 0.0;
bool comandoMovimentoAtivo =
percentualVelSp > 0.5 ||
rpmSp > 1.0;
bool comandoMovimentoAtivo = percentualVelSp > 0.5 || rpmSp > 1.0;
bool velocidadeFisicaAtiva =
Math.Abs(velocidadeMs) > 0.03; // 3 cm/s, ajustável
bool velocidadeFisicaAtiva = Math.Abs(velocidadeMs) > 0.03; // 3 cm/s, ajustável
bool carroEmMovimento =
comandoMovimentoAtivo &&
velocidadeFisicaAtiva;
bool carroEmMovimento = comandoMovimentoAtivo && velocidadeFisicaAtiva;
RedisService.AtualizarCampos(
CtxKey.DadosContexto,
@ -210,7 +206,7 @@ namespace AgroBase.Services.Operadores
),
("Atuador", new
{
pressao_linha_regular = _Sensoriamento.Atuador?.PressaoLinha >= ((Variaveis.OperacaoEmAndamento.Parametros.Controle?.AtuPressaoLinha ?? 0) - 20),
pressao_linha_regular = _Sensoriamento.Atuador?.PressaoLinha >= ((op.Parametros.Controle?.AtuPressaoLinha ?? 0) - 10),
pressao_linha = _Sensoriamento.Atuador?.PressaoLinha ?? 0,
potencia_bomba = _Sensoriamento.Atuador?.LeituraPotenciaBomba ?? 0,
estado_bomba = _Sensoriamento.Atuador?.LeituraComandoBomba ?? false,
@ -274,6 +270,8 @@ namespace AgroBase.Services.Operadores
public static void AtualizarDadosOperacao(bool forcar = false)
{
var op = Variaveis.OperacaoEmAndamento;
try
{
//if (AtualizandoRedis && !forcar)
@ -285,25 +283,25 @@ namespace AgroBase.Services.Operadores
AtualizarDadosEquipamento();
if (Variaveis.OperacaoEmAndamento.DispMvd == null)
if (op.DispMvd == null)
{
//AtualizandoRedis = false;
return;
}
var _Parametros = Variaveis.OperacaoEmAndamento.Parametros;
var _Parametros = op.Parametros;
var pControle = _Parametros.Controle;
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
var _Controle = op.Controle;
RedisService.AtualizarCampos(
CtxKey.DadosOperacao,
("configurado", true),
("modo", Variaveis.OperacaoEmAndamento.Parametros?.Modo ?? ModoOperacao.NaoDefinido),
("tempo_aguardar_inicio_operacao", Variaveis.OperacaoEmAndamento.TempoIniciarOperacao),
("modo", op.Parametros?.Modo ?? ModoOperacao.NaoDefinido),
("tempo_aguardar_inicio_operacao", op.TempoIniciarOperacao),
("modulos_mandatorios", _Parametros.ModulosMandatorios.Where(x => x.Mandatorio && x.Utilizar).Select(x => (int)x.Dispositivo).ToArray()),
("modulos_opcionais", _Parametros.ModulosMandatorios.Where(x => !x.Mandatorio && x.Utilizar).Select(x => (int)x.Dispositivo).ToArray()),
("parametros_mandatorios", _Parametros.ParametrosMandatorios.Where(x => x.Mandatorio && x.Utilizar).Select(x => (int)x.Parametro).ToArray()),
("ponto_mapa_ref", Variaveis.OperacaoEmAndamento.Trajetoria?._TrajetoriaFixa?.Select(p => new double[] { p.Posicao.Latitude, p.Posicao.Longitude }).FirstOrDefault()),
("ponto_mapa_ref", op.Trajetoria?._TrajetoriaFixa?.Select(p => new double[] { p.Posicao.Latitude, p.Posicao.Longitude }).FirstOrDefault()),
("Mov", new
{
percent_vel_max = pControle.MovVelocidadeSErvasPercent,
@ -317,7 +315,7 @@ namespace AgroBase.Services.Operadores
tipo_controle = (int)pControle.DirTipoMovimento,
mpc = new
{
pontos = Variaveis.OperacaoEmAndamento.Trajetoria?._TrajetoriaFixa?
pontos = op.Trajetoria?._TrajetoriaFixa?
.Select(p => new
{
lat = p.Posicao.Latitude,
@ -329,7 +327,7 @@ namespace AgroBase.Services.Operadores
angulo_max_graus = pControle.DirAnguloMaximo,
velocidade_min = Math.Round(FuncoesMatematicas.CalculaVelocidadeMsPercentual(pControle.MovVelocidadeCErvasPercent), 4),
velocidade_max = Math.Round(FuncoesMatematicas.CalculaVelocidadeMsPercentual(pControle.MovVelocidadeSErvasPercent), 4),
tempo_entre_comandos = (Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == Enums.T_Code.Dir)?.DelayEnvioComando ?? 500) / 1000.0,
tempo_entre_comandos = (op.Controle.TiposControle.FirstOrDefault(x => x.Tipo == Enums.T_Code.Dir)?.DelayEnvioComando ?? 500) / 1000.0,
horizonte = pControle.MpcHorizonte,
passos_atraso = 1,
}
@ -355,7 +353,7 @@ namespace AgroBase.Services.Operadores
)
);
if ((Variaveis.OperacaoEmAndamento.Parametros?.ControleAutomatico ?? false) && (Variaveis.OperacaoEmAndamento.Trajetoria?._TrajetoriaFixa?.Any() ?? false))
if ((op.Parametros?.ControleAutomatico ?? false) && (op.Trajetoria?._TrajetoriaFixa?.Any() ?? false))
{
var comando = new
{
@ -411,13 +409,14 @@ namespace AgroBase.Services.Operadores
private static void AtualizarDadosModulos()
{
var op = Variaveis.OperacaoEmAndamento;
try
{
if (Variaveis.OperacaoEmAndamento.DispMvd == null) return;
if (Variaveis.OperacaoEmAndamento.DispAtu == null) return;
if (Variaveis.OperacaoEmAndamento.DispSen == null) return;
if (op.DispMvd == null) return;
if (op.DispAtu == null) return;
if (op.DispSen == null) return;
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
var _Sensoriamento = op.Sensoriamento;
var agora_dt = DateTime.Now;
var agora = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
@ -434,7 +433,7 @@ namespace AgroBase.Services.Operadores
var dirAtivos = new List<int>();
var movAtivos = new List<int>();
foreach (var mod in Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos)
foreach (var mod in op.DispMvd.Dados.Modulos)
{
double erroAnguloDir = Math.Abs(mod.DirMotor.AnguloLeitura - mod.DirMotor.Angulo_SP);
@ -455,7 +454,7 @@ namespace AgroBase.Services.Operadores
($"{endereco_dir}.conectado", mod.DirMotor.Inicializado),
// legado
($"{endereco_dir}.freq_base", Variaveis.OperacaoEmAndamento.DispMvd.Dados.tmrRegistradorDIR.IntervalHz),
($"{endereco_dir}.freq_base", op.DispMvd.Dados.tmrRegistradorDIR.IntervalHz),
($"{endereco_dir}.endereco", mod.DirMotor._EnderecoCAN_Tx),
($"{endereco_dir}.mod_id", mod.Modulo_ID),
@ -586,9 +585,8 @@ namespace AgroBase.Services.Operadores
var DadosSen = Variaveis.OperacaoEmAndamento.DispSen.Dados;
DateTime ultimaRespostaSen =
DadosSen.DadosLeitura?.UltimoComandoRespondido ?? DateTime.MinValue;
var DadosSen = op.DispSen.Dados;
DateTime ultimaRespostaSen = DadosSen.DadosLeitura?.UltimoComandoRespondido ?? DateTime.MinValue;
double idadeUltimaRespostaSenMs =
ultimaRespostaSen == DateTime.MinValue
@ -821,9 +819,8 @@ namespace AgroBase.Services.Operadores
var DadosAtu = Variaveis.OperacaoEmAndamento.DispAtu.Dados;
DateTime ultimaRespostaAtu =
DadosAtu.DadosLeitura?.UltimoComandoRespondido ?? DateTime.MinValue;
var DadosAtu = op.DispAtu.Dados;
DateTime ultimaRespostaAtu = DadosAtu.DadosLeitura?.UltimoComandoRespondido ?? DateTime.MinValue;
double idadeUltimaRespostaAtuMs =
ultimaRespostaAtu == DateTime.MinValue
@ -831,10 +828,10 @@ namespace AgroBase.Services.Operadores
: (agora_dt - ultimaRespostaAtu).TotalMilliseconds;
bool pulverizadorAutomatico =
Variaveis.OperacaoEmAndamento.Parametros?.Controle?.PulverizadorAutomatico ?? false;
op.Parametros?.Controle?.PulverizadorAutomatico ?? false;
double pressaoAlvo =
Variaveis.OperacaoEmAndamento.Parametros?.Controle?.AtuPressaoLinha ?? 0;
op.Parametros?.Controle?.AtuPressaoLinha ?? 0;
double pressaoLinha =
DadosAtu.PressaoLinha;
@ -853,11 +850,11 @@ namespace AgroBase.Services.Operadores
("pulverizador_automatico", pulverizadorAutomatico),
("pulverizador_liberado", DadosAtu.ContadorCarga.PulverizadorLiberado),
("operacao_iniciada", Variaveis.OperacaoEmAndamento.Iniciado),
("calibrando", Variaveis.OperacaoEmAndamento.Calibrando),
("pausa", Variaveis.OperacaoEmAndamento.Pausa),
("emergencia", Variaveis.OperacaoEmAndamento.Emergencia),
("finalizando", Variaveis.OperacaoEmAndamento.Finalizando),
("operacao_iniciada", op.Sensoriamento.Operacao.OperacaoIniciada),
("calibrando", op.Sensoriamento.Operacao.Calibrando),
("pausa", op.Sensoriamento.Operacao.Pausa),
("emergencia", op.Sensoriamento.Operacao.Emergencia),
("finalizando", op.Sensoriamento.Operacao.Finalizando),
("percentual_reservatorio", DadosAtu.ContadorCarga.PercentualAtual),
("pressao_linha", pressaoLinha),
@ -1073,16 +1070,16 @@ namespace AgroBase.Services.Operadores
var DadosLra = Variaveis.LoraService;
RedisService.AtualizarCampos(RedisService.ModKey(Enums.T_Code.Lra),
("timestamp", agora),
("conectado", DadosLra.Conectado),
("configurado", DadosLra.Configurado),
("tempo_base_tx", DadosLra.TempoEnvioDadosBase / 1000.0),
("tempo_base_rx", VariaveisEquipamento.TempoEntrePingsConexao / 1000.0),
("last_tx", DadosLra.UltimoTxDados),
("last_rx", DadosLra.UltimoRxDados)
);
//var DadosLra = Variaveis.LoraService;
//RedisService.AtualizarCampos(RedisService.ModKey(Enums.T_Code.Lra),
// ("timestamp", agora),
// ("conectado", DadosLra.Conectado),
// ("configurado", DadosLra.Configurado),
// ("tempo_base_tx", DadosLra.TempoEnvioDadosBase / 1000.0),
// ("tempo_base_rx", VariaveisEquipamento.TempoEntrePingsConexao / 1000.0),
// ("last_tx", DadosLra.UltimoTxDados),
// ("last_rx", DadosLra.UltimoRxDados)
//);
var DadosMod = _Sensoriamento.DadosPerformance;
RedisService.AtualizarCampos(
@ -1090,7 +1087,7 @@ namespace AgroBase.Services.Operadores
// Base / sincronismo
("timestamp", agora),
("timestamp_unix_ms", DadosMod.TimestampUnixMs),
("freq_base", 1.0 / Variaveis.OperacaoEmAndamento.tmrLeiturasInterval),
("freq_base", 1.0 / op.tmrLeiturasInterval),
// CPU
("cpu_load_percent", DadosMod.CPU_load_percent ?? 0),

View File

@ -17,7 +17,7 @@ namespace AgroBase.Services.Operadores
public ManagerWorkerModel DadosLeitura = new ManagerWorkerModel();
public SaudeWorkerModel Saude { get; set; } = new SaudeWorkerModel();
private bool DebugMode = true;
private bool DebugMode = false;
public void MostrarLog(string message, int limite = 500)
{
@ -76,6 +76,8 @@ namespace AgroBase.Services.Operadores
public void RedisCallback(string mensagem)
{
var op = Variaveis.OperacaoEmAndamento;
try
{
var comando = JsonConvert.DeserializeObject<ComandoRedis>(mensagem);
@ -91,7 +93,7 @@ namespace AgroBase.Services.Operadores
break;
case ManagerWorkerCommandType.EnviarDadosControle:
if (Variaveis.OperacaoEmAndamento.Parametros.Controle.MovimentoAutomatico || Variaveis.OperacaoEmAndamento.Parametros.Controle.DirecionalAutomatico)
if (op.Parametros.Controle.MovimentoAutomatico || op.Parametros.Controle.DirecionalAutomatico)
{
AtualizarControle(comando.@params);
}
@ -100,7 +102,7 @@ namespace AgroBase.Services.Operadores
case ManagerWorkerCommandType.FinalizarOperacao:
Task.Run(async () =>
{
await Variaveis.OperacaoEmAndamento.FinalizarOperacao();
await op.FinalizarOperacao();
});
break;
@ -279,8 +281,10 @@ namespace AgroBase.Services.Operadores
if (novoComando == null)
return;
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
var pControle = Variaveis.OperacaoEmAndamento.Parametros.Controle;
var op = Variaveis.OperacaoEmAndamento;
var _Controle = op.Controle;
var pControle = op.Parametros.Controle;
if (_Controle == null || pControle == null)
return;
@ -318,10 +322,7 @@ namespace AgroBase.Services.Operadores
_Controle.PercentualVelocidadeSP = novoComando.percentual_velocidade;
_Controle.EmFreio = pControle.FrenagemAutomaticaAoParar && novoComando.em_freio;
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(
false,
new List<T_Code>() { T_Code.Mov }
);
op.AtualizarDadosControle(false, new List<T_Code>() { T_Code.Mov });
}
if (podeAtualizarDirecional && (direcionalMudou || forcarAplicacao))
@ -357,10 +358,7 @@ namespace AgroBase.Services.Operadores
novoComando.debug_custo ??
new Dictionary<string, ManagerWorkerMessageResponseDebugCustoModel>();
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(
false,
new List<T_Code>() { T_Code.Dir }
);
op.AtualizarDadosControle(false, new List<T_Code>() { T_Code.Dir });
}
}

View File

@ -69,6 +69,8 @@ namespace AgroBase.Services.Operadores
private async Task tmrHearthbeat_Tick()
{
var op = Variaveis.OperacaoEmAndamento;
Conectado = false;
foreach (var worker in Workers)
{
@ -79,7 +81,7 @@ namespace AgroBase.Services.Operadores
if (!Conectado)
{
TempoDesconectado++;
if (Variaveis.OperacaoEmAndamento.Iniciado && (Variaveis.OperacaoEmAndamento.Parametros.Controle.MovimentoAutomatico || Variaveis.OperacaoEmAndamento.Parametros.Controle.DirecionalAutomatico))
if (op.Sensoriamento.Operacao.OperacaoIniciada && (op.Parametros.Controle.MovimentoAutomatico || op.Parametros.Controle.DirecionalAutomatico))
{
RedisService.AtualizarCampos(
CtxKey.DadosOperacao,
@ -88,8 +90,8 @@ namespace AgroBase.Services.Operadores
("configurado", false)
);
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
if (Variaveis.OperacaoEmAndamento.Parametros.Controle.MovimentoAutomatico)
var _Controle = op.Controle;
if (op.Parametros.Controle.MovimentoAutomatico)
{
if (_Controle.PercentualVelocidadeSP > 0)
{
@ -101,7 +103,7 @@ namespace AgroBase.Services.Operadores
}
}
if (Variaveis.OperacaoEmAndamento.Parametros.Controle.DirecionalAutomatico)
if (op.Parametros.Controle.DirecionalAutomatico)
{
if (_Controle.Angulo != 0)
{
@ -113,7 +115,7 @@ namespace AgroBase.Services.Operadores
}
}
if (Variaveis.OperacaoEmAndamento.Parametros.Controle.PulverizadorAutomatico)
if (op.Parametros.Controle.PulverizadorAutomatico)
{
if (_Controle.Bicos.Any(x => x.ComandoAtuar))
{
@ -125,7 +127,7 @@ namespace AgroBase.Services.Operadores
}
}
Variaveis.OperacaoEmAndamento.AtualizaInformacoesControleOperacao();
op.AtualizaInformacoesControleOperacao();
}
RedisService.DefinirEquipamentoDesconectado();
@ -140,7 +142,7 @@ namespace AgroBase.Services.Operadores
else
{
TempoDesconectado = 0;
if (!Variaveis.OperacaoEmAndamento.OperacaoConfigurada)
if (!op.Sensoriamento.Operacao.OperacaoConfigurada)
{
HealthWorkerService.AtualizarDadosOperacao(true);
}

View File

@ -16,7 +16,7 @@ namespace AgroBase.Services.Operadores
public static VisualWorkerModel DadosLeitura = new VisualWorkerModel();
public SaudeWorkerModel Saude { get; set; } = new SaudeWorkerModel();
private bool DebugMode = true;
private bool DebugMode = false;
private static double _lastTsSegmentacao = -1;
private static double _lastTsDeteccao = -1;
@ -148,10 +148,7 @@ namespace AgroBase.Services.Operadores
{
AtualizarImu();
DadosLeitura.Status =
HealthWorkerService.ModulosSaude
.FirstOrDefault(x => x.modulo == Enums.T_Code.Snr)?.status
?? Enums.StatusModulo.Desconectado;
DadosLeitura.Status = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorSaude?.ModulosSaude?.FirstOrDefault(x => x.modulo == Enums.T_Code.Snr)?.status ?? Enums.StatusModulo.Desconectado;
string json = RedisService.Get(CtxKey.DadosVisualWorker);
@ -170,20 +167,11 @@ namespace AgroBase.Services.Operadores
return;
}
double tsAnalise =
root["ts_analise"]?.Value<double>() ?? 0.0;
double tsSegmentacao =
root["ts_segmentacao"]?.Value<double>() ?? 0.0;
double tsDeteccao =
root["ts_deteccao"]?.Value<double>() ?? 0.0;
double tsMatriz =
root["ts_matriz_confianca"]?.Value<double>() ?? 0.0;
double tsPerformance =
root["ts_performance_visual"]?.Value<double>() ?? 0.0;
double tsAnalise = root["ts_analise"]?.Value<double>() ?? 0.0;
double tsSegmentacao = root["ts_segmentacao"]?.Value<double>() ?? 0.0;
double tsDeteccao = root["ts_deteccao"]?.Value<double>() ?? 0.0;
double tsMatriz = root["ts_matriz_confianca"]?.Value<double>() ?? 0.0;
double tsPerformance = root["ts_performance_visual"]?.Value<double>() ?? 0.0;
DadosLeitura.Timestamps.analise = tsAnalise;
DadosLeitura.Timestamps.segmentacao = tsSegmentacao;
@ -193,24 +181,18 @@ namespace AgroBase.Services.Operadores
if (tsAnalise > 0)
{
DadosLeitura.Analises.timestamp =
FuncoesGlobais.UnixToDateTime(tsAnalise.ToString(
System.Globalization.CultureInfo.InvariantCulture
));
DadosLeitura.Analises.timestamp = FuncoesGlobais.UnixToDateTime(tsAnalise.ToString(System.Globalization.CultureInfo.InvariantCulture));
}
if (tsSegmentacao > 0 &&
tsSegmentacao != _lastTsSegmentacao)
if (tsSegmentacao > 0 && tsSegmentacao != _lastTsSegmentacao)
{
var token = root["segmentacao"];
if (token != null &&
token.Type != JTokenType.Null)
if (token != null && token.Type != JTokenType.Null)
{
try
{
var model =
token.ToObject<VisualWorkerMessageSegmentacaoSemanticaModel>();
var model = token.ToObject<VisualWorkerMessageSegmentacaoSemanticaModel>();
if (model != null)
DadosLeitura.Analises.segmentacao = model;
@ -224,21 +206,17 @@ namespace AgroBase.Services.Operadores
_lastTsSegmentacao = tsSegmentacao;
}
if (tsDeteccao > 0 &&
tsDeteccao != _lastTsDeteccao)
if (tsDeteccao > 0 && tsDeteccao != _lastTsDeteccao)
{
var token = root["deteccao"];
if (token != null &&
token.Type != JTokenType.Null)
if (token != null && token.Type != JTokenType.Null)
{
try
{
var model =
token.ToObject<List<VisualWorkerMessageDeteccaoModel>>();
var model = token.ToObject<List<VisualWorkerMessageDeteccaoModel>>();
DadosLeitura.Analises.deteccao =
model ?? new List<VisualWorkerMessageDeteccaoModel>();
DadosLeitura.Analises.deteccao = model ?? new List<VisualWorkerMessageDeteccaoModel>();
}
catch
{
@ -249,18 +227,15 @@ namespace AgroBase.Services.Operadores
_lastTsDeteccao = tsDeteccao;
}
if (tsMatriz > 0 &&
tsMatriz != _lastTsMatrizConfianca)
if (tsMatriz > 0 && tsMatriz != _lastTsMatrizConfianca)
{
var token = root["matriz_confianca"];
if (token != null &&
token.Type != JTokenType.Null)
if (token != null && token.Type != JTokenType.Null)
{
try
{
var model =
token.ToObject<VisualWorkerMessageMatrizConfiancaModel>();
var model = token.ToObject<VisualWorkerMessageMatrizConfiancaModel>();
if (model != null)
DadosLeitura.Analises.matriz_confianca = model;
@ -274,18 +249,15 @@ namespace AgroBase.Services.Operadores
_lastTsMatrizConfianca = tsMatriz;
}
if (tsPerformance > 0 &&
tsPerformance != _lastTsPerformanceVisual)
if (tsPerformance > 0 && tsPerformance != _lastTsPerformanceVisual)
{
var token = root["performance_visual"];
if (token != null &&
token.Type != JTokenType.Null)
if (token != null && token.Type != JTokenType.Null)
{
try
{
var model =
token.ToObject<VisualWorkerPerformanceModel>();
var model = token.ToObject<VisualWorkerPerformanceModel>();
if (model != null)
{

View File

@ -16,7 +16,7 @@ namespace AgroBase.Services.Operadores
public static WeedWorkerModel DadosLeitura = new WeedWorkerModel();
public SaudeWorkerModel Saude { get; set; } = new SaudeWorkerModel();
private bool DebugMode = true;
private bool DebugMode = false;
private static double _lastTsAnaliseWeed = -1;
private static double _lastTsPerformanceWeed = -1;
@ -54,6 +54,8 @@ namespace AgroBase.Services.Operadores
if (dictParams == null)
return;
var op = Variaveis.OperacaoEmAndamento;
var novoComando = dictParams
.Select(kv => new
{
@ -64,21 +66,21 @@ namespace AgroBase.Services.Operadores
.ToDictionary(x => x.Key, x => x.Value);
bool comandoMudou = false;
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
var _Controle = op.Controle;
foreach (var bico in _Controle.Bicos ?? new List<Models.Modules.AtuadorBicoModel>())
{
novoComando.TryGetValue(bico.Posicao, out bool atuado);
if (!(Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.ContadorCarga?.PulverizadorLiberado ?? false)) atuado = false;
if (!(op.DispAtu?.Dados?.ContadorCarga?.PulverizadorLiberado ?? false)) atuado = false;
if (!comandoMudou) comandoMudou = atuado != bico.ComandoAtuar;
bico.ComandoAtuar = atuado;
}
if (comandoMudou)
{
Variaveis.MostrarLog("[WeedWorkerService] [AtualizarControle] Comando dos bicos alterado: " + JsonConvert.SerializeObject(novoComando));
var pControle = Variaveis.OperacaoEmAndamento.Parametros.Controle;
var pControle = op.Parametros.Controle;
if (pControle.PulverizadorAutomatico)
{
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(false, new List<T_Code>() { T_Code.Atu });
op.AtualizarDadosControle(false, new List<T_Code>() { T_Code.Atu });
}
}
}
@ -189,37 +191,27 @@ namespace AgroBase.Services.Operadores
}
catch (Exception ex)
{
Console.WriteLine(
$"Erro ao interpretar DadosWeedWorker: {ex.Message}"
);
Variaveis.MostrarLog($"[WeedWorkerService.AtualizarAnalise] Erro ao interpretar DadosWeedWorker: {ex.Message}");
return;
}
double tsAnalise =
root["ts_analise"]?.Value<double>() ?? 0.0;
double tsAnaliseWeed =
root["ts_analise_weed"]?.Value<double>() ?? 0.0;
double tsPerformance =
root["ts_performance_weed"]?.Value<double>() ?? 0.0;
double tsAnalise = root["ts_analise"]?.Value<double>() ?? 0.0;
double tsAnaliseWeed = root["ts_analise_weed"]?.Value<double>() ?? 0.0;
double tsPerformance = root["ts_performance_weed"]?.Value<double>() ?? 0.0;
DadosLeitura.Timestamps.analise = tsAnalise;
DadosLeitura.Timestamps.analise_weed = tsAnaliseWeed;
DadosLeitura.Timestamps.performance_weed = tsPerformance;
if (tsAnaliseWeed > 0 &&
tsAnaliseWeed != _lastTsAnaliseWeed)
if (tsAnaliseWeed > 0 && tsAnaliseWeed != _lastTsAnaliseWeed)
{
JToken envelopeToken = root["analise"];
if (envelopeToken != null &&
envelopeToken.Type != JTokenType.Null)
if (envelopeToken != null && envelopeToken.Type != JTokenType.Null)
{
try
{
var envelope =
envelopeToken.ToObject<WeedWorkerAnaliseEnvelopeModel>();
var envelope = envelopeToken.ToObject<WeedWorkerAnaliseEnvelopeModel>();
if (envelope != null)
{
@ -233,33 +225,27 @@ namespace AgroBase.Services.Operadores
infer_gpu_ms = envelope.infer_gpu_ms
};
DadosLeitura.Analise =
envelope.analise ?? new WeedWorkerAnaliseModel();
DadosLeitura.Analise = envelope.analise ?? new WeedWorkerAnaliseModel();
}
}
catch (Exception ex)
{
Console.WriteLine(
$"Erro ao desserializar análise de ervas: {ex.Message}"
);
Variaveis.MostrarLog($"[WeedWorkerService.AtualizarAnalise] Erro ao desserializar análise de ervas: {ex.Message}");
}
}
_lastTsAnaliseWeed = tsAnaliseWeed;
}
if (tsPerformance > 0 &&
tsPerformance != _lastTsPerformanceWeed)
if (tsPerformance > 0 && tsPerformance != _lastTsPerformanceWeed)
{
JToken performanceToken = root["performance_weed"];
if (performanceToken != null &&
performanceToken.Type != JTokenType.Null)
if (performanceToken != null && performanceToken.Type != JTokenType.Null)
{
try
{
var performance =
performanceToken.ToObject<WeedWorkerPerformanceModel>();
var performance = performanceToken.ToObject<WeedWorkerPerformanceModel>();
if (performance != null)
{
@ -269,9 +255,7 @@ namespace AgroBase.Services.Operadores
}
catch (Exception ex)
{
Console.WriteLine(
$"Erro ao desserializar performance weed: {ex.Message}"
);
Variaveis.MostrarLog($"[WeedWorkerService.AtualizarAnalise] Erro ao desserializar performance weed: {ex.Message}");
}
}
@ -297,8 +281,7 @@ namespace AgroBase.Services.Operadores
JToken imuToken = root["imu"];
if (imuToken == null ||
imuToken.Type == JTokenType.Null)
if (imuToken == null || imuToken.Type == JTokenType.Null)
return;
var imu = imuToken.ToObject<OAKImuModel>();
@ -317,36 +300,15 @@ namespace AgroBase.Services.Operadores
{
RedisService.AtualizarCampos(
CtxKey.DadosWeedWorker,
("analise.analise.ervas_no_radar", false),
("analise.analise.controle",
new Dictionary<string, bool>(
Variaveis.OperacaoEmAndamento
.DispAtu
.Dados
.BicosPulverizadores
.ToDictionary(
x => x.Posicao.ToString(),
x => false
)
)
),
("analise.analise.estatisticas",
new WeedWorkerAnaliseEstatisticasModel()
),
("analise.analise.controle", new Dictionary<string, bool>(Variaveis.OperacaoEmAndamento.DispAtu.Dados.BicosPulverizadores.ToDictionary(x => x.Posicao.ToString(), x => false))),
("analise.analise.estatisticas", new WeedWorkerAnaliseEstatisticasModel()),
("ts_analise_weed", 0.0)
);
_lastTsAnaliseWeed = -1;
DadosLeitura.Analise =
new WeedWorkerAnaliseModel();
DadosLeitura.MetricasAnalise =
new WeedWorkerAnaliseMetricasModel();
DadosLeitura.Analise = new WeedWorkerAnaliseModel();
DadosLeitura.MetricasAnalise = new WeedWorkerAnaliseMetricasModel();
}
}

View File

@ -1,5 +1,5 @@
using AgroBase.Models.Operadores;
using AgroBase.Services.Operadores;
using AgroBase.Models;
using AgroBase.Models.Operadores;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using StackExchange.Redis;
@ -157,13 +157,14 @@ namespace AgroBase.Services
public static void DefinirEquipamentoDesconectado()
{
var saude = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorSaude?.ModulosSaude;
AtualizarCampos(
CtxKey.DadosOperacao,
("motivo_nao_liberado", "Sem comunicação com o núcleo de processamento central"),
("liberado", false),
("configurado", false)
);
foreach (var Mod in HealthWorkerService.ModulosSaude)
foreach (var Mod in saude)
{
Mod.conectado = false;
Mod.saude = 0;
@ -177,7 +178,7 @@ namespace AgroBase.Services
}
AtualizarCampos(
CtxKey.DadosOperacao,
("status_modulos", HealthWorkerService.ModulosSaude)
("status_modulos", saude)
);
}

View File

@ -850,43 +850,30 @@ namespace AgroBase.Services
// DETECÇÃO DE DISPOSITIVOS
// ============================================================
private static async Task<bool> ProcurarDispositivosCAN(
SerialPort porta = null,
CancellationToken cancellationToken =
default(CancellationToken))
private static async Task<bool> ProcurarDispositivosCAN(SerialPort porta = null, CancellationToken cancellationToken = default(CancellationToken))
{
cancellationToken.ThrowIfCancellationRequested();
string name =
porta?.PortName ??
CanManager.CanService._portName ??
"CAN";
string name = porta?.PortName ?? CanManager.CanService._portName ?? "CAN";
AtualizarConsole(
name +
" - Procurando dispositivos no barramento CAN"
);
AtualizarConsole(name + " - Procurando dispositivos no barramento CAN");
/*
* Uma candidata que não é CAN é simplesmente ignorada.
* Nunca removemos mapeamentos CAN por causa desse teste.
*/
if (porta != null &&
!CanManager.CanService.PortaIsCan(porta))
if (porta != null && !CanManager.CanService.PortaIsCan(porta))
{
return false;
}
if (!CanManager.CanService.Iniciado)
{
bool initialized =
CanManager.CanService.Inicializar(250);
bool initialized = CanManager.CanService.Inicializar(250);
if (!initialized)
{
AtualizarConsole(
"Adaptador " + name + " não conectado!"
);
AtualizarConsole("Adaptador " + name + " não conectado!");
return false;
}
@ -894,22 +881,11 @@ namespace AgroBase.Services
cancellationToken.ThrowIfCancellationRequested();
if (Variaveis.OperacaoEmAndamento.DispSen != null &&
!Variaveis.OperacaoEmAndamento
.DispSen
.Dados
.Conectado)
if (Variaveis.OperacaoEmAndamento.DispSen != null && !Variaveis.OperacaoEmAndamento.DispSen.Dados.Conectado)
{
AtualizarConsole(
name + " - Procurando dispositivo SEN"
);
AtualizarConsole(name + " - Procurando dispositivo SEN");
bool found =
await Variaveis.OperacaoEmAndamento
.DispSen
.Dados
.VerificaDispositivoConectado()
.ConfigureAwait(false);
bool found = await Variaveis.OperacaoEmAndamento.DispSen.Dados.VerificaDispositivoConectado().ConfigureAwait(false);
if (found)
AtualizarConsole("Dispositivo SEN encontrado");
@ -917,22 +893,11 @@ namespace AgroBase.Services
cancellationToken.ThrowIfCancellationRequested();
if (Variaveis.OperacaoEmAndamento.DispAtu != null &&
!Variaveis.OperacaoEmAndamento
.DispAtu
.Dados
.Conectado)
if (Variaveis.OperacaoEmAndamento.DispAtu != null && !Variaveis.OperacaoEmAndamento.DispAtu.Dados.Conectado)
{
AtualizarConsole(
name + " - Procurando dispositivo ATU"
);
AtualizarConsole(name + " - Procurando dispositivo ATU");
bool found =
await Variaveis.OperacaoEmAndamento
.DispAtu
.Dados
.VerificaDispositivoConectado()
.ConfigureAwait(false);
bool found = await Variaveis.OperacaoEmAndamento.DispAtu.Dados.VerificaDispositivoConectado().ConfigureAwait(false);
if (found)
AtualizarConsole("Dispositivo ATU encontrado");
@ -940,30 +905,17 @@ namespace AgroBase.Services
cancellationToken.ThrowIfCancellationRequested();
int expectedModules =
Variaveis.OperacaoEmAndamento
.DispMvd?
.Dados?
.Modulos?
.Count() ?? 4;
int expectedModules = Variaveis.OperacaoEmAndamento.DispMvd?.Dados?.Modulos?.Count() ?? 4;
if (Variaveis.OperacaoEmAndamento.DispMvd != null &&
!MKS057DCanService.Referenciando &&
if (Variaveis.OperacaoEmAndamento.DispMvd != null && !MKS057DCanService.Referenciando &&
(
!MKS057DCanService.Iniciado ||
MKS057DCanService.DadosLeitura
.Count(x => x.Iniciado) <
expectedModules
MKS057DCanService.DadosLeitura.Count(x => x.Iniciado) < expectedModules
))
{
AtualizarConsole(
name + " - Procurando dispositivos MKS"
);
AtualizarConsole(name + " - Procurando dispositivos MKS");
bool found =
await MKS057DCanService
.VerificaDispositivoConectado()
.ConfigureAwait(false);
bool found = await MKS057DCanService.VerificaDispositivoConectado().ConfigureAwait(false);
if (found)
AtualizarConsole("Dispositivo MKS encontrado");
@ -974,19 +926,12 @@ namespace AgroBase.Services
if (Variaveis.OperacaoEmAndamento.DispMvd != null &&
(
!OIDCanService.Iniciado ||
OIDCanService.DadosLeitura
.Count(x => x.Iniciado) <
expectedModules
OIDCanService.DadosLeitura.Count(x => x.Iniciado) < expectedModules
))
{
AtualizarConsole(
name + " - Procurando dispositivo OID"
);
AtualizarConsole(name + " - Procurando dispositivo OID");
bool found =
await OIDCanService
.VerificaDispositivoConectado()
.ConfigureAwait(false);
bool found = await OIDCanService.VerificaDispositivoConectado().ConfigureAwait(false);
if (found)
AtualizarConsole("Dispositivo OID encontrado");
@ -996,14 +941,9 @@ namespace AgroBase.Services
if (!DalyBMSService.Iniciado)
{
AtualizarConsole(
name + " - Procurando dispositivo BAT"
);
AtualizarConsole(name + " - Procurando dispositivo BAT");
bool found =
await DalyBMSService
.VerificaDispositivoConectado()
.ConfigureAwait(false);
bool found = await DalyBMSService.VerificaDispositivoConectado().ConfigureAwait(false);
if (found)
AtualizarConsole("Dispositivo BAT encontrado");
@ -1027,25 +967,14 @@ namespace AgroBase.Services
foreach (var camera in cameras)
{
var health =
HealthWorkerService.ModulosSaude
.FirstOrDefault(
x => x.modulo == camera.dispositivo
);
var health = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorSaude.ModulosSaude.FirstOrDefault(x => x.modulo == camera.dispositivo);
if (health == null)
continue;
DispositivoDetalhesModel mapped =
GetDispositivosMapeadosSnapshot()
.FirstOrDefault(
x => x.Dispositivo ==
camera.dispositivo
);
DispositivoDetalhesModel mapped = GetDispositivosMapeadosSnapshot().FirstOrDefault(x => x.Dispositivo == camera.dispositivo);
bool connected =
health.status !=
StatusModulo.Desconectado;
bool connected = health.status != StatusModulo.Desconectado;
if (mapped == null && connected)
{
@ -1066,24 +995,16 @@ namespace AgroBase.Services
}
}
private static async Task<bool> ProcurarDispositivoLoRa(
SerialPort porta,
CancellationToken cancellationToken)
private static async Task<bool> ProcurarDispositivoLoRa(SerialPort porta, CancellationToken cancellationToken)
{
if (porta == null)
return false;
cancellationToken.ThrowIfCancellationRequested();
AtualizarConsole(
porta.PortName +
" - Procurando dispositivo LRA"
);
AtualizarConsole(porta.PortName + " - Procurando dispositivo LRA");
bool found =
await LoRaBaseService
.VerificaPortaLoRa(porta)
.ConfigureAwait(false);
bool found = await LoRaBaseService.VerificaPortaLoRa(porta).ConfigureAwait(false);
if (found)
{
@ -1095,18 +1016,14 @@ namespace AgroBase.Services
return false;
}
private static async Task<bool> ProcurarDispositivoGPS(
SerialPort porta,
CancellationToken cancellationToken)
private static async Task<bool> ProcurarDispositivoGPS(SerialPort porta, CancellationToken cancellationToken)
{
if (porta == null ||
string.IsNullOrWhiteSpace(porta.PortName))
if (porta == null || string.IsNullOrWhiteSpace(porta.PortName))
{
return false;
}
SerialPort probe =
CriarPortaCandidata(porta.PortName);
SerialPort probe = CriarPortaCandidata(porta.PortName);
try
{
@ -1117,22 +1034,13 @@ namespace AgroBase.Services
try { probe.DiscardInBuffer(); }
catch { }
const string command =
"gngga com3 1\r\n";
const string command = "gngga com3 1\r\n";
byte[] commandBytes =
Encoding.ASCII.GetBytes(command);
byte[] commandBytes = Encoding.ASCII.GetBytes(command);
probe.Write(
commandBytes,
0,
commandBytes.Length
);
probe.Write(commandBytes, 0, commandBytes.Length);
AtualizarConsole(
probe.PortName +
" - Procurando dispositivo GPS"
);
AtualizarConsole(probe.PortName + " - Procurando dispositivo GPS");
byte[] received =
await LerAteCondicaoAsync(
@ -1153,9 +1061,7 @@ namespace AgroBase.Services
*/
GPSService.AtualizarPortaCOM(probe);
AtualizarConsole(
"Dispositivo GPS encontrado"
);
AtualizarConsole("Dispositivo GPS encontrado");
return true;
}
@ -1170,10 +1076,7 @@ namespace AgroBase.Services
}
catch (Exception ex)
{
RecordError(
"[SerialService.ProbeGPS] " +
porta.PortName + ": " + ex.Message
);
RecordError("[SerialService.ProbeGPS] " + porta.PortName + ": " + ex.Message);
return false;
}
@ -1185,24 +1088,14 @@ namespace AgroBase.Services
private static void ProcurarDispositivosEthernet()
{
var livox =
HealthWorkerService.ModulosSaude
.FirstOrDefault(
x => x.modulo == T_Code.Lvx
);
var livox = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorSaude.ModulosSaude.FirstOrDefault(x => x.modulo == T_Code.Lvx);
if (livox == null)
return;
DispositivoDetalhesModel mapped =
GetDispositivosMapeadosSnapshot()
.FirstOrDefault(
x => x.Dispositivo == livox.modulo
);
DispositivoDetalhesModel mapped = GetDispositivosMapeadosSnapshot().FirstOrDefault(x => x.Dispositivo == livox.modulo);
bool connected =
livox.status !=
StatusModulo.Desconectado;
bool connected = livox.status != StatusModulo.Desconectado;
if (mapped == null && connected)
{
@ -1210,18 +1103,9 @@ namespace AgroBase.Services
new DispositivoDetalhesModel
{
Dispositivo = livox.modulo,
Endereco =
LivoxManagerProcess
.DadosLeitura
.lidar_ip,
Versao =
LivoxManagerProcess
.DadosLeitura
.firmware_version,
Mod_ID =
LivoxManagerProcess
.DadosLeitura
.dev_type
Endereco = LivoxManagerProcess.DadosLeitura.lidar_ip,
Versao = LivoxManagerProcess.DadosLeitura.firmware_version,
Mod_ID = LivoxManagerProcess.DadosLeitura.dev_type
}
);
}
@ -1235,15 +1119,9 @@ namespace AgroBase.Services
// REMOÇÃO E ATUALIZAÇÃO DE MODELOS
// ============================================================
private static async Task RemoverDispositivosAusentesAsync(
string[] currentPorts,
CancellationToken cancellationToken)
private static async Task RemoverDispositivosAusentesAsync(string[] currentPorts, CancellationToken cancellationToken)
{
var current =
new HashSet<string>(
currentPorts ?? new string[0],
StringComparer.OrdinalIgnoreCase
);
var current = new HashSet<string>(currentPorts ?? new string[0], StringComparer.OrdinalIgnoreCase);
List<DispositivoDetalhesModel> mappedCom =
GetDispositivosMapeadosSnapshot()

View File

@ -164,7 +164,7 @@ namespace AgroBase.Services
public static Bitmap ExibirObstaculos(Bitmap bitmap, SonarCamModel leitura, bool ExibirTexto = false)
{
if (bitmap == null || (!false && Variaveis.OperacaoEmAndamento.Iniciado))
if (bitmap == null || (!false && Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoIniciada))
{
return bitmap;
}

View File

@ -33,7 +33,7 @@ namespace AgroBase.Services
bool sucesso = true;
if (!Variaveis.OperacaoEmAndamento.Iniciado && APIService.HasInternet)
if (!Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoIniciada && APIService.HasInternet)
{
List<string> Operacoes = Directory.GetDirectories(Variaveis.CaminhoOperacoes).ToList();
foreach (string OperacaoID in Operacoes.Select(x => x.Split('/')[1]))

View File

@ -377,8 +377,7 @@ namespace AgroBase.Services
try
{
if (Variaveis.OperacaoEmAndamento != null &&
Variaveis.OperacaoEmAndamento.Iniciado)
if (Variaveis.OperacaoEmAndamento != null && Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoIniciada)
{
ResultadoAtualizacao =
"Atualização ignorada: operação em andamento.";

View File

@ -12,7 +12,7 @@ def main():
from health_worker.modulos.movimentacao import ModuloMovimentacao
from health_worker.modulos.sensoriamento import ModuloSensoriamento
from health_worker.modulos.atuador import ModuloAtuador
from health_worker.modulos.lora import ModuloLoRa
#from health_worker.modulos.lora import ModuloLoRa
from health_worker.modulos.imu import CameraIMU
from health_worker.modulos.pc import ModuloPC
from health_worker.modulos.livox import ModuloLivox
@ -29,7 +29,7 @@ def main():
T_Code.Mov: ModuloMovimentacao(),
T_Code.Sen: ModuloSensoriamento(),
T_Code.Atu: ModuloAtuador(),
T_Code.Lra: ModuloLoRa(),
#T_Code.Lra: ModuloLoRa(),
T_Code.Imu: CameraIMU(modulos_imu=[T_Code.Snr]),
T_Code.Npc: ModuloPC(),
T_Code.Lvx: ModuloLivox(),