ajustes no weed worker para segmentacao

This commit is contained in:
Diego Freitas 2025-07-30 14:04:46 -03:00
parent 1e2bf6e885
commit 8b341d804b
192 changed files with 3168 additions and 767 deletions

Binary file not shown.

View File

@ -368,16 +368,16 @@
<Compile Include="Forms\frmPinout.Designer.cs">
<DependentUpon>frmPinout.cs</DependentUpon>
</Compile>
<Compile Include="Forms\frmSimulacaoMapaGPS.cs">
<Compile Include="Forms\Simuladores\frmSimulacaoMapaGPS.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\frmSimulacaoMapaGPS.Designer.cs">
<Compile Include="Forms\Simuladores\frmSimulacaoMapaGPS.Designer.cs">
<DependentUpon>frmSimulacaoMapaGPS.cs</DependentUpon>
</Compile>
<Compile Include="Forms\frmTreinamentoIA.cs">
<Compile Include="Forms\Simuladores\frmTreinamentoIA.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\frmTreinamentoIA.Designer.cs">
<Compile Include="Forms\Simuladores\frmTreinamentoIA.Designer.cs">
<DependentUpon>frmTreinamentoIA.cs</DependentUpon>
</Compile>
<Compile Include="Forms\frmWT901C.cs">
@ -494,6 +494,12 @@
<Compile Include="Forms\Sensoriamento\frmSonar.Designer.cs">
<DependentUpon>frmSonar.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Simuladores\frmSimulacaoMapeamentoVisual.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\Simuladores\frmSimulacaoMapeamentoVisual.Designer.cs">
<DependentUpon>frmSimulacaoMapeamentoVisual.cs</DependentUpon>
</Compile>
<Compile Include="Models\AlarmeModel.cs" />
<Compile Include="Models\Components\AsyncTaskTimerModel.cs" />
<Compile Include="Models\BLD300RModel.cs" />
@ -820,10 +826,13 @@
<EmbeddedResource Include="Forms\frmPinout.resx">
<DependentUpon>frmPinout.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\frmSimulacaoMapaGPS.resx">
<EmbeddedResource Include="Forms\Simuladores\frmSimulacaoMapaGPS.resx">
<DependentUpon>frmSimulacaoMapaGPS.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\frmTreinamentoIA.resx">
<EmbeddedResource Include="Forms\Simuladores\frmSimulacaoMapeamentoVisual.resx">
<DependentUpon>frmSimulacaoMapeamentoVisual.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Simuladores\frmTreinamentoIA.resx">
<DependentUpon>frmTreinamentoIA.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\frmWT901C.resx">

View File

@ -251,16 +251,6 @@ namespace AgroBase.Forms.Operacoes
}
);
}
/*txtVelocidadeSemErvas.Text = velocidadeMax.ToString("0.00");
txtVelocidadeComErvas.Text = velocidadeMin.ToString("0.00");
txtAnguloMaximo.Text = Variaveis.OperacaoEmAndamento.OpMapaGPS.Controle.Angulo_Max.ToString("0");
txtVelocidadeDirecional.Text = Variaveis.OperacaoEmAndamento.OpMapaGPS.Controle.VelocidadeMP.ToString("0");
txtPercentualAtuacao.Text = (Variaveis.OperacaoEmAndamento.OpMapaGPS.Controle.PercentualInicioPulverizacao * 100).ToString("0");
txtCapacidadeReservatorio.Text = Variaveis.OperacaoEmAndamento.CapacidadeReservatorio.ToString("0");
txtPressaoLinha.Text = Variaveis.OperacaoEmAndamento.OpMapaGPS.Controle.PressaoLinha.ToString("0");
txtDuracaoAtuacao.Text = Variaveis.OperacaoEmAndamento.OpMapaGPS.Controle.TempoAtuacao.ToString("0");*/
}
private void AddItemToFlowPanel(FlowLayoutPanel flowPanel, string path, bool isDirectory)

View File

@ -637,7 +637,7 @@ namespace AgroBase.Forms.Operacoes
private void chbPulverizador_CheckedChanged(object sender, EventArgs e)
{
Variaveis.OperacaoEmAndamento.Controle.PulverizadorAutomatico = ((CheckBox)sender).Checked;
HealthWorkerService.AtualizarDadosOperacao();
HealthWorkerService.AtualizarDadosControleOperacao();
}
private void chbSonarAtivado_CheckedChanged(object sender, EventArgs e)

View File

@ -169,6 +169,9 @@ namespace AgroBase.Forms.Operacoes
AtualizarDadosMomento();
//double distanciaOperacao = GPSUtils.DistanciaDoTrecho(LogsOperacao.Select(x => x.Gps).ToList());
//Console.WriteLine($"Distancia Percorrida: {distanciaOperacao.ToString("0.00")} m");
}
}
@ -983,8 +986,8 @@ namespace AgroBase.Forms.Operacoes
using (Graphics g = Graphics.FromImage(bitmapComObjetos))
{
// Proporção de escala
double scaleX = (double)bitmapComObjetos.Width / frame.frame_width;
double scaleY = (double)bitmapComObjetos.Height / frame.frame_height;
double scaleX = (double)bitmapComObjetos.Width / frame.width;
double scaleY = (double)bitmapComObjetos.Height / frame.height;
// Iterar sobre os objetos detectados
foreach (var objeto in frame.deteccoes)
@ -1046,8 +1049,6 @@ namespace AgroBase.Forms.Operacoes
int totalAtuacoes = Log.Atuador.ErvasIdentificadas.Sum(dict => dict.Values.Sum());
double herbicidaPorErva = Log.Atuador.HerbicidaPorErva != 0 ? Log.Atuador.HerbicidaPorErva : (herbicidaConsumido / (totalAtuacoes > 0 ? totalAtuacoes : 1));
double distanciaPercorrida = Log.Trajetoria.DistanciaPercorrida;
lblPercentualBateria.Text = $"Bateria {Log.Bateria.PorcentagemBateria.ToString("0.00")}%";
FuncoesGlobais.PreencheValorProgressBar(pgbPercentualBateria, Log.Bateria.PorcentagemBateria);
lblBateriaConsumida.Text = $"Consumido {Log.Bateria.BateriaConsumida.ToString("0.00")}%";
@ -1076,7 +1077,10 @@ namespace AgroBase.Forms.Operacoes
lblPercentualOperacao.Text = $"Operação {Log.Trajetoria.ProgressoTrajeto.ToString("0.00")}%";
FuncoesGlobais.PreencheValorProgressBar(pgbPercentualOperacao, Log.Trajetoria.ProgressoTrajeto);
txtDistanciaPercorrida.Text = distanciaPercorrida.ToString("0.00") + " m / " + Log.Trajetoria.DistanciaTotal.ToString("0.00") + " m";
double distanciaAtual = Log.Modo == Enums.ModoOperacao.MapaGPS ? Log.Trajetoria.DistanciaPercorrida : Log.Movimentacao.DistanciaPercorridaTotal;
double distanciaTotal = Log.Modo == Enums.ModoOperacao.MapaGPS ? LogsOperacao[LogsOperacao.Count - 1].Trajetoria.DistanciaTotal : LogsOperacao[LogsOperacao.Count - 1].Movimentacao.DistanciaPercorridaTotal;
txtDistanciaPercorrida.Text = distanciaAtual.ToString("0.00") + " m / " + distanciaTotal.ToString("0.00") + " m";
double percentualRua = Log.Trajetoria.CorredorAtual.Progresso;
lblPercentualRua.Text = $"Rua {percentualRua.ToString("0.00")}%";

View File

@ -102,6 +102,8 @@
this.lblTempoRestante = new System.Windows.Forms.Label();
this.lblPercentualRua = new System.Windows.Forms.Label();
this.lblPercentualOperacao = new System.Windows.Forms.Label();
this.label8 = new System.Windows.Forms.Label();
this.cmbStatusCorredor = new System.Windows.Forms.ComboBox();
this.pnlOpcoes.SuspendLayout();
this.gpbSonar.SuspendLayout();
this.gpbGPS.SuspendLayout();
@ -372,6 +374,8 @@
//
// gpbSonar
//
this.gpbSonar.Controls.Add(this.label8);
this.gpbSonar.Controls.Add(this.cmbStatusCorredor);
this.gpbSonar.Controls.Add(this.chbMoverObstaculo);
this.gpbSonar.Controls.Add(this.chbSonarVirando);
this.gpbSonar.Controls.Add(this.btnAdicionarDeteccao);
@ -393,7 +397,7 @@
// chbMoverObstaculo
//
this.chbMoverObstaculo.AutoSize = true;
this.chbMoverObstaculo.Location = new System.Drawing.Point(124, 35);
this.chbMoverObstaculo.Location = new System.Drawing.Point(127, 11);
this.chbMoverObstaculo.Margin = new System.Windows.Forms.Padding(2);
this.chbMoverObstaculo.Name = "chbMoverObstaculo";
this.chbMoverObstaculo.Size = new System.Drawing.Size(105, 17);
@ -404,7 +408,7 @@
// chbSonarVirando
//
this.chbSonarVirando.AutoSize = true;
this.chbSonarVirando.Location = new System.Drawing.Point(124, 68);
this.chbSonarVirando.Location = new System.Drawing.Point(127, 28);
this.chbSonarVirando.Margin = new System.Windows.Forms.Padding(2);
this.chbSonarVirando.Name = "chbSonarVirando";
this.chbSonarVirando.Size = new System.Drawing.Size(96, 17);
@ -949,6 +953,26 @@
this.lblPercentualOperacao.TabIndex = 42;
this.lblPercentualOperacao.Text = "Operação: 0,00%";
//
// label8
//
this.label8.AutoSize = true;
this.label8.Location = new System.Drawing.Point(117, 53);
this.label8.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label8.Name = "label8";
this.label8.Size = new System.Drawing.Size(80, 13);
this.label8.TabIndex = 41;
this.label8.Text = "Status Corredor";
//
// cmbStatusCorredor
//
this.cmbStatusCorredor.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmbStatusCorredor.FormattingEnabled = true;
this.cmbStatusCorredor.Location = new System.Drawing.Point(121, 68);
this.cmbStatusCorredor.Name = "cmbStatusCorredor";
this.cmbStatusCorredor.Size = new System.Drawing.Size(106, 21);
this.cmbStatusCorredor.TabIndex = 40;
this.cmbStatusCorredor.SelectedIndexChanged += new System.EventHandler(this.cmbStatusCorredor_SelectedIndexChanged);
//
// frmSimulacaoMapaGPS
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -1069,5 +1093,7 @@
private System.Windows.Forms.Label lblCarregado;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.TextBox txtErroTempoComando;
private System.Windows.Forms.Label label8;
private System.Windows.Forms.ComboBox cmbStatusCorredor;
}
}

View File

@ -48,6 +48,10 @@ namespace AgroBase.Forms
cmbTipoControleDirecional.Items.AddRange(Enum.GetNames(typeof(Enums.TiposControladorDirecional)));
cmbTipoControleDirecional.SelectedIndex = (int)Variaveis.OperacaoEmAndamento.Controle.TipoControleDirecional;
cmbStatusCorredor.Items.Clear();
cmbStatusCorredor.Items.AddRange(Enum.GetNames(typeof(Enums.StatusCarroMapa)));
cmbStatusCorredor.SelectedIndex = (int)StatusCarroMapa.Parado;
Variaveis.OperacaoEmAndamento.ReiniciarSimulacao();
tmrLeitura = new AsyncTaskTimerModel("tmrLeitura", tmrLeitura_Tick, (int)tempoGps, this);
@ -294,6 +298,8 @@ namespace AgroBase.Forms
AtualizarPosicaoGPS();
Variaveis.OperacaoEmAndamento.Sensoriamento.AtualizarDados();
if (!chbAutomatico.Checked)
{
AtualizarDadosTela();
@ -416,7 +422,7 @@ namespace AgroBase.Forms
{
try
{
double angulo = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.AnguloCarroDefinido;
double angulo = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps?.AnguloCarroDefinido ?? 0;
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90);
}
catch { }
@ -479,11 +485,13 @@ namespace AgroBase.Forms
Variaveis.OperacaoEmAndamento.Controle.TipoControleDirecional = (TiposControladorDirecional)cmbTipoControleDirecional.SelectedIndex;
}
private void cmbStatusCorredor_SelectedIndexChanged(object sender, EventArgs e)
{
RedisService.AtualizarCampos(
CtxKey.DadosVisualWorker,
("segmentacao.status_corredor", cmbStatusCorredor.SelectedIndex)
);
}
}

View File

@ -0,0 +1,323 @@
namespace AgroBase.Forms.Simuladores
{
partial class frmSimulacaoMapeamentoVisual
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.imgOriginal = new System.Windows.Forms.PictureBox();
this.imgSegmentacao = new System.Windows.Forms.PictureBox();
this.btnIniciarSimulacao = new System.Windows.Forms.Button();
this.btnCarregarFotos = new System.Windows.Forms.Button();
this.btnProximo = new System.Windows.Forms.Button();
this.btnAnterior = new System.Windows.Forms.Button();
this.lblErroAngular = new System.Windows.Forms.Label();
this.lblErroLateral = new System.Windows.Forms.Label();
this.lblStatusCarro = new System.Windows.Forms.Label();
this.lblVelocidadeSP = new System.Windows.Forms.Label();
this.lblAnguloSP = new System.Windows.Forms.Label();
this.lblTipoMovimento = new System.Windows.Forms.Label();
this.txtErroAngular = new System.Windows.Forms.TextBox();
this.txtErroLateral = new System.Windows.Forms.TextBox();
this.txtStatusCarro = new System.Windows.Forms.TextBox();
this.txtVelocidadeSP = new System.Windows.Forms.TextBox();
this.txtAnguloSP = new System.Windows.Forms.TextBox();
this.txtTipoMovimento = new System.Windows.Forms.TextBox();
this.lblInfo = new System.Windows.Forms.Label();
this.txtImagemAtual = new System.Windows.Forms.TextBox();
this.btnIr = new System.Windows.Forms.Button();
this.btnAtualizar = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.imgOriginal)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.imgSegmentacao)).BeginInit();
this.SuspendLayout();
//
// imgOriginal
//
this.imgOriginal.Location = new System.Drawing.Point(12, 12);
this.imgOriginal.Name = "imgOriginal";
this.imgOriginal.Size = new System.Drawing.Size(400, 400);
this.imgOriginal.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.imgOriginal.TabIndex = 0;
this.imgOriginal.TabStop = false;
//
// imgSegmentacao
//
this.imgSegmentacao.Location = new System.Drawing.Point(418, 12);
this.imgSegmentacao.Name = "imgSegmentacao";
this.imgSegmentacao.Size = new System.Drawing.Size(400, 400);
this.imgSegmentacao.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.imgSegmentacao.TabIndex = 1;
this.imgSegmentacao.TabStop = false;
//
// btnIniciarSimulacao
//
this.btnIniciarSimulacao.Location = new System.Drawing.Point(12, 594);
this.btnIniciarSimulacao.Name = "btnIniciarSimulacao";
this.btnIniciarSimulacao.Size = new System.Drawing.Size(125, 32);
this.btnIniciarSimulacao.TabIndex = 2;
this.btnIniciarSimulacao.Text = "Iniciar Simulação";
this.btnIniciarSimulacao.UseVisualStyleBackColor = true;
this.btnIniciarSimulacao.Click += new System.EventHandler(this.btnIniciarSimulacao_Click);
//
// btnCarregarFotos
//
this.btnCarregarFotos.Location = new System.Drawing.Point(12, 556);
this.btnCarregarFotos.Name = "btnCarregarFotos";
this.btnCarregarFotos.Size = new System.Drawing.Size(125, 32);
this.btnCarregarFotos.TabIndex = 3;
this.btnCarregarFotos.Text = "Carregar Fotos";
this.btnCarregarFotos.UseVisualStyleBackColor = true;
this.btnCarregarFotos.Click += new System.EventHandler(this.btnCarregarFotos_Click);
//
// btnProximo
//
this.btnProximo.Location = new System.Drawing.Point(287, 431);
this.btnProximo.Name = "btnProximo";
this.btnProximo.Size = new System.Drawing.Size(125, 32);
this.btnProximo.TabIndex = 4;
this.btnProximo.Text = "Próximo";
this.btnProximo.UseVisualStyleBackColor = true;
this.btnProximo.Click += new System.EventHandler(this.btnProximo_Click);
//
// btnAnterior
//
this.btnAnterior.Location = new System.Drawing.Point(12, 431);
this.btnAnterior.Name = "btnAnterior";
this.btnAnterior.Size = new System.Drawing.Size(125, 32);
this.btnAnterior.TabIndex = 5;
this.btnAnterior.Text = "Anterior";
this.btnAnterior.UseVisualStyleBackColor = true;
this.btnAnterior.Click += new System.EventHandler(this.btnAnterior_Click);
//
// lblErroAngular
//
this.lblErroAngular.AutoSize = true;
this.lblErroAngular.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblErroAngular.Location = new System.Drawing.Point(418, 423);
this.lblErroAngular.Name = "lblErroAngular";
this.lblErroAngular.Size = new System.Drawing.Size(98, 20);
this.lblErroAngular.TabIndex = 6;
this.lblErroAngular.Text = "Erro Angular";
//
// lblErroLateral
//
this.lblErroLateral.AutoSize = true;
this.lblErroLateral.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblErroLateral.Location = new System.Drawing.Point(418, 449);
this.lblErroLateral.Name = "lblErroLateral";
this.lblErroLateral.Size = new System.Drawing.Size(92, 20);
this.lblErroLateral.TabIndex = 7;
this.lblErroLateral.Text = "Erro Lateral";
//
// lblStatusCarro
//
this.lblStatusCarro.AutoSize = true;
this.lblStatusCarro.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblStatusCarro.Location = new System.Drawing.Point(418, 475);
this.lblStatusCarro.Name = "lblStatusCarro";
this.lblStatusCarro.Size = new System.Drawing.Size(99, 20);
this.lblStatusCarro.TabIndex = 8;
this.lblStatusCarro.Text = "Status Carro";
//
// lblVelocidadeSP
//
this.lblVelocidadeSP.AutoSize = true;
this.lblVelocidadeSP.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblVelocidadeSP.Location = new System.Drawing.Point(418, 501);
this.lblVelocidadeSP.Name = "lblVelocidadeSP";
this.lblVelocidadeSP.Size = new System.Drawing.Size(113, 20);
this.lblVelocidadeSP.TabIndex = 9;
this.lblVelocidadeSP.Text = "Velocidade SP";
//
// lblAnguloSP
//
this.lblAnguloSP.AutoSize = true;
this.lblAnguloSP.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblAnguloSP.Location = new System.Drawing.Point(418, 527);
this.lblAnguloSP.Name = "lblAnguloSP";
this.lblAnguloSP.Size = new System.Drawing.Size(84, 20);
this.lblAnguloSP.TabIndex = 10;
this.lblAnguloSP.Text = "Angulo SP";
//
// lblTipoMovimento
//
this.lblTipoMovimento.AutoSize = true;
this.lblTipoMovimento.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblTipoMovimento.Location = new System.Drawing.Point(418, 551);
this.lblTipoMovimento.Name = "lblTipoMovimento";
this.lblTipoMovimento.Size = new System.Drawing.Size(120, 20);
this.lblTipoMovimento.TabIndex = 11;
this.lblTipoMovimento.Text = "Tipo Movimento";
//
// txtErroAngular
//
this.txtErroAngular.Location = new System.Drawing.Point(544, 423);
this.txtErroAngular.Name = "txtErroAngular";
this.txtErroAngular.Size = new System.Drawing.Size(118, 20);
this.txtErroAngular.TabIndex = 12;
this.txtErroAngular.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// txtErroLateral
//
this.txtErroLateral.Location = new System.Drawing.Point(544, 449);
this.txtErroLateral.Name = "txtErroLateral";
this.txtErroLateral.Size = new System.Drawing.Size(118, 20);
this.txtErroLateral.TabIndex = 13;
this.txtErroLateral.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// txtStatusCarro
//
this.txtStatusCarro.Location = new System.Drawing.Point(544, 475);
this.txtStatusCarro.Name = "txtStatusCarro";
this.txtStatusCarro.Size = new System.Drawing.Size(118, 20);
this.txtStatusCarro.TabIndex = 14;
this.txtStatusCarro.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// txtVelocidadeSP
//
this.txtVelocidadeSP.Location = new System.Drawing.Point(544, 501);
this.txtVelocidadeSP.Name = "txtVelocidadeSP";
this.txtVelocidadeSP.Size = new System.Drawing.Size(118, 20);
this.txtVelocidadeSP.TabIndex = 15;
this.txtVelocidadeSP.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// txtAnguloSP
//
this.txtAnguloSP.Location = new System.Drawing.Point(544, 527);
this.txtAnguloSP.Name = "txtAnguloSP";
this.txtAnguloSP.Size = new System.Drawing.Size(118, 20);
this.txtAnguloSP.TabIndex = 16;
this.txtAnguloSP.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// txtTipoMovimento
//
this.txtTipoMovimento.Location = new System.Drawing.Point(544, 553);
this.txtTipoMovimento.Name = "txtTipoMovimento";
this.txtTipoMovimento.Size = new System.Drawing.Size(118, 20);
this.txtTipoMovimento.TabIndex = 17;
this.txtTipoMovimento.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// lblInfo
//
this.lblInfo.AutoSize = true;
this.lblInfo.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblInfo.Location = new System.Drawing.Point(12, 415);
this.lblInfo.Name = "lblInfo";
this.lblInfo.Size = new System.Drawing.Size(33, 13);
this.lblInfo.TabIndex = 18;
this.lblInfo.Text = "0/0 - ";
//
// txtImagemAtual
//
this.txtImagemAtual.Location = new System.Drawing.Point(12, 469);
this.txtImagemAtual.Name = "txtImagemAtual";
this.txtImagemAtual.Size = new System.Drawing.Size(53, 20);
this.txtImagemAtual.TabIndex = 19;
this.txtImagemAtual.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// btnIr
//
this.btnIr.Location = new System.Drawing.Point(71, 469);
this.btnIr.Name = "btnIr";
this.btnIr.Size = new System.Drawing.Size(66, 20);
this.btnIr.TabIndex = 20;
this.btnIr.Text = "Ir";
this.btnIr.UseVisualStyleBackColor = true;
this.btnIr.Click += new System.EventHandler(this.btnIr_Click);
//
// btnAtualizar
//
this.btnAtualizar.Location = new System.Drawing.Point(149, 431);
this.btnAtualizar.Name = "btnAtualizar";
this.btnAtualizar.Size = new System.Drawing.Size(125, 32);
this.btnAtualizar.TabIndex = 21;
this.btnAtualizar.Text = "Atualizar";
this.btnAtualizar.UseVisualStyleBackColor = true;
this.btnAtualizar.Click += new System.EventHandler(this.btnAtualizar_Click);
//
// frmSimulacaoMapeamentoVisual
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(833, 638);
this.Controls.Add(this.btnAtualizar);
this.Controls.Add(this.btnIr);
this.Controls.Add(this.txtImagemAtual);
this.Controls.Add(this.lblInfo);
this.Controls.Add(this.txtTipoMovimento);
this.Controls.Add(this.txtAnguloSP);
this.Controls.Add(this.txtVelocidadeSP);
this.Controls.Add(this.txtStatusCarro);
this.Controls.Add(this.txtErroLateral);
this.Controls.Add(this.txtErroAngular);
this.Controls.Add(this.lblTipoMovimento);
this.Controls.Add(this.lblAnguloSP);
this.Controls.Add(this.lblVelocidadeSP);
this.Controls.Add(this.lblStatusCarro);
this.Controls.Add(this.lblErroLateral);
this.Controls.Add(this.lblErroAngular);
this.Controls.Add(this.btnAnterior);
this.Controls.Add(this.btnProximo);
this.Controls.Add(this.btnCarregarFotos);
this.Controls.Add(this.btnIniciarSimulacao);
this.Controls.Add(this.imgSegmentacao);
this.Controls.Add(this.imgOriginal);
this.Name = "frmSimulacaoMapeamentoVisual";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Simulador de operação Mapeamento Visual";
((System.ComponentModel.ISupportInitialize)(this.imgOriginal)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.imgSegmentacao)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.PictureBox imgOriginal;
private System.Windows.Forms.PictureBox imgSegmentacao;
private System.Windows.Forms.Button btnIniciarSimulacao;
private System.Windows.Forms.Button btnCarregarFotos;
private System.Windows.Forms.Button btnProximo;
private System.Windows.Forms.Button btnAnterior;
private System.Windows.Forms.Label lblErroAngular;
private System.Windows.Forms.Label lblErroLateral;
private System.Windows.Forms.Label lblStatusCarro;
private System.Windows.Forms.Label lblVelocidadeSP;
private System.Windows.Forms.Label lblAnguloSP;
private System.Windows.Forms.Label lblTipoMovimento;
private System.Windows.Forms.TextBox txtErroAngular;
private System.Windows.Forms.TextBox txtErroLateral;
private System.Windows.Forms.TextBox txtStatusCarro;
private System.Windows.Forms.TextBox txtVelocidadeSP;
private System.Windows.Forms.TextBox txtAnguloSP;
private System.Windows.Forms.TextBox txtTipoMovimento;
private System.Windows.Forms.Label lblInfo;
private System.Windows.Forms.TextBox txtImagemAtual;
private System.Windows.Forms.Button btnIr;
private System.Windows.Forms.Button btnAtualizar;
}
}

View File

@ -0,0 +1,185 @@
using AgroBase.Models;
using AgroBase.Models.Operadores;
using AgroBase.Services;
using AgroBase.Services.Operadores;
using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AgroBase.Forms.Simuladores
{
public partial class frmSimulacaoMapeamentoVisual : Form
{
private List<string> imagens = new List<string>();
private int indiceAtual = 0;
private string pastaSelecionada = "";
private readonly object imgLock = new object();
public frmSimulacaoMapeamentoVisual()
{
InitializeComponent();
}
private void btnCarregarFotos_Click(object sender, EventArgs e)
{
using (var dialog = new FolderBrowserDialog())
{
if (dialog.ShowDialog() == DialogResult.OK)
{
pastaSelecionada = dialog.SelectedPath;
imagens = Directory.GetFiles(pastaSelecionada, "*_rgb.jpeg", SearchOption.TopDirectoryOnly)
.OrderBy(f =>
{
var nome = Path.GetFileNameWithoutExtension(f);
var numTexto = nome.Split('_').FirstOrDefault();
return int.TryParse(numTexto, out int num) ? num : int.MaxValue;
})
.ToList();
indiceAtual = 0;
MostrarImagemAtual();
}
}
}
private void MostrarImagemAtual()
{
if (imagens.Count == 0 || indiceAtual < 0 || indiceAtual >= imagens.Count)
return;
var caminho = imagens[indiceAtual];
var bmpTemp = new Bitmap(caminho); // evita locking de arquivo
imgOriginal.Image = new Bitmap(bmpTemp);
lblInfo.Text = $"{indiceAtual + 1}/{imagens.Count} - {Path.GetFileName(caminho)}";
Task.Run(async () => await EnviarImagemVisualWorker(caminho));
}
private void AtualizarDadosTela()
{
Task.Run(async () =>
{
OAKCameraFrameModel frame = await VisualWorkerService.GetCameraFrame(CameraFrameType.Segmentacao);
var dadosSeg = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorVisual.Analises.segmentacao;
DesenharCorredor(frame?.image(), dadosSeg.centros_corredor, dadosSeg.width, dadosSeg.height, 80);
this.Invoke((MethodInvoker)(() =>
{
var _controle = Variaveis.OperacaoEmAndamento.Controle;
txtErroAngular.Text = dadosSeg.erro_angular.ToString();
txtErroLateral.Text = dadosSeg.erro_lateral_pct.ToString();
txtStatusCarro.Text = dadosSeg.status_corredor.ToString();
txtVelocidadeSP.Text = _controle.PercentualVelocidadeSP.ToString();
txtAnguloSP.Text = _controle.Angulo.ToString();
txtTipoMovimento.Text = _controle.TipoMovimento.ToString();
txtImagemAtual.Text = indiceAtual.ToString();
}));
});
}
private async Task EnviarImagemVisualWorker(string caminho)
{
var comando = new
{
cmd = VisualWorkerCommandType.EnviarImagemMock,
@params = caminho
};
RedisService.Publish(CmdKey.VisualWorkerRx, JsonConvert.SerializeObject(comando));
await Task.Delay(50);
AtualizarDadosTela();
}
private void DesenharCorredor(Bitmap imagemBase, List<double[]> centrosCorredor, int largura, int altura, int larguraRoboPx)
{
try
{
if (imagemBase == null)
return;
Bitmap imagemComDesenho = new Bitmap(imagemBase.Clone() as Bitmap);
using (Graphics g = Graphics.FromImage(imagemComDesenho))
{
Pen penCentro = new Pen(Color.Yellow, 2);
Pen penLargura = new Pen(Color.Magenta, 1);
Brush brushCentro = Brushes.Yellow;
float fatorX = (float)imagemBase.Width / largura;
float fatorY = (float)imagemBase.Height / altura;
for (int i = 0; i < centrosCorredor.Count; i++)
{
Point ponto = new Point(
(int)(centrosCorredor[i][0] * fatorX),
(int)(centrosCorredor[i][1] * fatorY)
);
g.FillEllipse(brushCentro, ponto.X - 2, ponto.Y - 2, 4, 4);
g.DrawLine(penLargura, ponto.X - larguraRoboPx / 2, ponto.Y, ponto.X + larguraRoboPx / 2, ponto.Y);
if (i < centrosCorredor.Count - 1)
{
Point proximoPonto = new Point((int)(centrosCorredor[i + 1][0] * fatorX), (int)(centrosCorredor[i + 1][1] * fatorY));
g.DrawLine(penCentro, ponto, proximoPonto);
}
}
}
this.Invoke((MethodInvoker)(() =>
{
imgSegmentacao.Image?.Dispose();
imgSegmentacao.Image = imagemComDesenho;
}));
}
catch (Exception ex)
{
Console.WriteLine("Erro ao desenhar corredor: " + ex.Message);
}
}
private void btnAnterior_Click(object sender, EventArgs e)
{
if (indiceAtual > 0)
{
indiceAtual--;
MostrarImagemAtual();
}
}
private void btnProximo_Click(object sender, EventArgs e)
{
if (indiceAtual < imagens.Count - 1)
{
indiceAtual++;
MostrarImagemAtual();
}
}
private void btnIr_Click(object sender, EventArgs e)
{
indiceAtual = Convert.ToInt32(txtImagemAtual.Text);
MostrarImagemAtual();
}
private void btnIniciarSimulacao_Click(object sender, EventArgs e)
{
Variaveis.OperacaoEmAndamento.IniciarSimulacao();
}
private void btnAtualizar_Click(object sender, EventArgs e)
{
AtualizarDadosTela();
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -40,7 +40,7 @@ namespace AgroBase.Forms
Task.Run(async () =>
{
await VariaveisOperacao.Operadores.IniciarProcessamento(false);
await VariaveisOperacao.Operadores.IniciarProcessamento(true);
});
}

View File

@ -93,6 +93,7 @@ namespace AgroBase
this.btnForcarAtualizacao = new System.Windows.Forms.Button();
this.clbRotinas = new System.Windows.Forms.CheckedListBox();
this.btnAtualizarRotinas = new System.Windows.Forms.Button();
this.btnSimuladorMapeamentoVisual = new System.Windows.Forms.Button();
this.gpbAcoes.SuspendLayout();
this.erroStrip.SuspendLayout();
this.pnlLateral.SuspendLayout();
@ -489,6 +490,7 @@ namespace AgroBase
// pnlAtalhos
//
this.pnlAtalhos.AutoScroll = true;
this.pnlAtalhos.Controls.Add(this.btnSimuladorMapeamentoVisual);
this.pnlAtalhos.Controls.Add(this.btnVisualWorker);
this.pnlAtalhos.Controls.Add(this.btnTreinamentoIA);
this.pnlAtalhos.Controls.Add(this.btnOID);
@ -816,6 +818,17 @@ namespace AgroBase
this.btnAtualizarRotinas.UseVisualStyleBackColor = true;
this.btnAtualizarRotinas.Click += new System.EventHandler(this.btnAtualizarRotinas_Click);
//
// btnSimuladorMapeamentoVisual
//
this.btnSimuladorMapeamentoVisual.Location = new System.Drawing.Point(5, 487);
this.btnSimuladorMapeamentoVisual.Margin = new System.Windows.Forms.Padding(2);
this.btnSimuladorMapeamentoVisual.Name = "btnSimuladorMapeamentoVisual";
this.btnSimuladorMapeamentoVisual.Size = new System.Drawing.Size(84, 20);
this.btnSimuladorMapeamentoVisual.TabIndex = 34;
this.btnSimuladorMapeamentoVisual.Text = "Mapeamento";
this.btnSimuladorMapeamentoVisual.UseVisualStyleBackColor = true;
this.btnSimuladorMapeamentoVisual.Click += new System.EventHandler(this.btnSimuladorMapeamentoVisual_Click);
//
// frmPrincipal
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -931,6 +944,7 @@ namespace AgroBase
private System.Windows.Forms.Button btnOID;
private System.Windows.Forms.Button btnTreinamentoIA;
private System.Windows.Forms.Button btnVisualWorker;
private System.Windows.Forms.Button btnSimuladorMapeamentoVisual;
}
}

View File

@ -3,6 +3,7 @@ using AgroBase.Forms.Atuador;
using AgroBase.Forms.Movimentacao;
using AgroBase.Forms.Operacoes;
using AgroBase.Forms.Sensoriamento;
using AgroBase.Forms.Simuladores;
using AgroBase.Models;
using AgroBase.Services;
using System;
@ -454,6 +455,11 @@ namespace AgroBase
frm.Show();
}
private void btnSimuladorMapeamentoVisual_Click(object sender, EventArgs e)
{
frmSimulacaoMapeamentoVisual frm = new frmSimulacaoMapeamentoVisual();
frm.Show();
}
#endregion
@ -462,5 +468,6 @@ namespace AgroBase
MessageBox.Show($"{Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada}", "Status da Operacao", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}

View File

@ -165,6 +165,7 @@
Manual = 1,
MapaGPS = 2,
TreinamentoIA = 3,
MapeamentoVisual = 4
}
public enum StatusOperacao

View File

@ -419,6 +419,7 @@ namespace AgroBase.Models.Modules
Sentido_SP == Sentido.Antihorario ? -1 :
0;
float velocidade = RPM_SP * mx;
//velocidade = (Mod_ID.Contains("T") ? velocidade : velocidade * 0.7f);
OIDCanService.ComandoControle(_EnderecoCAN_Tx, _EnderecoCAN_Rx, modoControle, velocidade);

View File

@ -217,14 +217,14 @@ namespace AgroBase.Models.Modules
{
tmrRegistrador.SetInterval(_TaxaAmostragem);
var UltimaDirecao = Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Mov)?.UltimaDirecao ?? Direcao.Parado;
if (!Variaveis.OperacaoEmAndamento.Simulando)
{
VelocidadeMedia = FuncoesMatematicas.ConverteKmhParaMs(Modulos.Where(x => x.Conectado && x.MovMotor.ComandoLigado).DefaultIfEmpty().Average(x => x?.MovMotor?.VelocidadeInstantanea ?? 0));
}
var UltimaDirecao = Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Mov)?.UltimaDirecao ?? Direcao.Parado;
if (UltimaDirecao != Direcao.Parado)
{
if (!Variaveis.OperacaoEmAndamento.Simulando)
{
VelocidadeMedia = FuncoesMatematicas.ConverteKmhParaMs(Modulos.Where(x => x.Conectado && x.MovMotor.ComandoLigado).DefaultIfEmpty().Average(x => x?.MovMotor?.VelocidadeInstantanea ?? 0));
}
double tempo = _TaxaAmostragem / 1000.0;
double distancia = tempo * VelocidadeMedia;
DistanciaPercorridaTotal += distancia;

View File

@ -2018,7 +2018,7 @@ namespace AgroBase.Models.Modules
GeneralJoystick.EnviarComandoSensoriamento(S_Code.sLED, ledOP.ID, comportamento);
}
var statusLedAt = Variaveis.OperacaoEmAndamento.Modo == ModoOperacao.MapaGPS ? StatusLED.Aceso : StatusLED.Apagado;
var statusLedAt = Variaveis.OperacaoEmAndamento.Controle.MovimentoAutomatico ? StatusLED.Aceso : StatusLED.Apagado;
var valAt = (int?)(ledAT?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.StatusLEDComando)?.atual?.valor) ?? 0;
if (ledAT != null && (!ledAT.Comportamento.statusLED.Equals(statusLedAt) || (valAt != (int)statusLedAt)))
{

View File

@ -140,7 +140,9 @@ namespace AgroBase.Models
UltrasonicA05Configuracoes ConfigUltrassom,
bool sonarAtivado,
int qtdCamerasSolo,
TiposControladorDirecional tipoControleDirecional)
TiposControladorDirecional tipoControleDirecional,
bool movimentoAutomatico,
bool pulverizadorAutomatico)
{
if (string.IsNullOrEmpty(descricao))
{
@ -172,7 +174,9 @@ namespace AgroBase.Models
Mapa = Variaveis.OperacaoEmAndamento.Mapa,
ConfiguracaoUltrassom = ConfigUltrassom,
SonarAtivado = sonarAtivado,
QtdCamerasSolo = qtdCamerasSolo
QtdCamerasSolo = qtdCamerasSolo,
MovimentoAutomatico = movimentoAutomatico,
PulverizadorAutomatico = pulverizadorAutomatico
};
Parametros.Mapa.LimparDados(true);
@ -230,7 +234,8 @@ namespace AgroBase.Models
TiposControle = Variaveis.OperacaoEmAndamento.Controle.TiposControle.ToList(),
SonarAtivado = Parametros.SonarAtivado,
TipoControleDirecional = Parametros.DirTipoMovimento,
PulverizadorAutomatico = Parametros.Modo == ModoOperacao.MapaGPS,
PulverizadorAutomatico = Parametros.PulverizadorAutomatico,
MovimentoAutomatico = Parametros.MovimentoAutomatico,
TipoMovimento = TipoMovimentoDirecional.RodasDianteiras,
};
@ -303,6 +308,8 @@ namespace AgroBase.Models
Variaveis.OperacaoEmAndamento.ControleAnterior = new OperacaoControleModel();
Variaveis.OperacaoEmAndamento.Controle = new OperacaoControleModel()
{
MovimentoAutomatico = false,
PulverizadorAutomatico = false,
RPM_Max = 100,
RPM_Min = 15,
Angulo_Max = 25,
@ -333,7 +340,6 @@ namespace AgroBase.Models
},
},
SonarAtivado = false,
PulverizadorAutomatico = false,
TipoMovimento = TipoMovimentoDirecional.RodasDianteiras,
TipoControleDirecional = TiposControladorDirecional.Manual
};
@ -379,6 +385,8 @@ namespace AgroBase.Models
Variaveis.OperacaoEmAndamento.ControleAnterior = new OperacaoControleModel();
Variaveis.OperacaoEmAndamento.Controle = new OperacaoControleModel()
{
MovimentoAutomatico = true,
PulverizadorAutomatico = true,
RPM_Max = 50,
RPM_Min = 20,
Angulo_Max = 30,
@ -409,7 +417,6 @@ namespace AgroBase.Models
},
},
SonarAtivado = true,
PulverizadorAutomatico = true,
TipoMovimento = TipoMovimentoDirecional.RodasDianteiras,
TipoControleDirecional = TiposControladorDirecional.MPC,
};
@ -478,6 +485,8 @@ namespace AgroBase.Models
Variaveis.OperacaoEmAndamento.ControleAnterior = new OperacaoControleModel();
Variaveis.OperacaoEmAndamento.Controle = new OperacaoControleModel()
{
MovimentoAutomatico = true,
PulverizadorAutomatico = false,
RPM_Max = 100,
RPM_Min = 20,
Angulo_Max = 30,
@ -508,7 +517,6 @@ namespace AgroBase.Models
},
},
SonarAtivado = false,
PulverizadorAutomatico = false,
TipoMovimento = TipoMovimentoDirecional.RodasDianteiras,
TipoControleDirecional = TiposControladorDirecional.IA,
};
@ -574,6 +582,64 @@ namespace AgroBase.Models
}
};
break;
case ModoOperacao.MapeamentoVisual:
//Variaveis.OperacaoEmAndamento.frmOperacao = new frmOperacaoMapaGPS();
Variaveis.OperacaoEmAndamento.ControleAnterior = new OperacaoControleModel();
Variaveis.OperacaoEmAndamento.Controle = new OperacaoControleModel()
{
MovimentoAutomatico = true,
PulverizadorAutomatico = false,
RPM_Max = 40,
RPM_Min = 20,
Angulo_Max = 30,
Angulo_Min = -30,
VelocidadeMP = 50,
TiposControle = new List<OperacaoControleTipoModel>()
{
new OperacaoControleTipoModel()
{
Tipo = T_Code.Mov,
DelayEnvioComando = 500,
Comandos = new List<string>(),
UltimoComando = DateTime.Now
},
new OperacaoControleTipoModel()
{
Tipo = T_Code.Dir,
DelayEnvioComando = 200,
Comandos = new List<string>(),
UltimoComando = DateTime.Now
}
},
SonarAtivado = true,
TipoMovimento = TipoMovimentoDirecional.RodasDianteiras,
TipoControleDirecional = TiposControladorDirecional.PID,
};
Variaveis.OperacaoEmAndamento.ModulosMandatorios = new List<OperacaoModulosMandatoriosModel>()
{
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Mov,
Mandatorio = true,
Utilizar = true,
},
new OperacaoModulosMandatoriosModel()
{
Dispositivo = T_Code.Dir,
Mandatorio = true,
Utilizar = true,
}
};
Variaveis.OperacaoEmAndamento.ParametrosMandatorios = new List<OperacaoParametrosMandatoriosModel>()
{
new OperacaoParametrosMandatoriosModel()
{
Parametro = ParametrosOperacao.Sonar,
Mandatorio = true,
Utilizar = true,
}
};
break;
}
if (Variaveis.OperacaoEmAndamento.DispSen != null)
@ -601,8 +667,6 @@ namespace AgroBase.Models
Variaveis.OperacaoEmAndamento.Controle.Angulo = Variaveis.OperacaoEmAndamento.Controle.Angulo_Max;
Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP = Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeMin;
Variaveis.OperacaoEmAndamento.Sensoriamento.AtualizarDados();
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
}
@ -629,8 +693,8 @@ namespace AgroBase.Models
DispSen?.Dados?.ReiniciarLeituras(DispSen?.Dados);
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
Sensoriamento.AtualizarDados();
WeedWorkerService.ReiniciarLeituraAnalise();
VisualWorkerService.ReiniciarLeituraAnalise();
Controle.Angulo = 0;
Controle.PercentualVelocidadeSP = 0;
@ -639,8 +703,8 @@ namespace AgroBase.Models
GPSTrajetoria = new List<GPSModel>();
Controle.BicosAtuados = DispAtu.Dados.BicosPulverizadores.Select(x => x.Clone()).ToList();
ControleAnterior.BicosAtuados = DispAtu.Dados.BicosPulverizadores.Select(x => x.Clone()).ToList();
Controle.BicosAtuados.ForEach(x => x.ComandoAtuar = false);
ControleAnterior.BicosAtuados = Controle.BicosAtuados.Select(x => x.Clone()).ToList();
await RealizarCalibragemInicialAsync();
@ -738,11 +802,9 @@ namespace AgroBase.Models
DispAtu?.Dados?.ReiniciarLeituras(DispAtu.Dados);
DispSen?.Dados?.ReiniciarLeituras(DispSen.Dados);
await RealizarCalibragemInicialAsync();
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
Sensoriamento?.AtualizarDados();
WeedWorkerService.ReiniciarLeituraAnalise();
VisualWorkerService.ReiniciarLeituraAnalise();
Controle.Angulo = 0;
Controle.PercentualVelocidadeSP = 0;
@ -798,8 +860,6 @@ namespace AgroBase.Models
DispSen.Dados.ReiniciarLeituras(DispSen.Dados);
}
Sensoriamento.AtualizarDados();
Controle.Angulo = 0;
Controle.PercentualVelocidadeSP = 0;
@ -829,7 +889,7 @@ namespace AgroBase.Models
public void AtualizaInformacoesControleOperacao()
{
if (Variaveis.OperacaoEmAndamento.Modo == ModoOperacao.MapaGPS)
if (Variaveis.OperacaoEmAndamento.Controle.MovimentoAutomatico)
{
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(false, new List<T_Code>() { T_Code.Mov, T_Code.Dir });
}
@ -845,11 +905,16 @@ namespace AgroBase.Models
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
if (!ForcarEnvio && !_Controle.PulverizadorAutomatico)
return;
foreach (var Ctrl in _Controle.TiposControle.Where(x => Dispositivos.Contains(x.Tipo)))
{
if (!ForcarEnvio)
{
if (!_Controle.PulverizadorAutomatico && Ctrl.Tipo == T_Code.Atu)
continue;
else if (!_Controle.MovimentoAutomatico && (Ctrl.Tipo == T_Code.Mov || Ctrl.Tipo == T_Code.Dir))
continue;
}
if (ForcarEnvio || ((Agora - Ctrl.UltimoComando).TotalMilliseconds > Ctrl.DelayEnvioComando))
{
var Protocolos = EnviarProtocoloComando(Ctrl.Tipo, ForcarEnvio);
@ -875,27 +940,22 @@ namespace AgroBase.Models
{
case T_Code.Mov:
{
//Keys tecla = Keys.Escape;
if (_Controle.RPM_SP == 0)
{
_Controle.Direcao = Direcao.Parado;
//tecla = Keys.Escape;
}
else if (_Controle.RPM_SP < 0)
{
_Controle.PercentualVelocidadeSP *= -1;
_Controle.Direcao = Direcao.Tras;
//tecla = Keys.Down;
}
else if (_Controle.RPM_SP > 0)
{
_Controle.Direcao = Direcao.Frente;
//tecla = Keys.Up;
}
if (ForcarEnvio || _Controle.RPM_SP != _ControleAnterior.RPM_SP)
{
//GeneralJoystick.EnviaComandoMotor(tecla, Tipo, ForcarEnvio);
Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.ForEach(Mod => Mod.MovMotor.EnviarComandoControle(_Controle.Direcao));
_Controle.TiposControle.FirstOrDefault(x => x.Tipo == Tipo).UltimaDirecao = _Controle.Direcao;
@ -1204,7 +1264,7 @@ namespace AgroBase.Models
string nome = Variaveis.OperacaoEmAndamento.idxLog.ToString();
Camera.SaveFrames(new List<CameraFrameType>() { CameraFrameType.Rgb }, nome, Caminho);
Camera.SaveFrames(new List<CameraFrameType>() { CameraFrameType.Rgb, CameraFrameType.Segmentacao }, nome, Caminho);
var cam_data = JsonConvert.DeserializeObject<Dictionary<string, object>>(RedisService.Get(CtxKey.DadosCameras));
if (cam_data.ContainsKey(Camera.Id))
@ -1440,6 +1500,7 @@ namespace AgroBase.Models
public List<OperacaoControleTipoModel> TiposControle { get; set; } = new List<OperacaoControleTipoModel>();
public bool SonarAtivado { get; set; } = true;
public bool MovimentoAutomatico { get; set; }
private bool _pulverizadorAutomatico = false;
public bool PulverizadorAutomatico
{
@ -1587,6 +1648,7 @@ namespace AgroBase.Models
public class OperacaoSensoriamentoLogModel
{
public DateTime Momento { get; set; }
public ModoOperacao Modo { get; set; }
public ulong CodigoFalha { get; set; }
public bool OperacaoLiberada { get; set; }
public StatusOperacao StatusOperacao { get; set; } = StatusOperacao.Parado;
@ -1669,6 +1731,8 @@ namespace AgroBase.Models
VelocidadeMedia = _DispMvd.Dados.VelocidadeMedia,
RPMMedio = _DispMvd.Dados.Modulos.Where(x => x.MovMotor.Inicializado).DefaultIfEmpty()?.Average(x => x?.MovMotor?.RPM_Roda ?? 0) ?? 0,
TempoMovimentoSegs = _DispMvd.Dados.TempoEmAtividade,
DistanciaPercorridaTotal = _DispMvd.Dados.DistanciaPercorridaTotal,
DistanciaPercorridaParcial = _DispMvd.Dados.DistanciaPercorridaParcial,
Dir_Status = _DispMvd.Dados.StatusModulosDIR(_Controle.TipoMovimento),
MovEsq_Status = _DispMvd.Dados.StatusModulosMOV(Direcao.Esquerda),
MovDir_Status = _DispMvd.Dados.StatusModulosMOV(Direcao.Direita)
@ -1735,6 +1799,7 @@ namespace AgroBase.Models
OperacaoSensoriamentoLogModel dadosAtualizados = new OperacaoSensoriamentoLogModel()
{
Momento = DateTime.Now,
Modo = Variaveis.OperacaoEmAndamento.Modo,
OperacaoLiberada = Variaveis.OperacaoEmAndamento.OperacaoLiberada,
StatusOperacao = Variaveis.OperacaoEmAndamento.StatusAtual,
DataInicio = Variaveis.OperacaoEmAndamento.DataInicio,
@ -1872,6 +1937,8 @@ namespace AgroBase.Models
public double VelocidadeMedia { get; set; }
public double RPMMedio { get; set; }
public double TempoMovimentoSegs { get; set; }
public double DistanciaPercorridaTotal { get; set; }
public double DistanciaPercorridaParcial { get; set; }
public DateTime TempoMovimento
{
get
@ -1893,6 +1960,8 @@ namespace AgroBase.Models
Dir_Status = Dir_Status,
MovEsq_Status = MovEsq_Status,
MovDir_Status = MovDir_Status,
DistanciaPercorridaParcial = DistanciaPercorridaParcial,
DistanciaPercorridaTotal = DistanciaPercorridaTotal,
};
}
}

View File

@ -22,5 +22,7 @@ namespace AgroBase.Models.Operacoes
public UltrasonicA05Configuracoes ConfiguracaoUltrassom { get; set; }
public bool SonarAtivado { get; set; }
public int QtdCamerasSolo { get; set; }
public bool MovimentoAutomatico { get; set; }
public bool PulverizadorAutomatico { get; set; }
}
}

View File

@ -85,7 +85,7 @@ namespace AgroBase.Models.Operadores
{
ScriptCarregado = 1,
IniciarMPC = 2,
AtualizarMPC = 3,
AtualizarDadosControle = 3,
EnviarDadosControle = 4,
FinalizarOperacao = 5,
}

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using static AgroBase.Models.Enums;
namespace AgroBase.Models.Operadores
{
@ -184,6 +185,7 @@ namespace AgroBase.Models.Operadores
public VisualWorkerMessageAnaliseSoloModel solo { get; set; }
public List<VisualWorkerMessageRadar2DPerfilModel> corredor_prof { get; set; }
public List<VisualWorkerMessageRadar2DPerfilModel> corredor_seg { get; set; }
public VisualWorkerMessageSegmentacaoSemanticaModel segmentacao { get; set; }
public VisualWorkerMessageAnaliseModel Clone()
{
@ -195,6 +197,7 @@ namespace AgroBase.Models.Operadores
solo = solo?.Clone(),
corredor_prof = new List<VisualWorkerMessageRadar2DPerfilModel>(corredor_prof ?? new List<VisualWorkerMessageRadar2DPerfilModel>()),
corredor_seg = new List<VisualWorkerMessageRadar2DPerfilModel>(corredor_seg ?? new List<VisualWorkerMessageRadar2DPerfilModel>()),
segmentacao = segmentacao?.Clone() ?? new VisualWorkerMessageSegmentacaoSemanticaModel(),
};
}
@ -478,36 +481,23 @@ namespace AgroBase.Models.Operadores
public class VisualWorkerMessageSegmentacaoSemanticaModel
{
public OAKCameraFrameModel mask_frame { get; set; }
public double angulo_rua { get; set; }
public int height { get; set; }
public int width { get; set; }
public double erro_angular { get; set; }
public double erro_lateral_pct { get; set; }
public StatusCarroMapa status_corredor { get; set; }
public List<double[]> centros_corredor { get; set; }
private bool _newData = false;
public bool newData
{
get
{
if (_newData)
{
_newData = false;
return true;
}
else
{
return false;
}
}
set
{
_newData = value;
}
}
public VisualWorkerMessageSegmentacaoSemanticaModel Clone()
{
return new VisualWorkerMessageSegmentacaoSemanticaModel()
{
mask_frame = mask_frame.Clone(),
angulo_rua = angulo_rua,
newData = true
height = height,
width = width,
erro_angular = erro_angular,
erro_lateral_pct = erro_lateral_pct,
status_corredor = status_corredor,
centros_corredor = new List<double[]>(centros_corredor ?? new List<double[]>())
};
}
}
@ -520,6 +510,7 @@ namespace AgroBase.Models.Operadores
AtualizarSaudeCamera = 4,
GetCameraFrame = 5,
SaveCameraFrames = 6,
EnviarImagemMock = 7
}

View File

@ -41,8 +41,8 @@ namespace AgroBase.Models.Operadores
public class WeedWorkerAnaliseModel
{
public DateTime timestamp { get; set; }
public int frame_width { get; set; }
public int frame_height { get; set; }
public int width { get; set; }
public int height { get; set; }
public List<WeedWorkerAnaliseDeteccaoModel> deteccoes { get; set; }
public Dictionary<int, bool> controle { get; set; }
public List<Dictionary<string, int>> ervas_identificadas { get; set; }
@ -55,8 +55,8 @@ namespace AgroBase.Models.Operadores
deteccoes = new List<WeedWorkerAnaliseDeteccaoModel>(deteccoes),
controle = new Dictionary<int, bool>(controle),
ervas_identificadas = ervas_identificadas?.Select(dict => new Dictionary<string, int>(dict)).ToList(),
frame_height = frame_height,
frame_width = frame_width,
height = height,
width = width,
};
}
}

View File

@ -325,7 +325,7 @@ namespace AgroBase.Models
return;
}
if (PontoAtual.idxPonto == _TrajetoriaFixa.Count() - 1)
if (PontoAtual.idxPonto == _TrajetoriaFixa.Count - 1)
{
ProximoPonto = PontoAtual;
}
@ -601,6 +601,8 @@ namespace AgroBase.Models
AtualizarIndicesJanela();
AtualizarTrajetoriaJanela();
VerificaFimCorredorSegmentacao();
DefinirPontoAtual();
AtualizarCorredorAtual();
DefinirProximoPonto();
@ -622,6 +624,45 @@ namespace AgroBase.Models
AtualizarTrajetoriaDinamica();
}
private void VerificaFimCorredorSegmentacao()
{
double limiarDistanciaMargem = 4.0;
if (CorredorAtual != null)
{
double distanciaRestanteCorredor = CorredorAtual.DistanciaRestante;
double distanciaUltimoPontoCorredor = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, CorredorAtual.Pontos.LastOrDefault().Posicao);
if (distanciaRestanteCorredor < limiarDistanciaMargem && distanciaUltimoPontoCorredor < limiarDistanciaMargem)
{
var OpVisual = Variaveis.OperacaoEmAndamento.Sensoriamento?.OperadorVisual ?? new VisualWorkerModel();
StatusModulo OpVisualStatus = Variaveis.OperacaoEmAndamento.Sensoriamento.ModulosSaude.FirstOrDefault(x => x.modulo == T_Code.Snr)?.status ?? StatusModulo.Desconectado;
var DadosSegmentacao = OpVisual.Analises?.segmentacao ?? new VisualWorkerMessageSegmentacaoSemanticaModel();
if (OpVisual.Iniciado && OpVisualStatus == StatusModulo.Operante && DadosSegmentacao.status_corredor == StatusCarroMapa.Direcionando)
{
int pontosMarcar = 0;
foreach (var Ponto in CorredorAtual.Pontos.Where(x => !x.Visitado))
{
Ponto.Visitado = true;
pontosMarcar++;
}
if (!CorredorAtual.Ultimo)
{
_TrajetoriaFixa[CorredorAtual.Pontos[CorredorAtual.QtdPontos - 1].idxPonto + 1].Visitado = true;
AtualizarIndicesJanela();
AtualizarTrajetoriaJanela();
DefinirPontoAtual();
AtualizarCorredorAtual();
for (int i = 0; i < pontosMarcar; i++)
{
CorredorAtual.Pontos[i].Visitado = true;
}
AtualizarIndicesJanela();
AtualizarTrajetoriaJanela();
}
}
}
}
}
public void LoopAtualizaDados()
@ -630,11 +671,9 @@ namespace AgroBase.Models
AtualizarDadosTrajetoria();
Variaveis.OperacaoEmAndamento.Sensoriamento.AtualizarDados();
//Variaveis.OperacaoEmAndamento.AtualizaInformacoesControleOperacao();
RedisService.Publish(CmdKey.ManagerWorkerRx, JsonConvert.SerializeObject(new { cmd = ManagerWorkerCommandType.AtualizarMPC }));
RedisService.Publish(CmdKey.ManagerWorkerRx, JsonConvert.SerializeObject(new { cmd = ManagerWorkerCommandType.AtualizarDadosControle }));
}

View File

@ -554,7 +554,7 @@ namespace AgroBase.Services
{
if (Variaveis.IsAgroMonitor)
{
EnviarCoordenadasParaMapa(UltimaLeitura.Latitude, UltimaLeitura.Longitude, UltimaLeitura.AnguloCarroDefinido, false, Variaveis.LoraBaseParametros.address);
EnviarCoordenadasParaMapa(UltimaLeitura.Latitude, UltimaLeitura.Longitude, UltimaLeitura.AnguloCarroDefinido, false, LoRaBaseService.parametrosModel.address);
return;
}

View File

@ -220,7 +220,7 @@ namespace AgroBase.Services
private static async Task tmrLeitura_Tick()
{
while ((_PortaLoRa?.BytesToRead ?? 0) > 0)
while ((_PortaLoRa?.IsOpen ?? false) && (_PortaLoRa?.BytesToRead ?? 0) > 0)
{
byte b = (byte)_PortaLoRa.ReadByte();

View File

@ -168,6 +168,7 @@ namespace AgroBase.Services.Operadores
AtualizandoRedis = true;
AtualizarDadosEquipamento();
AtualizarDadosControleOperacao();
if (Variaveis.OperacaoEmAndamento.DispMvd == null)
{
@ -219,8 +220,7 @@ namespace AgroBase.Services.Operadores
percent_vertical_deteccao = _Controle.PercentualInicioPulverizacao,
tempo_atuacao = _Controle.TempoAtuacao,
capacidade_reservatorio = Variaveis.OperacaoEmAndamento.CapacidadeReservatorio,
pressao_linha = _Controle.PressaoLinha,
pulverizador_automatico = _Controle.PulverizadorAutomatico,
pressao_linha = _Controle.PressaoLinha
}
),
("Snr", new
@ -245,6 +245,15 @@ namespace AgroBase.Services.Operadores
AtualizandoRedis = false;
}
public static void AtualizarDadosControleOperacao()
{
RedisService.AtualizarCampos(
CtxKey.DadosControle,
("pulverizador_automatico", Variaveis.OperacaoEmAndamento.Controle.PulverizadorAutomatico),
("movimento_automatico", Variaveis.OperacaoEmAndamento.Controle.MovimentoAutomatico)
);
}
private static void AtualizarDadosModulos()
{
if (Variaveis.OperacaoEmAndamento.DispMvd == null) return;

View File

@ -99,7 +99,7 @@ namespace AgroBase.Services.Operadores
break;
case ManagerWorkerCommandType.EnviarDadosControle:
if (Variaveis.OperacaoEmAndamento.Modo == Enums.ModoOperacao.MapaGPS)
if (Variaveis.OperacaoEmAndamento.Controle.MovimentoAutomatico)
{
AtualizarControle(comando.@params);
}

View File

@ -79,7 +79,7 @@ namespace AgroBase.Services.Operadores
if (!Conectado)
{
TempoDesconectado++;
if (Variaveis.OperacaoEmAndamento.Iniciado && Variaveis.OperacaoEmAndamento.Modo == Enums.ModoOperacao.MapaGPS)
if (Variaveis.OperacaoEmAndamento.Iniciado && Variaveis.OperacaoEmAndamento.Controle.MovimentoAutomatico)
{
RedisService.AtualizarCampos(
CtxKey.DadosOperacao,

View File

@ -160,11 +160,13 @@ namespace AgroBase.Services.Operadores
var sombras = JsonConvert.DeserializeObject<List<VisualWorkerMessageAnaliseBBoxModel>>(JsonConvert.SerializeObject(anomalias["sombras"]));
var corredor = JsonConvert.DeserializeObject<Dictionary<string, object>>(dados["perfil_corredor"].ToString());
var segmentacao = JsonConvert.DeserializeObject<List<VisualWorkerMessageRadar2DPerfilModel>>(JsonConvert.SerializeObject(corredor["segmentacao"]));
var corredor_seg = JsonConvert.DeserializeObject<List<VisualWorkerMessageRadar2DPerfilModel>>(JsonConvert.SerializeObject(corredor["segmentacao"]));
var profundidade = JsonConvert.DeserializeObject<List<VisualWorkerMessageRadar2DPerfilModel>>(JsonConvert.SerializeObject(corredor["profundidade"]));
var solo = JsonConvert.DeserializeObject<VisualWorkerMessageAnaliseSoloModel>(JsonConvert.SerializeObject(dados["solo"]));
var segmentacao = JsonConvert.DeserializeObject<VisualWorkerMessageSegmentacaoSemanticaModel>(JsonConvert.SerializeObject(dados["segmentacao"]));
DadosLeitura.Analises = new VisualWorkerMessageAnaliseModel()
{
timestamp = timestamp,
@ -172,10 +174,22 @@ namespace AgroBase.Services.Operadores
anomalias = deteccoes,
sombras = sombras,
corredor_prof = profundidade,
corredor_seg = segmentacao,
corredor_seg = corredor_seg,
segmentacao = segmentacao
};
}
}
public static void ReiniciarLeituraAnalise()
{
RedisService.AtualizarCampos(
CtxKey.DadosWeedWorker,
("analise.anomalias", new Dictionary<string, object>()),
("analise.perfil_corredor", new Dictionary<string, object>()),
("analise.solo", new VisualWorkerMessageAnaliseSoloModel()),
("analise.segmentacao", new VisualWorkerMessageSegmentacaoSemanticaModel())
);
}
}
}

View File

@ -182,7 +182,7 @@ namespace AgroBase.Services.Operadores
var controleDict = JsonConvert.DeserializeObject<Dictionary<string, bool>>(
analise["controle"].ToString()
);
var ervasIdentificadas = JsonConvert.DeserializeObject<List<Dictionary<string, int>>>(
analise["ervas_identificadas"].ToString()
);
@ -191,8 +191,8 @@ namespace AgroBase.Services.Operadores
var analiseObj = new WeedWorkerAnaliseModel
{
timestamp = timestamp,
frame_height = Convert.ToInt32(analise["frame_height"].ToString()),
frame_width = Convert.ToInt32(analise["frame_width"].ToString()),
height = Convert.ToInt32(analise["height"].ToString()),
width = Convert.ToInt32(analise["width"].ToString()),
deteccoes = listaDeteccoes,
controle = controleDict.ToDictionary(x => Convert.ToInt32(x.Key), x => x.Value),
ervas_identificadas = ervasIdentificadas
@ -213,5 +213,15 @@ namespace AgroBase.Services.Operadores
}
}
public static void ReiniciarLeituraAnalise()
{
RedisService.AtualizarCampos(
CtxKey.DadosWeedWorker,
("analise.deteccoes", new List<WeedWorkerAnaliseDeteccaoModel>()),
("analise.controle", new Dictionary<string, bool>(Variaveis.OperacaoEmAndamento.DispAtu.Dados.BicosPulverizadores.ToDictionary(x => x.Posicao.ToString(), x => x.ComandoAtuar))),
("analise.ervas_identificadas", new List<Dictionary<string, int>>())
);
}
}
}

View File

@ -209,6 +209,7 @@ namespace AgroBase.Services
public static void EncerrarProcessos(int processId = -1)
{
//return;
foreach (var processo in Process.GetProcessesByName("python"))
{
try

View File

@ -79,7 +79,7 @@ namespace AgroBase.Services
atual = (JObject)atual[partes[i]];
}
atual[partes.Last()] = JToken.FromObject(campo.Value);
atual[partes.Last()] = JToken.FromObject(campo.Value ?? "");
}
Set(chave, root.ToString(Formatting.None));

View File

@ -1,12 +1,5 @@
{
"epochs": [ {
"calculation_time": "13395881044629269",
"config_version": 0,
"model_version": "0",
"padded_top_topics_start_index": 0,
"taxonomy_version": 0,
"top_topics_and_observing_domains": [ ]
}, {
"calculation_time": "13396617367014463",
"config_version": 0,
"model_version": "0",
@ -29,5 +22,5 @@
"top_topics_and_observing_domains": [ ]
} ],
"hex_encoded_hmac_key": "40F346D3248C3AFDF2BEE1FE496DBD32F7CED6E5AE98B881ABC421AA7E7B5642",
"next_scheduled_calculation_time": "13398455528649160"
"next_scheduled_calculation_time": "13398455528649568"
}

View File

@ -1,3 +1,3 @@
2025/07/25-15:32:54.048 6f60 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/07/25-15:32:54.053 6f60 Recovering log #3
2025/07/25-15:32:54.057 6f60 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log
2025/07/30-13:45:05.219 7cc4 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/07/30-13:45:05.225 7cc4 Recovering log #3
2025/07/30-13:45:05.228 7cc4 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log

View File

@ -1,3 +1,3 @@
2025/07/25-14:39:16.989 1248 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/07/25-14:39:16.995 1248 Recovering log #3
2025/07/25-14:39:16.998 1248 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log
2025/07/30-13:29:47.201 865c Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/07/30-13:29:47.207 865c Recovering log #3
2025/07/30-13:29:47.212 865c Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log

View File

@ -1 +1 @@
{"net":{"http_server_properties":{"servers":[{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13398028379944064","port":443,"protocol_str":"quic"}],"anonymization":["DAAAAAcAAABmaWxlOi8vAA==",false,0],"network_stats":{"srtt":83767},"server":"https://tile.openstreetmap.org","supports_spdy":true}],"supports_quic":{"address":"2804:d78:609:f200:5cd:ea88:ba11:c468","used_quic":true},"version":5},"network_qualities":{"CAASABiAgICA+P////8B":"4G","CAESABiAgICA+P////8B":"4G","CAISABiAgICA+P////8B":"4G","CAYSABiAgICA+P////8B":"Offline"}}}
{"net":{"http_server_properties":{"servers":[{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13398454400339748","port":443,"protocol_str":"quic"}],"anonymization":["DAAAAAcAAABmaWxlOi8vAA==",false,0],"network_stats":{"srtt":16690},"server":"https://tile.openstreetmap.org","supports_spdy":true}],"supports_quic":{"address":"2804:d78:609:f200:c506:7fc8:b135:b811","used_quic":true},"version":5},"network_qualities":{"CAASABiAgICA+P////8B":"4G","CAESABiAgICA+P////8B":"4G","CAISABiAgICA+P////8B":"4G","CAYSABiAgICA+P////8B":"Offline"}}}

View File

@ -1 +1 @@
{"sts":[{"expiry":1785004379.539092,"host":"bWGAftl61rqoc0YzqPncsLvQQh/iC2Bdp3ejUeGC83w=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1753468379.539105}],"version":2}
{"sts":[{"expiry":1785430400.33992,"host":"bWGAftl61rqoc0YzqPncsLvQQh/iC2Bdp3ejUeGC83w=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1753894400.339923}],"version":2}

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,3 @@
2025/07/25-15:40:48.866 6f60 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/07/25-15:40:48.867 6f60 Recovering log #3
2025/07/25-15:40:48.870 6f60 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log
2025/07/30-13:55:20.640 7cc4 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/07/30-13:55:20.641 7cc4 Recovering log #3
2025/07/30-13:55:20.644 7cc4 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log

View File

@ -1,3 +1,3 @@
2025/07/25-14:46:05.888 1248 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/07/25-14:46:05.889 1248 Recovering log #3
2025/07/25-14:46:05.892 1248 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log
2025/07/30-13:30:08.915 865c Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/07/30-13:30:08.916 865c Recovering log #3
2025/07/30-13:30:08.919 865c Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log

View File

@ -1,3 +1,3 @@
2025/07/25-15:32:53.968 7790 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/07/25-15:32:53.970 7790 Recovering log #7
2025/07/25-15:32:53.970 7790 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log
2025/07/30-13:45:05.146 2cb0 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/07/30-13:45:05.147 2cb0 Recovering log #7
2025/07/30-13:45:05.148 2cb0 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log

View File

@ -1,3 +1,3 @@
2025/07/25-14:39:16.915 5b28 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/07/25-14:39:16.917 5b28 Recovering log #7
2025/07/25-14:39:16.917 5b28 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log
2025/07/30-13:29:47.127 741c Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/07/30-13:29:47.129 741c Recovering log #7
2025/07/30-13:29:47.130 741c Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log

View File

@ -1 +1 @@
138.0.3351.95
138.0.3351.109

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3,19 +3,19 @@
"id": 1,
"Arquivo": "model",
"Diretorio": "C:\\AgroBaseModels\\Ervas\\",
"Extensao": ".pt",
"Extensao": ".onnx",
"Versao": "2_1",
"TipoArquivo": 1,
"ArquivoDownload": "weed_detector_model-2_1.pt"
"ArquivoDownload": "weed_detector_model-2_1.onnx"
},
{
"id": 2,
"Arquivo": "model",
"Diretorio": "C:\\AgroBaseModels\\Ervas\\",
"Extensao": ".json",
"Extensao": ".txt",
"Versao": "2_1",
"TipoArquivo": 1,
"ArquivoDownload": "weed_detector_model-2_1.json"
"ArquivoDownload": "weed_detector_model-2_1.txt"
},
{
"id": 3,

File diff suppressed because one or more lines are too long

View File

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

File diff suppressed because one or more lines are too long

View File

@ -217,6 +217,7 @@ class CameraOak:
return frame, resultado
except Exception as e:
print(f"Erro ao requisitar frame: {e}")
return None, {
"erro": str(e),
"duracao": 0,
@ -316,6 +317,11 @@ class CameraOak:
frame, resultado = self.requisitar_frame_rgb()
except Exception as e:
self.mostrar_log(f"Erro ao requisitar dados da camera para atualizar saude")
resultado = {
"erro": e,
"frame_valido": False,
"duracao": 0
}
if "Communication exception" in str(e) or "X_LINK_ERROR" in str(e):
conectado = False

View File

@ -67,6 +67,8 @@ def definir_saude_camera(mx_id: str, status: StatusModulo, saude: int, motivos:
"motivos": motivos,
"saude_idividual": []
}
if not conectado:
_cameras[mx_id] = {}
_cameras[mx_id]["saude"] = saude_geral
_cameras[mx_id]["rodando"] = rodando
_cameras[mx_id]["performance"] = performance

View File

@ -1,8 +1,7 @@
import time
from shared.mqtt_handler import enviar_mensagem_mqtt
from shared.contexto_global_redis import CmdKey, ContextoGlobalRedis
from shared.enums import ManagerWorkerCommandType, StatusOperacao, T_Code
from manager_worker.config import mostrar_log, topico_tx
from shared.enums import ManagerWorkerCommandType, StatusOperacao
from manager_worker.config import mostrar_log
from manager_worker.processadores._0_nao_iniciado import ProcessadorNaoIniciado
from manager_worker.processadores._1_parametrizando import ProcessadorParametrizando
@ -18,24 +17,16 @@ class ManagerWorker:
def executar(self):
t0 = time.time()
resposta = {}
self.definir_processador()
#log_status_operacao()
if self.processador:
#print(f"🔁 Processador ativo: {type(self.processador).__name__}")
comando = self.processador.processar()
#mostrar_log(f"Comando: {comando}")
resposta = {
"cmd": ManagerWorkerCommandType.EnviarDadosControle.value,
"params": comando,
}
ContextoGlobalRedis.publicar_comando(CmdKey.ManagerWorkerTx, resposta)
else:
mostrar_log("Processador nao definido")
movimento_automatico = ContextoGlobalRedis.get_controle().get("movimento_automatico", False)
if movimento_automatico:
self.definir_processador()
if self.processador:
comando = self.processador.processar()
if comando is not None:
ContextoGlobalRedis.publicar_comando(CmdKey.ManagerWorkerTx, { "cmd": ManagerWorkerCommandType.EnviarDadosControle.value, "params": comando })
else:
mostrar_log("Processador nao definido")
t1 = time.time()
latencia = t1 - t0
@ -43,20 +34,20 @@ class ManagerWorker:
def definir_processador(self):
_operacao = ContextoGlobalRedis.get_operacao()
status = _operacao.get("status")
if status == StatusOperacao.NaoIniciado.value:
status = StatusOperacao(_operacao.get("status", StatusOperacao.NaoIniciado.value))
if status == StatusOperacao.NaoIniciado:
self.processador = ProcessadorNaoIniciado()
elif status == StatusOperacao.Parado.value:
elif status == StatusOperacao.Parado:
self.processador = ProcessadorParado()
elif status == StatusOperacao.Calibrando.value:
elif status == StatusOperacao.Calibrando:
self.processador = ProcessadorCalibrando()
elif status == StatusOperacao.Parametrizando.value:
elif status == StatusOperacao.Parametrizando:
self.processador = ProcessadorParametrizando()
elif status == StatusOperacao.Aguardando.value:
elif status == StatusOperacao.Aguardando:
self.processador = ProcessadorAguardando()
elif status == StatusOperacao.EmAndamento.value:
elif status == StatusOperacao.EmAndamento:
self.processador = ProcessadorEmAndamento()
elif status == StatusOperacao.Concluido.value:
elif status == StatusOperacao.Concluido:
self.processador = ProcessadorConcluido()
else:
self.processador = None

View File

@ -15,13 +15,13 @@ def main():
from shared.mensagem_worker import WorkerFilaMensagens
def fila_callback(cmd):
mostrar_log("Processado da fila")
#mostrar_log("Processado da fila")
acao = ManagerWorkerCommandType(cmd)
if (acao == ManagerWorkerCommandType.AtualizarMPC):
if (acao == ManagerWorkerCommandType.AtualizarDadosControle):
manager.executar()
manager = ManagerWorker()
fila = WorkerFilaMensagens("mpc", fila_callback, 1, True, 120)
fila = WorkerFilaMensagens("controle", fila_callback, 1, True, 120)
frequencia_loop = 5 # hz
@ -61,8 +61,8 @@ def main():
if parametros is not None:
p_ref = ContextoGlobalRedis.get_operacao().get("ponto_mapa_ref", [])
iniciar_mpc(parametros, mapa, p_ref)
elif acao == ManagerWorkerCommandType.AtualizarMPC:
mostrar_log("Adicionado na fila")
elif acao == ManagerWorkerCommandType.AtualizarDadosControle:
#mostrar_log("Adicionado na fila")
fila.adicionar(acao)
#manager.executar()
else:

View File

@ -1,18 +1,16 @@
from shared.enums import StatusCarroMapa, StatusModulo, StatusOperacao, T_Code, TipoMovimentoDirecional
from shared.enums import ModoOperacao, StatusCarroMapa, StatusModulo, StatusOperacao, T_Code, TipoMovimentoDirecional
from shared.contexto_global_redis import ContextoGlobalRedis, CtxKey
from manager_worker.config import mostrar_log
from manager_worker.modulos.mpc import get_mpc, comando_parado, inicializar
from manager_worker.modulos.mpc import get_mpc, comando_parado
def definir_comando():
"""
Define o comando de direção com base em regras mockadas + MPC
"""
try:
_contexto = ContextoGlobalRedis.get_contexto()
_operacao = ContextoGlobalRedis.get_operacao()
_contexto = ContextoGlobalRedis.get_contexto()
_equipamento = ContextoGlobalRedis.get_equipamento()
_gps = ContextoGlobalRedis.get_modulo(T_Code.Gps)
_snr = ContextoGlobalRedis.get_modulo(T_Code.Snr)
_dados_vw = ContextoGlobalRedis.get(CtxKey.DadosVisualWorker, {})
_trajetoria = _contexto.get("Trajetoria", {})
visual_worker_operante = (_snr.get("saude", {}).get("status", StatusModulo.DESCONECTADO.value)) == StatusModulo.OPERANTE.value
contexto = {
@ -43,7 +41,7 @@ def definir_comando():
"DistanciaMax": _operacao.get("Snr", {}).get("distancia_maxima", 5000) / 1000.0,
"DistanciaMin": _operacao.get("Snr", {}).get("distancia_minima", 500) / 1000.0,
},
"MatrizCusto": [[]],
"MatrizCusto": _dados_vw.get("matrizes", {}).get("custo", [[]]),
},
"RegrasAtivas": {
"matriz_custo": True,
@ -55,19 +53,24 @@ def definir_comando():
}
}
comando = regras_taticas(contexto)
comando = _regras_taticas(contexto)
if (comando.get("comando_definido", False)):
return comando.get("angulo", 0.0), comando.get("tipo", TipoMovimentoDirecional.RodasDianteiras.value), comando.get("simulacao", []), comando.get("parada_necessaria", False)
if (comando["comando_definido"]):
return comando["angulo"], comando["tipo"], comando["simulacao"], comando["parada_necessaria"]
else:
if contexto.get("RegrasAtivas", {}).get("matriz_custo", False):
analise = ContextoGlobalRedis.get(CtxKey.DadosVisualWorker, {})
contexto["VisualWorker"]["MatrizCusto"] = analise.get("matrizes", {}).get("custo", [[]])
return definir_comando_mpc(contexto)
op_modo = ModoOperacao(_operacao.get("modo", ModoOperacao.NaoDefinido.value))
if op_modo == ModoOperacao.MapaGPS:
return _comando_mapa_gps_mpc(contexto)
elif op_modo == ModoOperacao.MapeamentoVisual:
return _comando_mapeamento_visual(contexto)
else:
comando = _comando_direcional_parado()
return comando["angulo"], comando["tipo"], comando["simulacao"], comando["parada_necessaria"]
except Exception as e:
mostrar_log(f"❌ Erro ao definir comando direcional: {e}")
def comando_direcional_parado(definido: bool):
def _comando_direcional_parado(definido: bool):
try:
angulo, tipo = comando_parado()
return {
@ -80,11 +83,11 @@ def comando_direcional_parado(definido: bool):
except Exception as e:
mostrar_log(f"❌ Erro ao montar comando direcional parado: {e}")
def regras_taticas(contexto):
def _regras_taticas(contexto):
try:
if contexto.get("Operacao", {}).get("Status", StatusOperacao.NaoIniciado.value) != StatusOperacao.EmAndamento.value or contexto.get("Operacao", {}).get("Finalizando", False):
mostrar_log("🟥 Direcional parado: operação não está em andamento ou está finalizando.")
return comando_direcional_parado(True)
return _comando_direcional_parado(True)
velocidade_media = contexto.get("Carro", {}).get("Velocidade", 0.0)
if velocidade_media < 0.01:
@ -95,18 +98,18 @@ def regras_taticas(contexto):
vw_operante = contexto.get("VisualWorker", {}).get("Operante", False)
if vw_ativado and not vw_operante:
mostrar_log("⚠️ Sensores principais inativos. Rodando MPC no modo básico.")
return comando_direcional_parado(False)
mostrar_log("⚠️ Sensores principais inativos. Rodando controle no modo básico.")
return _comando_direcional_parado(False)
imu = ContextoGlobalRedis.get_modulo(T_Code.Imu)
if imu is not None and imu.get("saude", {}).get("status", StatusModulo.DESCONECTADO.value) == StatusModulo.OPERANTE.value:
if abs(imu.get("pitch", 0.0)) > 15.0 or abs(imu.get("roll", 0.0)) > 10.0:
mostrar_log(f"🟥 Inclinação perigosa detectada. Parando movimentação. roll: {imu.get('roll')}, pitch: {imu.get('pitch')}, yaw: {imu.get('yaw')}")
return comando_direcional_parado(True)
return _comando_direcional_parado(True)
if not vw_ativado:
mostrar_log("Visual Worker desativado. Rodando MPC no modo básico.")
return comando_direcional_parado(False)
mostrar_log("⚠️ Sensores principais desativados. Rodando controle no modo básico.")
return _comando_direcional_parado(False)
if vw_operante and contexto.get("RegrasAtivas", {}).get("deteccao_obstaculos", False):
analise = ContextoGlobalRedis.get(CtxKey.DadosVisualWorker, {})
@ -115,14 +118,14 @@ def regras_taticas(contexto):
for obst in obstaculos:
if obst.get("distancia_m", 99) < 0.4:
mostrar_log("🟥 Obstáculo crítico detectado a menos de 40cm. Parando.")
return comando_direcional_parado(True)
return _comando_direcional_parado(True)
return comando_direcional_parado(False)
return _comando_direcional_parado(False)
except Exception as e:
mostrar_log(f"❌ Erro ao processar regras taticas do direcional: {e}")
def definir_comando_mpc(contexto):
def _comando_mapa_gps_mpc(contexto):
try:
mpc = get_mpc()
if mpc is None:
@ -147,6 +150,50 @@ def definir_comando_mpc(contexto):
return comando.get("angulo", 0.0), comando.get("tipo", TipoMovimentoDirecional.RodasDianteiras.value), comando.get("simulacao", []), comando.get("parada_necessaria", False)
except Exception as e:
mostrar_log(f"❌ Erro ao definir comando MPC: {e}")
mostrar_log(f"❌ Erro ao definir comando MapaGPS: {e}")
def _comando_mapeamento_visual(contexto):
try:
# ⛔ Fallback seguro se visual não operante
comando = _comando_direcional_parado(True)
if not contexto.get("VisualWorker", {}).get("Operante", False):
mostrar_log("Sensores principais inativos! Impossível definir controle")
return comando["angulo"], comando["tipo"], comando["simulacao"], comando["parada_necessaria"]
# 🔍 Dados visuais disponíveis
_dados_vw = ContextoGlobalRedis.get(CtxKey.DadosVisualWorker, {}).get("segmentacao", {})
status_carro = StatusCarroMapa(_dados_vw.get("status_corredor", StatusCarroMapa.Parado.value))
erro_angular = _dados_vw.get("erro_angular", 0.0) # em graus
erro_lateral_pct = _dados_vw.get("erro_lateral_pct", 0.0)
# ⚙️ Parâmetros do controle proporcional
k_ang = 1.0
k_lat = 0.5
ang_max = ContextoGlobalRedis.get_operacao().get("Dir", {}).get("angulo_max", 30)
# 📐 Cálculo do ângulo
angulo = k_ang * erro_angular + k_lat * erro_lateral_pct
angulo = max(min(angulo, ang_max), -ang_max)
# 🔁 Tipo de movimento baseado no status do corredor
if status_carro in [StatusCarroMapa.EntrandoRua, StatusCarroMapa.SaindoRua, StatusCarroMapa.Manobrando]:
tipo_movimento = TipoMovimentoDirecional.MovimentoArco
else:
tipo_movimento = TipoMovimentoDirecional.RodasDianteiras
# 🚦 Define se deve parar
parada_necessaria = (status_carro == StatusCarroMapa.Parado)
# 🔧 Monta comando final
comando = {
"angulo": round(angulo, 2),
"tipo": tipo_movimento.value,
"simulacao": [],
"parada_necessaria": parada_necessaria
}
return comando["angulo"], comando["tipo"], comando["simulacao"], comando["parada_necessaria"]
except Exception as e:
mostrar_log(f"❌ Erro ao definir comando MapeamentoVisual: {e}")
return 0.0, TipoMovimentoDirecional.RodasDianteiras.value, [], True

View File

@ -1,12 +1,12 @@
from shared.enums import StatusOperacao, StatusCarroMapa, T_Code
from shared.enums import ModoOperacao, StatusOperacao, StatusCarroMapa
from shared.contexto_global_redis import ContextoGlobalRedis, CtxKey
from manager_worker.config import mostrar_log
from manager_worker.filtros import FiltroVelocidade
def definir_comando(parada_necessaria: bool):
def definir_comando(parada_necessaria: bool, filtro_vel: FiltroVelocidade):
try:
_operacao = ContextoGlobalRedis.get_operacao()
status_operacao = StatusOperacao(_operacao.get("status"))
status_operacao = StatusOperacao(_operacao.get("status", StatusOperacao.NaoIniciado.value))
finalizando = _operacao.get("finalizando", False)
if parada_necessaria:
@ -14,45 +14,53 @@ def definir_comando(parada_necessaria: bool):
return 0.0
if (status_operacao != StatusOperacao.EmAndamento) or finalizando:
mostrar_log(f"🟥 Movimento parado: operação não está em andamento: {status_operacao.name}")
return 0.0 # percentual velocidade = 0
mostrar_log(f"🟥 Movimento parado: operação não está em andamento ou finalizando: {status_operacao.name}")
return 0.0
op_modo = ModoOperacao(_operacao.get("modo", ModoOperacao.NaoDefinido.value))
_contexto = ContextoGlobalRedis.get_contexto()
_trajetoria = _contexto.get("Trajetoria", {})
status_carro = StatusCarroMapa(_trajetoria.get("status"))
_controle = ContextoGlobalRedis.get_controle()
pulverizador_automatico = _controle.get("pulverizador_automatico", False)
ervas_no_radar = _contexto.get("Gerais", {}).get("ervas_no_radar")
controle_mov = _operacao.get("Mov", {})
vel_min = controle_mov.get("percent_vel_min", 0)
vel_max = controle_mov.get("percent_vel_max", 100)
erro = _trajetoria.get("erro_angular", 0)
vel_min = _operacao.get("Mov", {}).get("percent_vel_min", 0)
vel_max = _operacao.get("Mov", {}).get("percent_vel_max", 100)
ang_max = _operacao.get("Dir", {}).get("angulo_max", 30)
status_carro = StatusCarroMapa.Parado
erro = 0
manobrando = False
if op_modo == ModoOperacao.MapaGPS:
_trajetoria = _contexto.get("Trajetoria", {})
status_carro = StatusCarroMapa(_trajetoria.get("status", StatusCarroMapa.Parado.value))
erro = _trajetoria.get("erro_angular", 0)
manobrando = _trajetoria.get("manobrando", False)
elif op_modo == ModoOperacao.MapeamentoVisual:
_dados_vw = ContextoGlobalRedis.get(CtxKey.DadosVisualWorker, {}).get("segmentacao", {})
status_carro = StatusCarroMapa(_dados_vw.get("status_corredor", StatusCarroMapa.Parado.value))
erro = _dados_vw.get("erro_angular", 0)
velocidade_sp = vel_min
if status_carro == StatusCarroMapa.Parado:
velocidade_sp = 0
elif status_carro == StatusCarroMapa.Direcionando:
manobrando = _trajetoria.get("manobrando", False)
if manobrando:
velocidade_sp = vel_min
else:
velocidade_sp = calcular_velocidade_relativa(vel_min, vel_max, erro)
velocidade_sp = calcular_velocidade_relativa(vel_min, vel_max, ang_max, erro)
elif status_carro in [StatusCarroMapa.EntrandoRua, StatusCarroMapa.SaindoRua, StatusCarroMapa.Manobrando]:
velocidade_sp = vel_min
elif status_carro == StatusCarroMapa.CaminhandoRua:
if ervas_no_radar > 0:
if pulverizador_automatico and ervas_no_radar > 0:
velocidade_sp = vel_min
else:
velocidade_sp = calcular_velocidade_relativa(vel_min, vel_max, erro)
velocidade_sp = calcular_velocidade_relativa(vel_min, vel_max, ang_max, erro)
# Aplica limites
velocidade_sp = max(vel_min, min(vel_max, velocidade_sp))
filtro_vel = FiltroVelocidade()
if velocidade_sp <= vel_min:
filtro_vel.reset(velocidade_sp)
else:
@ -64,8 +72,9 @@ def definir_comando(parada_necessaria: bool):
except Exception as e:
mostrar_log(f"Erro ao definir o comando de movimentacao: {e}")
def calcular_velocidade_relativa(vel_min, vel_max, erro_orientacao):
severidade = min(abs(erro_orientacao) / 30.0, 1.0)
def calcular_velocidade_relativa(vel_min, vel_max, ang_max, erro_orientacao):
erro_orientacao = max(min(ang_max, erro_orientacao), -ang_max)
severidade = min(abs(erro_orientacao) / ang_max, 1.0)
penalidade = severidade * 0.85
faixa = vel_max - vel_min
velocidade = vel_max - (faixa * penalidade)

View File

@ -1,18 +1,24 @@
from shared.contexto_global_redis import ContextoGlobalRedis, CtxKey
from shared.enums import ModoOperacao
from shared.contexto_global_redis import ContextoGlobalRedis
from .base import ProcessadorBase
from manager_worker.filtros import FiltroVelocidade
from manager_worker.processadores.padroes import comando_controle
from manager_worker.modulos.direcional import definir_comando as definir_comando_dir
from manager_worker.modulos.movimentacao import definir_comando as definir_comando_mov
class ProcessadorEmAndamento(ProcessadorBase):
def __init__(self):
self.filtro_mov = FiltroVelocidade()
def processar(self):
try:
modo = ModoOperacao(ContextoGlobalRedis.get_operacao().get("modo"))
if modo == ModoOperacao.MapaGPS:
angulo_sp, tipo_dir, simulacao, parada_necessaria = definir_comando_dir()
velocidade_sp = definir_comando_mov(parada_necessaria)
return comando_controle(percentual_velocidade=velocidade_sp, angulo=angulo_sp, tipo_movimento=tipo_dir, simulacao=simulacao)
return None
angulo_sp, tipo_dir, simulacao, parada_necessaria = definir_comando_dir()
velocidade_sp = definir_comando_mov(parada_necessaria, self.filtro_mov)
return comando_controle(
percentual_velocidade=velocidade_sp,
angulo=angulo_sp,
tipo_movimento=tipo_dir,
simulacao=simulacao
)
except Exception as e:
print(f"Erro no processador EmAndamento: {e}")
return None

View File

@ -47,7 +47,7 @@ class ContextoGlobalRedis:
chave_str = chave.value if hasattr(chave, "value") else str(chave)
cls._redis.set(chave_str, json.dumps(valor))
except Exception as e:
mostrar_log(f"Erro no set: {e}")
mostrar_log(f"Erro no set: {e} - Chave: {chave}, Valor: {valor}")
@classmethod
def get(cls, chave: CtxKey, default=None):
@ -284,7 +284,7 @@ class ContextoGlobalRedis:
return
# 🔸 Modo MAPA GPS ou IA
if modo in (ModoOperacao.MapaGPS, ModoOperacao.TreinamentoIA):
if modo in (ModoOperacao.MapaGPS, ModoOperacao.TreinamentoIA, ModoOperacao.MapeamentoVisual):
# Iniciando operacao
if (iniciado and not status_iniciado_anterior):
cls._iniciar_operacao()

View File

@ -7,6 +7,7 @@ class VisualWorkerCommandType(IntEnum):
AtualizarSaudeCamera = 4
GetCameraFrame = 5
SaveCameraFrames = 6
EnviarImagemMock = 7
class HealthWorkerCommandType(IntEnum):
ScriptCarregado = 1
@ -19,7 +20,7 @@ class CameraWorkerCommandType(IntEnum):
class ManagerWorkerCommandType(IntEnum):
ScriptCarregado = 1
IniciarMPC = 2
AtualizarMPC = 3
AtualizarDadosControle = 3
EnviarDadosControle = 4
FinalizarOperacao = 5
@ -37,6 +38,7 @@ class ModoOperacao(IntEnum):
Manual = 1
MapaGPS = 2
TreinamentoIA = 3
MapeamentoVisual = 4
class StatusOperacao(IntEnum):
NaoIniciado = 0

Some files were not shown because too many files have changed in this diff Show More