implementaçao de dados do visual worker no fluxo automatico

This commit is contained in:
Diego Freitas 2026-04-01 08:26:37 -03:00
parent 635429479c
commit e401a31799
23 changed files with 355 additions and 231 deletions

View File

@ -335,7 +335,6 @@ namespace AgroBase.Forms.IHM
var pControle = Variaveis.OperacaoEmAndamento.Parametros.Controle;
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
cmbModoControle.SelectedIndex = (int)_Controle.TipoMovimento;
chbSonarAtivado.Checked = pControle.SonarAtivado;
chbFrenagemAutomatica.Checked = pControle.FrenagemAutomaticaAoParar;
nudVelSemErvas.Value = (int)pControle.MovVelocidadeSErvasPercent;
nudVelComErvas.Value = (int)pControle.MovVelocidadeCErvasPercent;
@ -876,7 +875,6 @@ namespace AgroBase.Forms.IHM
var pControle = Variaveis.OperacaoEmAndamento.Parametros.Controle;
if (res == DialogResult.Yes)
{
pControle.SonarAtivado = chbSonarAtivado.Checked;
pControle.FrenagemAutomaticaAoParar = chbFrenagemAutomatica.Checked;
pControle.MovVelocidadeSErvasPercent = (int)FuncoesMatematicas.CalculaRPMVelocidade(FuncoesMatematicas.CalculaVelocidadeMsPercentual((int)nudVelSemErvas.Value));
pControle.MovVelocidadeCErvasPercent = (int)FuncoesMatematicas.CalculaRPMVelocidade(FuncoesMatematicas.CalculaVelocidadeMsPercentual((int)nudVelComErvas.Value));
@ -900,7 +898,6 @@ namespace AgroBase.Forms.IHM
}
else
{
chbSonarAtivado.Checked = pControle.SonarAtivado;
chbFrenagemAutomatica.Checked = pControle.FrenagemAutomaticaAoParar;
nudVelSemErvas.Value = (int)pControle.MovVelocidadeSErvasPercent;
nudVelComErvas.Value = (int)pControle.MovVelocidadeCErvasPercent;

View File

@ -61,7 +61,8 @@ namespace AgroBase.Forms.Operacoes
}
chbPulverizador.Checked = Variaveis.OperacaoEmAndamento.Parametros.Controle.PulverizadorAutomatico;
chbSonarAtivado.Checked = Variaveis.OperacaoEmAndamento.Parametros.Controle.SonarAtivado;
chbSonarAtivado.Checked = Variaveis.OperacaoEmAndamento.Parametros.Controle.MovAuxilioSonar;
chbSonarAtivado.Checked = Variaveis.OperacaoEmAndamento.Parametros.Controle.DirAuxilioSonar;
InicializarComandosDirecional();
PopularInformacoesGerais();
@ -693,7 +694,8 @@ namespace AgroBase.Forms.Operacoes
private void chbSonarAtivado_CheckedChanged(object sender, EventArgs e)
{
Variaveis.OperacaoEmAndamento.Parametros.Controle.SonarAtivado = ((CheckBox)sender).Checked;
Variaveis.OperacaoEmAndamento.Parametros.Controle.MovAuxilioSonar = ((CheckBox)sender).Checked;
Variaveis.OperacaoEmAndamento.Parametros.Controle.DirAuxilioSonar = ((CheckBox)sender).Checked;
}
private void chbSonarDesvioAutomatico_CheckedChanged(object sender, EventArgs e)

View File

@ -33,10 +33,11 @@
this.lblOperacao = new System.Windows.Forms.Label();
this.gpbModulos = new System.Windows.Forms.GroupBox();
this.gpbP_Knt = new System.Windows.Forms.GroupBox();
this.chbFrenagem = new System.Windows.Forms.CheckBox();
this.lblAnteciparManobraM = new System.Windows.Forms.Label();
this.txtAnteciparManobraM = new System.Windows.Forms.TextBox();
this.lblAnteciparManobra = new System.Windows.Forms.Label();
this.chbMatrizCusto = new System.Windows.Forms.CheckBox();
this.chbDirAuxilioSonar = new System.Windows.Forms.CheckBox();
this.chbImuParadaInclinacao = new System.Windows.Forms.CheckBox();
this.chbOakParadaObstaculo = new System.Windows.Forms.CheckBox();
this.chbO_Snr = new System.Windows.Forms.CheckBox();
@ -91,7 +92,7 @@
this.nudCapacidadereservatorio = new System.Windows.Forms.NumericUpDown();
this.lblUnCapcaidadereservatorio = new System.Windows.Forms.Label();
this.lblCapacidadereservatorio = new System.Windows.Forms.Label();
this.chbFrenagem = new System.Windows.Forms.CheckBox();
this.chbMovAuxilioSonar = new System.Windows.Forms.CheckBox();
this.gpbModulos.SuspendLayout();
this.gpbP_Knt.SuspendLayout();
this.gpbP_Sen.SuspendLayout();
@ -170,17 +171,28 @@
this.gpbP_Knt.Controls.Add(this.lblAnteciparManobraM);
this.gpbP_Knt.Controls.Add(this.txtAnteciparManobraM);
this.gpbP_Knt.Controls.Add(this.lblAnteciparManobra);
this.gpbP_Knt.Controls.Add(this.chbMatrizCusto);
this.gpbP_Knt.Controls.Add(this.chbImuParadaInclinacao);
this.gpbP_Knt.Controls.Add(this.chbOakParadaObstaculo);
this.gpbP_Knt.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.gpbP_Knt.Location = new System.Drawing.Point(988, 105);
this.gpbP_Knt.Name = "gpbP_Knt";
this.gpbP_Knt.Size = new System.Drawing.Size(190, 187);
this.gpbP_Knt.Size = new System.Drawing.Size(190, 205);
this.gpbP_Knt.TabIndex = 15;
this.gpbP_Knt.TabStop = false;
this.gpbP_Knt.Text = "Ajustes";
//
// chbFrenagem
//
this.chbFrenagem.AutoSize = true;
this.chbFrenagem.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F);
this.chbFrenagem.Location = new System.Drawing.Point(9, 80);
this.chbFrenagem.Margin = new System.Windows.Forms.Padding(6);
this.chbFrenagem.Name = "chbFrenagem";
this.chbFrenagem.Size = new System.Drawing.Size(153, 22);
this.chbFrenagem.TabIndex = 18;
this.chbFrenagem.Text = "Frenagem ao parar";
this.chbFrenagem.UseVisualStyleBackColor = true;
//
// lblAnteciparManobraM
//
this.lblAnteciparManobraM.AutoSize = true;
@ -210,17 +222,17 @@
this.lblAnteciparManobra.TabIndex = 15;
this.lblAnteciparManobra.Text = "Antecipar manobra";
//
// chbMatrizCusto
// chbDirAuxilioSonar
//
this.chbMatrizCusto.AutoSize = true;
this.chbMatrizCusto.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F);
this.chbMatrizCusto.Location = new System.Drawing.Point(10, 80);
this.chbMatrizCusto.Margin = new System.Windows.Forms.Padding(6);
this.chbMatrizCusto.Name = "chbMatrizCusto";
this.chbMatrizCusto.Size = new System.Drawing.Size(132, 22);
this.chbMatrizCusto.TabIndex = 13;
this.chbMatrizCusto.Text = "Matriz de Custo";
this.chbMatrizCusto.UseVisualStyleBackColor = true;
this.chbDirAuxilioSonar.AutoSize = true;
this.chbDirAuxilioSonar.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F);
this.chbDirAuxilioSonar.Location = new System.Drawing.Point(9, 180);
this.chbDirAuxilioSonar.Margin = new System.Windows.Forms.Padding(6);
this.chbDirAuxilioSonar.Name = "chbDirAuxilioSonar";
this.chbDirAuxilioSonar.Size = new System.Drawing.Size(157, 22);
this.chbDirAuxilioSonar.TabIndex = 13;
this.chbDirAuxilioSonar.Text = "Assistido por Sonar";
this.chbDirAuxilioSonar.UseVisualStyleBackColor = true;
//
// chbImuParadaInclinacao
//
@ -264,7 +276,7 @@
this.gpbP_Gps.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.gpbP_Gps.Location = new System.Drawing.Point(792, 105);
this.gpbP_Gps.Name = "gpbP_Gps";
this.gpbP_Gps.Size = new System.Drawing.Size(190, 187);
this.gpbP_Gps.Size = new System.Drawing.Size(190, 205);
this.gpbP_Gps.TabIndex = 12;
this.gpbP_Gps.TabStop = false;
this.gpbP_Gps.Text = "Ajustes";
@ -290,7 +302,7 @@
this.gpbP_Sen.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.gpbP_Sen.Location = new System.Drawing.Point(596, 105);
this.gpbP_Sen.Name = "gpbP_Sen";
this.gpbP_Sen.Size = new System.Drawing.Size(190, 187);
this.gpbP_Sen.Size = new System.Drawing.Size(190, 205);
this.gpbP_Sen.TabIndex = 12;
this.gpbP_Sen.TabStop = false;
this.gpbP_Sen.Text = "Ajustes";
@ -356,7 +368,7 @@
this.gpbP_Atu.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.gpbP_Atu.Location = new System.Drawing.Point(400, 105);
this.gpbP_Atu.Name = "gpbP_Atu";
this.gpbP_Atu.Size = new System.Drawing.Size(190, 187);
this.gpbP_Atu.Size = new System.Drawing.Size(190, 205);
this.gpbP_Atu.TabIndex = 12;
this.gpbP_Atu.TabStop = false;
this.gpbP_Atu.Text = "Ajustes";
@ -432,13 +444,14 @@
this.gpbP_Dir.Controls.Add(this.lblAngulomax);
this.gpbP_Dir.Controls.Add(this.nudAnguloMinimo);
this.gpbP_Dir.Controls.Add(this.nudVelocidadeMP);
this.gpbP_Dir.Controls.Add(this.chbDirAuxilioSonar);
this.gpbP_Dir.Controls.Add(this.lblVelocidadeMP);
this.gpbP_Dir.Controls.Add(this.nudAnguloMaximo);
this.gpbP_Dir.Controls.Add(this.lblAngulomin);
this.gpbP_Dir.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.gpbP_Dir.Location = new System.Drawing.Point(204, 105);
this.gpbP_Dir.Name = "gpbP_Dir";
this.gpbP_Dir.Size = new System.Drawing.Size(190, 187);
this.gpbP_Dir.Size = new System.Drawing.Size(190, 205);
this.gpbP_Dir.TabIndex = 12;
this.gpbP_Dir.TabStop = false;
this.gpbP_Dir.Text = "Ajustes";
@ -530,6 +543,7 @@
//
// gpbP_Mov
//
this.gpbP_Mov.Controls.Add(this.chbMovAuxilioSonar);
this.gpbP_Mov.Controls.Add(this.chbMovimentacaoAutomatica);
this.gpbP_Mov.Controls.Add(this.nudVelocidadeComErvas);
this.gpbP_Mov.Controls.Add(this.lblKmhCErvas);
@ -540,7 +554,7 @@
this.gpbP_Mov.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.gpbP_Mov.Location = new System.Drawing.Point(8, 105);
this.gpbP_Mov.Name = "gpbP_Mov";
this.gpbP_Mov.Size = new System.Drawing.Size(190, 187);
this.gpbP_Mov.Size = new System.Drawing.Size(190, 205);
this.gpbP_Mov.TabIndex = 10;
this.gpbP_Mov.TabStop = false;
this.gpbP_Mov.Text = "Ajustes";
@ -844,17 +858,17 @@
this.lblCapacidadereservatorio.TabIndex = 9;
this.lblCapacidadereservatorio.Text = "Capacidade reservatório";
//
// chbFrenagem
// chbMovAuxilioSonar
//
this.chbFrenagem.AutoSize = true;
this.chbFrenagem.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F);
this.chbFrenagem.Location = new System.Drawing.Point(10, 104);
this.chbFrenagem.Margin = new System.Windows.Forms.Padding(6);
this.chbFrenagem.Name = "chbFrenagem";
this.chbFrenagem.Size = new System.Drawing.Size(153, 22);
this.chbFrenagem.TabIndex = 18;
this.chbFrenagem.Text = "Frenagem ao parar";
this.chbFrenagem.UseVisualStyleBackColor = true;
this.chbMovAuxilioSonar.AutoSize = true;
this.chbMovAuxilioSonar.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F);
this.chbMovAuxilioSonar.Location = new System.Drawing.Point(6, 180);
this.chbMovAuxilioSonar.Margin = new System.Windows.Forms.Padding(6);
this.chbMovAuxilioSonar.Name = "chbMovAuxilioSonar";
this.chbMovAuxilioSonar.Size = new System.Drawing.Size(157, 22);
this.chbMovAuxilioSonar.TabIndex = 16;
this.chbMovAuxilioSonar.Text = "Assistido por Sonar";
this.chbMovAuxilioSonar.UseVisualStyleBackColor = true;
//
// frmParametrizacaoOperacao
//
@ -956,7 +970,7 @@
private System.Windows.Forms.Label lblAtuarem;
private System.Windows.Forms.Label lblAngulomax;
private System.Windows.Forms.Button btnA05;
private System.Windows.Forms.CheckBox chbMatrizCusto;
private System.Windows.Forms.CheckBox chbDirAuxilioSonar;
private System.Windows.Forms.GroupBox gpbP_Knt;
private System.Windows.Forms.CheckBox chbO_Snr;
private System.Windows.Forms.CheckBox chbD_Snr;
@ -969,5 +983,6 @@
private System.Windows.Forms.TextBox txtAnteciparManobraM;
private System.Windows.Forms.Label lblAnteciparManobra;
private System.Windows.Forms.CheckBox chbFrenagem;
private System.Windows.Forms.CheckBox chbMovAuxilioSonar;
}
}

View File

@ -77,7 +77,8 @@ namespace AgroBase.Forms.Operacoes
chbImuParadaInclinacao.Checked = _Parametros.Controle.ImuParadaPorInclinacao;
chbOakParadaObstaculo.Checked = _Parametros.Controle.OakParadaPorObstaculo;
chbMatrizCusto.Checked = _Parametros.Controle.MpcMatrizCusto;
chbDirAuxilioSonar.Checked = _Parametros.Controle.DirAuxilioSonar;
chbMovAuxilioSonar.Checked = _Parametros.Controle.MovAuxilioSonar;
chbFrenagem.Checked = _Parametros.Controle.FrenagemAutomaticaAoParar;
txtAnteciparManobraM.Text = _Parametros.Controle.AnteciparManobraCorredorM.ToString();
@ -137,7 +138,8 @@ namespace AgroBase.Forms.Operacoes
{
Variaveis.OperacaoEmAndamento.Parametros.Controle.ImuParadaPorInclinacao = chbImuParadaInclinacao.Checked;
Variaveis.OperacaoEmAndamento.Parametros.Controle.OakParadaPorObstaculo = chbOakParadaObstaculo.Checked;
Variaveis.OperacaoEmAndamento.Parametros.Controle.MpcMatrizCusto = chbMatrizCusto.Checked;
Variaveis.OperacaoEmAndamento.Parametros.Controle.DirAuxilioSonar = chbDirAuxilioSonar.Checked;
Variaveis.OperacaoEmAndamento.Parametros.Controle.MovAuxilioSonar = chbMovAuxilioSonar.Checked;
Variaveis.OperacaoEmAndamento.Parametros.Controle.FrenagemAutomaticaAoParar = chbFrenagem.Checked;
Variaveis.OperacaoEmAndamento.Parametros.ModulosMandatorios = ModulosMandatorios.Where(x => x.Utilizar).ToList();

View File

@ -911,7 +911,7 @@ namespace AgroBase
{
List<Keys> ComandosImpedidos = new List<Keys>();
var Sonar = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorVisual;
var DeveParar = (Sonar?.Resumo?.DeveParar ?? false);
var DeveParar = Sonar?.StatusValido == true && Sonar?.Resumo?.DeveParar == true;
if (DeveParar)
{
ComandosImpedidos.Add(Keys.Up);

View File

@ -714,7 +714,8 @@ namespace AgroBase.Models.Modules
Componente = S_Code.sBIC,
Posicao = posicao,
Inicializado = false,
AnguloControle = 0,
AnguloNeutro = 90,
AnguloControle = 90,
AnguloAbertura = 30,
Comandar = true,
Mandatorio = true,
@ -1025,41 +1026,52 @@ namespace AgroBase.Models.Modules
{
if (Variaveis.Fechando) return;
foreach (var bico in BicosPulverizadores.Where(x => x.Comandar && x.Inicializado))
bool operacaoConcluida = Variaveis.OperacaoEmAndamento.Sensoriamento.StatusOperacao == StatusOperacao.Concluido;
bool pulverizadorAutomatico = Variaveis.OperacaoEmAndamento.Parametros.Controle.PulverizadorAutomatico;
foreach (var bico in BicosPulverizadores.Where(x => x.Inicializado))
{
Estado comandoEstado = bico.ComandoAtuar ? Estado.Ligado : Estado.Desligado;
if (comandoEstado != bico._EstadoLeitura || bico.AnguloControle != bico._AnguloBicoLeitura)
bool statusDesejado = bico.Comandar && bico.ComandoAtuar;
if (pulverizadorAutomatico)
statusDesejado &= !operacaoConcluida && Variaveis.OperacaoEmAndamento.Iniciado;
Estado estadoDesejado = statusDesejado ? Estado.Ligado : Estado.Desligado;
double anguloDesejado = statusDesejado ? bico.AnguloControle : bico.AnguloNeutro;
bool estadoDivergente = estadoDesejado != bico._EstadoLeitura;
bool anguloDivergente = statusDesejado && Math.Abs(anguloDesejado - bico._AnguloBicoLeitura) > 0.01;
if (estadoDivergente || anguloDivergente)
{
GeneralJoystick.EnviarComandoAtuador(bico.Componente, bico.ID, Status: bico.ComandoAtuar, Valor: bico.AnguloControle);
GeneralJoystick.EnviarComandoAtuador(
bico.Componente,
bico.ID,
Status: statusDesejado,
Valor: anguloDesejado
);
}
}
foreach (var bomba in BombasPressurizadoras.Where(x => x.Comandar && x.Inicializado))
foreach (var bomba in BombasPressurizadoras.Where(x => x.Inicializado))
{
// Desligar a bomba caso nao tenha herbicida suficiente no recipiente
if (!ContadorCarga.PulverizadorLiberado)
{
if (bomba._EstadoLeitura == Estado.Ligado)
{
GeneralJoystick.EnviarComandoAtuador(bomba.Componente, bomba.ID, Status: false);
}
}
else
{
if (Variaveis.OperacaoEmAndamento.Iniciado && Variaveis.OperacaoEmAndamento.Parametros.Controle.PulverizadorAutomatico)
{
if (bomba._EstadoLeitura == Estado.Desligado)
{
GeneralJoystick.EnviarComandoAtuador(bomba.Componente, bomba.ID, Status: true);
}
}
bool statusDesejado = bomba.Comandar && bomba.ComandoAtuar;
if (pulverizadorAutomatico)
statusDesejado &= ContadorCarga.PulverizadorLiberado && !operacaoConcluida && Variaveis.OperacaoEmAndamento.Iniciado;
Estado comandoEstado = bomba.ComandoAtuar ? Estado.Ligado : Estado.Desligado;
double pressaoSp = Variaveis.OperacaoEmAndamento.Parametros.Controle.AtuPressaoLinha;
if (comandoEstado != bomba._EstadoLeitura || pressaoSp != bomba._PressaoSP)
{
GeneralJoystick.EnviarComandoAtuador(bomba.Componente, bomba.ID, Status: bomba.ComandoAtuar, Valor: pressaoSp);
}
Estado estadoDesejado = statusDesejado ? Estado.Ligado : Estado.Desligado;
double pressaoDesejada = Variaveis.OperacaoEmAndamento.Parametros.Controle.AtuPressaoLinha;
bool estadoDivergente = estadoDesejado != bomba._EstadoLeitura;
bool pressaoDivergente = bomba.Sensor_ID_Num > -1 && Math.Abs(bomba._PressaoSP - pressaoDesejada) > 0.05;
if (estadoDivergente || pressaoDivergente)
{
GeneralJoystick.EnviarComandoAtuador(
bomba.Componente,
bomba.ID,
Status: statusDesejado,
Valor: pressaoDesejada
);
}
}
}
@ -1089,7 +1101,7 @@ namespace AgroBase.Models.Modules
public async Task<bool> RealizarTestesIniciais(bool forcar)
{
var calAtu = Variaveis.OperacaoEmAndamento.ModsCalibragem[T_Code.Atu];
var calAtu = Variaveis.OperacaoEmAndamento.ModsCalibragem[Dispositivo];
// Ligar bomba
foreach (var Bomba in BombasPressurizadoras.Where(x => x.Comandar))
@ -1102,10 +1114,18 @@ namespace AgroBase.Models.Modules
// Sem herbicida no reservatorio, bomba nao precisa ligar
if (!Bomba.Inicializado || ContadorCarga.PercentualAtual < VariaveisEquipamento.PercentualReservatorioMin)
{
break;
Variaveis.MostrarLog($"[AtuadorModel] [RealizarTestesIniciais] Bomba não iniciada ou nível do reservatório baixo, não irá ligar a bomba {Bomba.ID}");
continue;
}
GeneralJoystick.EnviarComandoAtuador(Bomba.Componente, Bomba.ID, Status: true);
GeneralJoystick.EnviarComandoAtuador(Bomba.Componente, Bomba.ID, Status: true, Forcar: true);
if (Bomba.Sensor_ID_Num == -1)
{
Variaveis.MostrarLog($"[AtuadorModel] [RealizarTestesIniciais] Bomba {Bomba.ID} não possui um sensor de pressão, será controlada mecanicamente pelo pressostato");
calAtu[Bomba.ID] = true;
continue;
}
await FuncoesGlobais.AguardarCondicaoAsync(Bomba.AtingiuPressao, 3000, 200);
@ -1118,23 +1138,20 @@ namespace AgroBase.Models.Modules
{
foreach (var Bico in BicosPulverizadores.Where(x => x.Comandar && x.Inicializado))
{
GeneralJoystick.EnviarComandoAtuador(Bico.Componente, Bico.ID, Status: true);
GeneralJoystick.EnviarComandoAtuador(Bico.Componente, Bico.ID, Status: true, Forcar: true);
}
await Task.Delay(3000);
foreach (var Bico in BicosPulverizadores.Where(x => x.Comandar && x.Inicializado))
{
GeneralJoystick.EnviarComandoAtuador(Bico.Componente, Bico.ID, Status: false);
GeneralJoystick.EnviarComandoAtuador(Bico.Componente, Bico.ID, Status: false, Forcar: true);
}
await FuncoesGlobais.AguardarCondicaoAsync(Bomba.AtingiuPressao, 4000, 200);
BombaOk = Bomba.AtingiuPressao();
if (BombaOk)
{
calAtu[Bomba.ID] = true;
}
calAtu[Bomba.ID] = BombaOk;
}
}
@ -1148,11 +1165,13 @@ namespace AgroBase.Models.Modules
if (Bico.Inicializado)
{
GeneralJoystick.EnviarComandoAtuador(Bico.Componente, Bico.ID, Status: true);
GeneralJoystick.EnviarComandoAtuador(Bico.Componente, Bico.ID, Status: true, Forcar: true);
await Task.Delay(200);
GeneralJoystick.EnviarComandoAtuador(Bico.Componente, Bico.ID, Status: false);
GeneralJoystick.EnviarComandoAtuador(Bico.Componente, Bico.ID, Status: false, Forcar: true);
await Task.Delay(200);
calAtu[Bico.ID] = true;
}
@ -1173,12 +1192,12 @@ namespace AgroBase.Models.Modules
{
tasks.Add(DispAtu.Dados.RealizarTestesIniciais(forcar).ContinueWith(t => {
if (t.IsFaulted)
Console.WriteLine($"Erro no referenciamento do módulo {Modulo_ID}: {t.Exception?.InnerException?.Message}");
Variaveis.MostrarLog($"[AtuadorModel] [RealizarCalibragemAsync] Erro no referenciamento do módulo {Modulo_ID}: {t.Exception?.InnerException?.Message}");
if (t.IsCompleted)
{
var calAtu = Variaveis.OperacaoEmAndamento.ModsCalibragem[T_Code.Atu];
var v = calAtu.Select(x => $"{x.Key} " + (x.Value ? "Sim" : "Não"));
Console.WriteLine($"Task de referenciamento do módulo {Modulo_ID} finalizada: " + string.Join(", ", v));
Variaveis.MostrarLog($"[AtuadorModel] [RealizarCalibragemAsync] Task de referenciamento do módulo {Modulo_ID} finalizada: " + string.Join(", ", v));
}
}));
@ -1240,6 +1259,7 @@ namespace AgroBase.Models.Modules
public int Posicao { get; set; }
public S_Code Componente { get; set; } = S_Code.sBIC;
public bool AtuacaoNivelAlto { get; set; }
public double AnguloNeutro { get; set; }
public double AnguloControle { get; set; }
public double AnguloAbertura { get; set; }
public bool ComandoAtuar { get; set; }

View File

@ -1819,6 +1819,7 @@ namespace AgroBase.Models.Modules
{
FuncoesPinout.Servo,
},
AnguloNeutro = 0,
_AnguloControle = 0,
Incremental = true,
ValoresLeituras = new List<SensorValoresLeituraModel>()
@ -1850,6 +1851,7 @@ namespace AgroBase.Models.Modules
{
FuncoesPinout.Servo,
},
AnguloNeutro = 0,
_AnguloControle = 0,
Incremental = true,
ValoresLeituras = new List<SensorValoresLeituraModel>()
@ -1881,6 +1883,7 @@ namespace AgroBase.Models.Modules
{
FuncoesPinout.Servo,
},
AnguloNeutro = 180,
_AnguloControle = 180,
Incremental = false,
ValoresLeituras = new List<SensorValoresLeituraModel>()
@ -1912,6 +1915,7 @@ namespace AgroBase.Models.Modules
{
FuncoesPinout.Servo,
},
AnguloNeutro = 180,
_AnguloControle = 180,
Incremental = false,
ValoresLeituras = new List<SensorValoresLeituraModel>()
@ -2340,27 +2344,33 @@ namespace AgroBase.Models.Modules
{
if (Variaveis.Fechando) return;
foreach (var sinaleiro in Sinaleiros.Where(x => x.Controlar && x.Inicializado))
foreach (var sinaleiro in Sinaleiros.Where(x => x.Inicializado))
{
if (sinaleiro.Comportamento.statusLED != sinaleiro._StatusLed || sinaleiro.Comportamento.id != sinaleiro._StatusLedId)
SensorSinaleiroComportamentoModel comportamentoDesejado = sinaleiro.Controlar ? sinaleiro.Comportamento : VariaveisEquipamento.ComportamentoLedPorStatus();
bool comportamentoDivergente = comportamentoDesejado.statusLED != sinaleiro._StatusLed || comportamentoDesejado.id != sinaleiro._StatusLedId;
if (comportamentoDivergente)
{
GeneralJoystick.EnviarComandoSensoriamento(sinaleiro.Componente, sinaleiro.ID, sinaleiro.Comportamento);
GeneralJoystick.EnviarComandoSensoriamento(sinaleiro.Componente, sinaleiro.ID, comportamentoDesejado);
}
}
foreach (var rele in Reles.Where(x => x.Controlar && x.Inicializado))
foreach (var rele in Reles.Where(x => x.Inicializado))
{
if (rele.StatusControle != rele._EstadoLeitura)
Estado estadoDesejado = rele.Controlar && rele.StatusControle == Estado.Ligado ? Estado.Ligado : Estado.Desligado;
bool estadoDivergente = estadoDesejado != rele._EstadoLeitura;
if (estadoDivergente)
{
GeneralJoystick.EnviarComandoSensoriamento(rele.Componente, rele.ID, rele.StatusControle);
GeneralJoystick.EnviarComandoSensoriamento(rele.Componente, rele.ID, estadoDesejado);
}
}
foreach (var servo in Servos.Where(x => x.Controlar && x.Inicializado))
foreach (var servo in Servos.Where(x => x.Inicializado))
{
if (servo._AnguloControle != servo._AnguloLeiutra)
double anguloDesejado = servo.Controlar ? servo._AnguloControle : servo.AnguloNeutro;
bool anguloDivergente = Math.Abs(anguloDesejado - servo._AnguloLeiutra) > 0.01;
if (anguloDivergente)
{
GeneralJoystick.EnviarComandoSensoriamento(servo.Componente, servo.ID, servo._AnguloControle);
GeneralJoystick.EnviarComandoSensoriamento(servo.Componente, servo.ID, anguloDesejado);
}
}
}
@ -2588,6 +2598,7 @@ namespace AgroBase.Models.Modules
return !Mandatorio || (Controlar && Inicializado);
}
}
public int AnguloNeutro { get; set; }
public int _AnguloControle { get; set; }
public int _AnguloLeiutra => (int)(ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.ServoAnguloLeitura)?.atual?.valor ?? -1);
public bool Inicializado { get; set; }

View File

@ -224,7 +224,6 @@ namespace AgroBase.Models
CapacidadeReservatorio = capacidadeReservatorio,
Controle = new OperacaoParametrosControleModel()
{
SonarAtivado = sonarAtivado,
MovimentoAutomatico = movimentoAutomatico,
DirecionalAutomatico = direcionalAutomatico,
PulverizadorAutomatico = pulverizadorAutomatico,
@ -384,11 +383,11 @@ namespace AgroBase.Models
DirecionalAutomatico = false,
PulverizadorAutomatico = false,
SonarAtivado = false,
FrenagemAutomaticaAoParar = false,
ImuParadaPorInclinacao = false,
OakParadaPorObstaculo = false,
MpcMatrizCusto = false,
DirAuxilioSonar = false,
MovAuxilioSonar = false,
MpcHorizonte = 4.0,
AnteciparManobraCorredorM = 0,
@ -493,11 +492,11 @@ namespace AgroBase.Models
DirecionalAutomatico = true,
PulverizadorAutomatico = true,
SonarAtivado = false,
FrenagemAutomaticaAoParar = true,
ImuParadaPorInclinacao = true,
OakParadaPorObstaculo = true,
MpcMatrizCusto = false,
DirAuxilioSonar = true,
MovAuxilioSonar = true,
MpcHorizonte = 4.0,
AnteciparManobraCorredorM = 10.0,
@ -632,11 +631,11 @@ namespace AgroBase.Models
DirecionalAutomatico = true,
PulverizadorAutomatico = false,
SonarAtivado = false,
FrenagemAutomaticaAoParar = false,
ImuParadaPorInclinacao = false,
OakParadaPorObstaculo = false,
MpcMatrizCusto = false,
DirAuxilioSonar = false,
MovAuxilioSonar = false,
MpcHorizonte = 4.0,
AnteciparManobraCorredorM = 0,
@ -769,11 +768,11 @@ namespace AgroBase.Models
DirecionalAutomatico = true,
PulverizadorAutomatico = false,
SonarAtivado = false,
FrenagemAutomaticaAoParar = true,
ImuParadaPorInclinacao = true,
OakParadaPorObstaculo = true,
MpcMatrizCusto = false,
DirAuxilioSonar = true,
MovAuxilioSonar = true,
MpcHorizonte = 4.0,
AnteciparManobraCorredorM = 10.0,
@ -867,11 +866,11 @@ namespace AgroBase.Models
DirecionalAutomatico = true,
PulverizadorAutomatico = false,
SonarAtivado = false,
FrenagemAutomaticaAoParar = true,
ImuParadaPorInclinacao = true,
OakParadaPorObstaculo = true,
MpcMatrizCusto = false,
DirAuxilioSonar = true,
MovAuxilioSonar = true,
MpcHorizonte = 4.0,
AnteciparManobraCorredorM = 0,
@ -1272,11 +1271,11 @@ namespace AgroBase.Models
if (!calibragemAtuNecessaria && !calibragemDirNecessaria && !calibragemMovNecessaria) return;
Console.WriteLine("Pausa para calibragem inicial");
Variaveis.MostrarLog("[OperacaoModel] [RealizarCalibragemInicialAsync] Pausa para calibragem inicial");
Variaveis.OperacaoEmAndamento.Pausa = true;
await Task.Delay(5000);
Console.WriteLine("Calibragem dos modulos inciada...");
Variaveis.MostrarLog("[OperacaoModel] [RealizarCalibragemInicialAsync] Calibragem dos modulos inciada...");
Variaveis.OperacaoEmAndamento.Calibrando = true;
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("calibrando", Variaveis.OperacaoEmAndamento.Calibrando));
@ -1290,7 +1289,7 @@ namespace AgroBase.Models
if (tasks.Count == 0)
{
Console.WriteLine("Nenhuma calibragem foi iniciada.");
Variaveis.MostrarLog("[OperacaoModel] [RealizarCalibragemInicialAsync] Nenhuma calibragem foi iniciada.");
_Controle.TipoMovimento = tipoControle;
Variaveis.OperacaoEmAndamento.Calibrando = false;
Variaveis.OperacaoEmAndamento.Pausa = false;
@ -1304,16 +1303,16 @@ namespace AgroBase.Models
if (completed == allTasks)
{
Console.WriteLine("Calibragem finalizada com sucesso!");
Variaveis.MostrarLog("[OperacaoModel] [RealizarCalibragemInicialAsync] Calibragem finalizada com sucesso!");
}
else
{
Console.WriteLine("Timeout na calibragem. Continuando mesmo assim.");
Variaveis.MostrarLog("[OperacaoModel] [RealizarCalibragemInicialAsync] Timeout na calibragem. Continuando mesmo assim.");
}
}
catch (Exception ex)
{
Console.WriteLine($"Erro durante calibragem: {ex.Message}");
Variaveis.MostrarLog($"[OperacaoModel] [RealizarCalibragemInicialAsync] Erro durante calibragem: {ex.Message}");
}
_Controle.TipoMovimento = tipoControle;
Variaveis.OperacaoEmAndamento.Calibrando = false;

View File

@ -206,20 +206,6 @@ namespace AgroBase.Models.Operacoes
}
}
private bool _sonarAtivado;
public bool SonarAtivado
{
get => _sonarAtivado;
set
{
if (_sonarAtivado != value)
{
_sonarAtivado = value;
OnPropertyChanged(nameof(SonarAtivado));
}
}
}
private bool _oakParadaPorObstaculo;
public bool OakParadaPorObstaculo
{
@ -450,16 +436,30 @@ namespace AgroBase.Models.Operacoes
}
}
private bool _mpcMatrizCusto;
public bool MpcMatrizCusto
private bool _movAuxilioSonar;
public bool MovAuxilioSonar
{
get => _mpcMatrizCusto;
get => _movAuxilioSonar;
set
{
if (_mpcMatrizCusto != value)
if (_movAuxilioSonar != value)
{
_mpcMatrizCusto = value;
OnPropertyChanged(nameof(MpcMatrizCusto));
_movAuxilioSonar = value;
OnPropertyChanged(nameof(MovAuxilioSonar));
}
}
}
private bool _dirAuxilioSonar;
public bool DirAuxilioSonar
{
get => _dirAuxilioSonar;
set
{
if (_dirAuxilioSonar != value)
{
_dirAuxilioSonar = value;
OnPropertyChanged(nameof(DirAuxilioSonar));
}
}
}

View File

@ -17,6 +17,7 @@ namespace AgroBase.Models.Operadores
public VisualWorkerMessageAnaliseModel Analises { get; set; } = new VisualWorkerMessageAnaliseModel();
public VisualWorkerMessageIMUModel Imu { get; set; } = new VisualWorkerMessageIMUModel();
public StatusModulo Status { get; set; }
public bool StatusValido => new List<StatusModulo>() { StatusModulo.Operante, StatusModulo.Alerta }.Contains(Status);
public VisualWorkerResumoModel Resumo { get; set; }
public VisualWorkerModel Clone()
@ -56,7 +57,8 @@ namespace AgroBase.Models.Operadores
public double ErroLateral { get; set; }
public double ErroAngular { get; set; }
public bool ObstaculoDetectado { get; set; } = false;
public string Modo { get; set; }
public bool ParadaDetectada { get; set; } = false;
public bool DeveParar { get; set; } = false;
public bool EnviarComandoParada { get; set; } = false;
public bool EnviarComandoRetomada { get; set; } = false;
@ -66,7 +68,8 @@ namespace AgroBase.Models.Operadores
public void AtualizarStatusBloqueio(bool consideraEmMovimento)
{
var Sonar = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorVisual;
ObstaculoDetectado = (Sonar?.Analises?.matriz_confianca?.block?.decision?.parar ?? false);
Modo = Sonar?.Analises?.matriz_confianca?.block?.decision?.mode ?? "free";
ParadaDetectada = (Sonar?.Analises?.matriz_confianca?.block?.decision?.parar ?? false);
StatusCarro = Sonar?.Analises?.segmentacao?.status_corredor ?? StatusCarroMapa.Indefinido;
ErroLateral = Sonar?.Analises?.segmentacao?.erro_lateral_pct ?? 0;
ErroAngular = Sonar?.Analises?.segmentacao?.erro_angular ?? 0;
@ -84,13 +87,13 @@ namespace AgroBase.Models.Operadores
Direcao _ultimaDirecaoControle = Variaveis.OperacaoEmAndamento.Controle?.TiposControle?.FirstOrDefault(x => x?.Tipo == T_Code.Mov)?.UltimaDirecao ?? Direcao.Parado;
bool _carroEmMovimento = _direcoesInterromperMovimento.Contains(_ultimaDirecaoControle);
bool emMovimento = consideraEmMovimento ? _carroEmMovimento : true;
DeveParar = Sonar?.Status == StatusModulo.Operante && ObstaculoDetectado;
DeveParar = Sonar?.StatusValido == true && (ParadaDetectada || Modo == "stop");
EnviarComandoParada = DeveParar && emMovimento;
if (EnviarComandoParada)
{
_comandoParadaEnviado = true;
}
EnviarComandoRetomada = !ObstaculoDetectado && _comandoParadaEnviado;
EnviarComandoRetomada = !ParadaDetectada && _comandoParadaEnviado;
if (EnviarComandoRetomada)
{
_comandoParadaEnviado = false;
@ -105,7 +108,8 @@ namespace AgroBase.Models.Operadores
StatusCarro = StatusCarro,
ErroLateral = ErroLateral,
ErroAngular = ErroAngular,
ObstaculoDetectado = ObstaculoDetectado,
Modo = Modo,
ParadaDetectada = ParadaDetectada,
DeveParar = DeveParar,
EnviarComandoParada = EnviarComandoParada,
EnviarComandoRetomada = EnviarComandoRetomada,

View File

@ -176,7 +176,7 @@ namespace AgroBase.Models
public void DetectarObstaculos(OAKDLiteSubdivisoesModel modelo)
{
Subdivisoes = service.ConverterSubdivisoes(modelo);
Obstaculos = service.IdentificarObstaculos(Subdivisoes, Variaveis.OperacaoEmAndamento.Parametros.Controle.SonarAtivado);
Obstaculos = service.IdentificarObstaculos(Subdivisoes, false);
AtualizarDadosObstaculos(modelo?.x_max ?? 640, modelo?.y_max ?? 480);
}

View File

@ -476,6 +476,13 @@ namespace AgroBase.Models
public static double CapacidadeReservatorio { get; set; } = 30;
public static double PressaoMinimaCavitacao { get; set; } = 30.0;
public static double ReducaoDirecional { get; set; } = 20.0;
public static double PercentualVelMin
{
get
{
return (RPM_Min_Roda / RPM_Max_Roda) * 100.0;
}
}
public static int RPM_Min_Roda { get; set; } = 15;
public static int RPM_Max_Roda
{

View File

@ -624,7 +624,7 @@ namespace AgroBase.Services
public static Bitmap ExibirObstaculos(Bitmap bitmap, List<Subdivisao> subdivisoes, List<Obstaculo> obstaculos, bool ExibirTexto = false)
{
if (bitmap == null || (!Variaveis.OperacaoEmAndamento.Parametros.Controle.SonarAtivado && Variaveis.OperacaoEmAndamento.Iniciado))
if (bitmap == null || (!false && Variaveis.OperacaoEmAndamento.Iniciado))
{
return bitmap;
}
@ -968,7 +968,7 @@ namespace AgroBase.Services
private static List<Obstaculo> IdentificarObstaculos()
{
if (!Variaveis.OperacaoEmAndamento.Parametros.Controle.SonarAtivado || Parametros.Subdivisoes == null)
if (!false || Parametros.Subdivisoes == null)
{
return new List<Obstaculo>();
}

View File

@ -209,6 +209,7 @@ namespace AgroBase.Services.Operadores
("base_porta_caminho", VariaveisEquipamento.Parametros.base_porta_caminho),
("base_porta_ervas", VariaveisEquipamento.Parametros.base_porta_ervas),
("serial_number", VariaveisEquipamento.Parametros.serial_number),
("pct_vel_min", VariaveisEquipamento.PercentualVelMin),
("largura", VariaveisEquipamento.LarguraEquipamentoMm / 1000.0),
("distancia_entre_eixos", VariaveisEquipamento.DistanciaEntreEixos / 100.0),
("qtd_bicos", VariaveisEquipamento.QuantidadeBicosPulverizadores),
@ -294,7 +295,6 @@ namespace AgroBase.Services.Operadores
velocidade_max = Math.Round(FuncoesMatematicas.CalculaVelocidadeMsPercentual(pControle.MovVelocidadeSErvasPercent), 4),
tempo_entre_comandos = (Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == Enums.T_Code.Dir)?.DelayEnvioComando ?? 500) / 1000.0,
horizonte = pControle.MpcHorizonte,
usa_matriz_custo = pControle.MpcMatrizCusto,
passos_atraso = 1,
}
}
@ -353,7 +353,8 @@ namespace AgroBase.Services.Operadores
("frenagem_automatica", pControle.FrenagemAutomaticaAoParar),
("oak_parada_por_bloqueio", pControle.OakParadaPorObstaculo),
("imu_parada_por_inclinacao", pControle.ImuParadaPorInclinacao),
("mpc_matriz_custo", pControle.MpcMatrizCusto),
("dir_auxilio_sonar", pControle.DirAuxilioSonar),
("mov_auxilio_sonar", pControle.MovAuxilioSonar),
("pressao_linha", pControle.AtuPressaoLinha),

View File

@ -71,7 +71,7 @@ namespace AgroBase.Services.Operadores
}
if (comandoMudou)
{
Console.WriteLine("Comando dos bicos alterado: " + JsonConvert.SerializeObject(novoComando));
Variaveis.MostrarLog("[WeedWorkerService] [AtualizarControle] Comando dos bicos alterado: " + JsonConvert.SerializeObject(novoComando));
var pControle = Variaveis.OperacaoEmAndamento.Parametros.Controle;
if (pControle.PulverizadorAutomatico)
{

View File

@ -164,7 +164,7 @@ namespace AgroBase.Services
public static Bitmap ExibirObstaculos(Bitmap bitmap, SonarCamModel leitura, bool ExibirTexto = false)
{
if (bitmap == null || (!Variaveis.OperacaoEmAndamento.Parametros.Controle.SonarAtivado && Variaveis.OperacaoEmAndamento.Iniciado))
if (bitmap == null || (!false && Variaveis.OperacaoEmAndamento.Iniciado))
{
return bitmap;
}

View File

@ -17,35 +17,48 @@ def definir_comando(pid: PIDAdaptativo, envio_necessario: bool):
_equipamento = ContextoGlobalRedis.get_equipamento()
_trajetoria = _contexto.get("Trajetoria", {})
_snr = ContextoGlobalRedis.get_modulo(T_Code.Snr)
usa_matriz_custo = _controle.get("mpc_matriz_custo", False)
visual_worker_operante = (_snr.get("saude", {}).get("status", StatusModulo.DESCONECTADO.value)) == StatusModulo.OPERANTE.value
_dados_vw = ContextoGlobalRedis.get(CtxKey.DadosVisualWorker, {})
_snapshot_vw = _dados_vw.get("matriz_confianca")
custo = None
nav = None
dists = None
escalas = None
block = None
if not _snapshot_vw:
visual_worker_atualizado = False
else:
visual_worker_atualizado = (time.time() - _snapshot_vw.get("ts", 0.0) <= 1.0)
if visual_worker_atualizado:
custo, conf, anom, nav = unpack_snapshot(_snapshot_vw)
dists = _snapshot_vw.get("row_dist_m", None)
escalas = _snapshot_vw.get("row_scale_x_m", None)
block = _snapshot_vw.get("block", None)
matriz_valida = (
visual_worker_operante
and visual_worker_atualizado
and _snapshot_vw is not None
and custo is not None
and nav is not None
and dists is not None
and escalas is not None
and block is not None
)
usar_dados_sonar = _controle.get("dir_auxilio_sonar", False)
dados_visual_worker = None
if usar_dados_sonar:
_snr = ContextoGlobalRedis.get_modulo(T_Code.Snr)
visual_worker_operante = (_snr.get("saude", {}).get("status", StatusModulo.DESCONECTADO.value)) == StatusModulo.OPERANTE.value
_dados_vw = ContextoGlobalRedis.get(CtxKey.DadosVisualWorker, {})
_snapshot_vw = _dados_vw.get("matriz_confianca")
custo = None
nav = None
dists = None
escalas = None
block = None
if not _snapshot_vw:
visual_worker_atualizado = False
else:
visual_worker_atualizado = (time.time() - _snapshot_vw.get("ts", 0.0) <= 1.0)
if visual_worker_atualizado:
custo, conf, anom, nav = unpack_snapshot(_snapshot_vw)
dists = _snapshot_vw.get("row_dist_m", None)
escalas = _snapshot_vw.get("row_scale_x_m", None)
block = _snapshot_vw.get("block", None)
matriz_valida = (
visual_worker_operante
and visual_worker_atualizado
and _snapshot_vw is not None
and custo is not None
and nav is not None
and dists is not None
and escalas is not None
and block is not None
)
dados_visual_worker = {
"Operante": visual_worker_operante,
"Atualizado": visual_worker_atualizado,
"MatrizCusto": {
"Valida": matriz_valida,
"Custo": custo,
"Navegavel": nav,
"DistanciasRef": dists,
"EscalasX": escalas,
},
}
_gps = ContextoGlobalRedis.get_modulo(T_Code.Gps)
_gps_pos_atualizada = _gps.get("heartbeat", 0) != _gps.get("old_heartbeat", 0)
@ -90,19 +103,7 @@ def definir_comando(pid: PIDAdaptativo, envio_necessario: bool):
"TempoEntreComandos": _operacao.get("Dir", {}).get("mpc", {}).get("tempo_entre_comandos", 0.5),
"PassosAtraso": _operacao.get("Dir", {}).get("mpc", {}).get("passos_atraso", 1),
},
"VisualWorker": {
"Ativado": usa_matriz_custo,
"Operante": visual_worker_operante,
"Atualizado": visual_worker_atualizado,
"MatrizCusto": {
"EmUso": usa_matriz_custo,
"Valida": matriz_valida,
"Custo": custo,
"Navegavel": nav,
"DistanciasRef": dists,
"EscalasX": escalas,
},
},
"VisualWorker": dados_visual_worker,
"Equipamento": {
"largura": _equipamento.get("largura", 0.85),
"entre_eixos": _equipamento.get("distancia_entre_eixos", 0.92)

View File

@ -1,3 +1,4 @@
import time
from shared.enums import ModoOperacao, StatusModulo, StatusCarroMapa, T_Code
from shared.contexto_global_redis import ContextoGlobalRedis, CtxKey
from manager_worker.config import mostrar_log
@ -7,27 +8,29 @@ def definir_comando(filtro_vel: FiltroVelocidade, erro_orientacao: float = None)
try:
_operacao = ContextoGlobalRedis.get_operacao()
_controle = ContextoGlobalRedis.get_controle()
_contexto = ContextoGlobalRedis.get_contexto()
_equipamento = ContextoGlobalRedis.get_equipamento()
op_modo = ModoOperacao(_operacao.get("modo", ModoOperacao.NaoDefinido.value))
_contexto = ContextoGlobalRedis.get_contexto()
pulverizador_automatico = _controle.get("pulverizador_automatico", False)
#ervas_no_radar = _contexto.get("Gerais", {}).get("ervas_no_radar", False)
#percentual_ervas_no_radar = (_contexto.get("Gerais", {}).get("percentual_ervas_no_radar", 0)) * 100.0
usar_dados_sonar = _controle.get("mov_auxilio_sonar", False)
_dados_ww = ContextoGlobalRedis.get(CtxKey.DadosWeedWorker, {}).get("analise", {})
ervas_no_radar = _dados_ww.get("ervas_no_radar", False)
percentual_ervas_no_radar = (_dados_ww.get("estatisticas", {}).get("erva", {}) or {}).get("ema_global", 0.0)
_dados_vw = ContextoGlobalRedis.get(CtxKey.DadosVisualWorker, {}) if usar_dados_sonar else {}
_snapshot_vw = _dados_vw.get("matriz_confianca")
visual_worker_atualizado = _snapshot_vw is not None and (time.time() - _snapshot_vw.get("ts", 0.0) <= 1.0)
pontos_min = 3
vel_min = 15.0
ervas_min_percenet = 0.005 # 0.5%
#pct_erva_bico_on = _contexto.get("Atu", {}).get("pct_erva_bico_on", 0.03)
#qtd_bicos = _contexto.get("Atu", {}).get("qtd_bicos", 3.0)
#ervas_min_percenet = round(pct_erva_bico_on / qtd_bicos, 5)
vel_com_ervas = _operacao.get("Mov", {}).get("percent_vel_min", 0)
vel_sem_ervas = _operacao.get("Mov", {}).get("percent_vel_max", 100)
ang_max = _operacao.get("Dir", {}).get("angulo_max", 30)
vel_min = max(0.0, float(_equipamento.get("pct_vel_min", 15.0)))
ervas_min_percent = 0.005 # 0.5%
vel_com_ervas = float(max(vel_min, _operacao.get("Mov", {}).get("percent_vel_min", 0)))
vel_sem_ervas = float(max(vel_com_ervas, _operacao.get("Mov", {}).get("percent_vel_max", 100)))
ang_max = float(_operacao.get("Dir", {}).get("angulo_max", 30))
status_ipb = StatusModulo(ContextoGlobalRedis.get_modulo(T_Code.Ipb).get("saude", {}).get("status", StatusModulo.DESCONECTADO.value))
debug_mode = _operacao.get("debug_mode", False)
@ -39,42 +42,106 @@ def definir_comando(filtro_vel: FiltroVelocidade, erro_orientacao: float = None)
if op_modo in [ModoOperacao.MapaGPS, ModoOperacao.RetornoBase]:
_trajetoria = _contexto.get("Trajetoria", {})
status_carro = StatusCarroMapa(_trajetoria.get("status", StatusCarroMapa.Parado.value))
if erro_orientacao is None: erro_orientacao = _trajetoria.get("erro_angular", 0)
if erro_orientacao is None:
erro_orientacao = _trajetoria.get("erro_angular", 0)
pontos_fim_corredor = _trajetoria.get("CorredorAtual", {}).get("pontos_restantes", -1)
elif op_modo == ModoOperacao.MapeamentoVisual:
_dados_vw = ContextoGlobalRedis.get(CtxKey.DadosVisualWorker, {})
status_carro = StatusCarroMapa(_dados_vw.get("segmentacao", {}).get("status_corredor", StatusCarroMapa.Parado.value))
if erro_orientacao is None: erro_orientacao = _dados_vw.get("segmentacao", {}).get("erro_angular", 0)
if erro_orientacao is None:
erro_orientacao = _dados_vw.get("segmentacao", {}).get("erro_angular", 0)
if erro_orientacao is None:
erro_orientacao = 0.0
velocidade_sp = vel_com_ervas
filtrar_velocidade = True
# -----------------------------
# 1) Velocidade base operacional
# -----------------------------
if status_ipb != StatusModulo.OPERANTE and not debug_mode:
velocidade_sp = vel_min
filtrar_velocidade = False
elif status_carro == StatusCarroMapa.Parado:
velocidade_sp = 0
velocidade_sp = 0.0
filtrar_velocidade = False
elif status_carro in [StatusCarroMapa.Direcionando, StatusCarroMapa.RetornandoBase]:
velocidade_sp = calcular_velocidade_relativa(vel_com_ervas, vel_sem_ervas, ang_max, erro_orientacao, k=0.85, curva=0.8, dead=10.0)
velocidade_sp = calcular_velocidade_relativa(
vel_com_ervas, vel_sem_ervas, ang_max, erro_orientacao,
k=0.85, curva=0.8, dead=10.0
)
elif status_carro in [StatusCarroMapa.EntrandoRua, StatusCarroMapa.SaindoRua, StatusCarroMapa.Manobrando]:
velocidade_sp = min(vel_min, vel_com_ervas)
velocidade_sp = vel_com_ervas
elif status_carro == StatusCarroMapa.CaminhandoRua:
reduzir_para_pulverizar = pulverizador_automatico and ervas_no_radar and percentual_ervas_no_radar > ervas_min_percenet
reduzir_para_pulverizar = (
pulverizador_automatico and
ervas_no_radar and
percentual_ervas_no_radar > ervas_min_percent
)
reduzir_para_manobrar = -1 < pontos_fim_corredor <= pontos_min
if reduzir_para_pulverizar or reduzir_para_manobrar:
velocidade_sp = vel_com_ervas
else:
velocidade_sp = calcular_velocidade_relativa(vel_com_ervas, vel_sem_ervas, ang_max, erro_orientacao, k=1.0, curva=0.7, dead=5.0)
velocidade_sp = calcular_velocidade_relativa(
vel_com_ervas, vel_sem_ervas, ang_max, erro_orientacao,
k=1.0, curva=0.7, dead=5.0
)
# Aplica limites
velocidade_sp = max(vel_com_ervas, min(vel_sem_ervas, velocidade_sp))
# -----------------------------
# 2) Limitadores do Visual Worker
# -----------------------------
if usar_dados_sonar and visual_worker_atualizado and filtrar_velocidade:
block = _dados_vw.get("matriz_confianca", {}).get("block", {})
decision = block.get("decision", {}) or {}
mode = str(decision.get("mode", "free") or "free").lower()
v_max_sugerida_mps = decision.get("v_max_sugerida_mps", None)
fator_mode = {
"free": 1.00,
"watch": 0.90,
"caution": 0.75,
"slowdown": 0.50,
"stop": 0.10,
}.get(mode, 1.00)
# aplica fator semântico do cenário
velocidade_sp *= fator_mode
# aplica teto por velocidade sugerida, se existir
if v_max_sugerida_mps is not None:
try:
vel_max_mps_operacao = float(_operacao.get("Mov", {}).get("velocidade_mps_max", 0.0))
if vel_max_mps_operacao > 1e-6:
vel_visual_pct = (float(v_max_sugerida_mps) / vel_max_mps_operacao) * vel_sem_ervas
vel_visual_pct = max(0.0, min(vel_sem_ervas, vel_visual_pct))
velocidade_sp = min(velocidade_sp, vel_visual_pct)
except Exception:
pass
# -----------------------------
# 3) Clamp final corrigido
# -----------------------------
velocidade_sp = max(0.0, min(vel_sem_ervas, velocidade_sp))
if velocidade_sp > 0.0:
velocidade_sp = max(vel_min, velocidade_sp)
# -----------------------------
# 4) Filtro final
# -----------------------------
if velocidade_sp < 1.0 or reduzir_para_pulverizar:
filtro_vel.reset(velocidade_sp)
else:
velocidade_sp = filtro_vel.filtrar(velocidade_sp)
#mostrar_log(f"🚗 Velocidade definida: {velocidade_sp:.1f}%")
return _montar_comando_retorno(round(velocidade_sp, 2))
return _montar_comando_retorno(velocidade_sp)
except Exception as e:
mostrar_log(f"Erro ao definir o comando de movimentacao: {e}")

View File

@ -1084,10 +1084,10 @@ class ControladorMPC:
tipos_validos = [TipoMovimentoDirecional.RodasDianteiras]
# 3) Flags de matriz
usar_dados_sonar = contexto.get("VisualWorker") is not None
dados_matriz_custo = contexto.get("VisualWorker", {}).get("MatrizCusto", {})
regra_matriz_custo = bool(dados_matriz_custo.get("EmUso", False))
matriz_custo_valida = bool(dados_matriz_custo.get("Valida", False))
filtrar_matriz = regra_matriz_custo and matriz_custo_valida
filtrar_matriz = usar_dados_sonar and matriz_custo_valida
# 4) Geração bruta (graus)
angulos_raw = self._gerar_candidatos_brutos(angulo_ideal_deg, filtrar_matriz)

View File

@ -45,7 +45,7 @@ class RegrasTaticas:
_snr_saude = StatusModulo(_snr.get("saude", {}).get("status", StatusModulo.DESCONECTADO.value))
snr_operante = _snr_saude in [StatusModulo.OPERANTE, StatusModulo.ALERTA]
_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.time() - _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)
obstaculo_persistente = self._avaliar_persistencia(

View File

@ -1,6 +1,5 @@
using AgroBase.Models;
using AgroBase.Services;
using OperationControl.ViewModels;
using OperationControl.Windows;
using static AgroBase.Models.Enums;
@ -8,8 +7,8 @@ namespace OperationControl.Models
{
public class AppShell
{
public static readonly bool Mock = true;
private static readonly bool AddRover = false;
public static readonly bool Mock = false;
public static readonly bool AddRover = false;
private readonly System.Timers.Timer tmrComunicacao = new(1000) { AutoReset = true };
private int tmrComunicacaoTicks = 0;
@ -171,10 +170,11 @@ namespace OperationControl.Models
MovVelocidadeCErvasPercent = 20,
MovVelocidadeSErvasPercent = 50,
MpcHorizonte = 4,
MpcMatrizCusto = false,
DirAuxilioSonar = false,
MovAuxilioSonar = false,
OakParadaPorObstaculo = false,
RegistrarDadosPosProcessamento = false,
SonarAtivado = false
AnteciparManobraCorredorM = 10
};
});
}

View File

@ -81,20 +81,6 @@
<StackPanel>
<TextBlock Text="Automação Geral" Foreground="White" FontSize="15" FontWeight="SemiBold" Margin="0,0,0,12"/>
<CheckBox Content="Movimento Automático" IsChecked="{Binding Parametros.Controle.MovimentoAutomatico}" Style="{StaticResource ParamCheckBoxStyle}"/>
<CheckBox Content="Direcional Automático" IsChecked="{Binding Parametros.Controle.DirecionalAutomatico}" Style="{StaticResource ParamCheckBoxStyle}"/>
<CheckBox Content="Pulverizador Automático" IsChecked="{Binding Parametros.Controle.PulverizadorAutomatico}" Style="{StaticResource ParamCheckBoxStyle}"/>
<CheckBox Content="Sonar Ativado" IsChecked="{Binding Parametros.Controle.SonarAtivado}" Style="{StaticResource ParamCheckBoxStyle}"/>
<CheckBox Content="Parada por Obstáculo (OAK)" IsChecked="{Binding Parametros.Controle.OakParadaPorObstaculo}" Style="{StaticResource ParamCheckBoxStyle}"/>
<CheckBox Content="Parada por Inclinação (IMU)" IsChecked="{Binding Parametros.Controle.ImuParadaPorInclinacao}" Style="{StaticResource ParamCheckBoxStyle}"/>
<CheckBox Content="Frenagem Automática ao Parar" IsChecked="{Binding Parametros.Controle.FrenagemAutomaticaAoParar}" Style="{StaticResource ParamCheckBoxStyle}"/>
<CheckBox Content="Registrar Dados Pós-Processamento" IsChecked="{Binding Parametros.Controle.RegistrarDadosPosProcessamento}" Style="{StaticResource ParamCheckBoxStyle}" Margin="0,0,0,0"/>
</StackPanel>
</Border>
@ -104,6 +90,12 @@
<StackPanel>
<TextBlock Text="Movimento" Foreground="White" FontSize="15" FontWeight="SemiBold" Margin="0,0,0,12"/>
<CheckBox Content="Automático" IsChecked="{Binding Parametros.Controle.MovimentoAutomatico}" Style="{StaticResource ParamCheckBoxStyle}"/>
<CheckBox Content="Parada por Obstáculo (OAK)" IsChecked="{Binding Parametros.Controle.OakParadaPorObstaculo}" Style="{StaticResource ParamCheckBoxStyle}"/>
<CheckBox Content="Parada por Inclinação (IMU)" IsChecked="{Binding Parametros.Controle.ImuParadaPorInclinacao}" Style="{StaticResource ParamCheckBoxStyle}"/>
<CheckBox Content="Frenagem Automática ao Parar" IsChecked="{Binding Parametros.Controle.FrenagemAutomaticaAoParar}" Style="{StaticResource ParamCheckBoxStyle}"/>
<CheckBox Content="Assistido por Sonar" IsChecked="{Binding Parametros.Controle.MovAuxilioSonar}" Style="{StaticResource ParamCheckBoxStyle}" />
<TextBlock Text="Velocidade sem Ervas (%)" Style="{StaticResource ParamLabelStyle}"/>
<TextBox Text="{Binding Parametros.Controle.MovVelocidadeSErvasPercent, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ParamTextBoxStyle}"/>
@ -123,6 +115,9 @@
<StackPanel>
<TextBlock Text="Direcional" Foreground="White" FontSize="15" FontWeight="SemiBold" Margin="0,0,0,12"/>
<CheckBox Content="Direcional Automático" IsChecked="{Binding Parametros.Controle.DirecionalAutomatico}" Style="{StaticResource ParamCheckBoxStyle}"/>
<CheckBox Content="Assistido por Sonar" IsChecked="{Binding Parametros.Controle.DirAuxilioSonar}" Style="{StaticResource ParamCheckBoxStyle}" />
<TextBlock Text="Ângulo Máximo (°)" Style="{StaticResource ParamLabelStyle}"/>
<TextBox Text="{Binding Parametros.Controle.DirAnguloMaximo, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ParamTextBoxStyle}"/>
@ -139,6 +134,8 @@
<StackPanel>
<TextBlock Text="Pulverização" Foreground="White" FontSize="15" FontWeight="SemiBold" Margin="0,0,0,12"/>
<CheckBox Content="Automático" IsChecked="{Binding Parametros.Controle.PulverizadorAutomatico}" Style="{StaticResource ParamCheckBoxStyle}"/>
<TextBlock Text="Quantidade de Bicos" Style="{StaticResource ParamLabelStyle}"/>
<TextBox Text="{Binding Parametros.QtdBicos, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ParamTextBoxStyle}"/>

View File

@ -1814,14 +1814,15 @@ namespace OperationControl.Windows
MovimentoAutomatico = modo != AgroBase.Models.Enums.ModoOperacao.Manual,
DirecionalAutomatico = modo != AgroBase.Models.Enums.ModoOperacao.Manual,
SonarAtivado = false,
FrenagemAutomaticaAoParar = chbParametros_Frenagem.IsChecked ?? false,
MovVelocidadeCErvasPercent = int.Parse(txtParametros_VelCErvas.Text),
MovVelocidadeSErvasPercent = int.Parse(txtParametros_VelSErvas.Text),
ImuParadaPorInclinacao = false,
MpcHorizonte = 4,
MpcMatrizCusto = false,
DirAuxilioSonar = false,
MovAuxilioSonar = false,
AnteciparManobraCorredorM = 10,
OakParadaPorObstaculo = chbParametros_ParadaObstaculo.IsChecked ?? false,
RegistrarDadosPosProcessamento = false,