Ajustes no IMU, regras taticas, joystick e controle da base
This commit is contained in:
parent
d898b493ce
commit
ecf4b571bf
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using static AgroBase.Models.Enums;
|
using static AgroBase.Models.Enums;
|
||||||
|
|
||||||
|
|
@ -25,14 +26,14 @@ namespace AgroBase.Forms
|
||||||
|
|
||||||
private void frmJoystick_KeyDown(object sender, KeyEventArgs e)
|
private void frmJoystick_KeyDown(object sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
T_Code disp = GeneralJoystick.GetDispositivoComando(e.KeyCode);
|
var comando = GeneralJoystick.DeParaComandos.FirstOrDefault(x => x.key == e.KeyCode);
|
||||||
GeneralJoystick.EnviaComandoMotor(e.KeyCode, disp);
|
GeneralJoystick.EnviaComandoMotor(comando?.key ?? e.KeyCode, comando?.Dispositivo ?? T_Code.Vzo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void frmJoystick_KeyUp(object sender, KeyEventArgs e)
|
private void frmJoystick_KeyUp(object sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
T_Code disp = GeneralJoystick.GetDispositivoComando(e.KeyCode);
|
var comando = GeneralJoystick.DeParaComandos.FirstOrDefault(x => x.key == e.KeyCode);
|
||||||
GeneralJoystick.EnviaComandoMotor(Keys.Escape, disp);
|
GeneralJoystick.EnviaComandoMotor(comando?.key ?? Keys.Escape, comando?.Dispositivo ?? T_Code.Vzo);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -523,7 +523,7 @@ namespace AgroBase
|
||||||
var Comando = DeParaComandos.FirstOrDefault(x => x.botaoJoy == botao.botao);
|
var Comando = DeParaComandos.FirstOrDefault(x => x.botaoJoy == botao.botao);
|
||||||
if (Comando != null)
|
if (Comando != null)
|
||||||
{
|
{
|
||||||
EnviaComandoMotor(Comando.key, Comando.Dispositivo, ID: Comando.IDcontrolar);
|
EnviaComandoMotor(Comando.key, Comando.Dispositivo, ID: Comando.IDcontrolar, botao: botao.botao);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
_botoesSoltos.ForEach(botao =>
|
_botoesSoltos.ForEach(botao =>
|
||||||
|
|
@ -534,7 +534,7 @@ namespace AgroBase
|
||||||
var Comando = DeParaComandos.FirstOrDefault(x => x.botaoJoy == botao);
|
var Comando = DeParaComandos.FirstOrDefault(x => x.botaoJoy == botao);
|
||||||
if (Comando != null && Comando.PararAoSoltar)
|
if (Comando != null && Comando.PararAoSoltar)
|
||||||
{
|
{
|
||||||
EnviaComandoMotor(Keys.Escape, Comando.Dispositivo, ID: Comando.IDcontrolar);
|
EnviaComandoMotor(Keys.Escape, Comando.Dispositivo, ID: Comando.IDcontrolar, botao: botao, ForcarComando: true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -547,6 +547,7 @@ namespace AgroBase
|
||||||
double centro = 32767;
|
double centro = 32767;
|
||||||
double deadzone = 3000;
|
double deadzone = 3000;
|
||||||
double maximo = 65535.0;
|
double maximo = 65535.0;
|
||||||
|
var pControle = Variaveis.OperacaoEmAndamento.Parametros.Controle;
|
||||||
|
|
||||||
switch (botao)
|
switch (botao)
|
||||||
{
|
{
|
||||||
|
|
@ -609,13 +610,13 @@ namespace AgroBase
|
||||||
case BotoesJoystick.Xis:
|
case BotoesJoystick.Xis:
|
||||||
direcao = Direcao.Frente;
|
direcao = Direcao.Frente;
|
||||||
dispositivo = T_Code.Mov;
|
dispositivo = T_Code.Mov;
|
||||||
percent = 1.0;
|
percent = Math.Max(pControle.MovVelocidadeCErvasPercent, (pControle.MovVelocidadeSErvasPercent - pControle.MovVelocidadeCErvasPercent) / 2.0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BotoesJoystick.Quadrado:
|
case BotoesJoystick.Quadrado:
|
||||||
direcao = Direcao.Tras;
|
direcao = Direcao.Tras;
|
||||||
dispositivo = T_Code.Mov;
|
dispositivo = T_Code.Mov;
|
||||||
percent = 1.0;
|
percent = Math.Max(pControle.MovVelocidadeCErvasPercent, (pControle.MovVelocidadeSErvasPercent - pControle.MovVelocidadeCErvasPercent) / 2.0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -624,7 +625,6 @@ namespace AgroBase
|
||||||
|
|
||||||
//Console.WriteLine($"botao: {botao}, valor: {valor}, percentual: {percent * 100.0:F2}%");
|
//Console.WriteLine($"botao: {botao}, valor: {valor}, percentual: {percent * 100.0:F2}%");
|
||||||
|
|
||||||
var pControle = Variaveis.OperacaoEmAndamento.Parametros.Controle;
|
|
||||||
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
||||||
_Controle.Direcao = direcao;
|
_Controle.Direcao = direcao;
|
||||||
int mx = direcao == Direcao.Esquerda || direcao == Direcao.Tras ? -1 : 1;
|
int mx = direcao == Direcao.Esquerda || direcao == Direcao.Tras ? -1 : 1;
|
||||||
|
|
@ -639,7 +639,7 @@ namespace AgroBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void EnviaComandoMotor(Keys Tecla, T_Code Disp = T_Code.Vzo, string ID = null, bool ForcarComando = false)
|
public static void EnviaComandoMotor(Keys Tecla, T_Code Disp = T_Code.Vzo, string ID = null, BotoesJoystick botao = BotoesJoystick.Vazio, bool ForcarComando = false)
|
||||||
{
|
{
|
||||||
// Verifica se deve interromper o fluxo
|
// Verifica se deve interromper o fluxo
|
||||||
// interrompe se nao estiver diagnosticando, nao forca o envio, e se o modo for manual vai verificar o status da operacao e do sonar, pois automatico faz esse controle em outro lugar
|
// interrompe se nao estiver diagnosticando, nao forca o envio, e se o modo for manual vai verificar o status da operacao e do sonar, pois automatico faz esse controle em outro lugar
|
||||||
|
|
@ -668,7 +668,8 @@ namespace AgroBase
|
||||||
|
|
||||||
Direcao DirecaoAtual = Direcao.Parado;
|
Direcao DirecaoAtual = Direcao.Parado;
|
||||||
|
|
||||||
var Controle = Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == Comando.Dispositivo);
|
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
||||||
|
var tipoControle = _Controle?.TiposControle?.FirstOrDefault(x => x?.Tipo == Comando.Dispositivo);
|
||||||
|
|
||||||
// Cancelar Comando Anterior
|
// Cancelar Comando Anterior
|
||||||
if (Comando.Comando == Keys.Escape)
|
if (Comando.Comando == Keys.Escape)
|
||||||
|
|
@ -688,6 +689,14 @@ namespace AgroBase
|
||||||
Comando.IDcontrolar = !string.IsNullOrEmpty(ID) ? ID : ComandosDisp[ComandosDisp.Count - 1].IDcontrolar;
|
Comando.IDcontrolar = !string.IsNullOrEmpty(ID) ? ID : ComandosDisp[ComandosDisp.Count - 1].IDcontrolar;
|
||||||
}
|
}
|
||||||
DirecaoAtual = Direcao.Parado;
|
DirecaoAtual = Direcao.Parado;
|
||||||
|
|
||||||
|
switch (botao)
|
||||||
|
{
|
||||||
|
case BotoesJoystick.Bolinha:
|
||||||
|
_Controle.EmFreio = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
Pressionado = true;
|
Pressionado = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -695,17 +704,15 @@ namespace AgroBase
|
||||||
else if (Comando.Comando == Keys.Add)
|
else if (Comando.Comando == Keys.Add)
|
||||||
{
|
{
|
||||||
Comando.Dispositivo = T_Code.Mov;
|
Comando.Dispositivo = T_Code.Mov;
|
||||||
Controle = Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == Comando.Dispositivo);
|
DirecaoAtual = tipoControle?.UltimaDirecao ?? Direcao.Parado;
|
||||||
DirecaoAtual = Controle?.UltimaDirecao ?? Direcao.Parado;
|
_Controle.PercentualVelocidadeSP++;
|
||||||
Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP++;
|
|
||||||
Pressionado = true;
|
Pressionado = true;
|
||||||
}
|
}
|
||||||
else if (Comando.Comando == Keys.Subtract)
|
else if (Comando.Comando == Keys.Subtract)
|
||||||
{
|
{
|
||||||
Comando.Dispositivo = T_Code.Mov;
|
Comando.Dispositivo = T_Code.Mov;
|
||||||
Controle = Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == Comando.Dispositivo);
|
DirecaoAtual = tipoControle?.UltimaDirecao ?? Direcao.Parado;
|
||||||
DirecaoAtual = Controle?.UltimaDirecao ?? Direcao.Parado;
|
_Controle.PercentualVelocidadeSP--;
|
||||||
Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP--;
|
|
||||||
Pressionado = true;
|
Pressionado = true;
|
||||||
}
|
}
|
||||||
// Controle Direcao dos Motores BLDC (MOV)
|
// Controle Direcao dos Motores BLDC (MOV)
|
||||||
|
|
@ -725,6 +732,7 @@ namespace AgroBase
|
||||||
{
|
{
|
||||||
Comando.Dispositivo = T_Code.Mov;
|
Comando.Dispositivo = T_Code.Mov;
|
||||||
DirecaoAtual = Direcao.EmFreio;
|
DirecaoAtual = Direcao.EmFreio;
|
||||||
|
_Controle.EmFreio = true;
|
||||||
Pressionado = true;
|
Pressionado = true;
|
||||||
}
|
}
|
||||||
// Controle de Rotação dos Motores de Passo (DIR)
|
// Controle de Rotação dos Motores de Passo (DIR)
|
||||||
|
|
@ -788,7 +796,7 @@ namespace AgroBase
|
||||||
case T_Code.Mov:
|
case T_Code.Mov:
|
||||||
{
|
{
|
||||||
//Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.ForEach(x => x.MovMotor.EnviarComandoControle(DirecaoAtual));
|
//Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.ForEach(x => x.MovMotor.EnviarComandoControle(DirecaoAtual));
|
||||||
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(false, new List<T_Code>() { Comando.Dispositivo });
|
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(ForcarComando, new List<T_Code>() { Comando.Dispositivo });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case T_Code.Dir:
|
case T_Code.Dir:
|
||||||
|
|
@ -806,7 +814,7 @@ namespace AgroBase
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(false, new List<T_Code>() { Comando.Dispositivo });
|
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(ForcarComando, new List<T_Code>() { Comando.Dispositivo });
|
||||||
//foreach (var mod in Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos)
|
//foreach (var mod in Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos)
|
||||||
//{
|
//{
|
||||||
// if (modsControlar == null || modsControlar.Contains(mod.DirMotor.Mod_ID))
|
// if (modsControlar == null || modsControlar.Contains(mod.DirMotor.Mod_ID))
|
||||||
|
|
@ -830,12 +838,11 @@ namespace AgroBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Controle = Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == Comando.Dispositivo);
|
//Controle = Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == Comando.Dispositivo);
|
||||||
|
//if (Controle != null)
|
||||||
if (Controle != null)
|
//{
|
||||||
{
|
// Controle.UltimaDirecao = DirecaoAtual;
|
||||||
Controle.UltimaDirecao = DirecaoAtual;
|
//}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UltimaDirecao = DirecaoAtual;
|
UltimaDirecao = DirecaoAtual;
|
||||||
|
|
@ -978,7 +985,6 @@ namespace AgroBase
|
||||||
{
|
{
|
||||||
List<Keys> ComandosImpedidos = new List<Keys>();
|
List<Keys> ComandosImpedidos = new List<Keys>();
|
||||||
var Sonar = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorVisual;
|
var Sonar = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorVisual;
|
||||||
Sonar?.Resumo?.AtualizarStatusBloqueio(false);
|
|
||||||
var DeveParar = Sonar?.Resumo?.DeveParar ?? false;
|
var DeveParar = Sonar?.Resumo?.DeveParar ?? false;
|
||||||
if (DeveParar)
|
if (DeveParar)
|
||||||
{
|
{
|
||||||
|
|
@ -1020,11 +1026,6 @@ namespace AgroBase
|
||||||
return !ComandosImpedidos.Any(x => x == Comando);
|
return !ComandosImpedidos.Any(x => x == Comando);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T_Code GetDispositivoComando(Keys Tecla, BotoesJoystick botao = BotoesJoystick.Vazio)
|
|
||||||
{
|
|
||||||
T_Code disp = DeParaComandos.FirstOrDefault(x => x.key == Tecla || x.botaoJoy == botao)?.Dispositivo ?? T_Code.Vzo;
|
|
||||||
return disp;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1334,7 +1334,7 @@ namespace AgroBase.Models
|
||||||
|
|
||||||
public List<string> EnviarProtocoloComando(T_Code Tipo, bool ForcarEnvio)
|
public List<string> EnviarProtocoloComando(T_Code Tipo, bool ForcarEnvio)
|
||||||
{
|
{
|
||||||
if (!Variaveis.OperacaoEmAndamento.Iniciado)
|
if (!Variaveis.OperacaoEmAndamento.Iniciado && !ForcarEnvio)
|
||||||
{
|
{
|
||||||
return new List<string>();
|
return new List<string>();
|
||||||
}
|
}
|
||||||
|
|
@ -1488,11 +1488,11 @@ namespace AgroBase.Models
|
||||||
Sonar?.Resumo?.AtualizarStatusBloqueio(true);
|
Sonar?.Resumo?.AtualizarStatusBloqueio(true);
|
||||||
if (Sonar?.Resumo?.EnviarComandoParada ?? false)
|
if (Sonar?.Resumo?.EnviarComandoParada ?? false)
|
||||||
{
|
{
|
||||||
GeneralJoystick.EnviaComandoMotor(Keys.Space, T_Code.Mov);
|
GeneralJoystick.EnviaComandoMotor(Keys.Escape, Disp: T_Code.Mov, ForcarComando: true);
|
||||||
}
|
}
|
||||||
else if (Sonar?.Resumo?.EnviarComandoRetomada ?? false)
|
else if (Sonar?.Resumo?.EnviarComandoRetomada ?? false)
|
||||||
{
|
{
|
||||||
GeneralJoystick.EnviaComandoMotor(Keys.Escape, T_Code.Mov);
|
//GeneralJoystick.EnviaComandoMotor(Keys.Escape, T_Code.Mov);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Variaveis.OperacaoEmAndamento.OperacaoLiberada)
|
if (!Variaveis.OperacaoEmAndamento.OperacaoLiberada)
|
||||||
|
|
@ -1501,12 +1501,12 @@ namespace AgroBase.Models
|
||||||
if ((_Controle.TiposControle?.FirstOrDefault(x => x?.Tipo == T_Code.Mov)?.UltimaDirecao ?? Direcao.Parado) != Direcao.Parado)
|
if ((_Controle.TiposControle?.FirstOrDefault(x => x?.Tipo == T_Code.Mov)?.UltimaDirecao ?? Direcao.Parado) != Direcao.Parado)
|
||||||
{
|
{
|
||||||
_Controle.PercentualVelocidadeSP = 0;
|
_Controle.PercentualVelocidadeSP = 0;
|
||||||
GeneralJoystick.EnviaComandoMotor(Keys.Escape, T_Code.Mov, ForcarComando: true);
|
GeneralJoystick.EnviaComandoMotor(Keys.Escape, Disp: T_Code.Mov, ForcarComando: true);
|
||||||
}
|
}
|
||||||
if ((_Controle.TiposControle?.FirstOrDefault(x => x?.Tipo == T_Code.Dir)?.UltimaDirecao ?? Direcao.Parado) != Direcao.Parado)
|
if ((_Controle.TiposControle?.FirstOrDefault(x => x?.Tipo == T_Code.Dir)?.UltimaDirecao ?? Direcao.Parado) != Direcao.Parado)
|
||||||
{
|
{
|
||||||
_Controle.Angulo = 0;
|
_Controle.Angulo = 0;
|
||||||
GeneralJoystick.EnviaComandoMotor(Keys.Escape, T_Code.Dir, ForcarComando: true);
|
GeneralJoystick.EnviaComandoMotor(Keys.Escape, Disp: T_Code.Dir, ForcarComando: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1719,8 +1719,9 @@ namespace AgroBase.Models
|
||||||
if (cmdRover?.Dispositivo == T_Code.Dir && Variaveis.OperacaoEmAndamento.Parametros.Controle.DirecionalAutomatico && Variaveis.OperacaoEmAndamento.Iniciado) return;
|
if (cmdRover?.Dispositivo == T_Code.Dir && Variaveis.OperacaoEmAndamento.Parametros.Controle.DirecionalAutomatico && Variaveis.OperacaoEmAndamento.Iniciado) return;
|
||||||
|
|
||||||
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
||||||
if (controleBase.Controle.PercentualVelocidadeSP != null) _Controle.PercentualVelocidadeSP = (double)controleBase.Controle.PercentualVelocidadeSP;
|
int mx = cmdRover.key == Keys.Escape || cmdRover.key == Keys.Down ? -1 : 1;
|
||||||
if (controleBase.Controle.AnguloSP != null) _Controle.Angulo = (double)controleBase.Controle.AnguloSP;
|
if (controleBase.Controle.PercentualVelocidadeSP != null) _Controle.PercentualVelocidadeSP = (double)controleBase.Controle.PercentualVelocidadeSP * mx;
|
||||||
|
if (controleBase.Controle.AnguloSP != null) _Controle.Angulo = (double)controleBase.Controle.AnguloSP * mx;
|
||||||
if (controleBase.Controle.TipoMovimentoDirecional != null) _Controle.TipoMovimento = (TipoMovimentoDirecional)controleBase.Controle.TipoMovimentoDirecional;
|
if (controleBase.Controle.TipoMovimentoDirecional != null) _Controle.TipoMovimento = (TipoMovimentoDirecional)controleBase.Controle.TipoMovimentoDirecional;
|
||||||
if (controleBase.Controle.EmFreio != null) _Controle.EmFreio = (bool)controleBase.Controle.EmFreio;
|
if (controleBase.Controle.EmFreio != null) _Controle.EmFreio = (bool)controleBase.Controle.EmFreio;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -284,12 +284,12 @@ namespace AgroBase.Models
|
||||||
{
|
{
|
||||||
if (disp == T_Code.Dir)
|
if (disp == T_Code.Dir)
|
||||||
{
|
{
|
||||||
controle.Controle.AnguloSP = msg.P1 / 100.0;
|
controle.Controle.AnguloSP = (msg.P1 / 100.0);
|
||||||
controle.Controle.TipoMovimentoDirecional = (TipoMovimentoDirecional)(byte)msg.P2;
|
controle.Controle.TipoMovimentoDirecional = (TipoMovimentoDirecional)(byte)msg.P2;
|
||||||
}
|
}
|
||||||
else if (disp == T_Code.Mov)
|
else if (disp == T_Code.Mov)
|
||||||
{
|
{
|
||||||
controle.Controle.PercentualVelocidadeSP = msg.P1 / 100.0;
|
controle.Controle.PercentualVelocidadeSP = (msg.P1 / 100.0);
|
||||||
controle.Controle.EmFreio = msg.P2 == 1;
|
controle.Controle.EmFreio = msg.P2 == 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,11 @@ class IMUCamera(ModuloDiagnosticoBase):
|
||||||
def __init__(self, queue=None, freq=100, angulo_inicial=26.3):
|
def __init__(self, queue=None, freq=100, angulo_inicial=26.3):
|
||||||
self.freq = freq
|
self.freq = freq
|
||||||
|
|
||||||
|
self.ativo = False
|
||||||
|
self.last_packet_ts = 0.0
|
||||||
|
self.last_publish_ts = 0.0
|
||||||
|
self.ultimo_erro_ts = 0.0
|
||||||
|
|
||||||
if queue is None:
|
if queue is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -56,8 +61,8 @@ class IMUCamera(ModuloDiagnosticoBase):
|
||||||
self.rugosidade_idx = 0.0
|
self.rugosidade_idx = 0.0
|
||||||
self.impacto_idx = 0.0
|
self.impacto_idx = 0.0
|
||||||
self.estabilidade_idx = 100.0
|
self.estabilidade_idx = 100.0
|
||||||
self.last_redis_ts = 0.0
|
|
||||||
self.redis_period = 0.10 # 100 ms
|
self.redis_period = 0.10 # 100 ms
|
||||||
|
self.last_redis_ts = 0.0
|
||||||
|
|
||||||
self.ativo = True
|
self.ativo = True
|
||||||
self.imu_thread = threading.Thread(target=self.imu_task_loop, daemon=True)
|
self.imu_thread = threading.Thread(target=self.imu_task_loop, daemon=True)
|
||||||
|
|
@ -189,6 +194,7 @@ class IMUCamera(ModuloDiagnosticoBase):
|
||||||
self.imu_em_falha = False
|
self.imu_em_falha = False
|
||||||
|
|
||||||
if imuData is not None and len(imuData.packets) > 0:
|
if imuData is not None and len(imuData.packets) > 0:
|
||||||
|
self.last_packet_ts = time.time()
|
||||||
now = time.perf_counter()
|
now = time.perf_counter()
|
||||||
if self.last_loop_ts is None:
|
if self.last_loop_ts is None:
|
||||||
dt_total = 1.0 / self.freq
|
dt_total = 1.0 / self.freq
|
||||||
|
|
@ -297,6 +303,7 @@ class IMUCamera(ModuloDiagnosticoBase):
|
||||||
|
|
||||||
t_pub = time.perf_counter()
|
t_pub = time.perf_counter()
|
||||||
if (t_pub - self.last_redis_ts) >= self.redis_period:
|
if (t_pub - self.last_redis_ts) >= self.redis_period:
|
||||||
|
self.last_publish_ts = time.time()
|
||||||
self.last_redis_ts = t_pub
|
self.last_redis_ts = t_pub
|
||||||
|
|
||||||
ContextoGlobalRedis.atualizar_ctx_dict(
|
ContextoGlobalRedis.atualizar_ctx_dict(
|
||||||
|
|
@ -318,6 +325,7 @@ class IMUCamera(ModuloDiagnosticoBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
self.ultimo_erro_ts = time.time()
|
||||||
self.mostrar_log(f"Erro no loop: {e}")
|
self.mostrar_log(f"Erro no loop: {e}")
|
||||||
if not self.imu_em_falha:
|
if not self.imu_em_falha:
|
||||||
self.imu_em_falha = True
|
self.imu_em_falha = True
|
||||||
|
|
@ -334,43 +342,110 @@ class IMUCamera(ModuloDiagnosticoBase):
|
||||||
|
|
||||||
def atualizar_saude(self):
|
def atualizar_saude(self):
|
||||||
try:
|
try:
|
||||||
modulo = ContextoGlobalRedis.get_modulo(T_Code.Imu)
|
agora = time.time()
|
||||||
|
modulo = ContextoGlobalRedis.get_modulo(T_Code.Imu) or {}
|
||||||
|
|
||||||
FREQ_BASE = self.freq
|
FREQ_BASE = self.freq
|
||||||
FREQ_MIN = FREQ_BASE * 0.5
|
FREQ_MIN = FREQ_BASE * 0.5
|
||||||
SAUDE_MIN_ALERTA = 80
|
SAUDE_MIN_ALERTA = 80
|
||||||
|
SAUDE_MIN_FALHA = 45
|
||||||
|
|
||||||
conectado = (time.time() * 1000) - modulo.get("timestamp", 0) < 2000
|
conectado = bool(
|
||||||
freq_hz = modulo.get("frequencia", 0.0)
|
self.ativo and
|
||||||
latencia = modulo.get("latencia", 0.0)
|
self.imu_thread is not None and
|
||||||
|
self.imu_thread.is_alive()
|
||||||
|
)
|
||||||
|
|
||||||
|
freq_hz = float(modulo.get("frequencia", 0.0) or 0.0)
|
||||||
|
latencia = float(modulo.get("latencia", 0.0) or 0.0)
|
||||||
|
|
||||||
|
last_packet_ts = float(self.last_packet_ts)
|
||||||
|
last_publish_ts = float(self.last_publish_ts)
|
||||||
|
ultimo_erro_ts = float(self.ultimo_erro_ts)
|
||||||
|
|
||||||
|
tempo_sem_packet = (agora - last_packet_ts) if last_packet_ts > 0 else 999.0
|
||||||
|
tempo_sem_publicar = (agora - last_publish_ts) if last_publish_ts > 0 else 999.0
|
||||||
|
tempo_desde_erro = (agora - ultimo_erro_ts) if ultimo_erro_ts > 0 else 999.0
|
||||||
|
|
||||||
saude = 100
|
saude = 100
|
||||||
motivos = []
|
motivos = []
|
||||||
|
|
||||||
if not conectado:
|
if not conectado:
|
||||||
motivos.append("IMU desconectado ou sem dados recentes")
|
motivos.append("Thread da IMU não está viva")
|
||||||
saude = 0
|
saude = 0
|
||||||
|
else:
|
||||||
|
# ============================
|
||||||
|
# 1) Penalização por ausência de packets
|
||||||
|
# ============================
|
||||||
|
if tempo_sem_packet > 1.5:
|
||||||
|
saude -= 45
|
||||||
|
motivos.append(f"Sem packets há {tempo_sem_packet:.2f}s")
|
||||||
|
elif tempo_sem_packet > 0.7:
|
||||||
|
saude -= 25
|
||||||
|
motivos.append(f"Packets atrasados há {tempo_sem_packet:.2f}s")
|
||||||
|
elif tempo_sem_packet > 0.3:
|
||||||
|
saude -= 10
|
||||||
|
motivos.append(f"Leve atraso de packets: {tempo_sem_packet:.2f}s")
|
||||||
|
|
||||||
|
# ============================
|
||||||
|
# 2) Penalização por ausência de publicação
|
||||||
|
# ============================
|
||||||
|
if tempo_sem_publicar > 1.5:
|
||||||
|
saude -= 30
|
||||||
|
motivos.append(f"Sem publicar no Redis há {tempo_sem_publicar:.2f}s")
|
||||||
|
elif tempo_sem_publicar > 0.8:
|
||||||
|
saude -= 15
|
||||||
|
motivos.append(f"Publicação atrasada há {tempo_sem_publicar:.2f}s")
|
||||||
|
elif tempo_sem_publicar > 0.3:
|
||||||
|
saude -= 5
|
||||||
|
motivos.append(f"Leve atraso na publicação: {tempo_sem_publicar:.2f}s")
|
||||||
|
|
||||||
|
# ============================
|
||||||
|
# 3) Frequência
|
||||||
|
# ============================
|
||||||
|
if freq_hz <= 0:
|
||||||
|
saude -= 20
|
||||||
|
motivos.append("Frequência zerada")
|
||||||
elif freq_hz <= FREQ_MIN:
|
elif freq_hz <= FREQ_MIN:
|
||||||
|
saude -= 35
|
||||||
motivos.append(f"Frequência baixa: {freq_hz:.2f} Hz")
|
motivos.append(f"Frequência baixa: {freq_hz:.2f} Hz")
|
||||||
saude -= 50
|
|
||||||
else:
|
else:
|
||||||
f = min(freq_hz, FREQ_BASE)
|
f = min(freq_hz, FREQ_BASE)
|
||||||
erro = (FREQ_BASE - f) / FREQ_BASE
|
erro = (FREQ_BASE - f) / FREQ_BASE
|
||||||
p = min(int(erro * 100), 30)
|
p = min(int(erro * 100), 20)
|
||||||
saude -= abs(p)
|
|
||||||
if p > 0:
|
|
||||||
motivos.append(f"Frequência abaixo do ideal: {freq_hz:.2f} Hz (penalidade {p}%)")
|
|
||||||
|
|
||||||
if latencia > 0.5:
|
|
||||||
p = int(min(latencia * 100, 30))
|
|
||||||
saude -= p
|
saude -= p
|
||||||
motivos.append(f"Latência alta: {latencia:.2f} s (penalidade {p}%)")
|
if p > 0:
|
||||||
|
motivos.append(f"Frequência abaixo do ideal: {freq_hz:.2f} Hz")
|
||||||
|
|
||||||
saude = max(saude, 0)
|
# ============================
|
||||||
|
# 4) Latência
|
||||||
|
# ============================
|
||||||
|
if latencia > 1.0:
|
||||||
|
saude -= 25
|
||||||
|
motivos.append(f"Latência muito alta: {latencia:.2f}s")
|
||||||
|
elif latencia > 0.5:
|
||||||
|
saude -= 15
|
||||||
|
motivos.append(f"Latência alta: {latencia:.2f}s")
|
||||||
|
elif latencia > 0.2:
|
||||||
|
saude -= 5
|
||||||
|
motivos.append(f"Latência moderada: {latencia:.2f}s")
|
||||||
|
|
||||||
|
# ============================
|
||||||
|
# 5) Erro recente
|
||||||
|
# ============================
|
||||||
|
if tempo_desde_erro < 2.0:
|
||||||
|
saude -= 20
|
||||||
|
motivos.append("Erro muito recente no loop")
|
||||||
|
elif tempo_desde_erro < 5.0:
|
||||||
|
saude -= 10
|
||||||
|
motivos.append("Erro recente no loop")
|
||||||
|
|
||||||
|
saude = max(0, min(100, saude))
|
||||||
|
|
||||||
status = StatusModulo.OPERANTE
|
status = StatusModulo.OPERANTE
|
||||||
if not conectado:
|
if not conectado:
|
||||||
status = StatusModulo.DESCONECTADO
|
status = StatusModulo.DESCONECTADO
|
||||||
elif saude <= 0:
|
elif saude <= SAUDE_MIN_FALHA:
|
||||||
status = StatusModulo.FALHA
|
status = StatusModulo.FALHA
|
||||||
elif saude < SAUDE_MIN_ALERTA:
|
elif saude < SAUDE_MIN_ALERTA:
|
||||||
status = StatusModulo.ALERTA
|
status = StatusModulo.ALERTA
|
||||||
|
|
@ -380,13 +455,14 @@ class IMUCamera(ModuloDiagnosticoBase):
|
||||||
"status": status.value,
|
"status": status.value,
|
||||||
"saude": saude,
|
"saude": saude,
|
||||||
"motivos": motivos,
|
"motivos": motivos,
|
||||||
"saude_idividual": []
|
"saude_idividual": [],
|
||||||
}
|
}
|
||||||
|
|
||||||
ContextoGlobalRedis.atualizar_ctx_dict(
|
ContextoGlobalRedis.atualizar_ctx_dict(
|
||||||
ContextoGlobalRedis.ModKey(T_Code.Imu),
|
ContextoGlobalRedis.ModKey(T_Code.Imu),
|
||||||
saude=saude_geral
|
saude=saude_geral
|
||||||
)
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.mostrar_log(f"Erro ao atualizar saude: {e}")
|
self.mostrar_log(f"Erro ao atualizar saude: {e}")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,28 @@ from shared.enums import StatusModulo, StatusOperacao, T_Code
|
||||||
from shared.contexto_global_redis import ContextoGlobalRedis, CtxKey
|
from shared.contexto_global_redis import ContextoGlobalRedis, CtxKey
|
||||||
from manager_worker.config import mostrar_log
|
from manager_worker.config import mostrar_log
|
||||||
|
|
||||||
def verifica_controle_liberado(ignorar_parada=False):
|
class RegrasTaticas:
|
||||||
|
def __init__(self):
|
||||||
|
self.persistencias = {
|
||||||
|
"obstaculo_sonar": {
|
||||||
|
"ativo": False,
|
||||||
|
"ts_inicio_true": None,
|
||||||
|
"ts_inicio_false": None,
|
||||||
|
"ultimo_estado_bruto": False,
|
||||||
|
},
|
||||||
|
"inclinacao_perigosa": {
|
||||||
|
"ativo": False,
|
||||||
|
"ts_inicio_true": None,
|
||||||
|
"ts_inicio_false": None,
|
||||||
|
"ultimo_estado_bruto": False,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
def verifica_controle_liberado(self, ignorar_parada=False):
|
||||||
try:
|
try:
|
||||||
motivos = []
|
motivos = []
|
||||||
|
freio_necessario = False
|
||||||
|
_controle = ContextoGlobalRedis.get_controle()
|
||||||
_operacao = ContextoGlobalRedis.get_operacao()
|
_operacao = ContextoGlobalRedis.get_operacao()
|
||||||
status_operacao = StatusOperacao(_operacao.get("status", StatusOperacao.NaoIniciado.value))
|
status_operacao = StatusOperacao(_operacao.get("status", StatusOperacao.NaoIniciado.value))
|
||||||
finalizando = _operacao.get("finalizando", False)
|
finalizando = _operacao.get("finalizando", False)
|
||||||
|
|
@ -13,8 +32,6 @@ def verifica_controle_liberado(ignorar_parada=False):
|
||||||
if not ignorar_parada and ((status_operacao != StatusOperacao.EmAndamento) or finalizando):
|
if not ignorar_parada and ((status_operacao != StatusOperacao.EmAndamento) or finalizando):
|
||||||
motivos.append(f"Operação não está em andamento ou finalizando: {status_operacao.name}")
|
motivos.append(f"Operação não está em andamento ou finalizando: {status_operacao.name}")
|
||||||
|
|
||||||
_controle = ContextoGlobalRedis.get_controle()
|
|
||||||
|
|
||||||
oak_parada_por_bloqueio = _controle.get("oak_parada_por_bloqueio", False)
|
oak_parada_por_bloqueio = _controle.get("oak_parada_por_bloqueio", False)
|
||||||
if oak_parada_por_bloqueio:
|
if oak_parada_por_bloqueio:
|
||||||
_snr = ContextoGlobalRedis.get_modulo(T_Code.Snr)
|
_snr = ContextoGlobalRedis.get_modulo(T_Code.Snr)
|
||||||
|
|
@ -22,30 +39,77 @@ def verifica_controle_liberado(ignorar_parada=False):
|
||||||
snr_operante = _snr_saude in [StatusModulo.OPERANTE, StatusModulo.ALERTA]
|
snr_operante = _snr_saude in [StatusModulo.OPERANTE, StatusModulo.ALERTA]
|
||||||
_dados_vw = ContextoGlobalRedis.get(CtxKey.DadosVisualWorker, {})
|
_dados_vw = ContextoGlobalRedis.get(CtxKey.DadosVisualWorker, {})
|
||||||
analise_deteccao_atualizada = (time.perf_counter() - _dados_vw.get("matriz_confianca", {}).get("ts", 10.0) <= 1.0)
|
analise_deteccao_atualizada = (time.perf_counter() - _dados_vw.get("matriz_confianca", {}).get("ts", 10.0) <= 1.0)
|
||||||
obstaculo_detectado = _dados_vw.get("matriz_confianca", {}).get("block", {}).get("decision", {}).get("parar", False) if analise_deteccao_atualizada else False
|
obstaculo_detectado = _dados_vw.get("matriz_confianca", {}).get("block", {}).get("decision", {}).get("parar", False)
|
||||||
|
|
||||||
if (not snr_operante):
|
obstaculo_persistente = self._avaliar_persistencia(
|
||||||
|
nome="obstaculo_sonar",
|
||||||
|
estado_bruto=(snr_operante and analise_deteccao_atualizada and obstaculo_detectado),
|
||||||
|
tempo_acionar=0.35,
|
||||||
|
tempo_liberar=1.0
|
||||||
|
)
|
||||||
|
|
||||||
|
if not snr_operante:
|
||||||
motivos.append(f"Sonar mandatório não operante: {_snr_saude.name}")
|
motivos.append(f"Sonar mandatório não operante: {_snr_saude.name}")
|
||||||
elif (snr_operante and obstaculo_detectado):
|
elif obstaculo_persistente:
|
||||||
motivos.append(f"Obstáculo próximo detectado no sonar")
|
motivos.append("Obstáculo próximo detectado no sonar")
|
||||||
|
freio_necessario = True
|
||||||
|
|
||||||
imu_parada_por_inclinacao = _controle.get("imu_parada_por_inclinacao", False)
|
imu_parada_por_inclinacao = _controle.get("imu_parada_por_inclinacao", False)
|
||||||
if imu_parada_por_inclinacao:
|
if imu_parada_por_inclinacao:
|
||||||
_imu = ContextoGlobalRedis.get_modulo(T_Code.Imu)
|
_imu = ContextoGlobalRedis.get_modulo(T_Code.Imu)
|
||||||
_imu_saude = StatusModulo(_imu.get("saude", {}).get("status", StatusModulo.DESCONECTADO.value))
|
_imu_saude = StatusModulo(_imu.get("saude", {}).get("status", StatusModulo.DESCONECTADO.value))
|
||||||
imu_operante = _imu_saude in [StatusModulo.OPERANTE, StatusModulo.ALERTA]
|
imu_operante = _imu_saude in [StatusModulo.OPERANTE, StatusModulo.ALERTA]
|
||||||
|
imu_ts = _imu.get("timestamp", 0) / 1000.0
|
||||||
|
imu_atualizada = (time.time() - imu_ts) <= 1.0
|
||||||
_equipamento = ContextoGlobalRedis.get_equipamento()
|
_equipamento = ContextoGlobalRedis.get_equipamento()
|
||||||
ang_roll_max = _equipamento.get("angulo_roll_max", 15.0)
|
ang_roll_max = _equipamento.get("angulo_roll_max", 15.0)
|
||||||
ang_pitch_max = _equipamento.get("angulo_pitch_max", 30.0)
|
ang_pitch_max = _equipamento.get("angulo_pitch_max", 30.0)
|
||||||
inclinacao_perigosa = abs(_imu.get("pitch_seg", 0.0)) > ang_pitch_max or abs(_imu.get("roll_seg", 0.0)) > ang_roll_max
|
roll = _imu.get("roll_seg", 0.0)
|
||||||
|
pitch = _imu.get("pitch_seg", 0.0)
|
||||||
|
inclinacao_perigosa = abs(pitch) > ang_pitch_max or abs(roll) > ang_roll_max
|
||||||
|
|
||||||
|
inclinacao_persistente = self._avaliar_persistencia(
|
||||||
|
nome="inclinacao_perigosa",
|
||||||
|
estado_bruto=(imu_operante and imu_atualizada and inclinacao_perigosa),
|
||||||
|
tempo_acionar=0.20,
|
||||||
|
tempo_liberar=1.2
|
||||||
|
)
|
||||||
|
|
||||||
if not imu_operante:
|
if not imu_operante:
|
||||||
motivos.append(f"IMU mandatório não operante: {_imu_saude.name}")
|
motivos.append(f"IMU mandatório não operante: {_imu_saude.name}")
|
||||||
elif imu_operante and inclinacao_perigosa:
|
elif inclinacao_persistente:
|
||||||
motivos.append(f"Inclinação perigosa detectada. roll: {_imu.get('roll')}, pitch: {_imu.get('pitch')}, yaw: {_imu.get('yaw')}")
|
motivos.append(f"Inclinação perigosa detectada. roll: {roll:.2f}/{ang_roll_max}, pitch: {pitch:.2f}/{ang_pitch_max}")
|
||||||
|
freio_necessario = True
|
||||||
|
|
||||||
return motivos
|
return motivos, freio_necessario
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
mostrar_log(f"Erro ao verificar liberacao do controle: {e}")
|
mostrar_log(f"Erro ao verificar liberacao do controle: {e}")
|
||||||
|
|
||||||
|
def _avaliar_persistencia(self, nome, estado_bruto, tempo_acionar, tempo_liberar):
|
||||||
|
agora = time.perf_counter()
|
||||||
|
p = self.persistencias[nome]
|
||||||
|
|
||||||
|
if estado_bruto:
|
||||||
|
if p["ultimo_estado_bruto"] != True:
|
||||||
|
p["ts_inicio_true"] = agora
|
||||||
|
p["ts_inicio_false"] = None
|
||||||
|
elif p["ts_inicio_true"] is None:
|
||||||
|
p["ts_inicio_true"] = agora
|
||||||
|
|
||||||
|
if not p["ativo"] and p["ts_inicio_true"] is not None:
|
||||||
|
if (agora - p["ts_inicio_true"]) >= tempo_acionar:
|
||||||
|
p["ativo"] = True
|
||||||
|
else:
|
||||||
|
if p["ultimo_estado_bruto"] != False:
|
||||||
|
p["ts_inicio_false"] = agora
|
||||||
|
p["ts_inicio_true"] = None
|
||||||
|
elif p["ts_inicio_false"] is None:
|
||||||
|
p["ts_inicio_false"] = agora
|
||||||
|
|
||||||
|
if p["ativo"] and p["ts_inicio_false"] is not None:
|
||||||
|
if (agora - p["ts_inicio_false"]) >= tempo_liberar:
|
||||||
|
p["ativo"] = False
|
||||||
|
|
||||||
|
p["ultimo_estado_bruto"] = estado_bruto
|
||||||
|
return p["ativo"]
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
from .base import ProcessadorBase
|
from .base import ProcessadorBase
|
||||||
from manager_worker.processadores.padroes import comando_parado
|
from manager_worker.processadores.padroes import comando_parado
|
||||||
from manager_worker.modulos.regras_taticas import verifica_controle_liberado
|
from manager_worker.modulos.regras_taticas import RegrasTaticas
|
||||||
|
|
||||||
class ProcessadorAguardando(ProcessadorBase):
|
class ProcessadorAguardando(ProcessadorBase):
|
||||||
|
def __init__(self):
|
||||||
|
self.regras = RegrasTaticas()
|
||||||
|
|
||||||
def processar(self):
|
def processar(self):
|
||||||
try:
|
try:
|
||||||
motivos_parada = verifica_controle_liberado(ignorar_parada=True)
|
motivos_parada, freio_necessario = self.regras.verifica_controle_liberado(ignorar_parada=True)
|
||||||
return comando_parado(motivos=motivos_parada)
|
return comando_parado(motivos=motivos_parada, frear=freio_necessario)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
from manager_worker.config import mostrar_log
|
from manager_worker.config import mostrar_log
|
||||||
mostrar_log(f"Erro no processador Aguardando: {e}")
|
mostrar_log(f"Erro no processador Aguardando: {e}")
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ from manager_worker.modulos.pid import PIDAdaptativo
|
||||||
from .base import ProcessadorBase
|
from .base import ProcessadorBase
|
||||||
from manager_worker.filtros import FiltroVelocidade
|
from manager_worker.filtros import FiltroVelocidade
|
||||||
from manager_worker.processadores.padroes import comando_controle
|
from manager_worker.processadores.padroes import comando_controle
|
||||||
from manager_worker.modulos.regras_taticas import verifica_controle_liberado
|
from manager_worker.modulos.regras_taticas import RegrasTaticas
|
||||||
from manager_worker.modulos.direcional import definir_comando as definir_comando_dir
|
from manager_worker.modulos.direcional import definir_comando as definir_comando_dir
|
||||||
from manager_worker.modulos.movimentacao import definir_comando as definir_comando_mov
|
from manager_worker.modulos.movimentacao import definir_comando as definir_comando_mov
|
||||||
|
|
||||||
|
|
@ -24,6 +24,7 @@ class ProcessadorEmAndamento(ProcessadorBase):
|
||||||
saida_max=ang_max
|
saida_max=ang_max
|
||||||
)
|
)
|
||||||
self.ultimo_comando_enviado = time.perf_counter()
|
self.ultimo_comando_enviado = time.perf_counter()
|
||||||
|
self.regras = RegrasTaticas()
|
||||||
|
|
||||||
|
|
||||||
def processar(self):
|
def processar(self):
|
||||||
|
|
@ -31,13 +32,13 @@ class ProcessadorEmAndamento(ProcessadorBase):
|
||||||
agora = time.perf_counter()
|
agora = time.perf_counter()
|
||||||
envio_necessario = (agora - self.ultimo_comando_enviado) > 0.3
|
envio_necessario = (agora - self.ultimo_comando_enviado) > 0.3
|
||||||
|
|
||||||
motivos_parada = verifica_controle_liberado()
|
motivos_parada, freio_necessario = self.regras.verifica_controle_liberado()
|
||||||
if len(motivos_parada) > 0:
|
if len(motivos_parada) > 0:
|
||||||
from manager_worker.config import mostrar_log
|
from manager_worker.config import mostrar_log
|
||||||
mostrar_log(f"⛔ Controle bloqueado: {' | '.join(motivos_parada)}")
|
mostrar_log(f"⛔ Controle bloqueado: {' | '.join(motivos_parada)}")
|
||||||
return comando_controle(
|
return comando_controle(
|
||||||
percentual_velocidade=0,
|
percentual_velocidade=0,
|
||||||
frear=True,
|
frear=freio_necessario,
|
||||||
angulo=0,
|
angulo=0,
|
||||||
tipo_movimento=TipoMovimentoDirecional.RodasDianteiras.value,
|
tipo_movimento=TipoMovimentoDirecional.RodasDianteiras.value,
|
||||||
simulacao=[],
|
simulacao=[],
|
||||||
|
|
@ -59,7 +60,7 @@ class ProcessadorEmAndamento(ProcessadorBase):
|
||||||
if direcional_automatico:
|
if direcional_automatico:
|
||||||
comando_dir = definir_comando_dir(self.pid_dir, envio_necessario)
|
comando_dir = definir_comando_dir(self.pid_dir, envio_necessario)
|
||||||
|
|
||||||
enviar_comando = (direcional_automatico and comando_dir.get("enviar_comando", False)) or not direcional_automatico
|
enviar_comando = comando_dir.get("enviar_comando", False) or movimento_automatico
|
||||||
|
|
||||||
if enviar_comando:
|
if enviar_comando:
|
||||||
self.ultimo_comando_enviado = agora
|
self.ultimo_comando_enviado = agora
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
from .base import ProcessadorBase
|
from .base import ProcessadorBase
|
||||||
from manager_worker.processadores.padroes import comando_parado
|
from manager_worker.processadores.padroes import comando_parado
|
||||||
from manager_worker.modulos.regras_taticas import verifica_controle_liberado
|
from manager_worker.modulos.regras_taticas import RegrasTaticas
|
||||||
|
|
||||||
class ProcessadorParado(ProcessadorBase):
|
class ProcessadorParado(ProcessadorBase):
|
||||||
|
def __init__(self):
|
||||||
|
self.regras = RegrasTaticas()
|
||||||
|
|
||||||
def processar(self):
|
def processar(self):
|
||||||
try:
|
try:
|
||||||
motivos_parada = verifica_controle_liberado(ignorar_parada=True)
|
motivos_parada, freio_necessario = self.regras.verifica_controle_liberado(ignorar_parada=True)
|
||||||
return comando_parado(motivos=motivos_parada)
|
return comando_parado(motivos=motivos_parada, frear=freio_necessario)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
from manager_worker.config import mostrar_log
|
from manager_worker.config import mostrar_log
|
||||||
mostrar_log(f"Erro no processador Parado: {e}")
|
mostrar_log(f"Erro no processador Parado: {e}")
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,8 @@ def comando_controle(percentual_velocidade: float, frear: bool, angulo: float, t
|
||||||
"motivos": motivos
|
"motivos": motivos
|
||||||
}
|
}
|
||||||
|
|
||||||
def comando_parado(motivos=None):
|
def comando_parado(motivos=None, frear=False):
|
||||||
return comando_controle(0, False, 0, TipoMovimentoDirecional.RodasDianteiras, motivos=motivos)
|
return comando_controle(0, frear, 0, TipoMovimentoDirecional.RodasDianteiras, motivos=motivos)
|
||||||
|
|
||||||
def log_status_operacao():
|
def log_status_operacao():
|
||||||
modo = ModoOperacao(ContextoGlobalRedis.get_operacao().get("modo"))
|
modo = ModoOperacao(ContextoGlobalRedis.get_operacao().get("modo"))
|
||||||
|
|
|
||||||
|
|
@ -392,7 +392,7 @@ class ContextoGlobalRedis:
|
||||||
controle_ok = False
|
controle_ok = False
|
||||||
motivos_dos_modulos_mandatorios.extend(_motivos_controle)
|
motivos_dos_modulos_mandatorios.extend(_motivos_controle)
|
||||||
|
|
||||||
liberou = ((base_ok and parametros_ok) or debug_mode) and emergencia_ok and pausa_ok and trajetoria_ok and controle_ok
|
liberou = ((base_ok and parametros_ok) or debug_mode) and emergencia_ok and pausa_ok and trajetoria_ok # and controle_ok
|
||||||
|
|
||||||
cls.atualizar_ctx_dict(
|
cls.atualizar_ctx_dict(
|
||||||
CtxKey.DadosOperacao,
|
CtxKey.DadosOperacao,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
using AgroBase.Models;
|
using AgroBase.Models.Operadores;
|
||||||
using AgroBase.Models.Operadores;
|
|
||||||
using OperationControl.Helpers;
|
using OperationControl.Helpers;
|
||||||
using OperationControl.Models;
|
using OperationControl.Models;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
|
@ -149,7 +148,7 @@ namespace OperationControl.ViewModels.Views.Operacao.Monitoramento
|
||||||
{
|
{
|
||||||
if (System.Windows.MessageBox.Show("Deseja solicitar o retorno do equipamento até a base?", "Retorno à base", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
|
if (System.Windows.MessageBox.Show("Deseja solicitar o retorno do equipamento até a base?", "Retorno à base", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
|
||||||
{
|
{
|
||||||
var gps = OperationControl.Models.Variaveis.GpsService.UltimaLeitura;
|
var gps = Variaveis.GpsService.UltimaLeitura;
|
||||||
double? lat = gps?.Latitude;
|
double? lat = gps?.Latitude;
|
||||||
double? lon = gps?.Longitude;
|
double? lon = gps?.Longitude;
|
||||||
if (lat == null || lon == null)
|
if (lat == null || lon == null)
|
||||||
|
|
@ -158,7 +157,16 @@ namespace OperationControl.ViewModels.Views.Operacao.Monitoramento
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await VariaveisControleOperacao.EnviarComandoParadaUDP(pausa: true);
|
||||||
|
await Task.Delay(500);
|
||||||
VariaveisControleOperacao.EnviarComandoRetornoBase(lat, lon);
|
VariaveisControleOperacao.EnviarComandoRetornoBase(lat, lon);
|
||||||
|
await Task.Delay(1000);
|
||||||
|
await VariaveisControleOperacao.EnviarComandoParadaUDP(pausa: false);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -319,15 +319,16 @@ namespace OperationControl.ViewModels.Views.Operacao
|
||||||
|
|
||||||
private void AlternarOperacao()
|
private void AlternarOperacao()
|
||||||
{
|
{
|
||||||
if (VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Iniciada ?? false)
|
var dadosRover = VariaveisControleOperacao.RoverEmFoco?.DadosLeitura;
|
||||||
|
if (dadosRover?.Operacao?.Iniciada ?? false)
|
||||||
{
|
{
|
||||||
bool PauseActivated = VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Pausa ?? false;
|
bool PauseActivated = dadosRover?.Operacao?.Pausa ?? false;
|
||||||
PauseActivated = !PauseActivated;
|
PauseActivated = !PauseActivated;
|
||||||
VariaveisControleOperacao.EnviarComandoParada(pausa: PauseActivated);
|
VariaveisControleOperacao.EnviarComandoParada(pausa: PauseActivated);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (((VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Modo ?? AgroBase.Models.Enums.ModoOperacao.NaoDefinido) == AgroBase.Models.Enums.ModoOperacao.MapaGPS) && !(VariaveisControleOperacao.RoverEmFoco?.RuasPercorrer?.Any() ?? false))
|
if (((dadosRover?.Operacao?.Modo ?? AgroBase.Models.Enums.ModoOperacao.NaoDefinido) == AgroBase.Models.Enums.ModoOperacao.MapaGPS) && !(VariaveisControleOperacao.RoverEmFoco?.RuasPercorrer?.Any() ?? false))
|
||||||
{
|
{
|
||||||
System.Windows.MessageBox.Show("Para iniciar a operação automática, é necessário carregar um mapa e selecionar as ruas onde o equipamento irá operar!", "Parametrização", MessageBoxButton.OK, MessageBoxImage.Warning);
|
System.Windows.MessageBox.Show("Para iniciar a operação automática, é necessário carregar um mapa e selecionar as ruas onde o equipamento irá operar!", "Parametrização", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||||
return;
|
return;
|
||||||
|
|
@ -335,13 +336,17 @@ namespace OperationControl.ViewModels.Views.Operacao
|
||||||
|
|
||||||
if (System.Windows.MessageBox.Show("Deseja iniciar a operação com os parâmetros atuais?", "Iniciar Operação", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
|
if (System.Windows.MessageBox.Show("Deseja iniciar a operação com os parâmetros atuais?", "Iniciar Operação", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
|
||||||
{
|
{
|
||||||
bool simulador = VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Gnss?.Iniciado != true;
|
|
||||||
VariaveisControleOperacao.EnviarComandoIniciarOperacao(true, simulador);
|
|
||||||
|
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
|
if ((dadosRover?.Operacao?.Status ?? StatusOperacao.NaoIniciado) == StatusOperacao.Concluido)
|
||||||
|
{
|
||||||
|
VariaveisControleOperacao.EnviarComandoIniciarOperacao(false, false);
|
||||||
|
await Task.Delay(500);
|
||||||
|
}
|
||||||
|
bool simulador = VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Gnss?.Iniciado != true;
|
||||||
|
VariaveisControleOperacao.EnviarComandoIniciarOperacao(true, simulador);
|
||||||
await Task.Delay(1000);
|
await Task.Delay(1000);
|
||||||
if (!(VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Liberada ?? false))
|
if (!(dadosRover?.Operacao?.Liberada ?? false))
|
||||||
{
|
{
|
||||||
System.Windows.MessageBox.Show($"{VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.ImpedimentoErro}", "Operação iniciada com impedimento!", MessageBoxButton.OK, MessageBoxImage.Warning);
|
System.Windows.MessageBox.Show($"{VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.ImpedimentoErro}", "Operação iniciada com impedimento!", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue