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) private void frmJoystick_KeyDown(object sender, KeyEventArgs e)
{ {
var comando = GeneralJoystick.DeParaComandos.FirstOrDefault(x => x.key == e.KeyCode); 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) private void frmJoystick_KeyUp(object sender, KeyEventArgs e)
{ {
var comando = GeneralJoystick.DeParaComandos.FirstOrDefault(x => x.key == e.KeyCode); 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.Minimum = 0;
trkKmh.Maximum = 100; trkKmh.Maximum = 100;
trkRPM.Minimum = Variaveis.OperacaoEmAndamento.Parametros.Controle.MovVelocidadeCErvasPercent; trkRPM.Minimum = Variaveis.OperacaoEmAndamento.Parametros.Controle?.MovVelocidadeCErvasPercent ?? 15;
trkRPM.Maximum = VariaveisEquipamento.RPM_Max_Roda; trkRPM.Maximum = VariaveisEquipamento.RPM_Max_Roda;
AtualizaRPM((int)Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP); AtualizaRPM((int)Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP);
@ -267,6 +267,8 @@ namespace AgroBase
private void tkbVelocidadeMP_ValueChanged(object sender, EventArgs e) private void tkbVelocidadeMP_ValueChanged(object sender, EventArgs e)
{ {
if (Variaveis.OperacaoEmAndamento.Parametros.Controle == null)
return;
Variaveis.OperacaoEmAndamento.Parametros.Controle.DirVelocidadeMovimento = tkbVelocidade.Value; Variaveis.OperacaoEmAndamento.Parametros.Controle.DirVelocidadeMovimento = tkbVelocidade.Value;
lblVelocidade.Text = "Velocidade: " + Variaveis.OperacaoEmAndamento.Parametros.Controle.DirVelocidadeMovimento + "%"; lblVelocidade.Text = "Velocidade: " + Variaveis.OperacaoEmAndamento.Parametros.Controle.DirVelocidadeMovimento + "%";
} }

View File

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

View File

@ -92,6 +92,7 @@ namespace AgroBase.Models
Variaveis.OperacaoEmAndamento.StatusAtual = (StatusOperacao)RedisService.GetField<int>(CtxKey.DadosOperacao, "status", 0); Variaveis.OperacaoEmAndamento.StatusAtual = (StatusOperacao)RedisService.GetField<int>(CtxKey.DadosOperacao, "status", 0);
Variaveis.OperacaoEmAndamento.OperacaoLiberada = RedisService.GetField(CtxKey.DadosOperacao, "liberado", false); Variaveis.OperacaoEmAndamento.OperacaoLiberada = RedisService.GetField(CtxKey.DadosOperacao, "liberado", false);
Variaveis.OperacaoEmAndamento.OperacaoConfigurada = RedisService.GetField(CtxKey.DadosOperacao, "configurado", 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); var tempoAguardando = RedisService.GetField<long>(CtxKey.DadosOperacao, "tempo_aguardando", 0);
Variaveis.OperacaoEmAndamento.TempoAguardando = DateTimeOffset.FromUnixTimeSeconds(tempoAguardando).UtcDateTime.AddSeconds(tempoAguardando % 1).ToLocalTime(); Variaveis.OperacaoEmAndamento.TempoAguardando = DateTimeOffset.FromUnixTimeSeconds(tempoAguardando).UtcDateTime.AddSeconds(tempoAguardando % 1).ToLocalTime();
Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada = RedisService.GetField<string>(CtxKey.DadosOperacao, "motivo_nao_liberado"); Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada = RedisService.GetField<string>(CtxKey.DadosOperacao, "motivo_nao_liberado");
@ -389,9 +390,9 @@ namespace AgroBase.Models
MpcMatrizCusto = false, MpcMatrizCusto = false,
MpcHorizonte = 4.0, MpcHorizonte = 4.0,
MovVelocidadeSErvasPercent = 50, MovVelocidadeSErvasPercent = 35,
MovVelocidadeCErvasPercent = 15, MovVelocidadeCErvasPercent = 12,
DirAnguloMaximo = 25, DirAnguloMaximo = 30,
DirVelocidadeMovimento = 40, DirVelocidadeMovimento = 40,
DirTipoMovimento = TiposControladorDirecional.Manual, DirTipoMovimento = TiposControladorDirecional.Manual,
@ -1349,7 +1350,7 @@ namespace AgroBase.Models
{ {
case T_Code.Mov: case T_Code.Mov:
{ {
if (pControle.FrenagemAutomaticaAoParar && _Controle.EmFreio) if (_Controle.EmFreio)
{ {
_Controle.Direcao = Direcao.EmFreio; _Controle.Direcao = Direcao.EmFreio;
} }
@ -1488,11 +1489,13 @@ namespace AgroBase.Models
Sonar?.Resumo?.AtualizarStatusBloqueio(true); Sonar?.Resumo?.AtualizarStatusBloqueio(true);
if (Sonar?.Resumo?.EnviarComandoParada ?? false) 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); GeneralJoystick.EnviaComandoMotor(Keys.Escape, Disp: T_Code.Mov, ForcarComando: true);
} if (Variaveis.OperacaoEmAndamento.Parametros?.Controle?.FrenagemAutomaticaAoParar ?? false)
else if (Sonar?.Resumo?.EnviarComandoRetomada ?? false)
{ {
//GeneralJoystick.EnviaComandoMotor(Keys.Escape, T_Code.Mov); 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) 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; 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;
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.PercentualVelocidadeSP != null) _Controle.PercentualVelocidadeSP = (double)controleBase.Controle.PercentualVelocidadeSP * mx;
if (controleBase.Controle.AnguloSP != null) _Controle.Angulo = (double)controleBase.Controle.AnguloSP * 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;
@ -1744,8 +1747,8 @@ namespace AgroBase.Models
else else
{ {
topico = Variaveis.MqttServiceBase.Topicos.FirstOrDefault(x => x.Topico == VariaveisEquipamento.TopicoMqttTelemetria.Replace("<id>", VariaveisEquipamento.Parametros.serial_number)); topico = Variaveis.MqttServiceBase.Topicos.FirstOrDefault(x => x.Topico == VariaveisEquipamento.TopicoMqttTelemetria.Replace("<id>", VariaveisEquipamento.Parametros.serial_number));
Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Atualizar(); Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura?.Atualizar();
var data = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Clone(); var data = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura?.Clone();
msg = JsonConvert.SerializeObject(data); msg = JsonConvert.SerializeObject(data);
} }
if (topico != null && !string.IsNullOrEmpty(msg)) if (topico != null && !string.IsNullOrEmpty(msg))

View File

@ -1046,7 +1046,7 @@ namespace AgroBase.Models
if (pControle.MovimentoAutomatico) if (pControle.MovimentoAutomatico)
{ {
_Controle.PercentualVelocidadeSP = novoComando.percentual_velocidade; _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 }); Variaveis.OperacaoEmAndamento.AtualizarDadosControle(false, new List<T_Code>() { T_Code.Mov });
} }

View File

@ -92,7 +92,7 @@ namespace AgroBase.Services.Operadores
if (pControle.MovimentoAutomatico) if (pControle.MovimentoAutomatico)
{ {
_Controle.PercentualVelocidadeSP = novoComando.percentual_velocidade; _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 }); 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), impacto_idx=round(self.impacto_idx, 1),
estabilidade_idx=round(self.estabilidade_idx, 1), estabilidade_idx=round(self.estabilidade_idx, 1),
timestamp=(time.time() * 1000), 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, latencia=latencia,
frequencia=f_tick frequencia=f_tick
) )
@ -344,24 +347,25 @@ class IMUCamera(ModuloDiagnosticoBase):
try: try:
agora = time.time() agora = time.time()
modulo = ContextoGlobalRedis.get_modulo(T_Code.Imu) or {} 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_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 SAUDE_MIN_FALHA = 45
conectado = bool( tempo_sem_dados = ((time.time() * 1000) - mod_ts) / 1000.0
self.ativo and conectado = tempo_sem_dados < 10
self.imu_thread is not None and
self.imu_thread.is_alive()
)
freq_hz = float(modulo.get("frequencia", 0.0) or 0.0) freq_hz = float(modulo.get("frequencia", 0.0) or 0.0)
latencia = float(modulo.get("latencia", 0.0) or 0.0) latencia = float(modulo.get("latencia", 0.0) or 0.0)
last_packet_ts = float(self.last_packet_ts) last_packet_ts = float(modulo.get("last_packet_ts", self.last_packet_ts) or 0.0)
last_publish_ts = float(self.last_publish_ts) last_publish_ts = float(modulo.get("last_publish_ts", self.last_publish_ts) or 0.0)
ultimo_erro_ts = float(self.ultimo_erro_ts) 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_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_sem_publicar = (agora - last_publish_ts) if last_publish_ts > 0 else 999.0
@ -371,7 +375,8 @@ class IMUCamera(ModuloDiagnosticoBase):
motivos = [] motivos = []
if not conectado: 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 saude = 0
else: else:
# ============================ # ============================
@ -467,4 +472,4 @@ class IMUCamera(ModuloDiagnosticoBase):
self.mostrar_log(f"Erro ao atualizar saude: {e}") self.mostrar_log(f"Erro ao atualizar saude: {e}")
def mostrar_log(self, mensagem): 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( obstaculo_persistente = self._avaliar_persistencia(
nome="obstaculo_sonar", nome="obstaculo_sonar",
estado_bruto=(snr_operante and analise_deteccao_atualizada and obstaculo_detectado), estado_bruto=(snr_operante and analise_deteccao_atualizada and obstaculo_detectado),
tempo_acionar=0.35, tempo_acionar=0.15,
tempo_liberar=1.0 tempo_liberar=1.0
) )