implementado matriz de custo ao MPC

This commit is contained in:
Diego Freitas 2025-07-11 13:38:08 -03:00
parent 766f8b4e8e
commit fa60088811
1364 changed files with 579439 additions and 4475 deletions

Binary file not shown.

View File

@ -531,6 +531,7 @@
<Compile Include="Models\OIDModel.cs" />
<Compile Include="Models\Operacoes\OperacaoModel.cs" />
<Compile Include="Models\Operacoes\OperacaoParametrosModel.cs" />
<Compile Include="Models\Operadores\CameraWorkerModel.cs" />
<Compile Include="Models\Operadores\HealthWorkerModel.cs" />
<Compile Include="Models\Operadores\ManagerWorkerModel.cs" />
<Compile Include="Models\Operadores\OperadoresModels.cs" />
@ -580,6 +581,7 @@
<Compile Include="Services\MqttService.cs" />
<Compile Include="Services\OIDCanService.cs" />
<Compile Include="Services\OIDService.cs" />
<Compile Include="Services\Operadores\CameraWorkerService.cs" />
<Compile Include="Services\Operadores\HealthWorkerService.cs" />
<Compile Include="Services\Operadores\ManagerWorkerService.cs" />
<Compile Include="Services\Operadores\OperadoresService.cs" />

View File

@ -1,6 +1,7 @@
using AgroBase.Models;
using AgroBase.Models.Components;
using AgroBase.Services;
using AgroBase.Services.Operadores;
using System;
using System.Collections.Generic;
using System.Data;
@ -266,7 +267,7 @@ namespace AgroBase.Forms.IHM
private async Task AtualizarCameras()
{
flwCamerasSolo.Controls.Clear();
ListaCameras = await VariaveisOperacao.Operadores.AtualizarListaCameras();
ListaCameras = CameraWorkerService.GetListaCameras();
CameraCaminho = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho.Clone();
CamerasSolo = new List<OAKCameraModel>(Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo);
@ -356,7 +357,7 @@ namespace AgroBase.Forms.IHM
CameraCaminho = CameraDisponivel(cmb.Text);
if (CameraCaminho.Index > -1)
{
Bitmap rgb = await CameraCaminho.GetFrame();
Bitmap rgb = await CameraCaminho.GetNewFrame();
pic.Image = rgb;
}
else
@ -376,7 +377,7 @@ namespace AgroBase.Forms.IHM
CamerasSolo[idx] = CameraDisponivel(cmb.Text, idx);
if (CamerasSolo[idx].Index > -1)
{
Bitmap rgb = await CamerasSolo[idx].GetFrame();
Bitmap rgb = await CamerasSolo[idx].GetNewFrame();
pic.Image = rgb;
}
else

View File

@ -5,6 +5,7 @@ using AgroBase.Models;
using AgroBase.Models.Components;
using AgroBase.Models.Modules;
using AgroBase.Services;
using AgroBase.Services.Operadores;
using System;
using System.Collections.Generic;
using System.Drawing;
@ -235,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, VariaveisOperacao.Operadores.ModulosSaude);
OperacaoModel.PopularTreeView(tvwFalhas, HealthWorkerService.ModulosSaude);
}
private async Task<bool> IniciarDiagnostico(int idx)
@ -244,7 +245,7 @@ namespace AgroBase.Forms.IHM
if (idx == 9)
{
OperacaoModel.PopularTreeView(tvwFalhas, VariaveisOperacao.Operadores.ModulosSaude);
OperacaoModel.PopularTreeView(tvwFalhas, HealthWorkerService.ModulosSaude);
return true;
}

View File

@ -4,6 +4,7 @@ using AgroBase.Models.Components;
using AgroBase.Models.Operadores;
using AgroBase.Properties;
using AgroBase.Services;
using AgroBase.Services.Operadores;
using System;
using System.Collections.Generic;
using System.Data;
@ -132,11 +133,6 @@ namespace AgroBase.Forms.IHM
lblCodigoFalha.Click -= LblCodigoFalha_Click;
lblCodigoFalha.Click += LblCodigoFalha_Click;
Task.Run(async () =>
{
await VariaveisOperacao.Operadores.AtualizarListaCameras();
});
}
private async Task tmrDispositivos_Tick()
@ -162,7 +158,7 @@ namespace AgroBase.Forms.IHM
private async Task AtualizarControlesUI()
{
var Labels = this.Controls.OfType<Label>().Where(y => y.Name.Contains("lblD_")).ToList();
var listaCameras = await VariaveisOperacao.Operadores.AtualizarListaCameras();
var listaCameras = CameraWorkerService.GetListaCameras();
foreach (var lbl in Labels)
{
T_Code Dispositivo = (T_Code)Enum.Parse(typeof(T_Code), lbl.Name.Split('_')[1]);
@ -299,7 +295,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 = VariaveisOperacao.Operadores.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo);
var saudeGeral = HealthWorkerService.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo);
ManagerWorkerMessageResponseModulosPendentesSaudeModel saudeIndividual = null;
switch (Dispositivo)
{

View File

@ -1202,7 +1202,7 @@ namespace AgroBase.Forms.Operacoes
.ToList();
var LogSnr = LogsSonar.FirstOrDefault(x => x.Leitura.MomentoLog == MomentoAtual);
var LogSnr = LogsSonar.FirstOrDefault(x => x.UltimaMensagem == MomentoAtual);
var LogOpe = LogsOperacao.FirstOrDefault(x => x.Momento == MomentoAtual);
MapaDinamico.AtualizarDados(
@ -1454,7 +1454,7 @@ namespace AgroBase.Forms.Operacoes
private void AtualizarInformacoesSonar()
{
var Log = LogsSonar.FirstOrDefault(x => x.Leitura.MomentoLog == MomentoAtual);
var Log = LogsSonar.FirstOrDefault(x => x.UltimaMensagem == MomentoAtual);
//txtEspacoLivreEsquerda.Text = Log.Leitura.obj.radar_2d.analise.corredor_perfil[1].esquerda_m.ToString("0.00");
//txtEspacoLivreDireita.Text = Log.Leitura.obj.radar_2d.analise.corredor_perfil[1].direita_m.ToString("0.00");
txtDesvioNecessario.Text = Log.Resumo.DesvioNecessario ? "Sim" : "Não";

View File

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

View File

@ -36,6 +36,7 @@ namespace AgroBase.Forms
PythonService.EncerrarProcessos();
RedisService.Iniciar();
RedisService.LimparDadosIniciais();
Task.Run(async () =>
{

View File

@ -1,5 +1,6 @@
using AgroBase.Models;
using AgroBase.Models.Operadores;
using AgroBase.Services.Operadores;
using System;
using System.Collections.Generic;
using System.Drawing;
@ -39,7 +40,7 @@ namespace AgroBase.Forms
private void AtualizarListaCameras()
{
cmbCameras.Items.Clear();
cmbCameras.Items.AddRange(VariaveisOperacao.Operadores.CamerasConectadas.Select(x => x.Name).ToArray());
cmbCameras.Items.AddRange(CameraWorkerService.GetListaCameras().Select(x => x.Name).ToArray());
cmbCameras.SelectedIndex = -1;
}
@ -58,34 +59,12 @@ namespace AgroBase.Forms
private async void btnAtualizarCameras_Click(object sender, EventArgs e)
{
VariaveisOperacao.Operadores.HealthWorker.AdicionarComandoNaFila(OperadoresModels.TipoComando.GetListaCameras);
await VariaveisOperacao.Operadores.HealthWorker.AguardarNovosDados(OperadoresModels.TipoComando.GetListaCameras);
AtualizarListaCameras();
}
private async void btnIniciarProcessamento_Click(object sender, EventArgs e)
{
bool sucesso = false; // await VariaveisOperacao.Operadores.VisualWorker.IniciarCamera(Convert.ToInt32(txtDistanciaMax.Text), Convert.ToInt32(txtSessoesSolo.Text), Convert.ToInt32(txtPercentualSolo.Text));
AtualizarLabelLeitura($", Comando: Configurar, Sucesso: {sucesso}");
if (!sucesso)
{
MessageBox.Show("Selecione uma camera para iniciar o processamento!");
}
else
{
MessageBox.Show("Camera configurada com sucesso!");
}
}
private void EnviarComando(VisualWorkerCommandType cmd, dynamic payload = null)
{
bool sucesso = VariaveisOperacao.Operadores.VisualWorker.AdicionarComandoNaFila(cmd, payload);
AtualizarLabelLeitura($", Comando: {cmd.ToString()}, Sucesso: {sucesso}");
}
private void AtualizarLabelLeitura(string texto)
{
lblUltimaLeitura.Text = $"Ultima Leitura em: {VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.MomentoLog.ToString("dd/MM/yyyy HH:mm:ss.fff")} {texto}";
}
private void btnPing_Click(object sender, EventArgs e)
@ -95,62 +74,56 @@ namespace AgroBase.Forms
private void btnCalibrarGrades_Click(object sender, EventArgs e)
{
//EnviarComando(VisualWorkerCommandType.Calibrar_Grades);
VisualWorkerService.RecalibrarGridProfundidade();
}
private void btnLeituraRGB_Click(object sender, EventArgs e)
private async void btnLeituraRGB_Click(object sender, EventArgs e)
{
//EnviarComandoReqFrame(VisualWorkerCommandType.Get_RGB_Frame);
EnviarComandoReqFrame(VisualWorkerFrameType.Rgb);
}
private void btnLeituraHeatmap_Click(object sender, EventArgs e)
{
//EnviarComandoReqFrame(VisualWorkerCommandType.Get_Heatmap_Frame);
EnviarComandoReqFrame(VisualWorkerFrameType.Heatmap);
}
private void btnLeituraRadar2D_Click(object sender, EventArgs e)
{
//EnviarComandoReqFrame(VisualWorkerCommandType.Get_Radar_2D);
EnviarComandoReqFrame(VisualWorkerFrameType.RadarTopDown);
}
private void btnLeituraSegmentacaoSemantica_Click(object sender, EventArgs e)
{
//EnviarComandoReqFrame(VisualWorkerCommandType.Get_Segmentacao_Semantica);
EnviarComandoReqFrame(VisualWorkerFrameType.Segmentacao);
}
private async void EnviarComandoReqFrame(VisualWorkerCommandType comando)
private async void EnviarComandoReqFrame(VisualWorkerFrameType tipo)
{
/*EnviarComando(comando);
await VariaveisOperacao.Operadores.VisualWorker.AguardarNovosDados(comando);
OAKCameraFrameModel frame =
comando == VisualWorkerCommandType.Get_RGB_Frame ? VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.rgb_frame :
comando == VisualWorkerCommandType.Get_Heatmap_Frame ? VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.heatmap_frame :
comando == VisualWorkerCommandType.Get_Radar_2D ? VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.radar_2d?.frame :
comando == VisualWorkerCommandType.Get_Segmentacao_Semantica ? VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.segmentacao?.mask_frame :
new OAKCameraFrameModel();
OAKCameraFrameModel frame = await VisualWorkerService.GetCameraFrame(tipo);
PictureBox pic =
comando == VisualWorkerCommandType.Get_RGB_Frame ? picRGB :
comando == VisualWorkerCommandType.Get_Heatmap_Frame ? picHeatmap :
comando == VisualWorkerCommandType.Get_Radar_2D ? picRadar2D :
comando == VisualWorkerCommandType.Get_Segmentacao_Semantica ? picSegmentacaoSemantica :
tipo == VisualWorkerFrameType.Rgb ? picRGB :
tipo == VisualWorkerFrameType.Heatmap ? picHeatmap :
tipo == VisualWorkerFrameType.RadarTopDown ? picRadar2D :
tipo == VisualWorkerFrameType.Segmentacao ? picSegmentacaoSemantica :
new PictureBox();
Label lbl =
comando == VisualWorkerCommandType.Get_RGB_Frame ? lblLeituraRGB :
comando == VisualWorkerCommandType.Get_Heatmap_Frame ? lblLeituraHeatmap :
comando == VisualWorkerCommandType.Get_Radar_2D ? lblLeituraRadar2D :
comando == VisualWorkerCommandType.Get_Segmentacao_Semantica ? lblLeituraSegmentacaoSemantica :
tipo == VisualWorkerFrameType.Rgb ? lblLeituraRGB :
tipo == VisualWorkerFrameType.Heatmap ? lblLeituraHeatmap :
tipo == VisualWorkerFrameType.RadarTopDown ? lblLeituraRadar2D :
tipo == VisualWorkerFrameType.Segmentacao ? lblLeituraSegmentacaoSemantica :
new Label();
pic.Image?.Dispose();
try { pic.Image = frame?.image; } catch { }
lbl.Text = $"Leitura em: {FuncoesGlobais.TimestampToDate(frame?.timestamp ?? 0)}";
try { pic.Image = frame?.image(); } catch { }
lbl.Text = $"Leitura em: " + frame?.timestamp.ToString("dd/MM/yyyy HH:mm:ss");
if (comando == VisualWorkerCommandType.Get_Radar_2D && VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.radar_2d != null)
if (tipo == VisualWorkerFrameType.RadarTopDown && VisualWorkerService.DadosLeitura.Analises != null)
{
pic.Image = VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.radar_2d.PlotarAnalsie(frame.image);
//pic.Image = VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.radar_2d.PlotarAnalsie(frame.image);
PlotarGraficoPerfilCorredor(VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.radar_2d.analise.corredor_perfil);
}*/
PlotarGraficoPerfilCorredor(VisualWorkerService.DadosLeitura.Analises.corredor_prof);
}
}
private void btnReqStatusDispositivo_Click(object sender, EventArgs e)
@ -160,55 +133,32 @@ namespace AgroBase.Forms
private void btnReqAnomalias_Click(object sender, EventArgs e)
{
//EnviarComandoAnalise(VisualWorkerCommandType.Get_Analise_Anomalia);
AtualizarDadosAnalise();
}
private void btnReqSolo_Click(object sender, EventArgs e)
{
//EnviarComandoAnalise(VisualWorkerCommandType.Get_Analise_Solo);
AtualizarDadosAnalise();
}
private async void btnLeituraIMU_Click(object sender, EventArgs e)
{
/*EnviarComando(VisualWorkerCommandType.Get_IMU_Data);
await VariaveisOperacao.Operadores.VisualWorker.AguardarNovosDados(VisualWorkerCommandType.Get_IMU_Data);
pnlInclinacao.Invalidate();
lblLeituraIMU.Text = $"Leitura em: {FuncoesGlobais.TimestampToDate(VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.imu?.timestamp ?? 0)}";*/
lblLeituraIMU.Text = $"Leitura em: {FuncoesGlobais.TimestampToDate(VisualWorkerService.DadosLeitura.Imu?.timestamp ?? 0)}";
}
private async void EnviarComandoAnalise(VisualWorkerCommandType comando)
private void AtualizarDadosAnalise()
{
EnviarComando(comando, new { velocidade_ms = txtVelocidade.Text.Replace(",", "."), distancia_max = txtDistanciaMax.Text.Replace(",", "."), largura_min = txtSessoesSolo.Text.Replace(",", "."), altura_min = txtPercentualSolo.Text.Replace(",", ".") });
await VariaveisOperacao.Operadores.VisualWorker.AguardarNovosDados(comando);
AtualizarDadosAnalise(comando);
}
var analise = VisualWorkerService.DadosLeitura.Analises;
private void AtualizarDadosAnalise(VisualWorkerCommandType comando)
{
/*VisualWorkerMessageAnaliseModel analise =
comando == VisualWorkerCommandType.Get_Analise_Anomalia ? VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.analise_anomalias :
comando == VisualWorkerCommandType.Get_Analise_Solo ? VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.analise_solo :
new VisualWorkerMessageAnaliseModel();
lblLeituraDebug.Text = $"Leitura em: {FuncoesGlobais.TimestampToDate(analise?.timestamp ?? 0)}";
OAKCameraFrameModel frame = VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.heatmap_frame;
lblLeituraDebug.Text = $"Leitura em: " + (analise?.timestamp ?? DateTime.MinValue).ToString("dd/MM/yyyy HH:mm:ss");
OAKCameraFrameModel frame = VisualWorkerService.DadosLeitura.CameraFrames[VisualWorkerFrameType.Heatmap];
picDebug.Image?.Dispose();
picDebug.Image = analise.PlotarAnalise(frame);
switch (comando)
{
case VisualWorkerCommandType.Get_Analise_Anomalia:
{
PreencherGridAnomalias(analise.anomalias ?? new List<VisualWorkerMessageAnaliseBBoxModel>());
break;
}
case VisualWorkerCommandType.Get_Analise_Solo:
{
PreencherGridSolo(analise.solo?.bbox_list ?? new List<VisualWorkerMessageAnaliseBBoxModel>());
//PreencherGridSolo(analise.solo?.bbox_list ?? new List<VisualWorkerMessageAnaliseBBoxModel>());
PlotarGraficoPerfilSolo(analise.solo?.perfil ?? new List<double>());
break;
}
}*/
}
void ConfigurarGridDeteccoes(DataGridView dgv)
@ -356,9 +306,9 @@ namespace AgroBase.Forms
private void pnlInclinacao_Paint(object sender, PaintEventArgs e)
{
/*Panel _pnlInclinacao = sender as Panel;
double AnguloX = VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj?.imu?.roll ?? 0;
double AnguloY = VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj?.imu?.pitch ?? 0;
Panel _pnlInclinacao = sender as Panel;
double AnguloX = VisualWorkerService.DadosLeitura.Imu?.roll ?? 0;
double AnguloY = VisualWorkerService.DadosLeitura.Imu?.pitch ?? 0;
Graphics g = e.Graphics;
int centerX = _pnlInclinacao.Width / 2;
@ -413,7 +363,7 @@ namespace AgroBase.Forms
// Desenhar o círculo
Brush brush = new SolidBrush(Color.Red);
g.FillEllipse(brush, circlePosX - radius, circlePosY - radius, radius * 2, radius * 2);*/
g.FillEllipse(brush, circlePosX - radius, circlePosY - radius, radius * 2, radius * 2);
}

View File

@ -43,7 +43,7 @@ namespace AgroBase
this.lblStripOperacaoLiberada = new System.Windows.Forms.ToolStripStatusLabel();
this.lblStripOperacaoStatus = new System.Windows.Forms.ToolStripStatusLabel();
this.lblStripMqtt = new System.Windows.Forms.ToolStripStatusLabel();
this.lblStripWifi = new System.Windows.Forms.ToolStripStatusLabel();
this.lblStripPython = new System.Windows.Forms.ToolStripStatusLabel();
this.gpbMovimentacao = new System.Windows.Forms.GroupBox();
this.lblKmh = new System.Windows.Forms.Label();
this.trkKmh = new System.Windows.Forms.TrackBar();
@ -196,7 +196,7 @@ namespace AgroBase
this.lblStripOperacaoLiberada,
this.lblStripOperacaoStatus,
this.lblStripMqtt,
this.lblStripWifi});
this.lblStripPython});
this.generalStrip.Location = new System.Drawing.Point(0, 612);
this.generalStrip.Name = "generalStrip";
this.generalStrip.Padding = new System.Windows.Forms.Padding(1, 0, 10, 0);
@ -235,11 +235,11 @@ namespace AgroBase
this.lblStripMqtt.Size = new System.Drawing.Size(121, 17);
this.lblStripMqtt.Text = "MQTT: Desconectado";
//
// lblStripWifi
// lblStripPython
//
this.lblStripWifi.Name = "lblStripWifi";
this.lblStripWifi.Size = new System.Drawing.Size(116, 17);
this.lblStripWifi.Text = "Wi-Fi: Desconectado";
this.lblStripPython.Name = "lblStripPython";
this.lblStripPython.Size = new System.Drawing.Size(99, 17);
this.lblStripPython.Text = "IA: Desconectado";
//
// gpbMovimentacao
//
@ -927,7 +927,7 @@ namespace AgroBase
private System.Windows.Forms.CheckedListBox clbRotinas;
private System.Windows.Forms.Button btnAtualizarRotinas;
public System.Windows.Forms.ProgressBar pgbAtualizacaoArquivos;
public System.Windows.Forms.ToolStripStatusLabel lblStripWifi;
public System.Windows.Forms.ToolStripStatusLabel lblStripPython;
private System.Windows.Forms.Button btnOID;
private System.Windows.Forms.Button btnTreinamentoIA;
private System.Windows.Forms.Button btnVisualWorker;

View File

@ -98,11 +98,12 @@ namespace AgroBase
AtualizaDadosGerais();
lblStripMqtt.Text = "MQTT: " + (Variaveis.MqttService.StatusConexao() ? "Conectado" : "Desconectado");
lblStripWifi.Text = "Wi-Fi: " + (WifiService.WifiConectado ? "Conectado" : WifiService.Conectando ? "Conectando..." : WifiService.WifiDisponivel ? "Disponivel" : "Desconectado");
bool opLiberada = Variaveis.OperacaoEmAndamento.OperacaoLiberada;
lblStripOperacaoLiberada.Text = "Operação Liberada: " + (opLiberada ? "Sim" : "Não");
lblStripOperacaoLiberada.ForeColor = opLiberada ? Color.Green : Color.Red;
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;
Variaveis.DebugMode = chbDebugMode.Checked;
}

View File

@ -21,6 +21,7 @@ namespace AgroBase.Forms
int ticksControle = 0;
List<GPSModel> passosOperacao = new List<GPSModel>();
int idxPassoOperacao = 0;
double velocidadeCarroMs = 0.0;
DateTime UltimaAtualizacaoGps = DateTime.MinValue;
@ -66,27 +67,45 @@ namespace AgroBase.Forms
Variaveis.OperacaoEmAndamento.Iniciado = false;
}
DateTime t0 = DateTime.Now;
private async Task tmrLeitura_Tick()
{
double latencia_tick = (DateTime.Now - t0).TotalSeconds;
t0 = DateTime.Now;
int.TryParse(txtTempoGPS.Text, out int tempo);
if (tempo > 0)
{
tempoGps = tempo;
}
tmrLeitura.SetInterval((int)tempoGps);
ticksControleMax = (int)(Variaveis.OperacaoEmAndamento.Controle.TiposControle.First(x => x.Tipo == T_Code.Dir).DelayEnvioComando / tempoGps);
Func<bool> funcAtt = new Func<bool>(() =>
{
AtualizarDadosTela();
return true;
});
Task.Run(() => FuncoesGlobais.ExecutarMetodoComVerificacaoCrossThread(this, funcAtt));
if (chbAutomatico.Checked)
{
btnAcrescentarGPS_Click(btnAcrescentarGPS, new EventArgs());
}
DateTime t1 = DateTime.Now;
double latencia_exec = (t1 - t0).TotalSeconds;
double frequencia_exec = 1.0 / Math.Max(latencia_exec, 1e-6);
double frequencia_tick = 1.0 / Math.Max(latencia_tick, 1e-6);
//Console.WriteLine($"Tempo por tick GPS: {Math.Round(latencia_exec, 4)} s, Frequencia: {Math.Round(frequencia_exec, 2)} Hz | Tempo entre tick GPS: {Math.Round(latencia_tick, 4)}, Frequencia: {Math.Round(frequencia_tick, 2)} Hz");
double novoDelay = Math.Max(tempoGps - (latencia_exec * 1000.0), 1);
tmrLeitura.SetInterval((int)novoDelay);
}
bool AtualizandoTela = false;
private void AtualizarDadosTela()
{
if (AtualizandoTela)
return;
AtualizandoTela = true;
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
var _Trajetoria = Variaveis.OperacaoEmAndamento.Trajetoria;
@ -152,6 +171,8 @@ namespace AgroBase.Forms
Variaveis.OperacaoEmAndamento.Mapa.AtualizarRuasSelecionadas();
}
AtualizandoTela = false;
}
@ -199,14 +220,14 @@ namespace AgroBase.Forms
{
GPSModel novaPosicao = new GPSModel();
double velocidadeMs = FuncoesMatematicas.CalculaVelocidadeMsPercentual(Variaveis.OperacaoEmAndamento.SimulacaoRpmControle);
double velocidade = FuncoesMatematicas.ConverteMsParaKmh(velocidadeMs);
velocidadeCarroMs = FuncoesMatematicas.ConverteMsParaKmh(velocidadeMs);
Variaveis.OperacaoEmAndamento.DispMvd.Dados.VelocidadeMedia = velocidadeMs;
TimeSpan tempoPassado =
double tempoPassado =
!chbAutomatico.Checked || UltimaAtualizacaoGps == DateTime.MinValue ? // esta no modo manual
new TimeSpan((int)tempoGps * 10000) : // 1 tick do tempo gps
DateTime.Now - UltimaAtualizacaoGps; // tempo decorrido entre ticks do timer de leitura
(tempoGps / 1000.0) : // 1 tick do tempo gps
(DateTime.Now - UltimaAtualizacaoGps).TotalSeconds; // tempo decorrido entre ticks do timer de leitura
// Obtém os parâmetros
double anguloAtual = double.Parse(txtAnguloGPS.Text);
@ -253,22 +274,55 @@ namespace AgroBase.Forms
}
// Calcula a nova posicao do robo
novaPosicao = VariaveisEquipamento.SimularNovaPosicao(tipoMovimento, anguloControle, velocidadeMs, tempoPassado.TotalSeconds, anguloAtual, _Gps);
//GPSModel pos = NovaPosicaoSimulacao(velocidadeMs, tempoPassado);
if (true || novaPosicao == null)
{
novaPosicao = VariaveisEquipamento.SimularNovaPosicao(tipoMovimento, anguloControle, velocidadeMs, tempoPassado, anguloAtual, _Gps);
}
//Console.WriteLine($"C#: {DadosPosicao(novaPosicao)}");
//Console.WriteLine($"Py: {DadosPosicao(pos)}");
// Atualiza a interface gráfica
txtAnguloGPS.Text = novaPosicao.OrientacaoReal.ToString("0.00");
txtVelocidade.Text = velocidade.ToString("0.00");
txtVelocidade.Text = velocidadeCarroMs.ToString("0.00");
txtDistanciaGPS.Text = novaPosicao.Distancia.ToString("0.0000");
txtLatitude.Text = novaPosicao.Latitude.ToString();
txtLongitude.Text = novaPosicao.Longitude.ToString();
UltimaAtualizacaoGps = DateTime.Now;
AtualizarPosicaoGPS();
if (!chbAutomatico.Checked)
{
AtualizarDadosTela();
}
}
private GPSModel NovaPosicaoSimulacao(double velocidadeMs, double tempo)
{
if (Variaveis.OperacaoEmAndamento.Controle.SimulacaoMPC.Count() > 1)
{
double distancia = velocidadeMs * tempo;
MPCSimulacaoModel posicao = Variaveis.OperacaoEmAndamento.Controle.SimulacaoMPC[1];
GPSModel novaPosicao = new GPSModel()
{
Latitude = posicao.latitude,
Longitude = posicao.longitude,
OrientacaoReal = posicao.orientacao,
Distancia = distancia,
};
return novaPosicao;
}
return null;
}
private string DadosPosicao(GPSModel pos)
{
if (pos == null) return "";
return $"Lat: {pos.Latitude}, Long: {pos.Longitude}, Theta: {pos.OrientacaoReal}, Distancia: {pos.Distancia}";
}
private void btnIniciarSimulacao_Click(object sender, EventArgs e)
{
@ -408,10 +462,7 @@ namespace AgroBase.Forms
private void chbAutomatico_CheckedChanged(object sender, EventArgs e)
{
if (chbAutomatico.Checked)
{
UltimaAtualizacaoGps = DateTime.Now.AddMilliseconds(-tempoGps);
}
UltimaAtualizacaoGps = DateTime.MinValue;
}
private void btnReiniciar_Click(object sender, EventArgs e)

View File

@ -1,4 +1,5 @@
using System;
using AgroBase.Services.Operadores;
using System;
using System.Linq;
using static AgroBase.Models.Enums;
@ -46,21 +47,21 @@ namespace AgroBase.Models
{
get
{
return VariaveisOperacao.Operadores.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo)?.status ?? StatusModulo.Desconectado;
return HealthWorkerService.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo)?.status ?? StatusModulo.Desconectado;
}
}
public double Saude
{
get
{
return VariaveisOperacao.Operadores.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo)?.saude ?? 0;
return HealthWorkerService.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo)?.saude ?? 0;
}
}
public string Erros
{
get
{
var motivos = VariaveisOperacao.Operadores.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo)?.motivos ?? new System.Collections.Generic.List<string>();
var motivos = HealthWorkerService.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo)?.motivos ?? new System.Collections.Generic.List<string>();
return string.Join(", ", motivos);
}
}

View File

@ -52,6 +52,7 @@
public enum T_Code
{
Vzo = -1,
Imu = 53,
Mov = 100,
Dir = 101,
Sen = 102,
@ -170,10 +171,11 @@
{
NaoIniciado = 0,
Parametrizando = 1,
Aguardando = 2,
EmAndamento = 3,
Parado = 4,
Concluido = 5
Calibrando = 2,
Aguardando = 3,
EmAndamento = 4,
Parado = 5,
Concluido = 6
}
public enum StatusCarroMapa

View File

@ -191,4 +191,5 @@ public class MPCSimulacaoModel
{
public double latitude { get; set; }
public double longitude { get; set; }
public double orientacao { get; set; }
}

View File

@ -1,4 +1,5 @@
using AgroBase.Services;
using AgroBase.Services.Operadores;
using System;
using System.Collections.Generic;
using System.Drawing;
@ -29,9 +30,10 @@ namespace AgroBase.Models.Modules
{
get
{
return VariaveisOperacao.Operadores.ModulosSaude.Any(x => x.modulo == Dispositivo && x.status == StatusModulo.Operante);
return HealthWorkerService.ModulosSaude.Any(x => x.modulo == Dispositivo && x.status == StatusModulo.Operante);
}
}
public bool AtuPronto { get; set; } = false;
public static PinoutDataModel Pinout { get; set; }
public static List<FuncoesPinout> Funcoes { get; set; } = new List<FuncoesPinout>()
@ -449,6 +451,7 @@ namespace AgroBase.Models.Modules
var Dados = _dados as AtuadorModel;
Dados.DadosLeitura = new AtuadorMensagemJsonModel();
Dados.DadosLeitura.Momento = DateTime.MinValue;
Dados.AtuPronto = false;
Dados.PercentualErvasTerreno = 0;
Dados.BombasPressurizadoras.ForEach(x => x.Funcoes = x.Funcoes.Distinct().ToList());
@ -758,6 +761,49 @@ namespace AgroBase.Models.Modules
}
}
public async Task<bool> RealizarTestesIniciais()
{
// Ligar bomba
bool BombaOk = false;
var Bomba = BombasPressurizadoras.FirstOrDefault();
if (Bomba.Inicializado)
{
GeneralJoystick.EnviarComandoAtuador(S_Code.sBMB, true, Bomba.ID);
bool AtingiuPressao() => PressaoLinha >= Variaveis.OperacaoEmAndamento.Controle.PressaoLinha;
await FuncoesGlobais.AguardarCondicaoAsync(AtingiuPressao, 10000, 200);
BombaOk = AtingiuPressao();
}
// Testar os bicos
foreach (var Bico in BicosPulverizadores)
{
if (Bico.Inicializado)
{
GeneralJoystick.EnviarComandoAtuador(S_Code.sBIC, true, Bico.ID);
await Task.Delay(200);
GeneralJoystick.EnviarComandoAtuador(S_Code.sBIC, false, Bico.ID);
}
}
await Task.Delay(1000);
return BombaOk;
}
public async Task RealizarCalibragemAsync()
{
var DispAtu = Variaveis.OperacaoEmAndamento.DispAtu;
if (DispAtu != null)
DispAtu.Dados.AtuPronto = await DispAtu.Dados.RealizarTestesIniciais();
}
}
public class AtuadorBicoModel

View File

@ -87,6 +87,8 @@ namespace AgroBase.Models.Modules
}
}
public bool Referenciando { get; set; } = false;
public DateTime UltimoReferenciamento { get; set; }
public bool Referenciado { get; set; } = false;
public bool Comandar { get; set; } = false;
public bool Inicializado
@ -303,7 +305,7 @@ namespace AgroBase.Models.Modules
if (Comandar)
{
Variaveis.OperacaoEmAndamento.SimulacaoAnguloControle = Angulo_SP;
Console.WriteLine($"Angulo Atualizado para {Variaveis.OperacaoEmAndamento.SimulacaoAnguloControle}");
//Console.WriteLine($"Angulo Atualizado para {Variaveis.OperacaoEmAndamento.SimulacaoAnguloControle}");
}
int mx = Sentido_SP == Sentido.Antihorario ? -1 : 1;
@ -328,6 +330,8 @@ namespace AgroBase.Models.Modules
await Task.Delay(1000);
Referenciado = false;
await SetZero();
bool Sucesso = false;
@ -382,6 +386,7 @@ namespace AgroBase.Models.Modules
{
await SetZero();
Console.WriteLine($"[DIR {Mod_ID}] - Referenciamento Concluído!");
Referenciado = true;
}
DateTime Inicio = DateTime.Now;
@ -390,6 +395,8 @@ namespace AgroBase.Models.Modules
}
Referenciando = false;
UltimoReferenciamento = DateTime.Now;
}
private int DefineVelocidadeReferenciamento()

View File

@ -380,7 +380,7 @@ namespace AgroBase.Models.Modules
RPM_SP = Convert.ToInt32(RPM_SP * FatorCompensacaoCurvas);
Variaveis.OperacaoEmAndamento.SimulacaoRpmControle = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.Average(x => x.MovMotor.RPM_SP) / VariaveisEquipamento.RelacaoRPM;
Console.WriteLine($"RPM Atualizado para {Variaveis.OperacaoEmAndamento.SimulacaoRpmControle}");
//Console.WriteLine($"RPM Atualizado para {Variaveis.OperacaoEmAndamento.SimulacaoRpmControle}");
switch (DirecaoAtual)
{

View File

@ -25,8 +25,10 @@ namespace AgroBase.Models.Modules
}
}
public bool DirPronto { get; set; } = false;
public bool MovPronto { get; set; } = false;
public int _TaxaAmostragem { get; set; } = 1000;
public int _TaxaAmostragem { get; set; } = 250;
public double DistanciaPercorridaOperacao { get; set; } = 0;
public double TempoEmAtividade { get; set; } = 0;
@ -119,10 +121,14 @@ namespace AgroBase.Models.Modules
public void LimparDados<T>(T _dados)
{
var Dados = _dados as MovimentacaoUnificadaModel;
Dados.DirPronto = false;
Dados.MovPronto = false;
Dados.Modulos.ForEach(x =>
{
x.MovMotor.Leitura = null;
x.DirMotor.Leitura = null;
x.DirMotor.UltimoReferenciamento = DateTime.MinValue;
x.DirMotor.Referenciado = false;
x.DirMotor.Referenciando = false;
});
@ -218,8 +224,11 @@ namespace AgroBase.Models.Modules
var UltimaDirecao = Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Mov)?.UltimaDirecao ?? Direcao.Parado;
if (UltimaDirecao != Direcao.Parado)
{
if (!Variaveis.OperacaoEmAndamento.Simulando)
{
VelocidadeMedia = FuncoesMatematicas.ConverteKmhParaMs(Modulos.Where(x => x.Conectado && x.MovMotor.ComandoLigado).DefaultIfEmpty().Average(x => x?.MovMotor?.VelocidadeInstantanea ?? 0));
}
double tempo = _TaxaAmostragem / 1000.0;
double distancia = tempo * VelocidadeMedia;
DistanciaPercorridaTotal += distancia;
@ -368,7 +377,7 @@ namespace AgroBase.Models.Modules
}
}
public async Task RealizarReferenciamentoDirecional()
public async Task<bool> RealizarReferenciamentoDirecional()
{
if (!MKS057DCanService.Referenciando)
{
@ -385,8 +394,21 @@ namespace AgroBase.Models.Modules
await FuncoesGlobais.AguardarCondicaoAsync(ReferenciamentoConcluido, 2 * 1000 * 60, 1000);
Variaveis.OperacaoEmAndamento.Controle.TipoMovimento = tipoControle;
}
return Modulos.All(x => x.DirMotor.Referenciado);
}
public async Task RealizarCalibragemAsync()
{
var DispMvd = Variaveis.OperacaoEmAndamento.DispMvd;
if (DispMvd != null)
{
DispMvd.Dados.MovPronto = DispMvd.Dados.Modulos.All(x => x.MovMotor.Inicializado);
DispMvd.Dados.DirPronto = DispMvd.Dados.Modulos.All(x => x.DirMotor.Inicializado);
if (DispMvd.Dados.Modulos.Any(x => x.DirMotor.Inicializado))
DispMvd.Dados.DirPronto &= await DispMvd.Dados.RealizarReferenciamentoDirecional();
}
}
}

View File

@ -8,6 +8,7 @@ using System.Globalization;
using System.Data;
using static AgroBase.Services.LoRaEspService;
using System.Windows.Forms;
using AgroBase.Services.Operadores;
namespace AgroBase.Models.Modules
{
@ -38,7 +39,7 @@ namespace AgroBase.Models.Modules
{
get
{
return VariaveisOperacao.Operadores.ModulosSaude.Any(x => x.modulo == Dispositivo && x.status == StatusModulo.Operante);
return HealthWorkerService.ModulosSaude.Any(x => x.modulo == Dispositivo && x.status == StatusModulo.Operante);
}
}
public SensoriamentoMensagemJsonModel DadosLeitura { get; set; } = new SensoriamentoMensagemJsonModel();
@ -1689,8 +1690,6 @@ namespace AgroBase.Models.Modules
public void LimparDados<T>(T _dados)
{
var Dados = _dados as SensoriamentoModel;
Dados.CameraCaminho.frames = new Dictionary<Operadores.OperadoresModels.TipoComando, System.Drawing.Bitmap>();
Dados.CamerasSolo.ForEach(cam => cam.frames = new Dictionary<Operadores.OperadoresModels.TipoComando, System.Drawing.Bitmap>());
Dados.DadosLeitura = new SensoriamentoMensagemJsonModel();
Dados.Reles.ForEach(x =>
{

View File

@ -1,9 +1,10 @@
using System;
using AgroBase.Models.Operadores;
using AgroBase.Services.Operadores;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Threading.Tasks;
using static AgroBase.Models.Enums;
using static AgroBase.Models.Operadores.OperadoresModels;
namespace AgroBase.Models
{
@ -31,20 +32,48 @@ namespace AgroBase.Models
public double fx { get; set; }
public double baseline { get; set; }
public Dictionary<TipoComando, Bitmap> frames { get; set; } = new Dictionary<TipoComando, Bitmap>();
public double DistanciaMaximaVisao { get; set; } = 5000;
public double DistanciaMinimaVisao { get; set; } = 500;
public double PercentualAlturaSolo { get; set; } = 30;
public bool newData { get; set; }
public void setVisto() => newData = false;
public async Task<Bitmap> GetFrame(TipoComando tipo = TipoComando.GetCameraFrame)
public Dictionary<VisualWorkerFrameType, OAKCameraFrameModel> frames
{
VariaveisOperacao.Operadores.HealthWorker.AdicionarComandoNaFila(tipo, new { mx_id = Id });
await VariaveisOperacao.Operadores.HealthWorker.AguardarNovosDados(tipo, 10000);
Bitmap bmp = (VariaveisOperacao.Operadores.HealthWorker.DadosLeitura.Leitura.obj?.frame ?? new OAKCameraFrameModel()).image;
frames[tipo] = bmp;
get
{
switch (Dispositivo)
{
case T_Code.Snr:
return VisualWorkerService.DadosLeitura.CameraFrames;
default:
return new Dictionary<VisualWorkerFrameType, OAKCameraFrameModel>();
}
}
}
public async Task<Bitmap> GetNewFrame(VisualWorkerFrameType tipo = VisualWorkerFrameType.Rgb)
{
OAKCameraFrameModel frame = null;
switch (Dispositivo)
{
case T_Code.Snr:
frame = await VisualWorkerService.GetCameraFrame(tipo);
break;
}
Bitmap bmp = frame?.image();
return bmp;
}
public void SaveFrames(List<VisualWorkerFrameType> frames, string nome, string caminho)
{
switch (Dispositivo)
{
case T_Code.Snr:
VisualWorkerService.SaveCameraFrames(frames, nome, caminho);
break;
}
}
public OAKCameraModel Clone()
{
return new OAKCameraModel()
@ -63,8 +92,6 @@ namespace AgroBase.Models
Version = Version,
fx = fx,
baseline = baseline,
frames = new Dictionary<TipoComando, Bitmap>(frames),
newData = true
};
}
}
@ -114,38 +141,19 @@ namespace AgroBase.Models
public class OAKCameraFrameModel
{
public long timestamp { get; set; }
public DateTime timestamp { get; set; } = DateTime.MinValue;
public string frame { get; set; }
public Bitmap image { get; set; } = null;
public Bitmap image()
{
return FuncoesGlobais.Base64ToBitmap(frame);
}
private bool _newData = true;
public bool newData
{
get
{
if (_newData)
{
_newData = false;
return true;
}
else
{
return false;
}
}
set
{
_newData = value;
}
}
public OAKCameraFrameModel Clone()
{
return new OAKCameraFrameModel()
{
timestamp = timestamp,
frame = frame,
image = FuncoesGlobais.Base64ToBitmap(frame),
newData = true
frame = frame
};
}
}

View File

@ -15,6 +15,8 @@ using System.Drawing;
using System.Text;
using static AgroBase.Services.OIDCanService.OidHandler;
using AgroBase.Models.Operadores;
using AgroBase.Services.Operadores;
using AgroBase.Forms;
namespace AgroBase.Models
{
@ -53,13 +55,15 @@ namespace AgroBase.Models
public Form frmOperacao { get; set; }
#region STATUS DE CONTEXTO
public StatusOperacao StatusAtual { get; set; }
public StatusOperacao StatusAtual { get; private set; } = StatusOperacao.NaoIniciado;
public bool Emergencia { get; set; } = false;
public bool OperacaoLiberada { get; set; }
public bool OperacaoLiberada { get; private set; } = false;
public bool OperacaoConfigurada { get; private set; } = false;
public string ErroOperacaoLiberada { get; set; }
public DateTime TempoAguardando { get; set; }
public DateTime TempoAguardando { get; private set; } = DateTime.Now;
public bool Iniciado { get; set; }
public bool Finalizando { get; set; } = false;
public bool Calibrando { get; set; } = false;
public DateTime DataInicio { get; set; } = DateTime.MinValue;
public DateTime DataFim { get; set; } = DateTime.MinValue;
public double TempoDecorridoSegs
@ -69,13 +73,28 @@ namespace AgroBase.Models
return (StatusAtual == StatusOperacao.Parametrizando ? 0 : ((Variaveis.OperacaoEmAndamento.DataFim != DateTime.MinValue ? Variaveis.OperacaoEmAndamento.DataFim : DateTime.Now) - Variaveis.OperacaoEmAndamento.DataInicio).TotalSeconds);
}
}
public bool MovimentoLiberado
public void AtualizarDadosContexto()
{
get
{
return StatusAtual == StatusOperacao.EmAndamento && !Finalizando && !MKS057DCanService.Referenciando;
}
DateTime t0 = DateTime.Now;
HealthWorkerService.AtualizarDadosContexto();
DateTime t1 = DateTime.Now;
Variaveis.OperacaoEmAndamento.StatusAtual = (StatusOperacao)RedisService.GetField<int>(CtxKey.DadosOperacao, "status", 0);
Variaveis.OperacaoEmAndamento.OperacaoLiberada = RedisService.GetField(CtxKey.DadosOperacao, "liberado", false);
Variaveis.OperacaoEmAndamento.OperacaoConfigurada = RedisService.GetField(CtxKey.DadosOperacao, "configurado", false);
var tempoAguardando = RedisService.GetField<long>(CtxKey.DadosOperacao, "tempo_aguardando", 0);
Variaveis.OperacaoEmAndamento.TempoAguardando = DateTimeOffset.FromUnixTimeSeconds(tempoAguardando).UtcDateTime.AddSeconds(tempoAguardando % 1).ToLocalTime();
//Console.WriteLine(Variaveis.OperacaoEmAndamento.OperacaoConfigurada);
HealthWorkerService.ModulosSaude = RedisService.GetField<ManagerWorkerMessageResponseModulosPendentesModel[]>(CtxKey.DadosOperacao, "status_modulos").ToList();
Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada = RedisService.GetField<string>(CtxKey.DadosOperacao, "motivo_nao_liberado");
DateTime t2 = DateTime.Now;
//Console.WriteLine($"Atualizacao de Contexto: {Math.Round((t1 - t0).TotalSeconds), 4}, Saude Modulos: {Math.Round((t2 - t1).TotalSeconds), 4}, Total: {Math.Round((t2 - t0).TotalSeconds),4}");
}
#endregion
@ -89,7 +108,7 @@ namespace AgroBase.Models
public List<OperacaoParametrosMandatoriosModel> ParametrosMandatorios { get; set; } = new List<OperacaoParametrosMandatoriosModel>();
public double CapacidadeReservatorio { get; set; } = 30;
public int QuantidadeCamerasSolo { get; set; } = 1;
public int TempoIniciarOperacao { get; set; } = 25;
public int TempoIniciarOperacao { get; set; } = 5;
public string ID { get; set; }
public double tmrLogsInterval
{
@ -249,7 +268,7 @@ namespace AgroBase.Models
//bool resultado = await FuncoesGlobais.AguardarCondicaoAsync(condicaoMapaCarregado, 5000, 200);
}
VariaveisOperacao.Operadores.HealthWorker.EnviarDadosOperacao();
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
return (true, ruasSelecionadas);
}
@ -593,7 +612,7 @@ namespace AgroBase.Models
Variaveis.OperacaoEmAndamento.Sensoriamento.AtualizarDados();
VariaveisOperacao.Operadores.HealthWorker?.EnviarDadosOperacao();
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
}
@ -618,7 +637,7 @@ namespace AgroBase.Models
DispAtu?.Dados?.ReiniciarLeituras(DispAtu?.Dados);
DispSen?.Dados?.ReiniciarLeituras(DispSen?.Dados);
VariaveisOperacao.Operadores.HealthWorker.EnviarDadosOperacao();
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
Sensoriamento.AtualizarDados();
@ -669,49 +688,43 @@ namespace AgroBase.Models
public async Task RealizarCalibragemInicialAsync()
{
Console.WriteLine("Calibragem inicial inciada...");
Variaveis.OperacaoEmAndamento.Calibrando = true;
var DispAtu = Variaveis.OperacaoEmAndamento.DispAtu;
if (DispAtu != null)
{
// Ligar bomba
var Bomba = DispAtu.Dados.BombasPressurizadoras.FirstOrDefault();
if (Bomba.Inicializado)
{
GeneralJoystick.EnviarComandoAtuador(S_Code.sBMB, true, Bomba.ID);
await Task.Delay(5000);
}
// Testar os bicos
for (int i = 0; i < DispAtu.Dados.QuantidadeBicos; i++)
{
var Bico = DispAtu.Dados.BicosPulverizadores[i];
if (Bico.Inicializado)
{
GeneralJoystick.EnviarComandoAtuador(S_Code.sBIC, true, Bico.ID);
await Task.Delay(200);
GeneralJoystick.EnviarComandoAtuador(S_Code.sBIC, false, Bico.ID);
}
}
await Task.Delay(1000);
}
var DispMvd = Variaveis.OperacaoEmAndamento.DispMvd;
if (DispMvd != null)
var tasks = new List<Task>();
if (DispAtu?.Dados != null) tasks.Add(DispAtu.Dados.RealizarCalibragemAsync());
if (DispMvd?.Dados != null) tasks.Add(DispMvd.Dados.RealizarCalibragemAsync());
if (tasks.Count == 0)
{
// Referenciar motores de passo
if (DispMvd.Dados.Modulos.Any(x => x.DirMotor.Inicializado))
{
//GeneralJoystick.EnviaComandoMotor(Keys.R);
}
Console.WriteLine("Nenhuma calibragem foi iniciada.");
Variaveis.OperacaoEmAndamento.Calibrando = false;
return;
}
/*if (KinectService.Iniciado)
try
{
KinectService.RecalibrarSubdivisoes();
}*/
var allTasks = Task.WhenAll(tasks);
var completed = await Task.WhenAny(allTasks, Task.Delay(2 * 60 * 1000));
if (completed == allTasks)
{
Console.WriteLine("Calibragem finalizada com sucesso!");
}
else
{
Console.WriteLine("Timeout na calibragem. Continuando mesmo assim.");
}
}
catch (Exception ex)
{
Console.WriteLine($"Erro durante calibragem: {ex.Message}");
}
Variaveis.OperacaoEmAndamento.Calibrando = false;
}
@ -729,7 +742,9 @@ namespace AgroBase.Models
DispAtu?.Dados?.ReiniciarLeituras(DispAtu.Dados);
DispSen?.Dados?.ReiniciarLeituras(DispSen.Dados);
VariaveisOperacao.Operadores.HealthWorker.EnviarDadosOperacao();
await RealizarCalibragemInicialAsync();
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
Sensoriamento?.AtualizarDados();
@ -741,7 +756,12 @@ namespace AgroBase.Models
public void ReiniciarSimulacao()
{
Variaveis.OperacaoEmAndamento.StatusAtual = StatusOperacao.Parametrizando;
RedisService.AtualizarCampos(
CtxKey.DadosOperacao,
("status", StatusOperacao.Parametrizando),
("iniciado", false)
);
Variaveis.OperacaoEmAndamento.Iniciado = false;
Variaveis.OperacaoEmAndamento.Simulando = false;
Variaveis.OperacaoEmAndamento.Mapa = new MapasModel();
@ -818,8 +838,6 @@ namespace AgroBase.Models
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
if (ForcarEnvio || MovimentoLiberado)
{
foreach (var Ctrl in _Controle.TiposControle)
{
if (ForcarEnvio || ((Agora - Ctrl.UltimoComando).TotalMilliseconds > Ctrl.DelayEnvioComando))
@ -839,7 +857,6 @@ namespace AgroBase.Models
}
}
}
}
public List<string> EnviarProtocoloComando(IDispositivosService Dispositivo, T_Code Tipo, bool ForcarEnvio)
{
@ -1078,7 +1095,7 @@ namespace AgroBase.Models
VolumeReservatorio = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VolumeReservatorio,
PressaoLinha_SP = Variaveis.OperacaoEmAndamento.Controle.PressaoLinha,
PressaoLinha = Variaveis.OperacaoEmAndamento.DispAtu.Dados.PressaoLinha,
PotenciaBomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault().ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.Potencia).atual.valor,
PotenciaBomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault().ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.Potencia).atual.valor ?? 0,
BombaLigada = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault().ComandoAtuar,
VazaoFluxoMLpSInstantanea = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VazaoFluxoMLpSInstantanea,
VazaoFluxoMLpSMedia = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VazaoFluxoMLpSMedia,
@ -1093,7 +1110,7 @@ namespace AgroBase.Models
Atuado = Bico.ComandoAtuar,
MediaNivelFluxo = Bico.MediaNivelFluxo,
Posicao = Bico.Posicao,
StatusBico = Bico.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura).atual.valor,
StatusBico = Bico.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura).atual.valor ?? false,
Atuacoes = Bico.Atuacoes,
TempoAtuado = Bico.TempoAtuado,
}).ToList(),
@ -1118,13 +1135,10 @@ namespace AgroBase.Models
SalvarLog(T_Code.Sen.ToString(), logSen, false);
VisualWorkerModel logSnr = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorVisual?.Clone();
logSnr.Leitura.MomentoLog = Agora;
logSnr.UltimaMensagem = Agora;
SalvarLog(T_Code.Snr.ToString(), logSnr, Fim);
Task.Run(async () =>
{
await SalvarLogCameraCaminho();
});
SalvarLogCameraCaminho();
string ArquivoOp = Variaveis.CaminhoOperacoes + Variaveis.OperacaoEmAndamento.ID + "/data.lgop";
if (!File.Exists(ArquivoOp))
@ -1184,67 +1198,19 @@ namespace AgroBase.Models
}
}
private async Task SalvarLogCameraCaminho()
private void SalvarLogCameraCaminho()
{
var Camera = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho;
string Caminho = Variaveis.CaminhoOperacoes + Variaveis.OperacaoEmAndamento.ID + "/" + Camera.Name;
string Caminho = Variaveis.CaminhoOperacoes + Variaveis.OperacaoEmAndamento.ID + "/" + Camera.Dispositivo;
if (!Directory.Exists(Caminho))
{
Directory.CreateDirectory(Caminho);
}
string caminhoRgb = Caminho + "/" + Variaveis.OperacaoEmAndamento.idxLog + "_rgb.jpg";
string caminhoHeatmap = Caminho + "/" + Variaveis.OperacaoEmAndamento.idxLog + "_heat.jpg";
string caminhoRadar = Caminho + "/" + Variaveis.OperacaoEmAndamento.idxLog + "_radar.jpg";
string caminhoSegmentacao = Caminho + "/" + Variaveis.OperacaoEmAndamento.idxLog + "_seg.jpg";
string nome = Variaveis.OperacaoEmAndamento.idxLog.ToString();
await VariaveisOperacao.Operadores.SalvarFramesSonar();
}
private void SalvarLogKinect(DateTime Agora)
{
KinectModel logKnt = new KinectModel()
{
Momento = Agora,
AccW = KinectService.Leitura.AccW,
AccX = KinectService.Leitura.AccX,
AccY = KinectService.Leitura.AccY,
AccZ = KinectService.Leitura.AccZ,
AnguloElevacao = KinectService.Leitura.AnguloElevacao,
Colisao = KinectService.Leitura.Colisao,
DistanciaDaDireita = KinectService.Leitura.DistanciaDaDireita,
DistanciaDaEsquerda = KinectService.Leitura.DistanciaDaEsquerda,
Obstaculos = new List<Obstaculo>(KinectService.Leitura.Obstaculos),
Subdivisoes = new List<Subdivisao>(KinectService.Parametros.Subdivisoes),
Pitch = KinectService.Leitura.Pitch,
Roll = KinectService.Leitura.Roll,
VelX = KinectService.Leitura.VelX,
VelY = KinectService.Leitura.VelY,
VelZ = KinectService.Leitura.VelZ,
Yaw = KinectService.Leitura.Yaw,
UltimoCalculo = KinectService.Leitura.UltimoCalculo,
UltimoComandoRespondido = KinectService.Leitura.Momento,
};
SalvarLog(T_Code.Knt.ToString(), logKnt, false);
string Caminho = Variaveis.CaminhoOperacoes + Variaveis.OperacaoEmAndamento.ID + "/" + T_Code.Knt.ToString();
if (!Directory.Exists(Caminho))
{
Directory.CreateDirectory(Caminho);
}
string rgb = Caminho + "/rgb_" + Variaveis.OperacaoEmAndamento.idxLog + ".jpg";
string heat = Caminho + "/heat_" + Variaveis.OperacaoEmAndamento.idxLog + ".jpg";
lock (KinectService._lockBitmapRGB)
{
FuncoesGlobais.SalvarImagemComprimida(KinectService.bitmapRGB, rgb, 75L, 512, 512);
}
lock (KinectService._lockBitmapHeat)
{
FuncoesGlobais.SalvarImagemComprimida(KinectService.bitmapHeat, heat, 30L);
}
Camera.SaveFrames(new List<VisualWorkerFrameType>() { VisualWorkerFrameType.Rgb, VisualWorkerFrameType.Heatmap, VisualWorkerFrameType.RadarTopDown, VisualWorkerFrameType.Segmentacao }, nome, Caminho);
}
@ -1361,7 +1327,8 @@ namespace AgroBase.Models
public double Angulo_Min { get; set; } = -30;
public double VelocidadeMP { get; set; } = 50;
public double Angulo { get; set; } = 0;
private double _angulo_sp = 0.0;
public double Angulo { get; set; }
public int RPM_SP
{
get
@ -1376,7 +1343,8 @@ namespace AgroBase.Models
return Convert.ToInt32(RPM_SP * VariaveisEquipamento.RelacaoRPM);
}
}
public double PercentualVelocidadeSP { get; set; } = 0.0;
private double _velocidade_sp = 0.0;
public double PercentualVelocidadeSP { get; set; }
public double PercentualVelocidadeMin
{
get
@ -1606,33 +1574,12 @@ namespace AgroBase.Models
public OperacaoControleModel Controle { get; set; }
public VisualWorkerModel OperadorVisual { get; set; }
private void AtualizarDadosOperacaoRedis()
{
var operacao = RedisService.Get(CtxKey.DadosOperacao);
var parametros = JsonConvert.DeserializeObject<Dictionary<string, object>>(operacao);
bool configurado = Convert.ToBoolean(parametros["configurado"]);
long tempoAguardando = (long)(parametros["tempo_aguardando"]);
int op_status = Convert.ToInt32(parametros["status"]);
StatusOperacao statusOperacao = (StatusOperacao)op_status;
bool liberado = Convert.ToBoolean(parametros["liberado"]);
List<ManagerWorkerMessageResponseModulosPendentesModel> status_modulos = JsonConvert.DeserializeObject<ManagerWorkerMessageResponseModulosPendentesModel[]>(parametros["status_modulos"].ToString()).ToList();
Variaveis.OperacaoEmAndamento.TempoAguardando = DateTimeOffset.FromUnixTimeSeconds(tempoAguardando).UtcDateTime.AddSeconds(tempoAguardando % 1).ToLocalTime();
Variaveis.OperacaoEmAndamento.StatusAtual = statusOperacao;
Variaveis.OperacaoEmAndamento.OperacaoLiberada = liberado;
VariaveisOperacao.Operadores.ModulosSaude = new List<ManagerWorkerMessageResponseModulosPendentesModel>(status_modulos);
var mandatorios = Variaveis.OperacaoEmAndamento.ModulosMandatorios.Select(x => x.Dispositivo).ToList();
var mods_com_falha = status_modulos.Where(x => mandatorios.Contains(x.modulo) && x.status == Enums.StatusModulo.Falha);
var motivos_por_modulo = mods_com_falha.Select(x => $"{x.modulo}: {string.Join("; ", x.motivos)}");
Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada = string.Join(Environment.NewLine + Environment.NewLine, motivos_por_modulo);
}
public void AtualizarDados()
{
AtualizarDadosOperacaoRedis();
Variaveis.OperacaoEmAndamento.AtualizarDadosContexto();
VisualWorkerService.AtualizarAnalise();
var _Trajetoria = Variaveis.OperacaoEmAndamento.Trajetoria;
var _DispMvd = Variaveis.OperacaoEmAndamento.DispMvd;
@ -1650,7 +1597,7 @@ namespace AgroBase.Models
? _DispAtu.Dados.VolumeVazaoML / totalAtuacoes
: 0.0;
/*var sIMU = VariaveisOperacao.Operadores.VisualWorker?.DadosLeitura?.Leitura?.obj?.imu;
var sIMU = VisualWorkerService.DadosLeitura.Imu;
var dadosIMU = sIMU != null ? new OperacaoSensoriamentoLogImuModel()
{
Iniciado = sIMU.timestamp > 0,
@ -1658,8 +1605,7 @@ namespace AgroBase.Models
InclinacaoFrontal = sIMU.pitch,
Rotacao = sIMU.yaw,
RotacaoCorrigida = sIMU.yaw_fixed,
} : new OperacaoSensoriamentoLogImuModel();*/
var dadosIMU = new OperacaoSensoriamentoLogImuModel();
} : new OperacaoSensoriamentoLogImuModel();
var dadosAtuador = _DispAtu != null ? new OperacaoSensoriamentoLogAtuModel()
{
@ -1730,12 +1676,6 @@ namespace AgroBase.Models
var dadosGps = GPSService.UltimaLeitura.Clone();
var visualWorker = VariaveisOperacao.Operadores.VisualWorker?.DadosLeitura?.Clone();
if (visualWorker == null)
{
visualWorker = new VisualWorkerModel();
}
var dadosControle = _Controle.Clone();
var dadosPerformance = Variaveis.OperacaoEmAndamento.DadosPerformance.Clone();
@ -1754,15 +1694,13 @@ namespace AgroBase.Models
Bateria = dadosBateria,
Trajetoria = dadosTrajetoria,
Gps = dadosGps,
OperadorVisual = visualWorker,
OperadorVisual = new VisualWorkerModel(),
Controle = dadosControle,
DadosPerformance = dadosPerformance
};
Variaveis.OperacaoEmAndamento.Sensoriamento = dadosAtualizados;
Variaveis.OperacaoEmAndamento.DispSen?.Dados?.ContadorCarga?.AtualizarConsumo();
VariaveisOperacao.Operadores.HealthWorker?.EnviarDadosContexto();
VariaveisOperacao.Operadores.HealthWorker?.EnviarDadosModulos();
}
public OperacaoSensoriamentoLogModel Clone(bool comSonar = false)

View File

@ -0,0 +1,59 @@
using System;
using static AgroBase.Models.Enums;
using static AgroBase.Models.Operadores.OperadoresModels;
namespace AgroBase.Models.Operadores
{
public class CameraWorkerModel
{
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 VisualWorkerModel Clone()
{
return new VisualWorkerModel()
{
Iniciado = Iniciado,
IniciadoEm = IniciadoEm,
Pronto = Pronto,
ProntoEm = ProntoEm,
};
}
public void ReiniciarEstado()
{
Iniciado = false;
IniciadoEm = DateTime.MinValue;
Pronto = false;
ProntoEm = DateTime.MinValue;
}
}
public class CameraWorkerItemModel
{
public T_Code dispositivo { get; set; }
public string mx_id { get; set; }
public string versao { get; set; }
public string modelo { get; set; }
public bool iniciado { get; set; }
public SaudeWorkerModel saude { get; set; }
public CameraWorkerItemPerformanceModel performance { get; set; }
}
public class CameraWorkerItemPerformanceModel
{
public double temperatura { get; set; }
public double memoria_usada { get; set; }
public bool executando { get; set; }
public string velocidade { get; set; }
}
public enum CameraWorkerCommandType
{
ScriptCarregado = 1,
}
}

View File

@ -11,7 +11,8 @@ namespace AgroBase.Models.Operadores
public DateTime IniciadoEm { get; set; }
public bool Pronto { get; set; }
public DateTime ProntoEm { get; set; }
public WorkerMessageModel<HealthWorkerMessageResponseModel> Leitura { get; set; } = new WorkerMessageModel<HealthWorkerMessageResponseModel>();
public DateTime UltimaMensagem { get; set; }
//public WorkerMessageModel<HealthWorkerMessageResponseModel> Leitura { get; set; } = new WorkerMessageModel<HealthWorkerMessageResponseModel>();
public HealthWorkerModel Clone()
{
@ -21,7 +22,7 @@ namespace AgroBase.Models.Operadores
IniciadoEm = IniciadoEm,
Pronto = Pronto,
ProntoEm = ProntoEm,
Leitura = Leitura.Clone()
//Leitura = Leitura.Clone()
};
}
@ -31,65 +32,16 @@ namespace AgroBase.Models.Operadores
IniciadoEm = DateTime.MinValue;
Pronto = false;
ProntoEm = DateTime.MinValue;
Leitura = new WorkerMessageModel<HealthWorkerMessageResponseModel>();
//Leitura = new WorkerMessageModel<HealthWorkerMessageResponseModel>();
}
}
public class HealthWorkerMessageResponseModel
{
public TipoComando cmd { get; set; }
public HealthWorkerMessageResponseCamerasModel cameras { get; set; }
public OAKCameraFrameModel frame { get; set; }
}
public class HealthWorkerMessageResponseCamerasModel
{
public long timestamp { get; set; }
public List<HealthWorkerMessageResponseCamerasItensModel> itens { get; set; }
private bool _newData = false;
public bool newData
{
get
{
if (_newData)
{
_newData = false;
return true;
}
else
{
return false;
}
}
set
{
_newData = value;
}
}
public HealthWorkerMessageResponseCamerasModel Clone()
{
return new HealthWorkerMessageResponseCamerasModel()
{
itens = new List<HealthWorkerMessageResponseCamerasItensModel>(itens),
newData = true
};
}
}
public class HealthWorkerMessageResponseCamerasItensModel
{
public T_Code dispositivo { get; set; }
public string mx_id { get; set; }
public string versao { get; set; }
public string modelo { get; set; }
}
public enum HealthWorkerCommandType
{
SetDadosModulo = 1,
SetDadosContexto = 2,
SetDadosOperacao = 3,
ScriptCarregado = 1,
AtualizarPontosMapa = 2,
}
}

View File

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using static AgroBase.Models.Enums;
using static AgroBase.Models.Operadores.OperadoresModels;
namespace AgroBase.Models.Operadores
{
@ -11,7 +10,8 @@ namespace AgroBase.Models.Operadores
public DateTime IniciadoEm { get; set; }
public bool Pronto { get; set; }
public DateTime ProntoEm { get; set; }
public WorkerMessageModel<ManagerWorkerMessageResponseModel> Leitura { get; set; }
public DateTime UltimaMensagem { get; set; }
//public WorkerMessageModel<ManagerWorkerMessageResponseModel> Leitura { get; set; }
public ManagerWorkerModel Clone()
{
@ -21,7 +21,7 @@ namespace AgroBase.Models.Operadores
IniciadoEm = IniciadoEm,
Pronto = Pronto,
ProntoEm = ProntoEm,
Leitura = Leitura.Clone()
//Leitura = Leitura.Clone()
};
}
@ -31,7 +31,7 @@ namespace AgroBase.Models.Operadores
IniciadoEm = DateTime.MinValue;
Pronto = false;
ProntoEm = DateTime.MinValue;
Leitura = new WorkerMessageModel<ManagerWorkerMessageResponseModel>();
//Leitura = new WorkerMessageModel<ManagerWorkerMessageResponseModel>();
}
}
@ -57,6 +57,7 @@ namespace AgroBase.Models.Operadores
{
public T_Code modulo { get; set; }
public StatusModulo status { get; set; }
public bool conectado { get; set; }
public double saude { get; set; }
public List<string> motivos { get; set; }
public List<ManagerWorkerMessageResponseModulosPendentesSaudeModel> saude_individual { get; set; }
@ -82,8 +83,11 @@ namespace AgroBase.Models.Operadores
public enum ManagerWorkerCommandType
{
IniciarMPC = 1,
EnviarDadosControle = 2,
ScriptCarregado = 1,
IniciarMPC = 2,
AtualizarMPC = 3,
EnviarDadosControle = 4,
FinalizarOperacao = 5,
}
}

View File

@ -1,9 +1,13 @@
using System;
using AgroBase.Services;
using System;
using System.Threading.Tasks;
namespace AgroBase.Models.Operadores
{
public class OperadoresModels
{
private static double HeartbeatWorkers = 2.0;
public enum TipoComando
{
SetDadosModulo = 1,
@ -16,6 +20,39 @@ namespace AgroBase.Models.Operadores
GetCameraFrame = 8,
}
public interface IWorkerModel
{
void MostrarLog(string message, int limite = 500);
Task<bool> IniciarProcessamento();
void RedisCallback(string mensagem);
void AtualizarSaude();
SaudeWorkerModel Saude { get; set; }
}
public static SaudeWorkerModel AtualizarSaude(string _CtxKey)
{
string unixTime = RedisService.GetField(_CtxKey, "momento", "0.0");
DateTime momento = FuncoesGlobais.UnixToDateTime(unixTime);
double frequencia = RedisService.GetField(_CtxKey, "frequencia", 0.0);
double latencia = RedisService.GetField(_CtxKey, "latencia", 0.0);
double tempoDesconectado = (DateTime.Now - momento).TotalSeconds;
bool conectado = tempoDesconectado < HeartbeatWorkers;
SaudeWorkerModel Saude = new SaudeWorkerModel()
{
momento = momento,
frequencia = frequencia,
latencia = latencia,
conectado = conectado,
tempo_desconectado = tempoDesconectado
};
return Saude;
}
public class WorkerMessageModel<T>
{
public DateTime AdicionadoEm { get; set; }
@ -45,6 +82,15 @@ namespace AgroBase.Models.Operadores
}
}
public class SaudeWorkerModel
{
public DateTime momento { get; set; }
public double frequencia { get; set; }
public double latencia { get; set; }
public bool conectado { get; set; }
public double tempo_desconectado { get; set; }
}
}

View File

@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using static AgroBase.Models.Operadores.OperadoresModels;
namespace AgroBase.Models.Operadores
{
@ -12,7 +11,11 @@ namespace AgroBase.Models.Operadores
public DateTime IniciadoEm { get; set; }
public bool Pronto { get; set; }
public DateTime ProntoEm { get; set; }
public WorkerMessageModel<VisualWorkerMessageResponseModel> Leitura { get; set; } = new WorkerMessageModel<VisualWorkerMessageResponseModel>();
public DateTime UltimaMensagem { get; set; }
public Dictionary<VisualWorkerFrameType, OAKCameraFrameModel> CameraFrames { get; set; }
//public WorkerMessageModel<VisualWorkerMessageResponseModel> Leitura { get; set; } = new WorkerMessageModel<VisualWorkerMessageResponseModel>();
public VisualWorkerMessageAnaliseModel Analises { get; set; } = new VisualWorkerMessageAnaliseModel();
public VisualWorkerMessageIMUModel Imu { get; set; } = new VisualWorkerMessageIMUModel();
public VisualWorkerDadosModel Resumo { get; set; } = new VisualWorkerDadosModel();
public VisualWorkerModel Clone()
@ -23,7 +26,10 @@ namespace AgroBase.Models.Operadores
IniciadoEm = IniciadoEm,
Pronto = Pronto,
ProntoEm = ProntoEm,
Leitura = Leitura.Clone(),
CameraFrames = new Dictionary<VisualWorkerFrameType, OAKCameraFrameModel>(CameraFrames ?? new Dictionary<VisualWorkerFrameType, OAKCameraFrameModel>()),
Analises = Analises.Clone(),
Imu = Imu.Clone(),
//Leitura = Leitura.Clone(),
Resumo = Resumo.Clone(),
};
}
@ -34,7 +40,10 @@ namespace AgroBase.Models.Operadores
IniciadoEm = DateTime.MinValue;
Pronto = false;
ProntoEm = DateTime.MinValue;
Leitura = new WorkerMessageModel<VisualWorkerMessageResponseModel>();
CameraFrames = new Dictionary<VisualWorkerFrameType, OAKCameraFrameModel>();
Analises = new VisualWorkerMessageAnaliseModel();
Imu = new VisualWorkerMessageIMUModel();
//Leitura = new WorkerMessageModel<VisualWorkerMessageResponseModel>();
Resumo = new VisualWorkerDadosModel();
}
}
@ -119,26 +128,6 @@ namespace AgroBase.Models.Operadores
public double yaw { get; set; }
public double yaw_fixed { get; set; }
private bool _newData = false;
public bool newData
{
get
{
if (_newData)
{
_newData = false;
return true;
}
else
{
return false;
}
}
set
{
_newData = value;
}
}
public VisualWorkerMessageIMUModel Clone()
{
return new VisualWorkerMessageIMUModel()
@ -147,7 +136,6 @@ namespace AgroBase.Models.Operadores
roll = roll,
pitch = pitch,
yaw = yaw,
newData = true
};
}
}
@ -190,48 +178,31 @@ namespace AgroBase.Models.Operadores
public class VisualWorkerMessageAnaliseModel
{
public long timestamp { get; set; }
public DateTime timestamp { get; set; }
public List<VisualWorkerMessageAnaliseBBoxModel> anomalias { get; set; }
public List<VisualWorkerMessageAnaliseBBoxModel> sombras { get; set; }
public VisualWorkerMessageAnaliseSoloModel solo { get; set; }
public List<VisualWorkerMessageRadar2DPerfilModel> corredor_prof { get; set; }
public List<VisualWorkerMessageRadar2DPerfilModel> corredor_seg { get; set; }
private bool _newData = false;
public bool newData
{
get
{
if (_newData)
{
_newData = false;
return true;
}
else
{
return false;
}
}
set
{
_newData = value;
}
}
public VisualWorkerMessageAnaliseModel Clone()
{
return new VisualWorkerMessageAnaliseModel()
{
timestamp = timestamp,
anomalias = new List<VisualWorkerMessageAnaliseBBoxModel>(anomalias ?? new List<VisualWorkerMessageAnaliseBBoxModel>()),
sombras = new List<VisualWorkerMessageAnaliseBBoxModel>(sombras ?? new List<VisualWorkerMessageAnaliseBBoxModel>()),
solo = solo?.Clone(),
newData = true
corredor_prof = new List<VisualWorkerMessageRadar2DPerfilModel>(corredor_prof ?? new List<VisualWorkerMessageRadar2DPerfilModel>()),
corredor_seg = new List<VisualWorkerMessageRadar2DPerfilModel>(corredor_seg ?? new List<VisualWorkerMessageRadar2DPerfilModel>()),
};
}
public Bitmap PlotarAnalise(OAKCameraFrameModel frame)
{
if (frame?.image == null) return null;
Bitmap img = frame?.image();
if (img == null) return null;
try { frame.image.Clone(); } catch { return null; }
Bitmap img = new Bitmap(frame.image);
using (Graphics g = Graphics.FromImage(img))
{
Pen penObstaculo = new Pen(Color.Red, 2);
@ -254,7 +225,7 @@ namespace AgroBase.Models.Operadores
// 🔸 Desenhar Bounding Boxes (Anomalias + Solo)
List<VisualWorkerMessageAnaliseBBoxModel> bboxes = new List<VisualWorkerMessageAnaliseBBoxModel>();
if (anomalias != null) bboxes.AddRange(anomalias);
if (solo?.bbox_list != null) bboxes.AddRange(solo.bbox_list);
//if (solo?.bbox_list != null) bboxes.AddRange(solo.bbox_list);
foreach (var bbox in bboxes)
{
@ -272,7 +243,11 @@ namespace AgroBase.Models.Operadores
fill = brushLombada;
}
var rect = new Rectangle(bbox.bbox[0], bbox.bbox[1], bbox.bbox[2], bbox.bbox[3]);
int x = (int)(bbox.bbox[0] * imgWidth);
int y = (int)(bbox.bbox[1] * imgHeight);
int w = (int)(bbox.bbox[2] * imgWidth);
int h = (int)(bbox.bbox[3] * imgHeight);
var rect = new Rectangle(x, y, w, h);
// 🔸 Preencher com opacidade
g.FillRectangle(fill, rect);
@ -288,7 +263,7 @@ namespace AgroBase.Models.Operadores
// 🔸 Linha da faixa do solo
if (solo != null)
{
int yInicio = solo.y_inicio;
int yInicio = imgHeight - (int)(solo.percent_y * imgHeight);
g.DrawLine(penFaixaSolo, 0, yInicio, imgWidth, yInicio);
}
@ -296,9 +271,9 @@ namespace AgroBase.Models.Operadores
if (solo?.perfil != null && solo.perfil.Count > 1)
{
var perfil = solo.perfil;
int setores = solo.n_setores;
int yInicio = solo.y_inicio;
int alturaRegiao = solo.altura_regiao;
int setores = solo.perfil.Count;
int yInicio = imgHeight - (int)(solo.percent_y * imgHeight);
int alturaRegiao = imgHeight / solo.perfil.Count;
double maxZ = perfil.Max();
double minZ = perfil.Min();
@ -331,20 +306,24 @@ namespace AgroBase.Models.Operadores
public class VisualWorkerMessageAnaliseSoloModel
{
public List<double> perfil { get; set; }
public List<VisualWorkerMessageAnaliseBBoxModel> bbox_list { get; set; }
public int y_inicio { get; set; }
public int altura_regiao { get; set; }
public int n_setores { get; set; }
public double percent_y { get; set; }
public double inclinacao { get; set; }
//public List<VisualWorkerMessageAnaliseBBoxModel> bbox_list { get; set; }
//public int y_inicio { get; set; }
//public int altura_regiao { get; set; }
//public int n_setores { get; set; }
public VisualWorkerMessageAnaliseSoloModel Clone()
{
return new VisualWorkerMessageAnaliseSoloModel()
{
perfil = new List<double>(perfil),
bbox_list = new List<VisualWorkerMessageAnaliseBBoxModel>(bbox_list),
y_inicio = y_inicio,
altura_regiao = altura_regiao,
n_setores = n_setores,
percent_y = percent_y,
inclinacao = inclinacao,
//bbox_list = new List<VisualWorkerMessageAnaliseBBoxModel>(bbox_list),
//y_inicio = y_inicio,
//altura_regiao = altura_regiao,
//n_setores = n_setores,
};
}
}
@ -352,7 +331,7 @@ namespace AgroBase.Models.Operadores
public class VisualWorkerMessageAnaliseBBoxModel
{
public string tipo { get; set; }
public List<int> bbox { get; set; } // [x, y, w, h]
public List<double> bbox { get; set; } // [x, y, w, h]
public List<double> centro_percentual { get; set; } // [x%, y%]
public double? distancia_m { get; set; }
public double? largura_m { get; set; }
@ -398,7 +377,7 @@ namespace AgroBase.Models.Operadores
public Bitmap PlotarAnalsie(Bitmap img)
{
try
/*try
{
using (Graphics g = Graphics.FromImage(img))
{
@ -443,7 +422,7 @@ namespace AgroBase.Models.Operadores
catch
{
}
}*/
return img;
}
}
@ -535,10 +514,21 @@ namespace AgroBase.Models.Operadores
public enum VisualWorkerCommandType
{
SalvarFrames = 1,
IniciarCameraManager = 2,
AtualizarSaudeCamera = 3,
GetCameraFrame = 4,
ScriptCarregado = 1,
CalibrarProfundidade = 2,
IniciarCameraManager = 3,
AtualizarSaudeCamera = 4,
GetCameraFrame = 5,
SaveCameraFrames = 6,
}
public enum VisualWorkerFrameType
{
Rgb = 1,
Heatmap = 2,
RadarTopDown = 3,
Segmentacao = 4,
Debug = 5
}
}

View File

@ -1,4 +1,5 @@
using AgroBase.Services;
using AgroBase.Models.Operadores;
using AgroBase.Services;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
@ -632,6 +633,8 @@ namespace AgroBase.Models
Variaveis.OperacaoEmAndamento.Sensoriamento.AtualizarDados();
//Variaveis.OperacaoEmAndamento.AtualizaInformacoesControleOperacao();
RedisService.Publish(CmdKey.ManagerWorkerRx, JsonConvert.SerializeObject(new { cmd = ManagerWorkerCommandType.AtualizarMPC }));
}
@ -1084,6 +1087,8 @@ namespace AgroBase.Models
AtualizarDadosTrajetoria();
LoopAtualizaDados();
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
}
private (int, int) AtualizaIndiceRuaLateralCorredor(int i, int idxDir, int incDir, int incEsq)

View File

@ -91,16 +91,16 @@ namespace AgroBase.Models
public static class VariaveisEquipamento
{
public static double LarguraEsquerda { get; } = 42.0;
public static double LarguraDireita { get; } = 42.0;
public static double ComprimentoFrente { get; } = 57.0;
public static double ComprimentoTras { get; } = 57.0;
public static double LarguraEsquerda { get; } = 62.0;
public static double LarguraDireita { get; } = 22.0;
public static double ComprimentoFrente { get; } = 7.0;
public static double ComprimentoTras { get; } = 107.0;
public static double DistanciaEntreEixos { get; } = 92.0;
public static double LarguraEquipamentoMm
{
get
{
return ((LarguraEsquerda + LarguraDireita + 20.0) * 10.0);
return ((LarguraEsquerda + LarguraDireita + 10.0) * 10.0);
}
}
public static double TensaoMinimaBateria { get; set; } = 20.0;
@ -312,7 +312,7 @@ namespace AgroBase.Models
double longitude = PosicaoAtual.Longitude;
// Conversão de ângulo de graus para radianos
double anguloRad = anguloAtual * (Math.PI / 180);
double anguloRad = novoAngulo * (Math.PI / 180);
// Raio da Terra em metros
double raioTerra = GPSUtils.RaioDaTerra;
@ -1151,6 +1151,14 @@ namespace AgroBase.Models
}
}
public static DateTime UnixToDateTime(string unixTime)
{
double time = Convert.ToDouble(unixTime.Replace(".", ","));
var dateTime = DateTimeOffset.FromUnixTimeMilliseconds((long)(time * 1000)).ToLocalTime();
DateTime momento = dateTime.DateTime;
return momento;
}
}
public static class FuncoesMatematicas

View File

@ -729,7 +729,11 @@ namespace AgroBase.Services
//Variaveis.OperacaoEmAndamento.DispSen.Dados?.DadosLeitura?.SensoresIMU?.FirstOrDefault()?.AtualizarOffset(UltimaLeitura);
}
if (gpsIniciado)
if (Variaveis.OperacaoEmAndamento.Simulando)
{
anguloFinal = UltimaLeitura.OrientacaoMovimento;
}
else if (gpsIniciado)
{
// O GPS está disponível
//anguloFinal = UltimaLeitura.OrientacaoReal;

View File

@ -0,0 +1,118 @@
using AgroBase.Models.Operadores;
using AgroBase.Models;
using Newtonsoft.Json;
using System;
using System.Threading.Tasks;
using static AgroBase.Models.Operadores.OperadoresModels;
using System.Collections.Generic;
using static AgroBase.Models.Enums;
using System.Linq;
namespace AgroBase.Services.Operadores
{
public class CameraWorkerService : IWorkerModel
{
public CameraWorkerModel DadosLeitura = new CameraWorkerModel();
public SaudeWorkerModel Saude { get; set; } = new SaudeWorkerModel();
private static List<OAKCameraModel> CamerasConectadas = new List<OAKCameraModel>();
private bool DebugMode = true;
public void MostrarLog(string message, int limite = 500)
{
if (DebugMode)
{
Console.WriteLine($"[CameraWorker] {message.Substring(0, Math.Min(limite, message.Length))}{(message.Length > limite ? "..." : "")}");
}
}
public async Task<bool> IniciarProcessamento()
{
RedisService.Subscribe(CmdKey.CameraWorkerTx, RedisCallback);
DadosLeitura.IniciadoEm = DateTime.Now;
DadosLeitura.Iniciado = true;
bool pronto() => DadosLeitura.Pronto;
await FuncoesGlobais.AguardarCondicaoAsync(pronto, 5000);
if (pronto())
{
MostrarLog("Processamento iniciado com sucesso");
return true;
}
MostrarLog("Timeout ao iniciar script");
DadosLeitura.ReiniciarEstado();
return false;
}
public void RedisCallback(string mensagem)
{
try
{
var comando = JsonConvert.DeserializeObject<ComandoRedis>(mensagem);
var cmd = (CameraWorkerCommandType)comando.cmd;
//MostrarLog($"Comando recebido: cmd = {cmd.ToString()}");
switch (cmd)
{
case CameraWorkerCommandType.ScriptCarregado:
DadosLeitura.Pronto = true;
DadosLeitura.ProntoEm = DateTime.Now;
MostrarLog($"Comando recebido: cmd = {cmd.ToString()}");
break;
default:
MostrarLog($"Comando não reconhecido: {comando.cmd}");
break;
}
}
catch (Exception ex)
{
MostrarLog($"Erro ao deserializar resposta: {ex.Message}");
}
finally
{
DadosLeitura.UltimaMensagem = DateTime.Now;
}
}
public void AtualizarSaude()
{
Saude = OperadoresModels.AtualizarSaude(CtxKey.DadosCameraWorker);
}
public static List<OAKCameraModel> GetListaCameras()
{
CamerasConectadas = new List<OAKCameraModel>()
{
new OAKCameraModel()
{
Dispositivo = T_Code.Vzo,
Index = -1,
Name = "Sem Video"
}
};
var cameras_str = RedisService.Get(CtxKey.DadosCameras);
var cameras = JsonConvert.DeserializeObject<Dictionary<string, CameraWorkerItemModel>>(cameras_str);
if (cameras.Any())
{
CamerasConectadas.AddRange(cameras.Values.Select(x => new OAKCameraModel()
{
Dispositivo = x.dispositivo,
Version = x.versao,
Name = x.modelo,
Id = x.mx_id,
}).ToList());
}
return CamerasConectadas;
}
}
}

View File

@ -2,31 +2,23 @@
using AgroBase.Models.Operadores;
using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using static AgroBase.Models.Enums;
using static AgroBase.Models.Operadores.OperadoresModels;
using static MqttService;
namespace AgroBase.Services.Operadores
{
public class HealthWorkerService
public class HealthWorkerService : IWorkerModel
{
private string TopicoMQTT_Tx = "operador/health/rx";
private MqttTopicosModel topicoTx;
private string TopicoMQTT_Rx = "operador/health/tx";
private MqttTopicosModel topicoRx;
public HealthWorkerModel DadosLeitura = new HealthWorkerModel();
public AsyncTaskTimerModel tmrFila;
public int TimeoutRespostaComando = 10;
public ConcurrentDictionary<TipoComando, WorkerMessageModel<HealthWorkerMessageResponseModel>> FilaComandos = new ConcurrentDictionary<TipoComando, WorkerMessageModel<HealthWorkerMessageResponseModel>>();
private Dictionary<TipoComando, Func<bool>> mapaRespostas;
public SaudeWorkerModel Saude { get; set; } = new SaudeWorkerModel();
public static List<ManagerWorkerMessageResponseModulosPendentesModel> ModulosSaude = new List<ManagerWorkerMessageResponseModulosPendentesModel>();
private bool DebugMode = true;
private static bool AtualizandoRedis = false;
private void MostrarLog(string message, int limite = 500)
public void MostrarLog(string message, int limite = 500)
{
if (DebugMode)
{
@ -36,24 +28,11 @@ namespace AgroBase.Services.Operadores
public async Task<bool> IniciarProcessamento()
{
topicoRx = await Variaveis.MqttService.AdicionarNovoTopico(TopicoMQTT_Rx, true, 2, MqttCallback);
topicoTx = await Variaveis.MqttService.AdicionarNovoTopico(TopicoMQTT_Tx);
RedisService.Subscribe(CmdKey.HealthWorkerTx, RedisCallback);
mapaRespostas = new Dictionary<TipoComando, Func<bool>>
{
{ TipoComando.GetListaCameras, () => DadosLeitura.Leitura.obj?.cameras?.newData ?? false },
{ TipoComando.GetCameraFrame, () => DadosLeitura.Leitura.obj?.frame?.newData ?? false },
};
DadosLeitura.IniciadoEm = DateTime.Now;
DadosLeitura.Iniciado = true;
tmrFila?.Dispose();
tmrFila = new AsyncTaskTimerModel("tmrHealthWorker_Fila", tmrFila_Tick, 10);
tmrFila.Start();
bool pronto() => DadosLeitura.Pronto;
await FuncoesGlobais.AguardarCondicaoAsync(pronto, 5000);
if (pronto())
@ -67,126 +46,77 @@ namespace AgroBase.Services.Operadores
return false;
}
public bool AdicionarComandoNaFila(TipoComando cmd, dynamic payload = null)
public void RedisCallback(string mensagem)
{
WorkerMessageModel<HealthWorkerMessageResponseModel> msg = new WorkerMessageModel<HealthWorkerMessageResponseModel>()
try
{
AdicionadoEm = DateTime.Now,
payload = new
{
cmd = cmd,
dados = payload
}
};
var comando = JsonConvert.DeserializeObject<ComandoRedis>(mensagem);
bool sucesso = FilaComandos.TryAdd(cmd, msg);
if (!sucesso)
{
MostrarLog($"Mensagem {cmd} nao adicionada na fila");
}
var cmd = (HealthWorkerCommandType)comando.cmd;
return sucesso;
}
//MostrarLog($"Comando recebido: cmd = {cmd.ToString()}");
private async Task tmrFila_Tick()
switch (cmd)
{
DateTime agora = DateTime.Now;
// remove as mensagens antigas que nao responderam para permitir envair novamente
foreach (var item in FilaComandos.Where(x => x.Value.Enviado && agora > x.Value.EnviadoEm.AddSeconds(TimeoutRespostaComando)))
{
FilaComandos.TryRemove(item.Key, out var _);
}
// pega a mensagem mais antiga
var msg = FilaComandos.Where(x => !x.Value.Enviado).OrderBy(x => x.Value.AdicionadoEm).FirstOrDefault();
if (msg.Value == null) return;
var mensagem = new
{
comando = (int)msg.Key,
dispositivo = (int)T_Code.Snr,
payload = msg.Value.payload
};
await Variaveis.MqttService.PublishAsync(topicoTx, JsonConvert.SerializeObject(mensagem), true);
msg.Value.Enviado = true;
msg.Value.EnviadoEm = DateTime.Now;
}
private async Task<bool> MqttCallback(MqttTopicosMensagensModel Mensagem)
{
if (!DadosLeitura.Pronto && Mensagem.Momento > DadosLeitura.IniciadoEm && Mensagem.Mensagem == "OK")
{
DadosLeitura.ProntoEm = DateTime.Now;
case HealthWorkerCommandType.ScriptCarregado:
DadosLeitura.Pronto = true;
}
else
{
var msgRx = JsonConvert.DeserializeObject<WorkerMessageModel<HealthWorkerMessageResponseModel>>(Mensagem.Mensagem);
if (msgRx == null)
{
return false;
}
FilaComandos.TryGetValue(msgRx.obj.cmd, out var msgTx);
if (msgTx != null)
{
FilaComandos.TryRemove(msgRx.obj.cmd, out var msg);
}
AtualizarDadosLeitura(msgRx);
}
return true;
}
private void RedisCallback(string mensagem)
{
}
private void AtualizarDadosLeitura(WorkerMessageModel<HealthWorkerMessageResponseModel> msg)
{
if (DadosLeitura.Leitura.obj == null)
{
DadosLeitura.Leitura.obj = new HealthWorkerMessageResponseModel();
}
switch (msg.obj.cmd)
{
case TipoComando.GetListaCameras:
{
DadosLeitura.Leitura.obj.cameras = msg.obj.cameras.Clone();
DadosLeitura.ProntoEm = DateTime.Now;
MostrarLog($"Comando recebido: cmd = {cmd.ToString()}");
break;
}
case TipoComando.GetCameraFrame:
{
DadosLeitura.Leitura.obj.frame = msg.obj.frame.Clone();
default:
MostrarLog($"Comando não reconhecido: {comando.cmd}");
break;
}
}
DadosLeitura.Leitura.MomentoLog = DateTime.Now;
catch (Exception ex)
{
MostrarLog($"Erro ao deserializar resposta: {ex.Message}");
}
public async Task AguardarNovosDados(TipoComando cmd, int timeout = 1000)
finally
{
if (mapaRespostas.TryGetValue(cmd, out var condicao))
{
await FuncoesGlobais.AguardarCondicaoAsync(condicao, timeout, 10);
}
else
{
MostrarLog($"Comando {cmd} não suportado no AguardarResposta.");
DadosLeitura.UltimaMensagem = DateTime.Now;
}
}
public void EnviarDadosContexto()
public void AtualizarSaude()
{
Saude = OperadoresModels.AtualizarSaude(CtxKey.DadosHealthWorker);
}
private static void AtualizarDadosContextoLocal()
{
RedisService.AtualizarCampos(
CtxKey.DadosOperacao,
("debug_mode", Variaveis.DebugMode),
("iniciado", Variaveis.OperacaoEmAndamento.Iniciado),
("finalizando", Variaveis.OperacaoEmAndamento.Finalizando),
("calibrando", Variaveis.OperacaoEmAndamento.Calibrando),
("emergencia", Variaveis.OperacaoEmAndamento.Emergencia)
);
}
public static void AtualizarDadosContexto()
{
if (AtualizandoRedis)
return;
AtualizandoRedis = true;
AtualizarDadosContextoLocal();
AtualizarDadosModulos();
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
if (_Sensoriamento.Trajetoria == null) return;
var dados = new
if (_Sensoriamento == null)
{
Trajetoria = new
AtualizandoRedis = false;
return;
}
RedisService.AtualizarCampos(
CtxKey.DadosContexto,
("Trajetoria", _Sensoriamento.Trajetoria != null ? new
{
status = (int)_Sensoriamento.Trajetoria.StatusCarro,
manobrando = _Sensoriamento.Trajetoria.ManobrandoEntreRuas,
@ -203,46 +133,60 @@ namespace AgroBase.Services.Operadores
dist_dir = _Sensoriamento.Trajetoria.DistanciaDireita,
angulo = _Sensoriamento.Trajetoria.AnguloCaminho,
},
},
Gerais = new
} : null
),
("Gerais", new
{
velocidade_ms = _Sensoriamento.Movimentacao.VelocidadeMedia,
ervas_no_radar = _Sensoriamento.Atuador.ErvasNoRadar,
},
};
velocidade_ms = _Sensoriamento.Movimentacao != null ? _Sensoriamento.Movimentacao.VelocidadeMedia : 0,
ervas_no_radar = _Sensoriamento.Atuador != null ? _Sensoriamento.Atuador.ErvasNoRadar : 0,
}
)
);
var comando = new
{
cmd = (int)HealthWorkerCommandType.SetDadosContexto,
@params = dados
};
RedisService.Publish(CmdKey.HealthWorkerRx, JsonConvert.SerializeObject(comando));
AtualizandoRedis = false;
}
public void EnviarDadosOperacao()
private static void AtualizarDadosEquipamento()
{
if (Variaveis.OperacaoEmAndamento.DispMvd == null) return;
RedisService.AtualizarCampos(
CtxKey.DadosEquipamento,
("largura", VariaveisEquipamento.LarguraEquipamentoMm / 1000.0),
("distancia_entre_eixos", VariaveisEquipamento.DistanciaEntreEixos / 100.0),
("percentual_reservatorio_min", VariaveisEquipamento.PercentualReservatorioMin),
("percentual_tensao_bateria_min", VariaveisEquipamento.PercentualTensaoBateriaMin)
);
}
public static void AtualizarDadosOperacao()
{
if (AtualizandoRedis)
return;
AtualizandoRedis = true;
AtualizarDadosEquipamento();
if (Variaveis.OperacaoEmAndamento.DispMvd == null)
{
AtualizandoRedis = false;
return;
}
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
var dados = new
{
modo = (int)Variaveis.OperacaoEmAndamento.Modo,
debug_mode = Variaveis.DebugMode,
iniciado = Variaveis.OperacaoEmAndamento.Iniciado,
finalizando = Variaveis.OperacaoEmAndamento.Finalizando,
emergencia = Variaveis.OperacaoEmAndamento.Emergencia,
tempo_aguardar_inicio_operacao = Variaveis.OperacaoEmAndamento.TempoIniciarOperacao,
sonar_ativado = _Controle.SonarAtivado,
modulos_mandatorios = Variaveis.OperacaoEmAndamento.ModulosMandatorios.Select(x => (int)x.Dispositivo).ToArray(),
parametros_mandatorios = Variaveis.OperacaoEmAndamento.ParametrosMandatorios.Select(x => (int)x.Parametro).ToArray(),
Mov = new
RedisService.AtualizarCampos(
CtxKey.DadosOperacao,
("configurado", true),
("modo", Variaveis.OperacaoEmAndamento.Modo),
("tempo_aguardar_inicio_operacao", Variaveis.OperacaoEmAndamento.TempoIniciarOperacao),
("modulos_mandatorios", Variaveis.OperacaoEmAndamento.ModulosMandatorios.Select(x => (int)x.Dispositivo).ToArray()),
("parametros_mandatorios", Variaveis.OperacaoEmAndamento.ParametrosMandatorios.Select(x => (int)x.Parametro).ToArray()),
("Mov", new
{
percent_vel_max = _Controle.PercentualVelocidadeMax,
percent_vel_min = _Controle.PercentualVelocidadeMin,
},
Dir = new
}
),
("Dir", new
{
angulo_max = _Controle.Angulo_Max,
vel_movimento = _Controle.VelocidadeMP,
@ -260,111 +204,135 @@ namespace AgroBase.Services.Operadores
.ToList(),
horizonte = 2.5,
angulo_max_graus = _Controle.Angulo_Max,
distancia_entre_eixos = (VariaveisEquipamento.DistanciaEntreEixos / 100.0),
largura_equipamento = (VariaveisEquipamento.LarguraEquipamentoMm / 1000.0),
velocidade_min = FuncoesMatematicas.CalculaVelocidadeMsPercentual(_Controle.PercentualVelocidadeMin),
velocidade_max = FuncoesMatematicas.CalculaVelocidadeMsPercentual(_Controle.PercentualVelocidadeMax)
}
},
Atu = new
}
),
("Atu", new
{
percent_vertical_deteccao = _Controle.PercentualInicioPulverizacao,
capacidade_reservatorio = Variaveis.OperacaoEmAndamento.CapacidadeReservatorio,
pressao_linha = _Controle.PressaoLinha,
},
Snr = new
{
mx_id = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho.Id
}
};
),
("Snr", new
{
mx_id = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho.Id,
percentual_altura_solo = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho.PercentualAlturaSolo,
distancia_maxima = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho.DistanciaMaximaVisao,
distancia_minima = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho.DistanciaMinimaVisao
}
)
);
if (Variaveis.OperacaoEmAndamento.Modo == Enums.ModoOperacao.MapaGPS && (Variaveis.OperacaoEmAndamento.Trajetoria?._TrajetoriaFixa?.Count() ?? 0) > 0)
{
var comando = new
{
cmd = (int)HealthWorkerCommandType.SetDadosOperacao,
@params = dados
cmd = HealthWorkerCommandType.AtualizarPontosMapa
};
RedisService.Publish(CmdKey.HealthWorkerRx, JsonConvert.SerializeObject(comando));
}
public void EnviarDadosModulos()
AtualizandoRedis = false;
}
private static void AtualizarDadosModulos()
{
if (Variaveis.OperacaoEmAndamento.DispMvd == null) return;
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
var agora = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
var dados = new
//Console.WriteLine(RedisService.Get(RedisService.ModKey(Enums.T_Code.Gps)));
//Console.WriteLine(RedisService.Get(RedisService.ModKey(Enums.T_Code.Dir)));
//Console.WriteLine(RedisService.Get(RedisService.ModKey(Enums.T_Code.Mov)));
//Console.WriteLine(RedisService.Get(RedisService.ModKey(Enums.T_Code.Sen)));
//RedisService.SetObject(RedisService.ModKey(Enums.T_Code.Gps), string.Empty);
//RedisService.SetObject(RedisService.ModKey(Enums.T_Code.Dir), string.Empty);
//RedisService.SetObject(RedisService.ModKey(Enums.T_Code.Mov), string.Empty);
//RedisService.SetObject(RedisService.ModKey(Enums.T_Code.Sen), string.Empty);
if (_Sensoriamento.Gps != null)
{
Gps = new
{
conectado = GPSService.Iniciado,
freq_base = GPSService.TaxaAmostragemHz,
lat = _Sensoriamento.Gps.Latitude,
lon = _Sensoriamento.Gps.Longitude,
theta = _Sensoriamento.Gps.AnguloCarroDefinido,
fix = (int)_Sensoriamento.Gps.QualidadeFix,
rtk = GPSService.UltimoEnvioCorrecaoRTK.AddSeconds(5) > DateTime.Now,
hAcc = _Sensoriamento.Gps.PrecisaoCm,
nSatelites = _Sensoriamento.Gps.NumeroSatelites.valor,
freq = _Sensoriamento.Gps.NumeroSatelites.frequencia,
},
Dir = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.Select(x => new
{
conectado = x.DirMotor.Inicializado,
freq_base = Variaveis.OperacaoEmAndamento.DispMvd.Dados.tmrRegistradorDIR.IntervalHz,
endereco = x.DirMotor._EnderecoCAN_Tx,
mod_id = x.Modulo_ID,
angulo = x.DirMotor.Angulo,
angulo_sp = x.DirMotor.Angulo_SP,
comandar = x.DirMotor.Comandar,
in1_atuado = x.DirMotor.IN1_Atuado,
sentido = x.DirMotor.Sentido,
sentido_sp = x.DirMotor.Sentido_SP,
sentido_real = x.DirMotor.SentidoReal,
freq = new
{
io = x.DirMotor.Leitura?.NumeroPulsos?.frequencia ?? 0,
pulsos = x.DirMotor.Leitura?.EntradaIN1?.frequencia ?? 0,
RedisService.AtualizarCampos(
RedisService.ModKey(Enums.T_Code.Gps),
("timestamp", agora),
("conectado", GPSService.Iniciado),
("freq_base", GPSService.TaxaAmostragemHz),
("lat", _Sensoriamento.Gps.Latitude),
("lon", _Sensoriamento.Gps.Longitude),
("theta", _Sensoriamento.Gps.AnguloCarroDefinido),
("fix", (int)_Sensoriamento.Gps.QualidadeFix),
("rtk", GPSService.UltimoEnvioCorrecaoRTK.AddSeconds(5) > DateTime.Now),
("hAcc", _Sensoriamento.Gps.PrecisaoCm),
("nSatelites", _Sensoriamento.Gps.NumeroSatelites.valor),
("freq", _Sensoriamento.Gps.NumeroSatelites.frequencia)
);
}
}).ToArray(),
Mov = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.Select(x => new
foreach (var mod in Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos)
{
conectado = x.MovMotor.Inicializado,
freq_base = Variaveis.OperacaoEmAndamento.DispMvd.Dados.tmrRegistradorMOV.IntervalHz,
endereco = x.MovMotor._EnderecoCAN_Tx,
mod_id = x.Modulo_ID,
cod_erro = x.MovMotor.CodigoAlarme,
rpm = x.MovMotor.RPM_Roda,
rpm_sp = x.MovMotor.RPM_SP_Leitura,
tensao = x.MovMotor.Tensao,
corrente_motor = x.MovMotor.Corrente_Motor,
corrente_barramento = x.MovMotor.Corrente_Barramento,
temperatura_driver = x.MovMotor.TemperaturaDriver,
temperatura_motor = x.MovMotor.Temperatura,
freado = x.MovMotor.Leitura?.Freado ?? false,
freq = new
{
erro = x.MovMotor.Leitura?.CodigoAlarme?.frequencia ?? 0,
rpm = x.MovMotor.Leitura?.ERPM?.frequencia ?? 0,
tensao = x.MovMotor.Leitura?.Tensao?.frequencia ?? 0,
corrente_motor = x.MovMotor.Leitura?.CorrenteMotor?.frequencia ?? 0,
corrente_barramento = x.MovMotor.Leitura?.CorrenteBarramento?.frequencia ?? 0,
temperatura = x.MovMotor.Leitura?.Temperatura?.frequencia ?? 0,
int endereco_dir = mod.DirMotor._EnderecoCAN_Tx;
RedisService.AtualizarCampos(
RedisService.ModKey(Enums.T_Code.Dir),
($"{endereco_dir}.timestamp", agora),
($"{endereco_dir}.conectado", mod.DirMotor.Inicializado),
($"{endereco_dir}.freq_base", Variaveis.OperacaoEmAndamento.DispMvd.Dados.tmrRegistradorDIR.IntervalHz),
($"{endereco_dir}.endereco", mod.DirMotor._EnderecoCAN_Tx),
($"{endereco_dir}.mod_id", mod.Modulo_ID),
($"{endereco_dir}.angulo", mod.DirMotor.Angulo),
($"{endereco_dir}.angulo_sp", mod.DirMotor.Angulo_SP),
($"{endereco_dir}.comandar", mod.DirMotor.Comandar),
($"{endereco_dir}.referenciado", mod.DirMotor.Referenciado),
($"{endereco_dir}.in1_atuado", mod.DirMotor.IN1_Atuado),
($"{endereco_dir}.sentido", mod.DirMotor.Sentido),
($"{endereco_dir}.sentido_sp", mod.DirMotor.Sentido_SP),
($"{endereco_dir}.sentido_real", mod.DirMotor.SentidoReal),
($"{endereco_dir}.freq.io", mod.DirMotor.Leitura?.NumeroPulsos?.frequencia ?? 0),
($"{endereco_dir}.freq.pulsos", mod.DirMotor.Leitura?.EntradaIN1?.frequencia ?? 0)
);
int endereco_mov = mod.MovMotor._EnderecoCAN_Tx;
RedisService.AtualizarCampos(
RedisService.ModKey(Enums.T_Code.Mov),
($"{endereco_mov}.timestamp", agora),
($"{endereco_mov}.conectado", mod.MovMotor.Inicializado),
($"{endereco_mov}.freq_base", Variaveis.OperacaoEmAndamento.DispMvd.Dados.tmrRegistradorMOV.IntervalHz),
($"{endereco_mov}.endereco", mod.MovMotor._EnderecoCAN_Tx),
($"{endereco_mov}.mod_id", mod.Modulo_ID),
($"{endereco_mov}.cod_erro", mod.MovMotor.CodigoAlarme),
($"{endereco_mov}.rpm", mod.MovMotor.RPM_Roda),
($"{endereco_mov}.rpm_sp", mod.MovMotor.RPM_SP_Leitura),
($"{endereco_mov}.tensao", mod.MovMotor.Tensao),
($"{endereco_mov}.corrente_motor", mod.MovMotor.Corrente_Motor),
($"{endereco_mov}.corrente_barramento", mod.MovMotor.Corrente_Barramento),
($"{endereco_mov}.temperatura_driver", mod.MovMotor.TemperaturaDriver),
($"{endereco_mov}.temperatura_motor", mod.MovMotor.Temperatura),
($"{endereco_mov}.freado", mod.MovMotor.Leitura?.Freado ?? false),
($"{endereco_mov}.freq.erro", mod.MovMotor.Leitura?.CodigoAlarme?.frequencia ?? 0),
($"{endereco_mov}.freq.rpm", mod.MovMotor.Leitura?.ERPM?.frequencia ?? 0),
($"{endereco_mov}.freq.tensao", mod.MovMotor.Leitura?.Tensao?.frequencia ?? 0),
($"{endereco_mov}.freq.corrente_motor", mod.MovMotor.Leitura?.CorrenteMotor?.frequencia ?? 0),
($"{endereco_mov}.freq.corrente_barramento", mod.MovMotor.Leitura?.CorrenteBarramento?.frequencia ?? 0),
($"{endereco_mov}.freq.temperatura", mod.MovMotor.Leitura?.Temperatura?.frequencia ?? 0)
);
}
}).ToArray(),
Sen = new
var sensoresAtualizados = new List<(string caminho, object valor)>();
foreach (var sensor in Variaveis.OperacaoEmAndamento.DispSen.Dados.Sensores)
{
conectado = Variaveis.OperacaoEmAndamento.DispSen.Dados.Conectado,
freq_base = Variaveis.OperacaoEmAndamento.DispSen.Dados.tmrRegistrador.IntervalHz,
sensores = Variaveis.OperacaoEmAndamento.DispSen.Dados.Sensores.Select(x => new
{
conectado = x.Inicializado,
id = x.ID_Num,
label = x.ID,
tipo = (int)x.Componente,
aferir = x.Aferir,
mandatorio = x.Mandatorio,
dados = x.ValoresLeituras.Where(y => y.analise_health).Select(y => new
int tipo = (int)sensor.Componente;
int id = sensor.ID_Num;
string basePath = $"sensores.{tipo}.{id}";
var saude = RedisService.GetField<object>(RedisService.ModKey(Enums.T_Code.Sen), $"{basePath}.saude");
var dados = sensor.ValoresLeituras
.Where(y => y.analise_health)
.Select(y => new
{
label = y.funcao.ToString(),
nominal = y.nominal,
@ -372,34 +340,64 @@ namespace AgroBase.Services.Operadores
minimo = y.minimo,
atual = y.atual.valor,
freq = y.atual.frequencia
}),
}).ToArray(),
servos = Variaveis.OperacaoEmAndamento.DispSen.Dados.Servos.Select(x => new
})
.ToList();
var sensorObj = new
{
conectado = x.Inicializado,
id = x.ID_Num,
label = x.ID,
controlar = x.Controlar,
mandatorio = x.Mandatorio,
angulo_sp = x._AnguloControle,
dados = x.ValoresLeituras.Where(y => y.analise_health).Select(y => new
conectado = sensor.Inicializado,
id,
label = sensor.ID,
tipo,
aferir = sensor.Aferir,
mandatorio = sensor.Mandatorio,
dados,
timestamp = agora,
saude = saude ?? new { }
};
sensoresAtualizados.Add(($"{basePath}", sensorObj));
}
RedisService.AtualizarCampos(RedisService.ModKey(Enums.T_Code.Sen), sensoresAtualizados.ToArray());
var servosAtualizados = new List<(string caminho, object valor)>();
foreach (var servo in Variaveis.OperacaoEmAndamento.DispSen.Dados.Servos)
{
int id = servo.ID_Num;
string basePath = $"servos.{id}";
var saude = RedisService.GetField<object>(RedisService.ModKey(Enums.T_Code.Sen), $"{basePath}.saude");
var dados = servo.ValoresLeituras
.Where(y => y.analise_health)
.Select(y => new
{
label = y.funcao.ToString(),
atual = y.atual.valor,
freq = y.atual.frequencia
}),
}).ToArray(),
},
};
})
.ToList();
var comando = new
var servoObj = new
{
cmd = (int)HealthWorkerCommandType.SetDadosModulo,
@params = dados
conectado = servo.Inicializado,
id,
label = servo.ID,
controlar = servo.Controlar,
mandatorio = servo.Mandatorio,
angulo_sp = servo._AnguloControle,
dados,
timestamp = agora,
saude = saude ?? new { }
};
RedisService.Publish(CmdKey.HealthWorkerRx, JsonConvert.SerializeObject(comando));
servosAtualizados.Add(($"{basePath}", servoObj));
}
RedisService.AtualizarCampos(RedisService.ModKey(Enums.T_Code.Sen), servosAtualizados.ToArray());
}
}
}

View File

@ -6,21 +6,17 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using static AgroBase.Models.Operadores.OperadoresModels;
using static MqttService;
namespace AgroBase.Services.Operadores
{
public class ManagerWorkerService
public class ManagerWorkerService : IWorkerModel
{
private string TopicoMQTT_Tx = "operador/manager/rx";
private MqttTopicosModel topicoTx;
private string TopicoMQTT_Rx = "operador/manager/tx";
private MqttTopicosModel topicoRx;
public ManagerWorkerModel DadosLeitura = new ManagerWorkerModel();
public SaudeWorkerModel Saude { get; set; } = new SaudeWorkerModel();
private bool DebugMode = true;
private void MostrarLog(string message, int limite = 500)
public void MostrarLog(string message, int limite = 500)
{
if (DebugMode)
{
@ -30,9 +26,6 @@ namespace AgroBase.Services.Operadores
public async Task<bool> IniciarProcessamento()
{
topicoRx = await Variaveis.MqttService.AdicionarNovoTopico(TopicoMQTT_Rx, true, 2, MqttCallback);
topicoTx = await Variaveis.MqttService.AdicionarNovoTopico(TopicoMQTT_Tx);
RedisService.Subscribe(CmdKey.ManagerWorkerTx, RedisCallback);
DadosLeitura.IniciadoEm = DateTime.Now;
@ -51,32 +44,7 @@ namespace AgroBase.Services.Operadores
return false;
}
private async Task<bool> MqttCallback(MqttTopicosMensagensModel Mensagem)
{
if (!DadosLeitura.Pronto && Mensagem.Momento > DadosLeitura.IniciadoEm && Mensagem.Mensagem == "OK")
{
DadosLeitura.ProntoEm = DateTime.Now;
DadosLeitura.Pronto = true;
}
else
{
try
{
DadosLeitura.Leitura = JsonConvert.DeserializeObject<WorkerMessageModel<ManagerWorkerMessageResponseModel>>(Mensagem.Mensagem);
}
catch (Exception e)
{
MostrarLog($"Erro ao deserializar mensagem: {e.Message}");
}
if (DadosLeitura.Leitura != null)
{
AtualizarDadosLeitura(DadosLeitura.Leitura);
}
}
return true;
}
private void RedisCallback(string mensagem)
public void RedisCallback(string mensagem)
{
try
{
@ -84,13 +52,19 @@ namespace AgroBase.Services.Operadores
var cmd = (ManagerWorkerCommandType)comando.cmd;
MostrarLog($"📥 Comando recebido: cmd = {cmd.ToString()}");
switch (cmd)
{
case ManagerWorkerCommandType.ScriptCarregado:
DadosLeitura.Pronto = true;
DadosLeitura.ProntoEm = DateTime.Now;
MostrarLog($"Comando recebido: cmd = {cmd.ToString()}");
break;
case ManagerWorkerCommandType.EnviarDadosControle:
if (Variaveis.OperacaoEmAndamento.Modo == Enums.ModoOperacao.MapaGPS)
{
if (comando.@params == null)
break;
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
var novoComando = new ManagerWorkerMessageResponseComandoModel()
{
@ -104,69 +78,37 @@ namespace AgroBase.Services.Operadores
_Controle.Angulo = novoComando.angulo;
_Controle.TipoMovimento = novoComando.tipo_movimento;
_Controle.PercentualVelocidadeSP = novoComando.percentual_velocidade;
_Controle.SimulacaoMPC = novoComando.simulacao.Select(x => new MPCSimulacaoModel() { latitude = x[0], longitude = x[1] }).ToList();
_Controle.SimulacaoMPC = novoComando.simulacao.Select(x => new MPCSimulacaoModel() { latitude = x[0], longitude = x[1], orientacao = x[2] }).ToList();
Variaveis.OperacaoEmAndamento.AtualizaInformacoesControleOperacao();
}
if (Variaveis.OperacaoEmAndamento.StatusAtual == Enums.StatusOperacao.Concluido && Variaveis.OperacaoEmAndamento.Iniciado)
{
}
break;
case ManagerWorkerCommandType.FinalizarOperacao:
Task.Run(async () =>
{
await Variaveis.OperacaoEmAndamento.FinalizarOperacao();
});
}
}
break;
default:
MostrarLog($"⚠️ Comando não reconhecido: {comando.cmd}");
MostrarLog($"Comando não reconhecido: {comando.cmd}");
break;
}
}
catch (Exception ex)
{
MostrarLog($"Erro ao deserializar resposta: {ex.Message}");
MostrarLog($"Erro ao deserializar resposta: {ex.Message}");
}
}
private void AtualizarDadosLeitura(WorkerMessageModel<ManagerWorkerMessageResponseModel> msg)
finally
{
Variaveis.OperacaoEmAndamento.TempoAguardando = DateTimeOffset.FromUnixTimeSeconds(msg.obj.tempo_aguardando).UtcDateTime.AddSeconds(msg.obj.tempo_aguardando % 1).ToLocalTime();
Variaveis.OperacaoEmAndamento.StatusAtual = msg.obj.status_operacao;
Variaveis.OperacaoEmAndamento.OperacaoLiberada = msg.obj.operacao_liberada;
VariaveisOperacao.Operadores.ModulosSaude = new System.Collections.Generic.List<ManagerWorkerMessageResponseModulosPendentesModel>(msg.obj.status_modulos);
var mandatorios = Variaveis.OperacaoEmAndamento.ModulosMandatorios.Select(x => x.Dispositivo).ToList();
var mods_com_falha = msg.obj.status_modulos.Where(x => mandatorios.Contains(x.modulo) && x.status == Enums.StatusModulo.Falha);
var motivos_por_modulo = mods_com_falha.Select(x => $"{x.modulo}: {string.Join("; ", x.motivos)}");
Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada = string.Join(Environment.NewLine + Environment.NewLine, motivos_por_modulo);
if (Variaveis.OperacaoEmAndamento.Modo == Enums.ModoOperacao.MapaGPS)
{
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
if (msg.obj.comando != null)
{
_Controle.Angulo = msg.obj.comando.angulo;
_Controle.TipoMovimento = msg.obj.comando.tipo_movimento;
_Controle.PercentualVelocidadeSP = msg.obj.comando.percentual_velocidade;
_Controle.SimulacaoMPC = msg.obj.comando.simulacao.Select(x => new MPCSimulacaoModel() { latitude = x[0], longitude = x[1] }).ToList();
Variaveis.OperacaoEmAndamento.AtualizaInformacoesControleOperacao();
}
if (Variaveis.OperacaoEmAndamento.StatusAtual == Enums.StatusOperacao.Concluido && Variaveis.OperacaoEmAndamento.Iniciado)
{
Task.Run(async () =>
{
await Variaveis.OperacaoEmAndamento.FinalizarOperacao();
});
DadosLeitura.UltimaMensagem = DateTime.Now;
}
}
DadosLeitura.Leitura.MomentoLog = DateTime.Now;
public void AtualizarSaude()
{
Saude = OperadoresModels.AtualizarSaude(CtxKey.DadosManagerWorker);
}
}
}

View File

@ -1,11 +1,7 @@
using AgroBase.Models;
using AgroBase.Models.Operadores;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using static AgroBase.Models.Enums;
using static AgroBase.Models.Operadores.OperadoresModels;
@ -16,13 +12,13 @@ namespace AgroBase.Services.Operadores
{
private Process pythonProcess;
public ManagerWorkerService ManagerWorker;
public VisualWorkerService VisualWorker;
public HealthWorkerService HealthWorker;
public List<OAKCameraModel> CamerasConectadas = new List<OAKCameraModel>();
public List<Bitmap> FramesSonar = new List<Bitmap>();
public List<ManagerWorkerMessageResponseModulosPendentesModel> ModulosSaude = new List<ManagerWorkerMessageResponseModulosPendentesModel>();
public List<IWorkerModel> Workers = new List<IWorkerModel>()
{
new ManagerWorkerService(),
new VisualWorkerService(),
new HealthWorkerService(),
new CameraWorkerService(),
};
private bool iniciarScript = false;
private int TimeoutDesconexao = 3;
@ -46,27 +42,16 @@ namespace AgroBase.Services.Operadores
private void IniciarOperadores()
{
foreach (var worker in Workers)
{
worker.IniciarProcessamento();
}
if (iniciarScript)
{
Encerrar();
pythonProcess = PythonService.RunScript(Path.Combine("workers", "main.py"), new string[] { });
pythonProcess = PythonService.RunScript(Path.Combine("workers", "main_async.py"), new string[] { });
}
Task.Run(async () =>
{
ManagerWorker = new ManagerWorkerService();
await ManagerWorker.IniciarProcessamento();
});
Task.Run(async () =>
{
VisualWorker = new VisualWorkerService();
await VisualWorker.IniciarProcessamento();
});
Task.Run(async () =>
{
HealthWorker = new HealthWorkerService();
await HealthWorker.IniciarProcessamento();
});
}
public bool Encerrar()
@ -82,91 +67,51 @@ namespace AgroBase.Services.Operadores
private async Task tmrHearthbeat_Tick()
{
// Houve leitura nos ultimos 3 segundos
TempoDesconectado = (DateTime.Now - (ManagerWorker.DadosLeitura.Leitura?.MomentoLog ?? DateTime.MinValue)).TotalSeconds;
Conectado = TempoDesconectado < TimeoutDesconexao;
Conectado = true;
foreach (var worker in Workers)
{
worker.AtualizarSaude();
Conectado &= worker.Saude.conectado;
}
if (!Conectado)
{
if (Variaveis.OperacaoEmAndamento.Iniciado && Variaveis.OperacaoEmAndamento.Modo == Enums.ModoOperacao.MapaGPS)
{
Variaveis.OperacaoEmAndamento.StatusAtual = Enums.StatusOperacao.Parado;
Variaveis.OperacaoEmAndamento.OperacaoLiberada = false;
Variaveis.OperacaoEmAndamento.Controle.Angulo = 0;
Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP = 0;
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(true);
RedisService.AtualizarCampos(
CtxKey.DadosOperacao,
("status", StatusOperacao.Parado),
("liberado", false),
("configurado", false)
);
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
_Controle.Angulo = 0;
_Controle.PercentualVelocidadeSP = 0;
RedisService.AtualizarCampos(
CtxKey.DadosControle,
("angulo_sp", _Controle.Angulo),
("velocidade_sp", _Controle.PercentualVelocidadeSP)
);
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(false);
}
Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada = "Sem comunicação com o núcleo de processamento central";
RedisService.DefinirEquipamentoDesconectado();
// A cada 10 segundos desconectado, tenta reiniciar o nucleo de processamento
if (TempoDesconectado % 10 == 0)
if (TempoDesconectado > 0 && TempoDesconectado % 10 == 0)
{
IniciarOperadores();
}
}
else if (!ManagerWorker.DadosLeitura.Leitura.obj.configurado)
else if (!Variaveis.OperacaoEmAndamento.OperacaoConfigurada)
{
HealthWorker.EnviarDadosOperacao();
HealthWorkerService.AtualizarDadosOperacao();
}
}
public async Task<List<OAKCameraModel>> AtualizarListaCameras()
{
HealthWorker.AdicionarComandoNaFila(TipoComando.GetListaCameras);
await HealthWorker.AguardarNovosDados(TipoComando.GetListaCameras, 5000);
CamerasConectadas = new List<OAKCameraModel>()
{
new OAKCameraModel()
{
Dispositivo = T_Code.Vzo,
Index = -1,
Name = "Sem Video"
}
};
if (HealthWorker.DadosLeitura.Leitura.obj?.cameras?.itens?.Any() ?? false)
{
CamerasConectadas.AddRange(HealthWorker.DadosLeitura.Leitura.obj?.cameras?.itens?.Select(x => new OAKCameraModel()
{
Dispositivo = x.dispositivo,
Version = x.versao,
Name = x.modelo,
Id = x.mx_id,
}).ToList());
}
return CamerasConectadas;
}
public async Task<List<Bitmap>> SalvarFramesSonar()
{
var frames = new List<Bitmap>();
VisualWorker.AdicionarComandoNaFila(VisualWorkerCommandType.SalvarFrames);
await VisualWorker.AguardarNovosDados(VisualWorkerCommandType.SalvarFrames, 5000);
var uris = VisualWorker.DadosLeitura.Leitura?.obj?.save_frames?.frames;
if (uris != null)
{
foreach (var uri in uris)
{
if (!string.IsNullOrWhiteSpace(uri) && File.Exists(uri))
{
using (var img = Image.FromFile(uri))
{
frames.Add((Bitmap)img.Clone());
}
}
}
}
FramesSonar = frames;
return FramesSonar;
}
}
}

View File

@ -2,31 +2,21 @@
using AgroBase.Models.Operadores;
using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using static AgroBase.Models.Enums;
using static AgroBase.Models.Operadores.OperadoresModels;
using static MqttService;
namespace AgroBase.Services.Operadores
{
public class VisualWorkerService
public class VisualWorkerService : IWorkerModel
{
public string TopicoMQTT_Tx = "operador/visual/rx";
private MqttTopicosModel topicoTx;
public string TopicoMQTT_Rx = "operador/visual/tx";
private MqttTopicosModel topicoRx;
public VisualWorkerModel DadosLeitura = new VisualWorkerModel();
public AsyncTaskTimerModel tmrFila;
public int TimeoutRespostaComando = 10;
public ConcurrentDictionary<VisualWorkerCommandType, WorkerMessageModel<VisualWorkerMessageResponseModel>> FilaComandos = new ConcurrentDictionary<VisualWorkerCommandType, WorkerMessageModel<VisualWorkerMessageResponseModel>>();
private Dictionary<VisualWorkerCommandType, Func<bool>> mapaRespostas;
public static VisualWorkerModel DadosLeitura = new VisualWorkerModel();
public SaudeWorkerModel Saude { get; set; } = new SaudeWorkerModel();
private bool DebugMode = true;
private void MostrarLog(string message, int limite = 500)
public void MostrarLog(string message, int limite = 500)
{
if (DebugMode)
{
@ -36,23 +26,11 @@ namespace AgroBase.Services.Operadores
public async Task<bool> IniciarProcessamento()
{
topicoRx = await Variaveis.MqttService.AdicionarNovoTopico(TopicoMQTT_Rx, true, 2, MqttCallback);
topicoTx = await Variaveis.MqttService.AdicionarNovoTopico(TopicoMQTT_Tx);
RedisService.Subscribe(CmdKey.VisualWorkerTx, RedisCallback);
mapaRespostas = new Dictionary<VisualWorkerCommandType, Func<bool>>
{
{ VisualWorkerCommandType.SalvarFrames, () => DadosLeitura.Leitura.obj?.save_frames?.newData ?? false },
};
DadosLeitura.IniciadoEm = DateTime.Now;
DadosLeitura.Iniciado = true;
tmrFila?.Dispose();
tmrFila = new AsyncTaskTimerModel("tmrVisualWorker_Fila", tmrFila_Tick, 10);
tmrFila.Start();
bool pronto() => DadosLeitura.Pronto;
await FuncoesGlobais.AguardarCondicaoAsync(pronto, 5000);
if (pronto())
@ -66,80 +44,7 @@ namespace AgroBase.Services.Operadores
return false;
}
public bool AdicionarComandoNaFila(VisualWorkerCommandType cmd, dynamic payload = null)
{
WorkerMessageModel<VisualWorkerMessageResponseModel> msg = new WorkerMessageModel<VisualWorkerMessageResponseModel>()
{
AdicionadoEm = DateTime.Now,
payload = payload,
obj = new VisualWorkerMessageResponseModel()
{
cmd = cmd,
}
};
bool sucesso = FilaComandos.TryAdd(cmd, msg);
if (!sucesso)
{
MostrarLog($"Mensagem {cmd} nao adicionada na fila");
}
return sucesso;
}
private async Task tmrFila_Tick()
{
DateTime agora = DateTime.Now;
// remove as mensagens antigas que nao responderam para permitir envair novamente
foreach (var item in FilaComandos.Where(x => x.Value.Enviado && agora > x.Value.EnviadoEm.AddSeconds(TimeoutRespostaComando)))
{
FilaComandos.TryRemove(item.Key, out var _);
}
// pega a mensagem mais antiga
var msg = FilaComandos.Where(x => !x.Value.Enviado).OrderBy(x => x.Value.AdicionadoEm).FirstOrDefault();
if (msg.Value == null) return;
var mensagem = new
{
comando = (int)msg.Value.obj.cmd,
dispositivo = (int)T_Code.Snr,
payload = msg.Value.payload
};
await Variaveis.MqttService.PublishAsync(topicoTx, JsonConvert.SerializeObject(mensagem), true);
msg.Value.Enviado = true;
msg.Value.EnviadoEm = DateTime.Now;
}
private async Task<bool> MqttCallback(MqttTopicosMensagensModel Mensagem)
{
if (!DadosLeitura.Pronto && Mensagem.Momento > DadosLeitura.IniciadoEm && Mensagem.Mensagem == "OK")
{
DadosLeitura.ProntoEm = DateTime.Now;
DadosLeitura.Pronto = true;
}
else
{
var msgRx = JsonConvert.DeserializeObject<WorkerMessageModel<VisualWorkerMessageResponseModel>>(Mensagem.Mensagem);
if (msgRx == null)
{
return false;
}
FilaComandos.TryGetValue(msgRx.obj.cmd, out var msgTx);
if (msgTx != null)
{
FilaComandos.TryRemove(msgTx.obj.cmd, out var msg);
}
AtualizarDadosLeitura(msgRx);
}
return true;
}
private void RedisCallback(string mensagem)
public void RedisCallback(string mensagem)
{
try
{
@ -147,54 +52,123 @@ namespace AgroBase.Services.Operadores
var cmd = (VisualWorkerCommandType)comando.cmd;
MostrarLog($"📥 Comando recebido: cmd = {cmd.ToString()}");
//MostrarLog($"Comando recebido: cmd = {cmd.ToString()}");
switch (cmd)
{
case VisualWorkerCommandType.ScriptCarregado:
DadosLeitura.Pronto = true;
DadosLeitura.ProntoEm = DateTime.Now;
MostrarLog($"Comando recebido: cmd = {cmd.ToString()}");
break;
case VisualWorkerCommandType.GetCameraFrame:
var frameModel = JsonConvert.DeserializeObject<OAKCameraFrameModel>(comando.@params.ToString());
VisualWorkerFrameType tipo = (VisualWorkerFrameType)Convert.ToInt32(comando.@params["tipo"].ToString());
DadosLeitura.CameraFrames[tipo] = new OAKCameraFrameModel()
{
frame = comando.@params["frame"].ToString(),
timestamp = FuncoesGlobais.UnixToDateTime(comando.@params["timestamp"].ToString()),
};
break;
default:
MostrarLog($"⚠️ Comando não reconhecido: {comando.cmd}");
MostrarLog($"Comando não reconhecido: {comando.cmd}");
break;
}
}
catch (Exception ex)
{
MostrarLog($"❌ Erro ao deserializar resposta: {ex.Message}");
MostrarLog($"Erro ao deserializar resposta: {ex.Message}");
}
finally
{
DadosLeitura.UltimaMensagem = DateTime.Now;
}
}
private void AtualizarDadosLeitura(WorkerMessageModel<VisualWorkerMessageResponseModel> msg)
public void AtualizarSaude()
{
if (DadosLeitura.Leitura.obj == null)
{
DadosLeitura.Leitura.obj = new VisualWorkerMessageResponseModel();
}
switch (msg.obj.cmd)
{
case VisualWorkerCommandType.SalvarFrames:
{
DadosLeitura.Leitura.obj.save_frames = msg.obj.save_frames.Clone();
break;
}
}
DadosLeitura.Leitura.MomentoLog = DateTime.Now;
Saude = OperadoresModels.AtualizarSaude(CtxKey.DadosVisualWorker);
}
public async Task AguardarNovosDados(VisualWorkerCommandType cmd, int timeout = 1000)
public static void RecalibrarGridProfundidade(int qtd_frames = 50)
{
if (mapaRespostas.TryGetValue(cmd, out var condicao))
{
await FuncoesGlobais.AguardarCondicaoAsync(condicao, timeout, 10);
}
else
{
MostrarLog($"Comando {cmd} não suportado no AguardarResposta.");
}
var comando = new {
cmd = VisualWorkerCommandType.CalibrarProfundidade,
@params = qtd_frames
};
RedisService.Publish(CmdKey.VisualWorkerRx, JsonConvert.SerializeObject(comando));
}
public static async Task<OAKCameraFrameModel> GetCameraFrame(VisualWorkerFrameType tipo = VisualWorkerFrameType.Rgb)
{
DateTime Inicio = DateTime.Now;
var comando = new
{
cmd = VisualWorkerCommandType.GetCameraFrame,
@params = tipo,
};
RedisService.Publish(CmdKey.VisualWorkerRx, JsonConvert.SerializeObject(comando));
bool Frame() => DadosLeitura.CameraFrames.TryGetValue(tipo, out var frame) && (frame?.timestamp ?? DateTime.MinValue) > Inicio;
await FuncoesGlobais.AguardarCondicaoAsync(Frame, 1000, 100);
DadosLeitura.CameraFrames.TryGetValue(tipo, out OAKCameraFrameModel _frame);
return _frame;
}
public static void SaveCameraFrames(List<VisualWorkerFrameType> frames, string nome, string caminho)
{
var comando = new
{
cmd = VisualWorkerCommandType.SaveCameraFrames,
@params = new
{
nome = nome,
caminho = caminho,
tipos = frames.Select(x => (int)x).ToArray(),
},
};
RedisService.Publish(CmdKey.VisualWorkerRx, JsonConvert.SerializeObject(comando));
}
public static void AtualizarAnalise()
{
DadosLeitura.Imu = JsonConvert.DeserializeObject<VisualWorkerMessageIMUModel>(RedisService.Get(RedisService.ModKey(Enums.T_Code.Imu)));
var json = RedisService.Get(CtxKey.DadosVisualWorker);
var dados = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
DateTime timestamp = FuncoesGlobais.UnixToDateTime(dados["ts_analise"].ToString());
//var matrizes = JsonConvert.DeserializeObject<Dictionary<string, object>>(dados["matrizes"].ToString());
//var confianca = JsonConvert.DeserializeObject<List<List<double>>>(JsonConvert.SerializeObject(matrizes["confianca"]));
//var custo = JsonConvert.DeserializeObject<List<List<double>>>(JsonConvert.SerializeObject(matrizes["custo"]));
var anomalias = JsonConvert.DeserializeObject<Dictionary<string, object>>(dados["anomalias"].ToString());
var deteccoes = JsonConvert.DeserializeObject<List<VisualWorkerMessageAnaliseBBoxModel>>(JsonConvert.SerializeObject(anomalias["deteccoes"]));
var sombras = JsonConvert.DeserializeObject<List<VisualWorkerMessageAnaliseBBoxModel>>(JsonConvert.SerializeObject(anomalias["sombras"]));
var corredor = JsonConvert.DeserializeObject<Dictionary<string, object>>(dados["perfil_corredor"].ToString());
var segmentacao = JsonConvert.DeserializeObject<List<VisualWorkerMessageRadar2DPerfilModel>>(JsonConvert.SerializeObject(corredor["segmentacao"]));
var profundidade = JsonConvert.DeserializeObject<List<VisualWorkerMessageRadar2DPerfilModel>>(JsonConvert.SerializeObject(corredor["profundidade"]));
var solo = JsonConvert.DeserializeObject<VisualWorkerMessageAnaliseSoloModel>(JsonConvert.SerializeObject(dados["solo"]));
DadosLeitura.Analises = new VisualWorkerMessageAnaliseModel()
{
timestamp = timestamp,
solo = solo,
anomalias = deteccoes,
sombras = sombras,
corredor_prof = profundidade,
corredor_seg = segmentacao,
};
}
}
}

View File

@ -1,6 +1,12 @@
using StackExchange.Redis;
using AgroBase.Models.Operadores;
using AgroBase.Services.Operadores;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using static AgroBase.Models.Enums;
namespace AgroBase.Services
{
@ -15,16 +21,109 @@ namespace AgroBase.Services
_db = _redis.GetDatabase();
}
public static string ModKey(T_Code dispositivo)
{
return CtxKey.DadosModulo + dispositivo.ToString();
}
public static string Get(string chave)
{
return _db.StringGet(chave);
}
public static void Set(string chave, string valor)
private static void Set(string chave, string valor)
{
_db.StringSet(chave, valor);
}
public static void SetObject(string chave, object valor)
{
try
{
string json = JsonConvert.SerializeObject(valor, Formatting.None);
Set(chave, json); // chama o método original que salva string
}
catch (Exception ex)
{
Console.WriteLine($"Erro ao salvar objeto no Redis: {ex.Message}");
}
}
public static void AtualizarCampos(string chave, params (string campo, object valor)[] campos)
{
var dict = campos.ToDictionary(x => x.campo, x => x.valor);
AtualizarCampos(chave, dict);
}
private static void AtualizarCampos(string chave, Dictionary<string, object> novosCampos)
{
try
{
string jsonAtual = Get(chave);
if (jsonAtual == "\"\"")
jsonAtual = "";
JObject root = string.IsNullOrWhiteSpace(jsonAtual) ? new JObject() : JObject.Parse(jsonAtual);
foreach (var campo in novosCampos)
{
// Exemplo de campo: "Operacao.status"
string[] partes = campo.Key.Split('.');
JObject atual = root;
for (int i = 0; i < partes.Length - 1; i++)
{
if (atual[partes[i]] == null || atual[partes[i]].Type != JTokenType.Object)
{
atual[partes[i]] = new JObject();
}
atual = (JObject)atual[partes[i]];
}
atual[partes.Last()] = JToken.FromObject(campo.Value);
}
Set(chave, root.ToString(Formatting.None));
var d = Get(chave);
}
catch (Exception ex)
{
Console.WriteLine($"❌ Erro ao atualizar campos Redis: {ex.Message}");
}
}
public static T GetField<T>(string chave, string caminhoCampo = "", T valorDefault = default(T))
{
try
{
string json = Get(chave);
if (string.IsNullOrWhiteSpace(json))
return valorDefault;
JObject obj = JObject.Parse(json);
string[] partes = caminhoCampo.Split('.');
JToken atual = obj;
foreach (var parte in partes)
{
if (atual == null || atual.Type == JTokenType.Null)
return valorDefault;
// Acesso seguro para JObject
if (atual is JObject jo && jo.TryGetValue(parte, out var prox))
atual = prox;
else
return valorDefault;
}
return atual.ToObject<T>();
}
catch (Exception ex)
{
Console.WriteLine($"❌ Erro ao obter campo '{caminhoCampo}': {ex.Message}");
return valorDefault;
}
}
public static void Publish(string canal, string mensagem)
{
var pub = _redis.GetSubscriber();
@ -38,6 +137,39 @@ namespace AgroBase.Services
callback(msg);
});
}
public static void LimparDadosIniciais()
{
Set(CtxKey.DadosCameras, JsonConvert.SerializeObject(new Dictionary<string, CameraWorkerItemModel>()));
DefinirEquipamentoDesconectado();
}
public static void DefinirEquipamentoDesconectado()
{
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)
{
Mod.conectado = false;
Mod.saude = 0;
Mod.status = StatusModulo.Desconectado;
Mod.saude_individual = new List<ManagerWorkerMessageResponseModulosPendentesSaudeModel>();
Mod.motivos = new List<string>() { "Desconectado" };
AtualizarCampos(
ModKey(Mod.modulo),
("saude", Mod)
);
}
AtualizarCampos(
CtxKey.DadosOperacao,
("status_modulos", HealthWorkerService.ModulosSaude)
);
}
}
public class ComandoRedis
@ -53,7 +185,11 @@ namespace AgroBase.Services
public const string DadosOperacao = "ctx:dados_operacao";
public const string DadosContexto = "ctx:dados_contexto";
public const string DadosControle = "ctx:dados_controle";
public const string DadosEquipamento = "ctx:dados_equipamento";
public const string DadosVisualWorker = "ctx:dados_visual_worker";
public const string DadosManagerWorker = "ctx:dados_manager_worker";
public const string DadosHealthWorker = "ctx:dados_health_worker";
public const string DadosCameraWorker = "ctx:dados_camera_worker";
}
public static class CmdKey

View File

@ -1,5 +1,6 @@
using AgroBase.Forms;
using AgroBase.Models;
using AgroBase.Services.Operadores;
using System;
using System.Collections.Generic;
using System.IO;
@ -236,7 +237,9 @@ namespace AgroBase.Services
DispositivosMapeados.Remove(Dispositivo);
}
foreach (var cam in VariaveisOperacao.Operadores.CamerasConectadas.Where(x => x.Index > -1))
var cameras = CameraWorkerService.GetListaCameras().Where(x => x.Index > -1).ToList();
foreach (var cam in cameras)
{
if (!DispositivosMapeados.Any(x => x.Dispositivo == cam.Dispositivo))
{
@ -251,7 +254,7 @@ namespace AgroBase.Services
foreach (var cam in DispositivosMapeados.Where(x => x.Tipo == TipoConexao.USB))
{
if (!VariaveisOperacao.Operadores.CamerasConectadas.Any(x => x.Dispositivo == cam.Dispositivo))
if (!cameras.Any(x => x.Dispositivo == cam.Dispositivo))
{
DispositivosMapeados.Remove(cam);
}

View File

@ -0,0 +1,143 @@
0:00:00 Startup
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
0:00:00 Microsoft.NewBrowser_Popup
0:00:00 Microsoft.BrowserList.AddBrowser
0:00:00 Browser1 Insert active Tab1 at 0
0:00:00 Tab1 StartNav1 #auto_toplevel
0:00:00 Tab1 StartNav2 #typed
0:00:00 Tab1 FinishNav1
0:00:00 Tab1 PageLoad
0:00:00 Tab1 FinishNav2
0:00:00 Tab1 PageLoad
0:00:17 Widget Closed: StatusBubble
0:37:43 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp
0:00:00 Startup
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
0:00:00 Microsoft.NewBrowser_Popup
0:00:00 Microsoft.BrowserList.AddBrowser
0:00:00 Browser1 Insert active Tab1 at 0
0:00:00 Tab1 StartNav1 #auto_toplevel
0:00:00 Tab1 StartNav2 #typed
0:00:00 Tab1 FinishNav1
0:00:00 Tab1 PageLoad
0:00:00 Tab1 FinishNav2
0:00:00 Tab1 PageLoad
0:00:26 Widget Closed: StatusBubble
1:06:55 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp
0:00:00 Startup
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
0:00:00 Microsoft.NewBrowser_Popup
0:00:00 Microsoft.BrowserList.AddBrowser
0:00:00 Browser1 Insert active Tab1 at 0
0:00:00 Tab1 StartNav1 #auto_toplevel
0:00:00 Tab1 StartNav2 #typed
0:00:00 Tab1 FinishNav1
0:00:00 Tab1 PageLoad
0:00:00 Tab1 FinishNav2
0:00:00 Tab1 PageLoad
0:00:21 Widget Closed: StatusBubble
0:05:18 Widget Closed: StatusBubble
0:08:17 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp
0:00:00 Startup
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
0:00:00 Microsoft.NewBrowser_Popup
0:00:00 Microsoft.BrowserList.AddBrowser
0:00:00 Browser1 Insert active Tab1 at 0
0:00:00 Tab1 StartNav1 #auto_toplevel
0:00:00 Tab1 StartNav2 #typed
0:00:00 Tab1 FinishNav1
0:00:00 Tab1 PageLoad
0:00:00 Tab1 FinishNav2
0:00:00 Tab1 PageLoad
3:37:51 Widget Closed: StatusBubble
6:54:19 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp
0:00:00 Startup
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
0:00:00 Microsoft.NewBrowser_Popup
0:00:00 Microsoft.BrowserList.AddBrowser
0:00:00 Browser1 Insert active Tab1 at 0
0:00:00 Tab1 StartNav1 #auto_toplevel
0:00:00 Tab1 StartNav2 #typed
0:00:00 Tab1 FinishNav1
0:00:00 Tab1 PageLoad
0:00:00 Tab1 FinishNav2
0:00:00 Tab1 PageLoad
0:30:02 Widget Closed: StatusBubble
1:24:04 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp
0:00:00 Startup
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
0:00:00 Microsoft.NewBrowser_Popup
0:00:00 Microsoft.BrowserList.AddBrowser
0:00:00 Browser1 Insert active Tab1 at 0
0:00:00 Tab1 StartNav1 #auto_toplevel
0:00:00 Tab1 StartNav2 #typed
0:00:00 Tab1 FinishNav1
0:00:00 Tab1 PageLoad
0:00:00 Tab1 FinishNav2
0:00:00 Tab1 PageLoad
0:00:41 Widget Closed: StatusBubble
0:02:00 Widget Closed: StatusBubble
0:06:37 Widget Closed: StatusBubble
4:46:27 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp
0:00:00 Startup
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
0:00:00 Microsoft.NewBrowser_Popup
0:00:00 Microsoft.BrowserList.AddBrowser
0:00:00 Browser1 Insert active Tab1 at 0
0:00:00 Tab1 StartNav1 #auto_toplevel
0:00:00 Tab1 StartNav2 #typed
0:00:00 Tab1 FinishNav1
0:00:00 Tab1 PageLoad
0:00:00 Tab1 FinishNav2
0:00:00 Tab1 PageLoad
0:05:25 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp
0:00:00 Startup
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
0:00:00 Microsoft.NewBrowser_Popup
0:00:00 Microsoft.BrowserList.AddBrowser
0:00:00 Browser1 Insert active Tab1 at 0
0:00:00 Tab1 StartNav1 #auto_toplevel
0:00:00 Tab1 StartNav2 #typed
0:00:00 Tab1 FinishNav1
0:00:00 Tab1 PageLoad
0:00:00 Tab1 FinishNav2
0:00:00 Tab1 PageLoad
0:00:22 Widget Closed: StatusBubble
0:03:52 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp
0:00:00 Startup
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
0:00:00 Microsoft.NewBrowser_Popup
0:00:00 Microsoft.BrowserList.AddBrowser
0:00:00 Browser1 Insert active Tab1 at 0
0:00:00 Tab1 StartNav1 #auto_toplevel
0:00:00 Tab1 StartNav2 #typed
0:00:00 Tab1 FinishNav1
0:00:00 Tab1 PageLoad
0:00:00 Tab1 FinishNav2
0:00:00 Tab1 PageLoad
0:00:10 Widget Closed: StatusBubble
0:03:06 Widget Closed: StatusBubble
0:16:21 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp
0:00:00 Startup
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
0:00:00 Microsoft.NewBrowser_Popup
0:00:00 Microsoft.BrowserList.AddBrowser
0:00:00 Browser1 Insert active Tab1 at 0
0:00:00 Tab1 StartNav1 #auto_toplevel
0:00:00 Tab1 StartNav2 #typed
0:00:00 Tab1 FinishNav1
0:00:00 Tab1 PageLoad
0:00:00 Tab1 FinishNav2
0:00:00 Tab1 PageLoad
0:00:36 Widget Closed: StatusBubble
0:04:19 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp

View File

@ -1,12 +1,5 @@
{
"epochs": [ {
"calculation_time": "13393963069284106",
"config_version": 0,
"model_version": "0",
"padded_top_topics_start_index": 0,
"taxonomy_version": 0,
"top_topics_and_observing_domains": [ ]
}, {
"calculation_time": "13394567869286013",
"config_version": 0,
"model_version": "0",
@ -20,7 +13,21 @@
"padded_top_topics_start_index": 0,
"taxonomy_version": 0,
"top_topics_and_observing_domains": [ ]
}, {
"calculation_time": "13395881044629269",
"config_version": 0,
"model_version": "0",
"padded_top_topics_start_index": 0,
"taxonomy_version": 0,
"top_topics_and_observing_domains": [ ]
}, {
"calculation_time": "13396617367014463",
"config_version": 0,
"model_version": "0",
"padded_top_topics_start_index": 0,
"taxonomy_version": 0,
"top_topics_and_observing_domains": [ ]
} ],
"hex_encoded_hmac_key": "40F346D3248C3AFDF2BEE1FE496DBD32F7CED6E5AE98B881ABC421AA7E7B5642",
"next_scheduled_calculation_time": "13395777469290985"
"next_scheduled_calculation_time": "13397222167014715"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -1,3 +1,3 @@
2025/06/27-20:56:49.222 2104 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/06/27-20:56:49.231 2104 Recovering log #3
2025/06/27-20:56:49.234 2104 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log
2025/07/11-13:13:55.663 6de4 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/07/11-13:13:55.671 6de4 Recovering log #3
2025/07/11-13:13:55.675 6de4 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log

View File

@ -1,3 +1,3 @@
2025/06/27-07:21:30.670 746c Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/06/27-07:21:30.676 746c Recovering log #3
2025/06/27-07:21:30.679 746c Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log
2025/07/11-12:34:04.813 7d74 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/07/11-12:34:04.820 7d74 Recovering log #3
2025/07/11-12:34:04.824 7d74 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log

View File

@ -1 +1 @@
{"net":{"http_server_properties":{"servers":[{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13395628615843983","port":443,"protocol_str":"quic"}],"anonymization":["DAAAAAcAAABmaWxlOi8vAA==",false,0],"network_stats":{"srtt":7016},"server":"https://tile.openstreetmap.org","supports_spdy":true}],"supports_quic":{"address":"2804:d78:6d4:dc00:ad47:84dd:a027:10ff","used_quic":true},"version":5},"network_qualities":{"CAASABiAgICA+P////8B":"4G","CAESABiAgICA+P////8B":"4G","CAISABiAgICA+P////8B":"4G","CAYSABiAgICA+P////8B":"Offline"}}}
{"net":{"http_server_properties":{"servers":[{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13396810500919879","port":443,"protocol_str":"quic"}],"anonymization":["DAAAAAcAAABmaWxlOi8vAA==",false,0],"network_stats":{"srtt":6500},"server":"https://tile.openstreetmap.org","supports_spdy":true}],"supports_quic":{"address":"2804:d78:60b:6f00:1cb:7dd5:9647:ea0","used_quic":true},"version":5},"network_qualities":{"CAASABiAgICA+P////8B":"4G","CAESABiAgICA+P////8B":"4G","CAISABiAgICA+P////8B":"4G","CAYSABiAgICA+P////8B":"Offline"}}}

View File

@ -1 +1 @@
{"sts":[{"expiry":1782604614.73,"host":"bWGAftl61rqoc0YzqPncsLvQQh/iC2Bdp3ejUeGC83w=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1751068614.730003}],"version":2}
{"sts":[{"expiry":1783786447.236962,"host":"bWGAftl61rqoc0YzqPncsLvQQh/iC2Bdp3ejUeGC83w=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1752250447.236964}],"version":2}

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,3 @@
2025/06/27-20:57:03.060 2104 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/06/27-20:57:03.061 2104 Recovering log #3
2025/06/27-20:57:03.064 2104 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log
2025/07/11-13:18:15.006 6de4 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/07/11-13:18:15.007 6de4 Recovering log #3
2025/07/11-13:18:15.010 6de4 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log

View File

@ -1,3 +1,3 @@
2025/06/27-07:56:02.137 746c Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/06/27-07:56:02.138 746c Recovering log #3
2025/06/27-07:56:02.141 746c Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log
2025/07/11-12:50:26.119 7d74 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/07/11-12:50:26.121 7d74 Recovering log #3
2025/07/11-12:50:26.124 7d74 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log

View File

@ -1,3 +1,3 @@
2025/06/27-20:56:49.144 3264 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/06/27-20:56:49.146 3264 Recovering log #3
2025/06/27-20:56:49.146 3264 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000003.log
2025/07/11-13:13:55.583 58ac Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/07/11-13:13:55.584 58ac Recovering log #3
2025/07/11-13:13:55.585 58ac Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000003.log

View File

@ -1,3 +1,3 @@
2025/06/27-07:21:30.596 aec Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/06/27-07:21:30.597 aec Recovering log #3
2025/06/27-07:21:30.598 aec Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000003.log
2025/07/11-12:34:04.743 6ec0 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/07/11-12:34:04.744 6ec0 Recovering log #3
2025/07/11-12:34:04.745 6ec0 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000003.log

Some files were not shown because too many files have changed in this diff Show More