ajustes no joystick

This commit is contained in:
Diego Freitas 2026-03-19 17:12:56 -03:00
parent ecf4b571bf
commit 523d6924c3
8 changed files with 43 additions and 32 deletions

View File

@ -27,13 +27,13 @@ namespace AgroBase.Forms
private void frmJoystick_KeyDown(object sender, KeyEventArgs e)
{
var comando = GeneralJoystick.DeParaComandos.FirstOrDefault(x => x.key == e.KeyCode);
GeneralJoystick.EnviaComandoMotor(comando?.key ?? e.KeyCode, comando?.Dispositivo ?? T_Code.Vzo);
GeneralJoystick.EnviaComandoMotor(e.KeyCode, comando?.Dispositivo ?? T_Code.Vzo);
}
private void frmJoystick_KeyUp(object sender, KeyEventArgs e)
{
var comando = GeneralJoystick.DeParaComandos.FirstOrDefault(x => x.key == e.KeyCode);
GeneralJoystick.EnviaComandoMotor(comando?.key ?? Keys.Escape, comando?.Dispositivo ?? T_Code.Vzo);
GeneralJoystick.EnviaComandoMotor(Keys.Escape, comando?.Dispositivo ?? T_Code.Vzo);
}
}

View File

@ -181,7 +181,7 @@ namespace AgroBase
trkKmh.Minimum = 0;
trkKmh.Maximum = 100;
trkRPM.Minimum = Variaveis.OperacaoEmAndamento.Parametros.Controle.MovVelocidadeCErvasPercent;
trkRPM.Minimum = Variaveis.OperacaoEmAndamento.Parametros.Controle?.MovVelocidadeCErvasPercent ?? 15;
trkRPM.Maximum = VariaveisEquipamento.RPM_Max_Roda;
AtualizaRPM((int)Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP);
@ -267,6 +267,8 @@ namespace AgroBase
private void tkbVelocidadeMP_ValueChanged(object sender, EventArgs e)
{
if (Variaveis.OperacaoEmAndamento.Parametros.Controle == null)
return;
Variaveis.OperacaoEmAndamento.Parametros.Controle.DirVelocidadeMovimento = tkbVelocidade.Value;
lblVelocidade.Text = "Velocidade: " + Variaveis.OperacaoEmAndamento.Parametros.Controle.DirVelocidadeMovimento + "%";
}

View File

@ -610,18 +610,18 @@ namespace AgroBase
case BotoesJoystick.Xis:
direcao = Direcao.Frente;
dispositivo = T_Code.Mov;
percent = Math.Max(pControle.MovVelocidadeCErvasPercent, (pControle.MovVelocidadeSErvasPercent - pControle.MovVelocidadeCErvasPercent) / 2.0);
percent = ((double)pControle.MovVelocidadeCErvasPercent / (double)pControle.MovVelocidadeSErvasPercent);
break;
case BotoesJoystick.Quadrado:
direcao = Direcao.Tras;
dispositivo = T_Code.Mov;
percent = Math.Max(pControle.MovVelocidadeCErvasPercent, (pControle.MovVelocidadeSErvasPercent - pControle.MovVelocidadeCErvasPercent) / 2.0);
percent = ((double)pControle.MovVelocidadeCErvasPercent / (double)pControle.MovVelocidadeSErvasPercent);
break;
}
percent = FuncoesMatematicas.Clamp(percent, 0, 100);
percent = FuncoesMatematicas.Clamp(percent, 0, 1);
//Console.WriteLine($"botao: {botao}, valor: {valor}, percentual: {percent * 100.0:F2}%");
@ -634,7 +634,8 @@ namespace AgroBase
_Controle.Angulo = solto ? 0 : pControle.DirAnguloMaximo * percent * mx;
break;
case T_Code.Mov:
_Controle.PercentualVelocidadeSP = solto ? 0 : Math.Max(pControle.MovVelocidadeCErvasPercent, pControle.MovVelocidadeSErvasPercent * percent) * mx;
double map = FuncoesMatematicas.Map(valor, 0, maximo, pControle.MovVelocidadeCErvasPercent, pControle.MovVelocidadeSErvasPercent);
_Controle.PercentualVelocidadeSP = solto ? 0 : map * mx;
break;
}
}
@ -654,7 +655,7 @@ namespace AgroBase
)
);
if (deveInterromper)
if (deveInterromper && false)
{
return;
}

View File

@ -92,6 +92,7 @@ namespace AgroBase.Models
Variaveis.OperacaoEmAndamento.StatusAtual = (StatusOperacao)RedisService.GetField<int>(CtxKey.DadosOperacao, "status", 0);
Variaveis.OperacaoEmAndamento.OperacaoLiberada = RedisService.GetField(CtxKey.DadosOperacao, "liberado", false);
Variaveis.OperacaoEmAndamento.OperacaoConfigurada = RedisService.GetField(CtxKey.DadosOperacao, "configurado", false);
Variaveis.OperacaoEmAndamento.Controle.Motivos = RedisService.GetField<List<string>>(CtxKey.DadosControle, "motivos", new List<string>());
var tempoAguardando = RedisService.GetField<long>(CtxKey.DadosOperacao, "tempo_aguardando", 0);
Variaveis.OperacaoEmAndamento.TempoAguardando = DateTimeOffset.FromUnixTimeSeconds(tempoAguardando).UtcDateTime.AddSeconds(tempoAguardando % 1).ToLocalTime();
Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada = RedisService.GetField<string>(CtxKey.DadosOperacao, "motivo_nao_liberado");
@ -389,9 +390,9 @@ namespace AgroBase.Models
MpcMatrizCusto = false,
MpcHorizonte = 4.0,
MovVelocidadeSErvasPercent = 50,
MovVelocidadeCErvasPercent = 15,
DirAnguloMaximo = 25,
MovVelocidadeSErvasPercent = 35,
MovVelocidadeCErvasPercent = 12,
DirAnguloMaximo = 30,
DirVelocidadeMovimento = 40,
DirTipoMovimento = TiposControladorDirecional.Manual,
@ -1349,7 +1350,7 @@ namespace AgroBase.Models
{
case T_Code.Mov:
{
if (pControle.FrenagemAutomaticaAoParar && _Controle.EmFreio)
if (_Controle.EmFreio)
{
_Controle.Direcao = Direcao.EmFreio;
}
@ -1488,11 +1489,13 @@ namespace AgroBase.Models
Sonar?.Resumo?.AtualizarStatusBloqueio(true);
if (Sonar?.Resumo?.EnviarComandoParada ?? false)
{
Variaveis.MostrarLog("[OperacaoModel] Deve enviar o comando de parada em tmrLeituras_Tick");
GeneralJoystick.EnviaComandoMotor(Keys.Escape, Disp: T_Code.Mov, ForcarComando: true);
}
else if (Sonar?.Resumo?.EnviarComandoRetomada ?? false)
{
//GeneralJoystick.EnviaComandoMotor(Keys.Escape, T_Code.Mov);
if (Variaveis.OperacaoEmAndamento.Parametros?.Controle?.FrenagemAutomaticaAoParar ?? false)
{
Variaveis.MostrarLog("[OperacaoModel] Deve enviar o comando de freio em tmrLeituras_Tick");
GeneralJoystick.EnviaComandoMotor(Keys.Space, Disp: T_Code.Mov, ForcarComando: true);
}
}
if (!Variaveis.OperacaoEmAndamento.OperacaoLiberada)
@ -1719,7 +1722,7 @@ namespace AgroBase.Models
if (cmdRover?.Dispositivo == T_Code.Dir && Variaveis.OperacaoEmAndamento.Parametros.Controle.DirecionalAutomatico && Variaveis.OperacaoEmAndamento.Iniciado) return;
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
int mx = cmdRover.key == Keys.Escape || cmdRover.key == Keys.Down ? -1 : 1;
int mx = cmdRover?.key == Keys.Left || cmdRover?.key == Keys.Down ? -1 : 1;
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;
@ -1744,8 +1747,8 @@ namespace AgroBase.Models
else
{
topico = Variaveis.MqttServiceBase.Topicos.FirstOrDefault(x => x.Topico == VariaveisEquipamento.TopicoMqttTelemetria.Replace("<id>", VariaveisEquipamento.Parametros.serial_number));
Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Atualizar();
var data = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Clone();
Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura?.Atualizar();
var data = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura?.Clone();
msg = JsonConvert.SerializeObject(data);
}
if (topico != null && !string.IsNullOrEmpty(msg))

View File

@ -1046,7 +1046,7 @@ namespace AgroBase.Models
if (pControle.MovimentoAutomatico)
{
_Controle.PercentualVelocidadeSP = novoComando.percentual_velocidade;
_Controle.EmFreio = novoComando.em_freio;
_Controle.EmFreio = pControle.FrenagemAutomaticaAoParar && novoComando.em_freio;
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(false, new List<T_Code>() { T_Code.Mov });
}

View File

@ -92,7 +92,7 @@ namespace AgroBase.Services.Operadores
if (pControle.MovimentoAutomatico)
{
_Controle.PercentualVelocidadeSP = novoComando.percentual_velocidade;
_Controle.EmFreio = novoComando.em_freio;
_Controle.EmFreio = pControle.FrenagemAutomaticaAoParar && novoComando.em_freio;
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(false, new List<T_Code>() { T_Code.Mov });
}

View File

@ -320,6 +320,9 @@ class IMUCamera(ModuloDiagnosticoBase):
impacto_idx=round(self.impacto_idx, 1),
estabilidade_idx=round(self.estabilidade_idx, 1),
timestamp=(time.time() * 1000),
last_packet_ts=self.last_packet_ts,
last_publish_ts=self.last_publish_ts,
ultimo_erro_ts=self.ultimo_erro_ts,
latencia=latencia,
frequencia=f_tick
)
@ -344,24 +347,25 @@ class IMUCamera(ModuloDiagnosticoBase):
try:
agora = time.time()
modulo = ContextoGlobalRedis.get_modulo(T_Code.Imu) or {}
mod_ts = modulo.get("timestamp")
if mod_ts is None or mod_ts == 0:
return
FREQ_BASE = self.freq
FREQ_MIN = FREQ_BASE * 0.5
SAUDE_MIN_ALERTA = 80
SAUDE_MIN_FALHA = 45
conectado = bool(
self.ativo and
self.imu_thread is not None and
self.imu_thread.is_alive()
)
tempo_sem_dados = ((time.time() * 1000) - mod_ts) / 1000.0
conectado = tempo_sem_dados < 10
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)
last_packet_ts = float(modulo.get("last_packet_ts", self.last_packet_ts) or 0.0)
last_publish_ts = float(modulo.get("last_publish_ts", self.last_publish_ts) or 0.0)
ultimo_erro_ts = float(modulo.get("ultimo_erro_ts", self.ultimo_erro_ts) or 0.0)
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
@ -371,7 +375,8 @@ class IMUCamera(ModuloDiagnosticoBase):
motivos = []
if not conectado:
motivos.append("Thread da IMU não está viva")
print(f"Thread da IMU não está viva à {tempo_sem_dados:.2f} s, mod_ts: {mod_ts}")
motivos.append(f"Thread da IMU não está viva à {tempo_sem_dados:.2f} s")
saude = 0
else:
# ============================
@ -467,4 +472,4 @@ class IMUCamera(ModuloDiagnosticoBase):
self.mostrar_log(f"Erro ao atualizar saude: {e}")
def mostrar_log(self, mensagem):
print(f"{time.time()} - [IMU] {mensagem}")
print(f"{time.time()} - [IMU][id={id(self)}] {mensagem}")

View File

@ -44,7 +44,7 @@ class RegrasTaticas:
obstaculo_persistente = self._avaliar_persistencia(
nome="obstaculo_sonar",
estado_bruto=(snr_operante and analise_deteccao_atualizada and obstaculo_detectado),
tempo_acionar=0.35,
tempo_acionar=0.15,
tempo_liberar=1.0
)