ajustes no controle da operacao

This commit is contained in:
Diego Freitas 2025-07-25 16:14:52 -03:00
parent 6cb1f14779
commit 3d0077624f
65 changed files with 359 additions and 279 deletions

Binary file not shown.

View File

@ -96,7 +96,14 @@ namespace AgroBase.Forms
var temperatura = sensor.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.Temperatura); var temperatura = sensor.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.Temperatura);
var energia = sensor.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.Energia); var energia = sensor.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.Energia);
var codAlarme = sensor.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.CodAlarme); var codAlarme = sensor.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.CodAlarme);
lbl.Text = $"{id.Replace("AB", "Barramento ")}: {codAlarme.atual?.valor ?? 0}, {(tensao.atual.valor ?? -1).ToString("0.00")} {tensao.unidade_medida}, {(corrente.atual.valor ?? -1).ToString("0.00")} {corrente.unidade_medida}, {(potencia.atual.valor ?? -1).ToString("0.00")} {potencia.unidade_medida}, {(temperatura.atual.valor ?? -1).ToString("0.00")} {temperatura.unidade_medida}, {(energia.atual.valor ?? -1).ToString("0.00")} {energia.unidade_medida}"; lbl.Text =
$"{id.Replace("AB", "Barramento ")}: " +
$"{codAlarme?.atual?.valor ?? 0}, " +
$"{(tensao?.atual?.valor ?? -1).ToString("0.00")} {tensao?.unidade_medida}, " +
$"{(corrente?.atual?.valor ?? -1).ToString("0.00")} {corrente?.unidade_medida}, " +
$"{(potencia?.atual?.valor ?? -1).ToString("0.00")} {potencia?.unidade_medida}, " +
$"{(temperatura?.atual?.valor ?? -1).ToString("0.00")} {temperatura?.unidade_medida}, " +
$"{(energia?.atual?.valor ?? -1).ToString("0.00")} {energia?.unidade_medida}";
lbl.ForeColor = sensor.Inicializado ? Color.Green : Color.Red; lbl.ForeColor = sensor.Inicializado ? Color.Green : Color.Red;
} }
} }

View File

@ -111,7 +111,7 @@ namespace AgroBase.Forms
PythonService.EncerrarProcessos(); PythonService.EncerrarProcessos();
Environment.Exit(0); try { Environment.Exit(0); } catch { }
} }

View File

@ -100,43 +100,50 @@ namespace AgroBase.Models
public void AtualizarDados(int _idx, List<string> momentos = null, List<GraficoInterativoSerieModel> series = null) public void AtualizarDados(int _idx, List<string> momentos = null, List<GraficoInterativoSerieModel> series = null)
{ {
Idx = _idx; try
int startIdx, endIdx;
(startIdx, endIdx) = DefineInicioFimLogs(Idx, Momentos.Count());
_idxMeio = (endIdx - startIdx) / 2;
Minimo = double.MaxValue;
Maximo = double.MinValue;
chart = Inicializar(chart);
if (momentos != null && !momentos.SequenceEqual(Momentos))
{ {
Momentos.Clear(); Idx = _idx;
Momentos.AddRange(momentos.ToList()); int startIdx, endIdx;
} (startIdx, endIdx) = DefineInicioFimLogs(Idx, Momentos.Count());
_idxMeio = (endIdx - startIdx) / 2;
if (series != null && !series.SequenceEqual(Series)) Minimo = double.MaxValue;
{ Maximo = double.MinValue;
Series.Clear();
Series.AddRange(series.ToList());
}
foreach (var Serie in Series) chart = Inicializar(chart);
{
if (Serie.ChartType == SeriesChartType.Pie) if (momentos != null && !momentos.SequenceEqual(Momentos))
{ {
// Para gráfico de pizza, acumula valores até o índice atual Momentos.Clear();
var acumuladoErvas = Series.ToDictionary(s => s.Titulo + (s.MostrarValor ? (" - " + s.Valores[Idx].ToString("0.00")) : ""), s => s.Valores[Idx]); Momentos.AddRange(momentos.ToList());
PopularSerieGraficoPizza(chart, acumuladoErvas);
} }
else
if (series != null && !series.SequenceEqual(Series))
{ {
// Para gráficos de linha Series.Clear();
var _momentos = Momentos.GetRange(startIdx, endIdx - startIdx + 1).ToList(); Series.AddRange(series.ToList());
var _valores = Serie.Valores.GetRange(startIdx, endIdx - startIdx + 1).ToList();
PopularSerieGraficoLinha(chart, Serie.Titulo, _momentos, _valores, Serie.Visivel, Serie.MostrarValor);
} }
foreach (var Serie in Series)
{
if (Serie.ChartType == SeriesChartType.Pie)
{
// Para gráfico de pizza, acumula valores até o índice atual
var acumuladoErvas = Series.ToDictionary(s => s.Titulo + (s.MostrarValor ? (" - " + s.Valores[Idx].ToString("0.00")) : ""), s => s.Valores[Idx]);
PopularSerieGraficoPizza(chart, acumuladoErvas);
}
else
{
// Para gráficos de linha
var _momentos = Momentos.GetRange(startIdx, endIdx - startIdx + 1).ToList();
var _valores = Serie.Valores.GetRange(startIdx, endIdx - startIdx + 1).ToList();
PopularSerieGraficoLinha(chart, Serie.Titulo, _momentos, _valores, Serie.Visivel, Serie.MostrarValor);
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Erro ao atualizar dados do grafico: {ex.Message}");
} }
} }

View File

@ -107,7 +107,7 @@ namespace AgroBase.Models
public List<OperacaoParametrosMandatoriosModel> ParametrosMandatorios { get; set; } = new List<OperacaoParametrosMandatoriosModel>(); public List<OperacaoParametrosMandatoriosModel> ParametrosMandatorios { get; set; } = new List<OperacaoParametrosMandatoriosModel>();
public double CapacidadeReservatorio { get; set; } = 30; public double CapacidadeReservatorio { get; set; } = 30;
public int QuantidadeCamerasSolo { get; set; } = 1; public int QuantidadeCamerasSolo { get; set; } = 1;
public int TempoIniciarOperacao { get; set; } = 5; public int TempoIniciarOperacao { get; set; } = 25;
public string ID { get; set; } public string ID { get; set; }
public double tmrLogsInterval public double tmrLogsInterval
{ {
@ -684,6 +684,7 @@ namespace AgroBase.Models
{ {
Console.WriteLine("Calibragem inicial inciada..."); Console.WriteLine("Calibragem inicial inciada...");
Variaveis.OperacaoEmAndamento.Calibrando = true; Variaveis.OperacaoEmAndamento.Calibrando = true;
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("calibrando", Variaveis.OperacaoEmAndamento.Calibrando));
var DispAtu = Variaveis.OperacaoEmAndamento.DispAtu; var DispAtu = Variaveis.OperacaoEmAndamento.DispAtu;
var DispMvd = Variaveis.OperacaoEmAndamento.DispMvd; var DispMvd = Variaveis.OperacaoEmAndamento.DispMvd;
@ -719,6 +720,7 @@ namespace AgroBase.Models
} }
Variaveis.OperacaoEmAndamento.Calibrando = false; Variaveis.OperacaoEmAndamento.Calibrando = false;
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("calibrando", Variaveis.OperacaoEmAndamento.Calibrando));
} }
@ -829,54 +831,37 @@ namespace AgroBase.Models
{ {
if (Variaveis.OperacaoEmAndamento.Modo == ModoOperacao.MapaGPS) if (Variaveis.OperacaoEmAndamento.Modo == ModoOperacao.MapaGPS)
{ {
Variaveis.OperacaoEmAndamento.AtualizarDadosControleMovimento(false); Variaveis.OperacaoEmAndamento.AtualizarDadosControle(false, new List<T_Code>() { T_Code.Mov, T_Code.Dir });
} }
if (Variaveis.OperacaoEmAndamento.Controle.PulverizadorAutomatico) if (Variaveis.OperacaoEmAndamento.Controle.PulverizadorAutomatico)
{ {
Variaveis.OperacaoEmAndamento.AtualizarDadosControleAtuador(false); Variaveis.OperacaoEmAndamento.AtualizarDadosControle(false, new List<T_Code>() { T_Code.Atu });
} }
} }
public void AtualizarDadosControleAtuador(bool ForcarEnvio) public void AtualizarDadosControle(bool ForcarEnvio, List<T_Code> Dispositivos)
{ {
DateTime Agora = DateTime.Now; DateTime Agora = DateTime.Now;
var _Controle = Variaveis.OperacaoEmAndamento.Controle; var _Controle = Variaveis.OperacaoEmAndamento.Controle;
if (!_Controle.PulverizadorAutomatico) if (!ForcarEnvio && !_Controle.PulverizadorAutomatico)
return; return;
foreach (var Ctrl in _Controle.TiposControle.Where(x => x.Tipo == T_Code.Atu)) foreach (var Ctrl in _Controle.TiposControle.Where(x => Dispositivos.Contains(x.Tipo)))
{ {
if (ForcarEnvio || ((Agora - Ctrl.UltimoComando).TotalMilliseconds > Ctrl.DelayEnvioComando)) if (ForcarEnvio || ((Agora - Ctrl.UltimoComando).TotalMilliseconds > Ctrl.DelayEnvioComando))
{ {
var Protocolos = EnviarProtocoloComando(Variaveis.OperacaoEmAndamento.DispAtu, Ctrl.Tipo, ForcarEnvio); var Protocolos = EnviarProtocoloComando(Ctrl.Tipo, ForcarEnvio);
Ctrl.UltimoComando = Agora; Ctrl.UltimoComando = Agora;
Ctrl.Comandos.AddRange(Protocolos); Ctrl.Comandos.AddRange(Protocolos);
} }
} }
} }
public void AtualizarDadosControleMovimento(bool ForcarEnvio) public List<string> EnviarProtocoloComando(T_Code Tipo, bool ForcarEnvio)
{ {
DateTime Agora = DateTime.Now; if (!Variaveis.OperacaoEmAndamento.Iniciado)
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
foreach (var Ctrl in _Controle.TiposControle.Where(x => x.Tipo != T_Code.Atu))
{
if (ForcarEnvio || ((Agora - Ctrl.UltimoComando).TotalMilliseconds > Ctrl.DelayEnvioComando))
{
var Protocolos = EnviarProtocoloComando(Variaveis.OperacaoEmAndamento.DispMvd, Ctrl.Tipo, ForcarEnvio);
Ctrl.UltimoComando = Agora;
Ctrl.Comandos.AddRange(Protocolos);
}
}
}
public List<string> EnviarProtocoloComando(IDispositivosService Dispositivo, T_Code Tipo, bool ForcarEnvio)
{
if (Dispositivo == null || !Variaveis.OperacaoEmAndamento.Iniciado)
{ {
return new List<string>(); return new List<string>();
} }
@ -886,101 +871,94 @@ namespace AgroBase.Models
var _Controle = Variaveis.OperacaoEmAndamento.Controle; var _Controle = Variaveis.OperacaoEmAndamento.Controle;
var _ControleAnterior = Variaveis.OperacaoEmAndamento.ControleAnterior; var _ControleAnterior = Variaveis.OperacaoEmAndamento.ControleAnterior;
if (Dispositivo.Dados is MovimentacaoUnificadaModel) switch (Tipo)
{ {
switch (Tipo) case T_Code.Mov:
{
case T_Code.Mov:
{
if (_Controle.RPM_SP == 0)
{
_Controle.Direcao = Direcao.Parado;
}
else if(_Controle.RPM_SP < 0)
{
_Controle.PercentualVelocidadeSP *= -1;
_Controle.Direcao = Direcao.Tras;
}
else if (_Controle.RPM_SP > 0)
{
_Controle.Direcao = Direcao.Frente;
}
if (ForcarEnvio || _Controle.RPM_SP != _ControleAnterior.RPM_SP)
{
((MovimentacaoUnificadaModel)Dispositivo.Dados).Modulos.ForEach(Mod => Mod.MovMotor.EnviarComandoControle(_Controle.Direcao));
_Controle.TiposControle.FirstOrDefault(x => x.Tipo == Tipo).UltimaDirecao = _Controle.Direcao;
}
_ControleAnterior.PercentualVelocidadeSP = _Controle.PercentualVelocidadeSP;
_ControleAnterior.Direcao = _Controle.Direcao;
break;
}
case T_Code.Dir:
{
if (_Controle.Angulo > 0)
{
_Controle.Direcao = Direcao.Direita;
}
else if (_Controle.Angulo < 0)
{
_Controle.Direcao = Direcao.Esquerda;
}
else
{
_Controle.Direcao = Direcao.Parado;
}
// Só enviar comando se a direção realmente mudou
if (ForcarEnvio || _Controle.Angulo != _ControleAnterior.Angulo)
{
((MovimentacaoUnificadaModel)Dispositivo.Dados).Modulos.ForEach(Mod => Mod.DirMotor.EnviarComandoControle(_Controle.Direcao));
_Controle.TiposControle.FirstOrDefault(x => x.Tipo == Tipo).UltimaDirecao = _Controle.Direcao;
}
_ControleAnterior.Angulo = _Controle.Angulo;
_ControleAnterior.Direcao = _Controle.Direcao;
break;
}
}
Protocolos = new List<string>()
{
Tipo.ToString() + ";" + _Controle.Direcao.ToString() + ";" + _Controle.RPM_SP.ToString() + ";" + _Controle.Angulo.ToString()
};
}
else if (Dispositivo.Dados is AtuadorModel)
{
bool AlteracaoDeEstado = false;
for (int i = 0; i < _Controle.BicosAtuados.Count; i++)
{
if (_Controle.BicosAtuados[i].ComandoAtuar != _ControleAnterior.BicosAtuados[i].ComandoAtuar)
{ {
AlteracaoDeEstado = true; //Keys tecla = Keys.Escape;
if (_Controle.RPM_SP == 0)
{
_Controle.Direcao = Direcao.Parado;
//tecla = Keys.Escape;
}
else if (_Controle.RPM_SP < 0)
{
_Controle.PercentualVelocidadeSP *= -1;
_Controle.Direcao = Direcao.Tras;
//tecla = Keys.Down;
}
else if (_Controle.RPM_SP > 0)
{
_Controle.Direcao = Direcao.Frente;
//tecla = Keys.Up;
}
if (ForcarEnvio || _Controle.RPM_SP != _ControleAnterior.RPM_SP)
{
//GeneralJoystick.EnviaComandoMotor(tecla, Tipo, ForcarEnvio);
Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.ForEach(Mod => Mod.MovMotor.EnviarComandoControle(_Controle.Direcao));
_Controle.TiposControle.FirstOrDefault(x => x.Tipo == Tipo).UltimaDirecao = _Controle.Direcao;
}
_ControleAnterior.PercentualVelocidadeSP = _Controle.PercentualVelocidadeSP;
_ControleAnterior.Direcao = _Controle.Direcao;
Protocolos = new List<string>()
{
Tipo.ToString() + ";" + _Controle.Direcao.ToString() + ";" + _Controle.RPM_SP.ToString() + ";" + _Controle.Angulo.ToString()
};
break; break;
} }
} case T_Code.Dir:
if (ForcarEnvio || AlteracaoDeEstado)
{
for (int i = 0; i < _Controle.BicosAtuados.Count; i++)
{ {
if (_Controle.BicosAtuados[i].ComandoAtuar != _ControleAnterior.BicosAtuados[i].ComandoAtuar) if (_Controle.Angulo > 0)
{ {
GeneralJoystick.EnviarComandoAtuador(S_Code.sBIC, _Controle.BicosAtuados[i].ComandoAtuar, _Controle.BicosAtuados[i].ID); _Controle.Direcao = Direcao.Direita;
} }
else if (_Controle.Angulo < 0)
{
_Controle.Direcao = Direcao.Esquerda;
}
else
{
_Controle.Direcao = Direcao.Parado;
}
// Só enviar comando se a direção realmente mudou
if (ForcarEnvio || _Controle.Angulo != _ControleAnterior.Angulo)
{
Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.ForEach(Mod => Mod.DirMotor.EnviarComandoControle(_Controle.Direcao));
_Controle.TiposControle.FirstOrDefault(x => x.Tipo == Tipo).UltimaDirecao = _Controle.Direcao;
}
_ControleAnterior.Angulo = _Controle.Angulo;
_ControleAnterior.Direcao = _Controle.Direcao;
Protocolos = new List<string>()
{
Tipo.ToString() + ";" + _Controle.Direcao.ToString() + ";" + _Controle.RPM_SP.ToString() + ";" + _Controle.Angulo.ToString()
};
break;
} }
} case T_Code.Atu:
{
for (int i = 0; i < _Controle.BicosAtuados.Count; i++)
{
if (ForcarEnvio || _Controle.BicosAtuados[i].ComandoAtuar != _ControleAnterior.BicosAtuados[i].ComandoAtuar)
{
GeneralJoystick.EnviarComandoAtuador(S_Code.sBIC, _Controle.BicosAtuados[i].ComandoAtuar, _Controle.BicosAtuados[i].ID);
_ControleAnterior.BicosAtuados[i].ComandoAtuar = _Controle.BicosAtuados[i].ComandoAtuar;
}
}
_ControleAnterior.BicosAtuados = _Controle.BicosAtuados.Select(x => x.Clone()).ToList(); Protocolos = new List<string>()
{
Protocolos = new List<string>() Tipo.ToString() + ";" + string.Join(";", _Controle.BicosAtuados.Select(x => x.ComandoAtuar ? "1" : "0"))
{ };
Tipo.ToString() + ";" + string.Join(";", _Controle.BicosAtuados.Select(x => x.ComandoAtuar ? "1" : "0")) break;
}; }
} }
return Protocolos; return Protocolos;
@ -1462,7 +1440,23 @@ namespace AgroBase.Models
public List<OperacaoControleTipoModel> TiposControle { get; set; } = new List<OperacaoControleTipoModel>(); public List<OperacaoControleTipoModel> TiposControle { get; set; } = new List<OperacaoControleTipoModel>();
public bool SonarAtivado { get; set; } = true; public bool SonarAtivado { get; set; } = true;
public bool PulverizadorAutomatico { get; set; } = false; private bool _pulverizadorAutomatico = false;
public bool PulverizadorAutomatico
{
get
{
return _pulverizadorAutomatico;
}
set
{
_pulverizadorAutomatico = value;
if (!_pulverizadorAutomatico)
{
Variaveis.OperacaoEmAndamento.Controle.BicosAtuados.ForEach(bico => bico.ComandoAtuar = false);
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(true, new List<T_Code>() { T_Code.Atu });
}
}
}
public TiposControladorDirecional TipoControleDirecional { get; set; } = TiposControladorDirecional.PID; public TiposControladorDirecional TipoControleDirecional { get; set; } = TiposControladorDirecional.PID;
public List<MPCSimulacaoModel> SimulacaoMPC { get; set; } = new List<MPCSimulacaoModel>(); public List<MPCSimulacaoModel> SimulacaoMPC { get; set; } = new List<MPCSimulacaoModel>();

View File

@ -82,5 +82,6 @@ namespace AgroBase.Models.Operadores
GetCameraFrame = 4, GetCameraFrame = 4,
SaveCameraFrames = 5, SaveCameraFrames = 5,
EnviarDadosControle = 6, EnviarDadosControle = 6,
ReiniciarDeteccoes = 7
} }
} }

View File

@ -41,6 +41,7 @@ namespace AgroBase.Services
public static int TaxaAmostragemHz { get; set; } = 5; public static int TaxaAmostragemHz { get; set; } = 5;
private static bool LoopRTK = false;
public static bool CorrecaoRTK = true; public static bool CorrecaoRTK = true;
public static DateTime UltimoEnvioCorrecaoRTK = DateTime.MinValue; public static DateTime UltimoEnvioCorrecaoRTK = DateTime.MinValue;
@ -473,12 +474,17 @@ namespace AgroBase.Services
private static async Task AplicarCorrecaoRTK() private static async Task AplicarCorrecaoRTK()
{ {
if (LoopRTK)
return;
LoopRTK = true;
// Configurações do NTRIP caster para RTK2Go // Configurações do NTRIP caster para RTK2Go
string host = "gps-ntrip.ibge.gov.br"; string host = "gps-ntrip.ibge.gov.br";
int port = 2101; int port = 2101;
string mountpoint = "EESC0"; string mountpoint = "EESC0";
string username = "Zendion"; // Geralmente vazio para RTK2Go string username = "Zendion"; // Geralmente vazio para RTK2Go
string password = "Diego21*"; // Geralmente vazio para RTK2Go string password = "vyNEF$5*"; // Geralmente vazio para RTK2Go
while (true) // Loop para reconectar em caso de falha while (true) // Loop para reconectar em caso de falha
{ {
@ -538,6 +544,8 @@ namespace AgroBase.Services
await Task.Delay(5000); // Aguarde antes de tentar novamente await Task.Delay(5000); // Aguarde antes de tentar novamente
} }
} }
LoopRTK = false;
} }

View File

@ -156,8 +156,8 @@ namespace AgroBase.Services.Operadores
("percentual_tensao_bateria_min", VariaveisEquipamento.PercentualTensaoBateriaMin), ("percentual_tensao_bateria_min", VariaveisEquipamento.PercentualTensaoBateriaMin),
("camera_caminho_id", Variaveis.OperacaoEmAndamento.DispSen?.Dados?.CameraCaminho?.Id ?? ""), ("camera_caminho_id", Variaveis.OperacaoEmAndamento.DispSen?.Dados?.CameraCaminho?.Id ?? ""),
("camera_solo_id", Variaveis.OperacaoEmAndamento.DispSen?.Dados?.CamerasSolo?.FirstOrDefault()?.Id ?? ""), ("camera_solo_id", Variaveis.OperacaoEmAndamento.DispSen?.Dados?.CamerasSolo?.FirstOrDefault()?.Id ?? ""),
("path_ia_model_ruas", VersionamentoService.ArquivoModeloStreetDetector), ("path_ia_model_ruas", VersionamentoService.ArquivoModeloStreetDetector.CaminhoCompleto),
("path_ia_model_ervas", VersionamentoService.ArquivoModeloWeedDetector) ("path_ia_model_ervas", VersionamentoService.ArquivoModeloWeedDetector.CaminhoCompleto)
); );
} }

View File

@ -13,7 +13,6 @@ namespace AgroBase.Services.Operadores
{ {
public ManagerWorkerModel DadosLeitura = new ManagerWorkerModel(); public ManagerWorkerModel DadosLeitura = new ManagerWorkerModel();
public SaudeWorkerModel Saude { get; set; } = new SaudeWorkerModel(); public SaudeWorkerModel Saude { get; set; } = new SaudeWorkerModel();
public AsyncTaskTimerModel tmrPooling;
private bool DebugMode = true; private bool DebugMode = true;
@ -32,10 +31,6 @@ namespace AgroBase.Services.Operadores
DadosLeitura.IniciadoEm = DateTime.Now; DadosLeitura.IniciadoEm = DateTime.Now;
DadosLeitura.Iniciado = true; DadosLeitura.Iniciado = true;
tmrPooling?.Dispose();
tmrPooling = new AsyncTaskTimerModel("tmrManagerWorkerPooling", tmrPooling_Tick, 500);
tmrPooling.Start();
bool pronto() => DadosLeitura.Pronto; bool pronto() => DadosLeitura.Pronto;
await FuncoesGlobais.AguardarCondicaoAsync(pronto, 5000); await FuncoesGlobais.AguardarCondicaoAsync(pronto, 5000);
if (pronto()) if (pronto())
@ -49,36 +44,36 @@ namespace AgroBase.Services.Operadores
return false; return false;
} }
private async Task tmrPooling_Tick()
{
if (Variaveis.OperacaoEmAndamento.Modo == Enums.ModoOperacao.MapaGPS)
{
var dictParams = JsonConvert.DeserializeObject<Dictionary<string, object>>(RedisService.Get(CtxKey.DadosControle));
AtualizarControle(dictParams);
}
}
private void AtualizarControle(Dictionary<string, object> dictParams) private void AtualizarControle(Dictionary<string, object> dictParams)
{ {
if (dictParams == null) if (dictParams == null)
return; return;
dictParams.TryGetValue("angulo_sp", out object _angulo); ManagerWorkerMessageResponseComandoModel novoComando = null;
dictParams.TryGetValue("velocidade_sp", out object _velocidade);
dictParams.TryGetValue("tipo_movimento_direcional", out object _movimento);
dictParams.TryGetValue("simulacao", out object _simulacao);
var novoComando = new ManagerWorkerMessageResponseComandoModel() try
{ {
angulo = Convert.ToDouble(_angulo), dictParams.TryGetValue("angulo_sp", out object _angulo);
percentual_velocidade = Convert.ToDouble(_velocidade), dictParams.TryGetValue("velocidade_sp", out object _velocidade);
tipo_movimento = (Enums.TipoMovimentoDirecional)Convert.ToInt32(_movimento), dictParams.TryGetValue("tipo_movimento_direcional", out object _movimento);
simulacao = JsonConvert.DeserializeObject<List<double[]>>((_simulacao ?? "").ToString()) dictParams.TryGetValue("simulacao", out object _simulacao);
}; novoComando = new ManagerWorkerMessageResponseComandoModel()
{
angulo = Convert.ToDouble(_angulo),
percentual_velocidade = Convert.ToDouble(_velocidade),
tipo_movimento = (Enums.TipoMovimentoDirecional)Convert.ToInt32(_movimento),
simulacao = JsonConvert.DeserializeObject<List<double[]>>((_simulacao ?? "").ToString())
};
}
catch (Exception ex)
{
MostrarLog($"Erro ao receber novo comando: {ex.Message}");
}
if (novoComando != null) var _Controle = Variaveis.OperacaoEmAndamento.Controle;
bool comandoMudou = (_Controle.Angulo != novoComando.angulo || _Controle.PercentualVelocidadeSP != novoComando.percentual_velocidade || _Controle.TipoMovimento != novoComando.tipo_movimento);
if (novoComando != null && comandoMudou)
{ {
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
_Controle.Angulo = novoComando.angulo; _Controle.Angulo = novoComando.angulo;
_Controle.TipoMovimento = novoComando.tipo_movimento; _Controle.TipoMovimento = novoComando.tipo_movimento;
_Controle.PercentualVelocidadeSP = novoComando.percentual_velocidade; _Controle.PercentualVelocidadeSP = novoComando.percentual_velocidade;

View File

@ -92,11 +92,12 @@ namespace AgroBase.Services.Operadores
_Controle.Angulo = 0; _Controle.Angulo = 0;
_Controle.PercentualVelocidadeSP = 0; _Controle.PercentualVelocidadeSP = 0;
_Controle.BicosAtuados.ForEach(x => x.ComandoAtuar = false);
RedisService.AtualizarCampos( RedisService.AtualizarCampos(
CtxKey.DadosControle, CtxKey.DadosControle,
("angulo_sp", _Controle.Angulo), ("angulo_sp", _Controle.Angulo),
("velocidade_sp", _Controle.PercentualVelocidadeSP), ("velocidade_sp", _Controle.PercentualVelocidadeSP),
("controle_bicos", _Controle.BicosAtuados.ToDictionary(x => x.Posicao - 1, x => false)) ("controle_bicos", _Controle.BicosAtuados.ToDictionary(x => x.Posicao - 1, x => x.ComandoAtuar))
); );
Variaveis.OperacaoEmAndamento.AtualizaInformacoesControleOperacao(); Variaveis.OperacaoEmAndamento.AtualizaInformacoesControleOperacao();

View File

@ -13,7 +13,6 @@ namespace AgroBase.Services.Operadores
{ {
public static WeedWorkerModel DadosLeitura = new WeedWorkerModel(); public static WeedWorkerModel DadosLeitura = new WeedWorkerModel();
public SaudeWorkerModel Saude { get; set; } = new SaudeWorkerModel(); public SaudeWorkerModel Saude { get; set; } = new SaudeWorkerModel();
public AsyncTaskTimerModel tmrPooling;
private bool DebugMode = true; private bool DebugMode = true;
@ -32,10 +31,6 @@ namespace AgroBase.Services.Operadores
DadosLeitura.IniciadoEm = DateTime.Now; DadosLeitura.IniciadoEm = DateTime.Now;
DadosLeitura.Iniciado = true; DadosLeitura.Iniciado = true;
tmrPooling?.Dispose();
tmrPooling = new AsyncTaskTimerModel("tmrWeedWorkerPooling", tmrPooling_Tick, 500);
tmrPooling.Start();
bool pronto() => DadosLeitura.Pronto; bool pronto() => DadosLeitura.Pronto;
await FuncoesGlobais.AguardarCondicaoAsync(pronto, 5000); await FuncoesGlobais.AguardarCondicaoAsync(pronto, 5000);
if (pronto()) if (pronto())
@ -49,15 +44,6 @@ namespace AgroBase.Services.Operadores
return false; return false;
} }
private async Task tmrPooling_Tick()
{
if (Variaveis.OperacaoEmAndamento.Controle.PulverizadorAutomatico)
{
var dictParams = RedisService.GetField<Dictionary<string, object>>(CtxKey.DadosControle, "controle_bicos");
AtualizarControle(dictParams);
}
}
private void AtualizarControle(Dictionary<string, object> dictParams) private void AtualizarControle(Dictionary<string, object> dictParams)
{ {
if (dictParams == null) if (dictParams == null)
@ -72,13 +58,18 @@ namespace AgroBase.Services.Operadores
.Where(x => x.Key >= 0) .Where(x => x.Key >= 0)
.ToDictionary(x => x.Key, x => x.Value); .ToDictionary(x => x.Key, x => x.Value);
bool comandoMudou = false;
var _Controle = Variaveis.OperacaoEmAndamento.Controle; var _Controle = Variaveis.OperacaoEmAndamento.Controle;
foreach (var bico in _Controle.BicosAtuados) foreach (var bico in _Controle.BicosAtuados)
{ {
novoComando.TryGetValue(bico.Posicao, out bool atuado); novoComando.TryGetValue(bico.Posicao, out bool atuado);
if (!comandoMudou) comandoMudou = atuado != bico.ComandoAtuar;
bico.ComandoAtuar = atuado; bico.ComandoAtuar = atuado;
} }
Variaveis.OperacaoEmAndamento.AtualizaInformacoesControleOperacao(); if (comandoMudou)
{
Variaveis.OperacaoEmAndamento.AtualizaInformacoesControleOperacao();
}
} }
public void RedisCallback(string mensagem) public void RedisCallback(string mensagem)

View File

@ -20,7 +20,14 @@
"padded_top_topics_start_index": 0, "padded_top_topics_start_index": 0,
"taxonomy_version": 0, "taxonomy_version": 0,
"top_topics_and_observing_domains": [ ] "top_topics_and_observing_domains": [ ]
}, {
"calculation_time": "13397850728648898",
"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", "hex_encoded_hmac_key": "40F346D3248C3AFDF2BEE1FE496DBD32F7CED6E5AE98B881ABC421AA7E7B5642",
"next_scheduled_calculation_time": "13397830127958150" "next_scheduled_calculation_time": "13398455528649160"
} }

View File

@ -1,3 +1,3 @@
2025/07/23-16:19:21.420 63a0 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001 2025/07/25-15:32:54.048 6f60 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/07/23-16:19:21.426 63a0 Recovering log #3 2025/07/25-15:32:54.053 6f60 Recovering log #3
2025/07/23-16:19:21.430 63a0 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log 2025/07/25-15:32:54.057 6f60 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/07/23-15:20:21.774 65d4 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001 2025/07/25-14:39:16.989 1248 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/07/23-15:20:21.779 65d4 Recovering log #3 2025/07/25-14:39:16.995 1248 Recovering log #3
2025/07/23-15:20:21.782 65d4 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log 2025/07/25-14:39:16.998 1248 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":"13397858361948646","port":443,"protocol_str":"quic"}],"anonymization":["DAAAAAcAAABmaWxlOi8vAA==",false,0],"network_stats":{"srtt":63514},"server":"https://tile.openstreetmap.org","supports_spdy":true}],"supports_quic":{"address":"2804:d78:69b:cf00:29fa:804d:a396:9df2","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":"13398028379944064","port":443,"protocol_str":"quic"}],"anonymization":["DAAAAAcAAABmaWxlOi8vAA==",false,0],"network_stats":{"srtt":83767},"server":"https://tile.openstreetmap.org","supports_spdy":true}],"supports_quic":{"address":"2804:d78:609:f200:5cd:ea88:ba11:c468","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":1784831644.778334,"host":"bWGAftl61rqoc0YzqPncsLvQQh/iC2Bdp3ejUeGC83w=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1753295644.778338}],"version":2} {"sts":[{"expiry":1785004379.539092,"host":"bWGAftl61rqoc0YzqPncsLvQQh/iC2Bdp3ejUeGC83w=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1753468379.539105}],"version":2}

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,3 @@
2025/07/23-16:24:00.426 63a0 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001 2025/07/25-15:40:48.866 6f60 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/07/23-16:24:00.427 63a0 Recovering log #3 2025/07/25-15:40:48.867 6f60 Recovering log #3
2025/07/23-16:24:00.430 63a0 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log 2025/07/25-15:40:48.870 6f60 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/07/23-16:05:03.023 65d4 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001 2025/07/25-14:46:05.888 1248 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/07/23-16:05:03.024 65d4 Recovering log #3 2025/07/25-14:46:05.889 1248 Recovering log #3
2025/07/23-16:05:03.027 65d4 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log 2025/07/25-14:46:05.892 1248 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/07/23-16:19:21.344 66f4 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001 2025/07/25-15:32:53.968 7790 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/07/23-16:19:21.346 66f4 Recovering log #7 2025/07/25-15:32:53.970 7790 Recovering log #7
2025/07/23-16:19:21.346 66f4 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log 2025/07/25-15:32:53.970 7790 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log

View File

@ -1,3 +1,3 @@
2025/07/23-15:20:21.702 5b6c Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001 2025/07/25-14:39:16.915 5b28 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/07/23-15:20:21.704 5b6c Recovering log #7 2025/07/25-14:39:16.917 5b28 Recovering log #7
2025/07/23-15:20:21.704 5b6c Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log 2025/07/25-14:39:16.917 5b28 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -17,7 +17,7 @@
<meta name="viewport" content="width=device-width, <meta name="viewport" content="width=device-width,
initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<style> <style>
#map_6f8ca8c5dfe7b8b63d63e19da79d278d { #map_715f9e252e2f4bae22eab57e31529a20 {
position: relative; position: relative;
width: 100.0%; width: 100.0%;
height: 100.0%; height: 100.0%;
@ -54,14 +54,14 @@
<body> <body>
<div class="folium-map" id="map_6f8ca8c5dfe7b8b63d63e19da79d278d" ></div> <div class="folium-map" id="map_715f9e252e2f4bae22eab57e31529a20" ></div>
</body> </body>
<script> <script>
var map_6f8ca8c5dfe7b8b63d63e19da79d278d = L.map( var map_715f9e252e2f4bae22eab57e31529a20 = L.map(
"map_6f8ca8c5dfe7b8b63d63e19da79d278d", "map_715f9e252e2f4bae22eab57e31529a20",
{ {
center: [0.0, 0.0], center: [0.0, 0.0],
crs: L.CRS.EPSG3857, crs: L.CRS.EPSG3857,
@ -78,7 +78,7 @@
var tile_layer_6f380eff690083296f61e652991bf073 = L.tileLayer( var tile_layer_38a74eb4a2738f5f164472dd42724114 = L.tileLayer(
"https://tile.openstreetmap.org/{z}/{x}/{y}.png", "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
{ {
"minZoom": 0, "minZoom": 0,
@ -95,7 +95,7 @@
); );
tile_layer_6f380eff690083296f61e652991bf073.addTo(map_6f8ca8c5dfe7b8b63d63e19da79d278d); tile_layer_38a74eb4a2738f5f164472dd42724114.addTo(map_715f9e252e2f4bae22eab57e31529a20);
</script> </script>
@ -116,7 +116,7 @@
} }
trajeto_json_add({"features": []}); trajeto_json_add({"features": []});
trajeto_json.addTo(map_6f8ca8c5dfe7b8b63d63e19da79d278d); trajeto_json.addTo(map_715f9e252e2f4bae22eab57e31529a20);
function adicionarGeometria(novaGeometria) { function adicionarGeometria(novaGeometria) {
trajeto_json.addData(novaGeometria); trajeto_json.addData(novaGeometria);
@ -179,9 +179,9 @@
var marcadorEquipamento = L.marker([0, 0], { var marcadorEquipamento = L.marker([0, 0], {
icon: customIcon icon: customIcon
}).addTo(map_6f8ca8c5dfe7b8b63d63e19da79d278d); }).addTo(map_715f9e252e2f4bae22eab57e31529a20);
var marcadorBase = L.marker([0, 0], {}).addTo(map_6f8ca8c5dfe7b8b63d63e19da79d278d); var marcadorBase = L.marker([0, 0], {}).addTo(map_715f9e252e2f4bae22eab57e31529a20);
var icon = L.AwesomeMarkers.icon( var icon = L.AwesomeMarkers.icon(
{"extraClasses": "fa-rotate-0", "icon": "info-sign", "iconColor": "white", "markerColor": "red", "prefix": "glyphicon"} {"extraClasses": "fa-rotate-0", "icon": "info-sign", "iconColor": "white", "markerColor": "red", "prefix": "glyphicon"}
); );
@ -246,7 +246,7 @@
} }
if (foco) { if (foco) {
map_6f8ca8c5dfe7b8b63d63e19da79d278d.setView(novaPosicao, map_6f8ca8c5dfe7b8b63d63e19da79d278d.getZoom()); map_715f9e252e2f4bae22eab57e31529a20.setView(novaPosicao, map_715f9e252e2f4bae22eab57e31529a20.getZoom());
} }
} }
@ -268,7 +268,7 @@
marcadorDinamico.setRotationAngle(angulo); marcadorDinamico.setRotationAngle(angulo);
adicionarCoordenada("Tj", [novaLongitude, novaLatitude]); adicionarCoordenada("Tj", [novaLongitude, novaLatitude]);
map_6f8ca8c5dfe7b8b63d63e19da79d278d.setView(novaPosicao, map_6f8ca8c5dfe7b8b63d63e19da79d278d.getZoom());*/ map_715f9e252e2f4bae22eab57e31529a20.setView(novaPosicao, map_715f9e252e2f4bae22eab57e31529a20.getZoom());*/
}); });
function calcularOrientacao(P1latitude, P1longitude, P2latitude, P2longitude) { function calcularOrientacao(P1latitude, P1longitude, P2latitude, P2longitude) {

File diff suppressed because one or more lines are too long

View File

@ -119,7 +119,12 @@ with open(caminho_completo_html, 'r+') as arquivo_html:
<script src="folium/mqtt.min.js"></script> <script src="folium/mqtt.min.js"></script>
<script src="folium/leaflet.rotatedMarker.js"></script> <script src="folium/leaflet.rotatedMarker.js"></script>
<script> <script>
let posicaoAtual = {{ let posicaoAtualEquipamento = {{
lat: 0,
long: 0
}};
let posicaoAtualBase = {{
lat: 0, lat: 0,
long: 0 long: 0
}}; }};
@ -131,10 +136,16 @@ with open(caminho_completo_html, 'r+') as arquivo_html:
popupAnchor: [0, -16] popupAnchor: [0, -16]
}}); }});
var marcadorDinamico = L.marker([0, 0], {{ var marcadorEquipamento = L.marker([0, 0], {{
icon: customIcon icon: customIcon
}}).addTo({id_mapa}); }}).addTo({id_mapa});
var marcadorBase = L.marker([0, 0], {{}}).addTo({id_mapa});
var icon = L.AwesomeMarkers.icon(
{{"extraClasses": "fa-rotate-0", "icon": "info-sign", "iconColor": "white", "markerColor": "red", "prefix": "glyphicon"}}
);
marcadorBase.setIcon(icon);
// Conectar ao broker MQTT // Conectar ao broker MQTT
const client = mqtt.connect('ws://localhost:9001'); // Use wss para conexão segura const client = mqtt.connect('ws://localhost:9001'); // Use wss para conexão segura
@ -154,9 +165,54 @@ with open(caminho_completo_html, 'r+') as arquivo_html:
// Lidar com mensagens recebidas para o tópico inscrito // Lidar com mensagens recebidas para o tópico inscrito
client.on('message', function (topic, message) {{ client.on('message', function (topic, message) {{
var dados = JSON.parse(message);
if (topic === "{topico_gps}") {{
// A mensagem e um Buffer, converta para string ou objeto conforme necessario
//console.log(`Mensagem recebida no topico '${{topic}}': ${{message.toString()}}`);
var id = dados.id;
var novaLatitude = dados.latitude;
var novaLongitude = dados.longitude;
var novaPosicao = [novaLatitude, novaLongitude];
var orientacao = dados.orientacao;
var foco = dados.foco;
if (id == 1) {{
marcadorBase.setLatLng(novaPosicao);
// Calcular angulo de rotacao
var angulo = dados.orientacao;
posicaoAtualBase.lat = novaPosicao[0];
posicaoAtualBase.long = novaPosicao[1];
// Rotacionar o marcador para o angulo calculado
marcadorBase.setRotationAngle(angulo);
}}
else {{
marcadorEquipamento.setLatLng(novaPosicao);
// Calcular angulo de rotacao
var angulo = dados.orientacao;
posicaoAtualEquipamento.lat = novaPosicao[0];
posicaoAtualEquipamento.long = novaPosicao[1];
// Rotacionar o marcador para o angulo calculado
marcadorEquipamento.setRotationAngle(angulo);
adicionarCoordenada("Tj", [novaLongitude, novaLatitude]);
}}
if (foco) {{
{id_mapa}.setView(novaPosicao, {id_mapa}.getZoom());
}}
}}
// A mensagem é um Buffer, converta para string ou objeto conforme necessário // A mensagem é um Buffer, converta para string ou objeto conforme necessário
//console.log(`Mensagem recebida no tópico '${{topic}}': ${{message.toString()}}`); //console.log(`Mensagem recebida no tópico '${{topic}}': ${{message.toString()}}`);
var dados = JSON.parse(message); /*var dados = JSON.parse(message);
var novaLatitude = dados.latitude; var novaLatitude = dados.latitude;
var novaLongitude = dados.longitude; var novaLongitude = dados.longitude;
var novaPosicao = [novaLatitude, novaLongitude]; var novaPosicao = [novaLatitude, novaLongitude];
@ -171,7 +227,7 @@ with open(caminho_completo_html, 'r+') as arquivo_html:
marcadorDinamico.setRotationAngle(angulo); marcadorDinamico.setRotationAngle(angulo);
adicionarCoordenada("Tj", [novaLongitude, novaLatitude]); adicionarCoordenada("Tj", [novaLongitude, novaLatitude]);
{id_mapa}.setView(novaPosicao, {id_mapa}.getZoom()); {id_mapa}.setView(novaPosicao, {id_mapa}.getZoom());*/
}}); }});
function calcularOrientacao(P1latitude, P1longitude, P2latitude, P2longitude) {{ function calcularOrientacao(P1latitude, P1longitude, P2latitude, P2longitude) {{

View File

@ -43,8 +43,8 @@ def main():
mostrar_log(f"❌ Erro ao atualizar módulos: {e}") mostrar_log(f"❌ Erro ao atualizar módulos: {e}")
ultimo_saude_modulos = agora ultimo_saude_modulos = agora
# Atualizar STATUS DA OPERAÇÃO a cada 0.25s # Atualizar STATUS DA OPERAÇÃO a cada 0.1s
if (agora - ultimo_status_operacao) >= 0.25: if (agora - ultimo_status_operacao) >= 0.1:
ContextoGlobalRedis.atualizar_dados_operacao() ContextoGlobalRedis.atualizar_dados_operacao()
ultimo_status_operacao = agora ultimo_status_operacao = agora

View File

@ -12,13 +12,6 @@ class ProcessadorEmAndamento(ProcessadorBase):
if modo == ModoOperacao.MapaGPS: if modo == ModoOperacao.MapaGPS:
angulo_sp, tipo_dir, simulacao, parada_necessaria = definir_comando_dir() angulo_sp, tipo_dir, simulacao, parada_necessaria = definir_comando_dir()
velocidade_sp = definir_comando_mov(parada_necessaria) velocidade_sp = definir_comando_mov(parada_necessaria)
ContextoGlobalRedis.atualizar_ctx_dict(
CtxKey.DadosControle,
angulo_sp=angulo_sp,
tipo_movimento_direcional=tipo_dir,
velocidade_sp=velocidade_sp,
simulacao=simulacao
)
return comando_controle(percentual_velocidade=velocidade_sp, angulo=angulo_sp, tipo_movimento=tipo_dir, simulacao=simulacao) return comando_controle(percentual_velocidade=velocidade_sp, angulo=angulo_sp, tipo_movimento=tipo_dir, simulacao=simulacao)
return None return None
except Exception as e: except Exception as e:

View File

@ -1,9 +1,16 @@
from shared.enums import T_Code, TipoMovimentoDirecional from shared.enums import T_Code, TipoMovimentoDirecional
from shared.enums import ModoOperacao, StatusOperacao from shared.enums import ModoOperacao, StatusOperacao
from manager_worker.config import mostrar_log from manager_worker.config import mostrar_log
from shared.contexto_global_redis import ContextoGlobalRedis from shared.contexto_global_redis import ContextoGlobalRedis, CtxKey
def comando_controle(percentual_velocidade: float, angulo: float, tipo_movimento: int, simulacao = []): def comando_controle(percentual_velocidade: float, angulo: float, tipo_movimento: int, simulacao = []):
ContextoGlobalRedis.atualizar_ctx_dict(
CtxKey.DadosControle,
angulo_sp=angulo,
tipo_movimento_direcional=tipo_movimento,
velocidade_sp=percentual_velocidade,
simulacao=simulacao
)
return { return {
"velocidade_sp": percentual_velocidade, "velocidade_sp": percentual_velocidade,
"angulo_sp": angulo, "angulo_sp": angulo,

View File

@ -5,7 +5,7 @@ import redis
import json import json
from enum import Enum from enum import Enum
from shared.enums import ManagerWorkerCommandType, ModoOperacao, StatusModulo, StatusOperacao, T_Code, TiposControladorDirecional from shared.enums import ManagerWorkerCommandType, ModoOperacao, StatusModulo, StatusOperacao, T_Code, TiposControladorDirecional, WeedWorkerCommandType
class CtxKey(str, Enum): class CtxKey(str, Enum):
DadosCameras = "ctx:dados_cameras" DadosCameras = "ctx:dados_cameras"
@ -346,6 +346,7 @@ class ContextoGlobalRedis:
@classmethod @classmethod
def _iniciar_operacao(cls): def _iniciar_operacao(cls):
cls.publicar_comando(CmdKey.WeedWorkerRx, { "cmd": WeedWorkerCommandType.ReiniciarDeteccoes.value })
cls._atualizar_mpc() cls._atualizar_mpc()
cls.atualizar_ctx_dict( cls.atualizar_ctx_dict(
CtxKey.DadosOperacao, CtxKey.DadosOperacao,

View File

@ -30,6 +30,7 @@ class WeedWorkerCommandType(IntEnum):
GetCameraFrame = 4 GetCameraFrame = 4
SaveCameraFrames = 5 SaveCameraFrames = 5
EnviarDadosControle = 6 EnviarDadosControle = 6
ReiniciarDeteccoes = 7
class ModoOperacao(IntEnum): class ModoOperacao(IntEnum):
NaoDefinido = 0 NaoDefinido = 0

View File

@ -141,13 +141,13 @@ class CameraManager:
atuacao_bicos = {i: False for i in analise.get("controle", {}).keys()} atuacao_bicos = {i: False for i in analise.get("controle", {}).keys()}
analise["controle"] = atuacao_bicos analise["controle"] = atuacao_bicos
ContextoGlobalRedis.atualizar_ctx_dict(
CtxKey.DadosControle,
controle_bicos=atuacao_bicos
)
if pulverizador_automatico: if pulverizador_automatico:
ContextoGlobalRedis.atualizar_ctx_dict( ContextoGlobalRedis.publicar_comando(CmdKey.WeedWorkerTx, { "cmd": WeedWorkerCommandType.EnviarDadosControle.value, "params": atuacao_bicos })
CtxKey.DadosControle,
controle_bicos=atuacao_bicos
)
if self._ultima_analise.get("controle") != atuacao_bicos:
ContextoGlobalRedis.publicar_comando(CmdKey.WeedWorkerTx, { "cmd": WeedWorkerCommandType.EnviarDadosControle.value, "params": atuacao_bicos })
self._ultima_analise = analise.copy() self._ultima_analise = analise.copy()

View File

@ -60,6 +60,9 @@ def main():
pasta = dados.get("params", {}).get("caminho", "frames_salvos") pasta = dados.get("params", {}).get("caminho", "frames_salvos")
tipos = dados.get("params", {}).get("tipos", []) tipos = dados.get("params", {}).get("tipos", [])
get_camera_manager().salvar_frames(tipos, nome, pasta) get_camera_manager().salvar_frames(tipos, nome, pasta)
elif acao == WeedWorkerCommandType.ReiniciarDeteccoes:
if get_camera_manager().weed_detector is not None:
get_camera_manager().weed_detector.reiniciar_deteccoes()
else: else:
mostrar_log(f"⚠️ Comando desconhecido: {acao.name}") mostrar_log(f"⚠️ Comando desconhecido: {acao.name}")
except Exception as e: except Exception as e:

View File

@ -6,7 +6,7 @@ from models.experimental import attempt_load
from utils.general import non_max_suppression, scale_coords, check_img_size from utils.general import non_max_suppression, scale_coords, check_img_size
from utils.torch_utils import select_device from utils.torch_utils import select_device
from utils.datasets import letterbox from utils.datasets import letterbox
from shared.contexto_global_redis import ContextoGlobalRedis from shared.contexto_global_redis import ContextoGlobalRedis, CtxKey
class WeedDetector: class WeedDetector:
def __init__(self, weights_path, img_size=512, conf_thres=0.25, iou_thres=0.45, device=''): def __init__(self, weights_path, img_size=512, conf_thres=0.25, iou_thres=0.45, device=''):
@ -20,12 +20,19 @@ class WeedDetector:
self.imgsz = check_img_size(img_size, s=self.stride) self.imgsz = check_img_size(img_size, s=self.stride)
self.conf_thres = conf_thres self.conf_thres = conf_thres
self.iou_thres = iou_thres self.iou_thres = iou_thres
self.reiniciar_deteccoes()
def reiniciar_deteccoes(self):
self.ervas_ativas = [] self.ervas_ativas = []
self.next_erva_id = 1 self.next_erva_id = 1
self.frame_idx = 0 self.frame_idx = 0
self.ervas_identificadas = [dict() for _ in range(4)] self.ervas_identificadas = [dict() for _ in range(4)]
self.ultimo_status_bicos = {i: False for i in range(4)} self.ultimo_status_bicos = {i: False for i in range(4)}
self.ervas_registradas_bico = [set() for _ in range(4)] self.ervas_registradas_bico = [set() for _ in range(4)]
ContextoGlobalRedis.atualizar_ctx_dict(
CtxKey.DadosWeedWorker,
analise__ervas_identificadas=self.ervas_identificadas
)
def detectar(self, frame_bgr): def detectar(self, frame_bgr):
try: try:

View File

@ -3,7 +3,7 @@
#include "Utils.h" #include "Utils.h"
#include "IComponenteCAN.h" #include "IComponenteCAN.h"
#include "SensorPressaoModel.h" #include "SensorPressaoModel.h"
#include <PID_v1.h> //#include <PID_v1.h>
#ifndef BombaPressurizadoraModel #ifndef BombaPressurizadoraModel
#define BombaPressurizadoraModel #define BombaPressurizadoraModel
@ -31,7 +31,7 @@ class BombaPressurizadora : public ComponenteCAN {
float _Kd = 0.5; float _Kd = 0.5;
const int histerese = 3; const int histerese = 3;
bool bombaDesligadaPorPressao = false; bool bombaDesligadaPorPressao = false;
PID* _PID = nullptr; //PID* _PID = nullptr;
SensorPressao* sensorPressao; SensorPressao* sensorPressao;
@ -79,9 +79,9 @@ class BombaPressurizadora : public ComponenteCAN {
AtualizarLeitura(); AtualizarLeitura();
if (Iniciado) { if (Iniciado) {
_PID = new PID(&sensorPressao->Pressao, &PotenciaLeitura, &_PressaoSP, _Kp, _Ki, _Kd, DIRECT); //_PID = new PID(&sensorPressao->Pressao, &PotenciaLeitura, &_PressaoSP, _Kp, _Ki, _Kd, DIRECT);
_PID->SetOutputLimits(ZeroRampa, RampaMax); //_PID->SetOutputLimits(ZeroRampa, RampaMax);
_PID->SetMode(AUTOMATIC); //_PID->SetMode(AUTOMATIC);
PrintTela(_ID + " iniciado"); PrintTela(_ID + " iniciado");
} }
@ -96,8 +96,8 @@ class BombaPressurizadora : public ComponenteCAN {
return; return;
} }
delete _PID; //delete _PID;
_PID = nullptr; //_PID = nullptr;
//delete sensorPressao; //delete sensorPressao;
sensorPressao = nullptr; sensorPressao = nullptr;
@ -139,7 +139,8 @@ class BombaPressurizadora : public ComponenteCAN {
if (_EstadoControle == Desligado || bombaDesligadaPorPressao) { if (_EstadoControle == Desligado || bombaDesligadaPorPressao) {
PotenciaLeitura = ZeroRampa; PotenciaLeitura = ZeroRampa;
} else { } else {
_PID->Compute(); PotenciaLeitura = RampaMax;
//_PID->Compute();
// Ajusta PotenciaAtual com base no PID // Ajusta PotenciaAtual com base no PID
} }