From 1be5691402e278d86bfd66a82ea1df8e706f1554 Mon Sep 17 00:00:00 2001 From: Diego Freitas Date: Thu, 26 Mar 2026 17:10:03 -0300 Subject: [PATCH] Ajuste no retorno a base em modo manual e controle da base --- AgroBase/AgroBase/Forms/IHM/frmDialogoMapa.cs | 12 +- .../AgroBase/Forms/IHM/frmInicioOperacao.cs | 2 +- .../Operacoes/frmParametrizacaoOperacao.cs | 6 +- .../Forms/Operacoes/frmResultadosOperacao.cs | 7 +- .../Forms/Simuladores/frmSimulacaoMapaGPS.cs | 2 +- .../AgroBase/Forms/frmPrincipal.Designer.cs | 26 +- AgroBase/AgroBase/Forms/frmPrincipal.cs | 2 +- AgroBase/AgroBase/Models/Enums.cs | 3 +- AgroBase/AgroBase/Models/GeneralJoystick.cs | 4 +- .../Models/Operacoes/OperacaoModel.cs | 320 ++++++++++++++++-- .../Operacoes/OperacaoParametrosModel.cs | 4 +- .../Models/TrajetoriaMapaOperacaoModel.cs | 11 +- AgroBase/AgroBase/Models/Variaveis.cs | 2 +- .../Operadores/HealthWorkerService.cs | 4 +- AgroBase/AgroBase/Services/SerialService.cs | 8 +- .../manager_worker/modulos/direcional.py | 2 +- .../manager_worker/modulos/movimentacao.py | 2 +- .../workers/shared/contexto_global_redis.py | 2 +- .../Python/Scripts/workers/shared/enums.py | 1 + .../Monitoramento/ControleManualViewModel.cs | 7 +- .../-47.19313E-22.09470N600H.pos | 0 Mapas/SAO_MANOEL_PIVO/LineFeature.dbf | Bin 0 -> 5329 bytes Mapas/SAO_MANOEL_PIVO/LineFeature.shp | Bin 0 -> 19940 bytes Mapas/SAO_MANOEL_PIVO/LineFeature.shx | Bin 0 -> 228 bytes 24 files changed, 354 insertions(+), 73 deletions(-) create mode 100644 Mapas/SAO_MANOEL_PIVO/-47.19313E-22.09470N600H.pos create mode 100644 Mapas/SAO_MANOEL_PIVO/LineFeature.dbf create mode 100644 Mapas/SAO_MANOEL_PIVO/LineFeature.shp create mode 100644 Mapas/SAO_MANOEL_PIVO/LineFeature.shx diff --git a/AgroBase/AgroBase/Forms/IHM/frmDialogoMapa.cs b/AgroBase/AgroBase/Forms/IHM/frmDialogoMapa.cs index 1fd5c914f..ec69d5306 100644 --- a/AgroBase/AgroBase/Forms/IHM/frmDialogoMapa.cs +++ b/AgroBase/AgroBase/Forms/IHM/frmDialogoMapa.cs @@ -76,7 +76,7 @@ namespace AgroBase.Forms.IHM if (res == DialogResult.Yes) { Task.Run(async () => await Variaveis.OperacaoEmAndamento.FinalizarOperacao()); - if (Variaveis.OperacaoEmAndamento.Modo == Enums.ModoOperacao.Manual) + if (Variaveis.OperacaoEmAndamento.Parametros?.Modo == Enums.ModoOperacao.Manual) { this.Close(); } @@ -168,7 +168,7 @@ namespace AgroBase.Forms.IHM lblMapaCarregado.Text = "Operação: " + Variaveis.OperacaoEmAndamento.Descricao; - txtModoOperacao.Text = Variaveis.OperacaoEmAndamento.Modo.ToString(); + txtModoOperacao.Text = (Variaveis.OperacaoEmAndamento.Parametros?.Modo ?? ModoOperacao.NaoDefinido).ToString(); bool opLiberada = _Sensoriamento.OperacaoLiberada; txtOperacaoLiberada.Text = opLiberada ? "Sim" : "Não"; txtOperacaoLiberada.ForeColor = opLiberada ? Color.Black : Color.Red; @@ -197,7 +197,7 @@ namespace AgroBase.Forms.IHM lblCorrecaoGPS.Text = (_Sensoriamento.Gps.Ntrip_ativado ? "N " : "B ") + _Sensoriamento.Gps.IdadeCorrecao + ": " + _Sensoriamento.Gps.QualidadeFix.ToString(); lblPrecisaoGPS.Text = $"Precisão: {_Sensoriamento.Gps.PrecisaoCm.ToString("0.00")} cm"; - bool automatico = Variaveis.OperacaoEmAndamento.Modo != ModoOperacao.Manual; + bool automatico = Variaveis.OperacaoEmAndamento.Parametros?.ControleAutomatico ?? false; cmbModoControle.Enabled = !automatico; tkbVelocidade.Enabled = !automatico; tkbAnguloDirecional.Enabled = !automatico; @@ -527,7 +527,7 @@ namespace AgroBase.Forms.IHM // Iniciar o arraste private void BrakePanel_MouseDown(object sender, MouseEventArgs e) { - if (Variaveis.OperacaoEmAndamento.Modo != Enums.ModoOperacao.Manual) + if (Variaveis.OperacaoEmAndamento.Parametros?.Modo != Enums.ModoOperacao.Manual) { return; } @@ -541,7 +541,7 @@ namespace AgroBase.Forms.IHM // Movimentar o botão de freio private void BrakePanel_MouseMove(object sender, MouseEventArgs e) { - if (Variaveis.OperacaoEmAndamento.Modo != Enums.ModoOperacao.Manual) + if (Variaveis.OperacaoEmAndamento.Parametros?.Modo != Enums.ModoOperacao.Manual) { return; } @@ -583,7 +583,7 @@ namespace AgroBase.Forms.IHM // Soltar o botão de freio private void BrakePanel_MouseUp(object sender, MouseEventArgs e) { - if (Variaveis.OperacaoEmAndamento.Modo != Enums.ModoOperacao.Manual) + if (Variaveis.OperacaoEmAndamento.Parametros?.Modo != Enums.ModoOperacao.Manual) { return; } diff --git a/AgroBase/AgroBase/Forms/IHM/frmInicioOperacao.cs b/AgroBase/AgroBase/Forms/IHM/frmInicioOperacao.cs index f1c201a15..f0ac375c5 100644 --- a/AgroBase/AgroBase/Forms/IHM/frmInicioOperacao.cs +++ b/AgroBase/AgroBase/Forms/IHM/frmInicioOperacao.cs @@ -230,7 +230,7 @@ namespace AgroBase.Forms.Operacoes chb.Checked = Variaveis.OperacaoEmAndamento.Parametros.ModulosMandatorios.Any(x => x.Dispositivo == Dispositivo && x.Mandatorio); } - txtModoOperacao.Text = Variaveis.OperacaoEmAndamento.Modo.ToString(); + txtModoOperacao.Text = (Variaveis.OperacaoEmAndamento.Parametros?.Modo ?? ModoOperacao.NaoDefinido).ToString(); txtDescricao.Text = Variaveis.OperacaoEmAndamento.Descricao; txtCriadoEm.Text = new FileInfo(path).CreationTime.ToString("dd/MM/yyyy HH:mm"); txtRuasPercorrer.Text = (Variaveis.OperacaoEmAndamento.Trajetoria?.Corredores?.Count() ?? 0).ToString(); diff --git a/AgroBase/AgroBase/Forms/Operacoes/frmParametrizacaoOperacao.cs b/AgroBase/AgroBase/Forms/Operacoes/frmParametrizacaoOperacao.cs index a00fb5592..887843214 100644 --- a/AgroBase/AgroBase/Forms/Operacoes/frmParametrizacaoOperacao.cs +++ b/AgroBase/AgroBase/Forms/Operacoes/frmParametrizacaoOperacao.cs @@ -29,7 +29,7 @@ namespace AgroBase.Forms.Operacoes cmbOperacao.Items.Clear(); cmbOperacao.Items.AddRange(Enum.GetNames(typeof(ModoOperacao))); - cmbOperacao.SelectedIndex = (int)Variaveis.OperacaoEmAndamento.Modo; + cmbOperacao.SelectedIndex = (int)Variaveis.OperacaoEmAndamento.Parametros?.Modo; var chbModulos = gpbModulos.Controls.OfType().Where(x => x.Name.Contains("chbD_")).ToList(); chbModulos.ForEach(chb => @@ -151,7 +151,7 @@ namespace AgroBase.Forms.Operacoes if (chbSalvar.Checked) { //OperacaoModel.SalvarOperacaoPersonalizada(Variaveis.OperacaoEmAndamento); - MessageBox.Show("Operação " + Enum.GetName(typeof(ModoOperacao), Variaveis.OperacaoEmAndamento.Modo) + " salva com sucesso!", "Sucesso"); + MessageBox.Show($"Operação {Variaveis.OperacaoEmAndamento.Parametros?.Modo ?? ModoOperacao.NaoDefinido} salva com sucesso!", "Sucesso"); } } @@ -164,7 +164,7 @@ namespace AgroBase.Forms.Operacoes { string operacaoPath = ofd.FileName; //Variaveis.OperacaoEmAndamento = OperacaoModel.CarregarOperacaoPersonalizada(operacaoPath); - MessageBox.Show("Operação " + Enum.GetName(typeof(ModoOperacao), Variaveis.OperacaoEmAndamento.Modo) + " carregada com sucesso!", "Sucesso"); + MessageBox.Show($"Operação {Variaveis.OperacaoEmAndamento.Parametros?.Modo ?? ModoOperacao.NaoDefinido} carregada com sucesso!", "Sucesso"); CarregarParametros(); } diff --git a/AgroBase/AgroBase/Forms/Operacoes/frmResultadosOperacao.cs b/AgroBase/AgroBase/Forms/Operacoes/frmResultadosOperacao.cs index 84a07071f..466633514 100644 --- a/AgroBase/AgroBase/Forms/Operacoes/frmResultadosOperacao.cs +++ b/AgroBase/AgroBase/Forms/Operacoes/frmResultadosOperacao.cs @@ -30,7 +30,7 @@ namespace AgroBase.Forms.Operacoes List picsCamSoloSeg = new List(); List picsCamSoloOverlay = new List(); List LogsCam_Caminho = new List(); - OperacaoModel operacaoSelecionada = new OperacaoModel(Enums.ModoOperacao.NaoDefinido); + OperacaoModel operacaoSelecionada = new OperacaoModel(); private readonly TopDownBboxView view_top_down = new TopDownBboxView(); private readonly FrontalBboxView view_frontal = new FrontalBboxView(); private readonly Bbox3DViewer view_3d = new Bbox3DViewer(); @@ -1168,8 +1168,9 @@ namespace AgroBase.Forms.Operacoes lblPercentualOperacao.Text = $"Operação {Log.Trajetoria.ProgressoTrajeto.ToString("0.00")}%"; FuncoesGlobais.PreencheValorProgressBar(pgbPercentualOperacao, Log.Trajetoria.ProgressoTrajeto); - 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; + bool comTrajetoria = new List() { Enums.ModoOperacao.MapaGPS, Enums.ModoOperacao.RetornoBase }.Contains(Log.Modo); + double distanciaAtual = comTrajetoria ? Log.Trajetoria.DistanciaPercorrida : Log.Movimentacao.DistanciaPercorridaTotal; + double distanciaTotal = comTrajetoria ? 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; diff --git a/AgroBase/AgroBase/Forms/Simuladores/frmSimulacaoMapaGPS.cs b/AgroBase/AgroBase/Forms/Simuladores/frmSimulacaoMapaGPS.cs index 0db2ed74f..11e098f78 100644 --- a/AgroBase/AgroBase/Forms/Simuladores/frmSimulacaoMapaGPS.cs +++ b/AgroBase/AgroBase/Forms/Simuladores/frmSimulacaoMapaGPS.cs @@ -1,6 +1,5 @@ using AgroBase.Models; using AgroBase.Services; -using AgroBase.Services.Operadores; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; @@ -551,6 +550,7 @@ namespace AgroBase.Forms private void btnRetornarBase_Click(object sender, EventArgs e) { + //OperacaoModel.CarregarParametrosOperacaoPadrao(ModoOperacao.RetornoBase, true); Variaveis.OperacaoEmAndamento.Trajetoria.IniciarRetornoBase(VariaveisOperacao.PosicaoBase); Variaveis.OperacaoEmAndamento.Simulando = true; } diff --git a/AgroBase/AgroBase/Forms/frmPrincipal.Designer.cs b/AgroBase/AgroBase/Forms/frmPrincipal.Designer.cs index 84b52d11b..e8294831f 100644 --- a/AgroBase/AgroBase/Forms/frmPrincipal.Designer.cs +++ b/AgroBase/AgroBase/Forms/frmPrincipal.Designer.cs @@ -66,6 +66,7 @@ namespace AgroBase this.gpbControleDirecional = new System.Windows.Forms.GroupBox(); this.gpbAtalhos = new System.Windows.Forms.GroupBox(); this.pnlAtalhos = new System.Windows.Forms.Panel(); + this.btnSimuladorMapeamentoVisual = new System.Windows.Forms.Button(); this.btnVisualWorker = new System.Windows.Forms.Button(); this.btnTreinamentoIA = new System.Windows.Forms.Button(); this.btnOID = new System.Windows.Forms.Button(); @@ -93,7 +94,6 @@ 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(); @@ -517,6 +517,17 @@ namespace AgroBase this.pnlAtalhos.Size = new System.Drawing.Size(112, 286); this.pnlAtalhos.TabIndex = 0; // + // 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); + // // btnVisualWorker // this.btnVisualWorker.Location = new System.Drawing.Point(5, 463); @@ -818,17 +829,6 @@ 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); @@ -910,7 +910,6 @@ namespace AgroBase private System.Windows.Forms.GroupBox gpbAtalhos; private System.Windows.Forms.GroupBox gpbOperacao; private System.Windows.Forms.Label lblModoOperacao; - private System.Windows.Forms.ComboBox cmbModoOperacao; private System.Windows.Forms.Button btnIniciarOperacao; private System.Windows.Forms.Label lblKmh; public System.Windows.Forms.TrackBar trkKmh; @@ -945,6 +944,7 @@ namespace AgroBase private System.Windows.Forms.Button btnTreinamentoIA; private System.Windows.Forms.Button btnVisualWorker; private System.Windows.Forms.Button btnSimuladorMapeamentoVisual; + public System.Windows.Forms.ComboBox cmbModoOperacao; } } diff --git a/AgroBase/AgroBase/Forms/frmPrincipal.cs b/AgroBase/AgroBase/Forms/frmPrincipal.cs index 7a8573f9c..58e4ec878 100644 --- a/AgroBase/AgroBase/Forms/frmPrincipal.cs +++ b/AgroBase/AgroBase/Forms/frmPrincipal.cs @@ -34,7 +34,7 @@ namespace AgroBase cmbModoOperacao.Items.Clear(); cmbModoOperacao.Items.AddRange(Enum.GetNames(typeof(ModoOperacao))); - cmbModoOperacao.SelectedIndex = (int)Variaveis.OperacaoEmAndamento.Modo; + cmbModoOperacao.SelectedIndex = (int)(Variaveis.OperacaoEmAndamento.Parametros?.Modo ?? ModoOperacao.NaoDefinido); } private async void frmPrincipal_FormClosing(object sender, FormClosingEventArgs e) diff --git a/AgroBase/AgroBase/Models/Enums.cs b/AgroBase/AgroBase/Models/Enums.cs index 7f4e33404..33abf90c6 100644 --- a/AgroBase/AgroBase/Models/Enums.cs +++ b/AgroBase/AgroBase/Models/Enums.cs @@ -176,7 +176,8 @@ Manual = 1, MapaGPS = 2, TreinamentoIA = 3, - MapeamentoVisual = 4 + MapeamentoVisual = 4, + RetornoBase = 5 } public enum StatusOperacao diff --git a/AgroBase/AgroBase/Models/GeneralJoystick.cs b/AgroBase/AgroBase/Models/GeneralJoystick.cs index c08d29dc2..e1aeafde0 100644 --- a/AgroBase/AgroBase/Models/GeneralJoystick.cs +++ b/AgroBase/AgroBase/Models/GeneralJoystick.cs @@ -595,7 +595,7 @@ namespace AgroBase bool deveInterromper = !Forms.IHM.frmDiagnosticos.Diagnosticando && !ForcarComando && ( - Variaveis.OperacaoEmAndamento.Modo == ModoOperacao.Manual && ( + Variaveis.OperacaoEmAndamento.Parametros?.Modo == ModoOperacao.Manual && ( Variaveis.OperacaoEmAndamento.Calibrando || !Variaveis.OperacaoEmAndamento.OperacaoLiberada || !Variaveis.OperacaoEmAndamento.Iniciado || @@ -949,6 +949,8 @@ namespace AgroBase var pControle = Variaveis.OperacaoEmAndamento.Parametros.Controle; var controle = Variaveis.OperacaoEmAndamento.Controle; + if (pControle == null || controle == null) return; + double velMin = pControle.MovVelocidadeCErvasPercent; double velMax = pControle.MovVelocidadeSErvasPercent; diff --git a/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs b/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs index 8378c3f1c..143ee8981 100644 --- a/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs +++ b/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs @@ -18,16 +18,15 @@ using AgroBase.Models.Operadores; using AgroBase.Services.Operadores; using AgroMonitor; using Newtonsoft.Json.Linq; +using System.Globalization; namespace AgroBase.Models { public class OperacaoModel { - public OperacaoModel(ModoOperacao Modo) + public OperacaoModel() { - this.Modo = Modo; - if (Variaveis.OperacaoEmAndamento != null) { tmrLogs?.Dispose(); @@ -45,7 +44,6 @@ namespace AgroBase.Models - public ModoOperacao Modo { get; set; } public StatusModulo Status { get; set; } public string Descricao { get; set; } public string OprPath { get; set; } @@ -222,7 +220,6 @@ namespace AgroBase.Models OperacaoParametrosModel Parametros = new OperacaoParametrosModel() { - Modo = Variaveis.OperacaoEmAndamento.Modo, Descricao = descricao, CapacidadeReservatorio = capacidadeReservatorio, Controle = new OperacaoParametrosControleModel() @@ -356,7 +353,7 @@ namespace AgroBase.Models var AtuConectado = (DispositivosService)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == T_Code.Atu); var MvdConectado = (DispositivosService)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == T_Code.Mvd); tmrLogs?.Stop(); - Variaveis.OperacaoEmAndamento = new OperacaoModel(Modo) + Variaveis.OperacaoEmAndamento = new OperacaoModel() { Iniciado = false, DataInicio = DateTime.MinValue, @@ -374,6 +371,9 @@ namespace AgroBase.Models switch (Modo) { + case ModoOperacao.NaoDefinido: + p.ModulosMandatorios = new List(); + break; case ModoOperacao.Manual: p.Controle = new OperacaoParametrosControleModel() { @@ -853,6 +853,122 @@ namespace AgroBase.Models }; } break; + case ModoOperacao.RetornoBase: + p.Controle = new OperacaoParametrosControleModel() + { + RegistrarDadosPosProcessamento = false, + + MovimentoAutomatico = true, + DirecionalAutomatico = true, + PulverizadorAutomatico = false, + + SonarAtivado = false, + FrenagemAutomaticaAoParar = true, + ImuParadaPorInclinacao = true, + OakParadaPorObstaculo = true, + MpcMatrizCusto = false, + MpcHorizonte = 4.0, + + MovVelocidadeSErvasPercent = 60, + MovVelocidadeCErvasPercent = 20, + DirAnguloMaximo = 30, + DirVelocidadeMovimento = 50, + + DirTipoMovimento = TiposControladorDirecional.MPC, + + AtuAlturaAreaPulverizacao = 10, + AtuDuracaoAtuacao = 200, + AtuPercentualErvasBicoOff = 2, + AtuPercentualErvasBicoOn = 1, + AtuPercentualInicioPulverizacao = 70, + AtuPressaoLinha = 85, + }; + p.ModulosMandatorios = new List() + { + new OperacaoModulosMandatoriosModel() + { + Dispositivo = T_Code.Ipb, + Mandatorio = true, + Utilizar = true, + }, + new OperacaoModulosMandatoriosModel() + { + Dispositivo = T_Code.Mov, + Mandatorio = true, + Utilizar = true, + }, + new OperacaoModulosMandatoriosModel() + { + Dispositivo = T_Code.Dir, + Mandatorio = true, + Utilizar = true, + }, + new OperacaoModulosMandatoriosModel() + { + Dispositivo = T_Code.Sen, + Mandatorio = true, + Utilizar = true, + }, + new OperacaoModulosMandatoriosModel() + { + Dispositivo = T_Code.Atu, + Mandatorio = true, + Utilizar = true, + }, + new OperacaoModulosMandatoriosModel() + { + Dispositivo = T_Code.Gps, + Mandatorio = true, + Utilizar = true, + }, + new OperacaoModulosMandatoriosModel() + { + Dispositivo = T_Code.Snr, + Mandatorio = true, + Utilizar = true, + }, + }; + p.ParametrosMandatorios = new List(); + if (isagrobase) + { + Variaveis.OperacaoEmAndamento.frmOperacao = new frmOperacaoMapaGPS(); + Variaveis.OperacaoEmAndamento.ControleAnterior = new OperacaoControleModel(); + Variaveis.OperacaoEmAndamento.Controle = new OperacaoControleModel() + { + TipoMovimento = TipoMovimentoDirecional.RodasDianteiras, + Angulo = 0, + EmFreio = false, + PercentualVelocidadeSP = 0, + AlturaBarra = 50, + TiposControle = new List() + { + new OperacaoControleTipoModel() + { + Tipo = T_Code.Mov, + DelayEnvioComandoBase = 500, + DelayEnvioComando = 500, + DelayEnvioComandoExtra = 0, + Comandos = new List(), + UltimoComando = DateTime.Now, + DirecaoAtual = Direcao.Parado, + UltimaDirecao = Direcao.Parado + }, + new OperacaoControleTipoModel() + { + Tipo = T_Code.Dir, + DelayEnvioComandoBase = 300, + DelayEnvioComando = 300, + DelayEnvioComandoExtra = 0, + Comandos = new List(), + UltimoComando = DateTime.Now, + DirecaoAtual = Direcao.Parado, + UltimaDirecao = Direcao.Parado + }, + }, + }; + } + break; + } p.ModulosMandatorios.Add(new OperacaoModulosMandatoriosModel() { Dispositivo = T_Code.Npc, Mandatorio = true, Utilizar = true }); @@ -1044,7 +1160,7 @@ namespace AgroBase.Models DataFim = DateTime.MinValue; idxLog = 0; - ID = DataInicio.ToString("dd_MM_yyyy_HH_mm_ss") + "_" + Modo.ToString(); + ID = DataInicio.ToString("dd_MM_yyyy_HH_mm_ss") + "_" + (Parametros?.Modo ?? ModoOperacao.NaoDefinido).ToString(); Directory.CreateDirectory(Variaveis.CaminhoOperacoes + ID + "/"); SalvarOperacao(); @@ -1262,17 +1378,55 @@ namespace AgroBase.Models public static string DeserializarDadosOperacao(string caminho, string arquivo) { - string opPath = caminho.Replace("data.lgop", arquivo) + ".json"; - string opStr = ""; - if (File.Exists(opPath)) - opStr = File.ReadAllText(opPath); - else - opStr = "["; - if (opStr != "" && !opStr.EndsWith("]")) + string pastaBase = Path.GetDirectoryName(caminho) ?? ""; + + // compatibilidade com o modelo antigo: + // data.lgop -> {arquivo}.json + string caminhoJsonAntigo = Path.Combine(pastaBase, arquivo + ".json"); + if (File.Exists(caminhoJsonAntigo)) { - opStr += "]"; + string opStr = File.ReadAllText(caminhoJsonAntigo); + if (!string.IsNullOrWhiteSpace(opStr) && !opStr.TrimEnd().EndsWith("]")) + opStr += "]"; + + return string.IsNullOrWhiteSpace(opStr) ? "[]" : opStr; } - return opStr; + + // novo modelo: + // {arquivo}_{idx}_{datahora}.jsonl + string[] arquivosJsonl = Directory.Exists(pastaBase) + ? Directory.GetFiles(pastaBase, $"{arquivo}_*.jsonl") + .OrderBy(f => f, StringComparer.OrdinalIgnoreCase) + .ToArray() + : Array.Empty(); + + if (arquivosJsonl.Length == 0) + return "[]"; + + var sb = new StringBuilder(); + sb.Append("["); + + bool primeiro = true; + + foreach (string arq in arquivosJsonl) + { + foreach (string linha in File.ReadLines(arq)) + { + string json = linha?.Trim(); + + if (string.IsNullOrWhiteSpace(json)) + continue; + + if (!primeiro) + sb.Append(","); + + sb.Append(json); + primeiro = false; + } + } + + sb.Append("]"); + return sb.ToString(); } private void SalvarOperacao() @@ -1463,12 +1617,12 @@ namespace AgroBase.Models return; } - Variaveis.OperacaoEmAndamento.Sensoriamento.AtualizarDados(); + Variaveis.OperacaoEmAndamento.Sensoriamento?.AtualizarDados(); //Variaveis.LoraService?.EnviarDadosParaBase(); - if (Variaveis.OperacaoEmAndamento.Modo == ModoOperacao.Manual) + if (Variaveis.OperacaoEmAndamento.Parametros?.Modo == ModoOperacao.Manual) { - var Sonar = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorVisual; + var Sonar = Variaveis.OperacaoEmAndamento.Sensoriamento?.OperadorVisual; Sonar?.Resumo?.AtualizarStatusBloqueio(true); if (Sonar?.Resumo?.EnviarComandoParada ?? false) { @@ -1781,7 +1935,7 @@ namespace AgroBase.Models OperacaoSensoriamentoLogModel logGeral = Variaveis.OperacaoEmAndamento.Sensoriamento.Clone(); logGeral.Momento = Agora; - SalvarLog("operacao", logGeral, Fim); + SalvarLogLine("operacao", logGeral); Variaveis.OperacaoEmAndamento.Sensoriamento.UltimoRegistroLog = DateTime.Now; Variaveis.OperacaoEmAndamento.Controle.TiposControle.ForEach(x => x.Comandos.Clear()); @@ -1812,7 +1966,7 @@ namespace AgroBase.Models Potencia = Modulo.MovMotor.Potencia, CicloTrabalho = Modulo.MovMotor.CicloTrabalho }; - SalvarLog(T_Code.Mov.ToString(), logMov, false); + SalvarLogLine(T_Code.Mov.ToString(), logMov); DirSensoriamentoLogModel logDir = new DirSensoriamentoLogModel() { @@ -1831,7 +1985,7 @@ namespace AgroBase.Models AnguloFolgaCompensar = Modulo.DirMotor.AnguloFolgaCompensar, AnguloReal = Modulo.DirMotor.AnguloReal }; - SalvarLog(T_Code.Dir.ToString(), logDir, false); + SalvarLogLine(T_Code.Dir.ToString(), logDir); }); AtuSensoriamentoLogModel logAtu = new AtuSensoriamentoLogModel() @@ -1866,7 +2020,7 @@ namespace AgroBase.Models }).ToList(), UltimoComandoRespondido = Variaveis.OperacaoEmAndamento.DispAtu.Dados.DadosLeitura.Momento, }; - SalvarLog(T_Code.Atu.ToString(), logAtu, false); + SalvarLogLine(T_Code.Atu.ToString(), logAtu); var senLeitura = Variaveis.OperacaoEmAndamento.DispSen.Dados; SensoriamentoMensagemJsonModel logSen = new SensoriamentoMensagemJsonModel() @@ -1882,7 +2036,7 @@ namespace AgroBase.Models Servos = new List(senLeitura.Servos), Sinaleiros = new List(senLeitura.Sinaleiros), }; - SalvarLog(T_Code.Sen.ToString(), logSen, false); + SalvarLogLine(T_Code.Sen.ToString(), logSen); SalvarLogCameraSolo(); SalvarLogCameraCaminho(); @@ -1955,7 +2109,7 @@ namespace AgroBase.Models if (conectada) { var cam_data = JsonConvert.DeserializeObject>(RedisService.Get(RedisService.CamKey(Camera.Id))); - SalvarLog(camera_name, cam_data, false); + SalvarLogLine(camera_name, cam_data); } } } @@ -1980,11 +2134,112 @@ namespace AgroBase.Models if (conectada) { var cam_data = JsonConvert.DeserializeObject>(RedisService.Get(RedisService.CamKey(Camera.Id))); - SalvarLog(Camera.Dispositivo.ToString(), cam_data, false); + SalvarLogLine(Camera.Dispositivo.ToString(), cam_data); } } + + + private static readonly object _lockLog = new object(); + + const long TAMANHO_MAX_LOG_BYTES = 50 * 1024 * 1024; // 50 MB + + private void SalvarLogLine(string arquivo, T objeto) + { + try + { + var pasta = Path.Combine( + Variaveis.CaminhoOperacoes, + Variaveis.OperacaoEmAndamento.ID + ); + + if (!Directory.Exists(pasta)) + Directory.CreateDirectory(pasta); + + string json = JsonConvert.SerializeObject(objeto, Formatting.None); + + lock (_lockLog) + { + string caminhoAtual = ObterOuCriarArquivoLogAtual(pasta, arquivo, json); + + File.AppendAllText(caminhoAtual, json + Environment.NewLine); + } + } + catch (Exception ex) + { + Console.WriteLine($"Erro ao salvar log '{arquivo}': {ex.Message}"); + } + } + + private string ObterOuCriarArquivoLogAtual(string pasta, string arquivoBase, string proximoJson) + { + var arquivosExistentes = Directory + .GetFiles(pasta, $"{arquivoBase}_*.jsonl") + .OrderBy(x => x, StringComparer.OrdinalIgnoreCase) + .ToList(); + + string ultimoArquivo = arquivosExistentes.LastOrDefault(); + + if (string.IsNullOrWhiteSpace(ultimoArquivo)) + return CriarNovoArquivoLog(pasta, arquivoBase, 1); + + var info = new FileInfo(ultimoArquivo); + + long tamanhoAposAppend = + info.Exists + ? info.Length + System.Text.Encoding.UTF8.GetByteCount(proximoJson + Environment.NewLine) + : System.Text.Encoding.UTF8.GetByteCount(proximoJson + Environment.NewLine); + + if (tamanhoAposAppend > TAMANHO_MAX_LOG_BYTES) + { + int proximoIdx = ExtrairIndiceArquivo(ultimoArquivo, arquivoBase) + 1; + return CriarNovoArquivoLog(pasta, arquivoBase, proximoIdx); + } + + return ultimoArquivo; + } + + private string CriarNovoArquivoLog(string pasta, string arquivoBase, int idx) + { + string horario = DateTime.Now.ToString("yyyyMMdd_HHmmss", CultureInfo.InvariantCulture); + string nomeArquivo = $"{arquivoBase}_{idx:0000}_{horario}.jsonl"; + string caminho = Path.Combine(pasta, nomeArquivo); + + // já cria vazio para “reservar” o nome + using (File.Create(caminho)) { } + + return caminho; + } + + private int ExtrairIndiceArquivo(string caminhoArquivo, string arquivoBase) + { + try + { + string nome = Path.GetFileNameWithoutExtension(caminhoArquivo); + + // esperado: {arquivo}_{idx}_{horario} + string prefixo = arquivoBase + "_"; + if (!nome.StartsWith(prefixo, StringComparison.OrdinalIgnoreCase)) + return 0; + + string restante = nome.Substring(prefixo.Length); + string[] partes = restante.Split('_'); + + if (partes.Length < 2) + return 0; + + if (int.TryParse(partes[0], out int idx)) + return idx; + + return 0; + } + catch + { + return 0; + } + } + #endregion #region FORMULARIO @@ -1994,8 +2249,8 @@ namespace AgroBase.Models if (Variaveis.OperacaoEmAndamento.OperacaoLiberada) { frmOperacao = - Modo == ModoOperacao.Manual ? new frmOperacaoManual() : - Modo == ModoOperacao.MapaGPS ? new frmOperacaoMapaGPS() : + Parametros?.Modo == ModoOperacao.Manual ? new frmOperacaoManual() : + Parametros?.Modo == ModoOperacao.MapaGPS ? new frmOperacaoMapaGPS() : new Form(); frmOperacao.Show(); @@ -2318,6 +2573,7 @@ namespace AgroBase.Models { public DateTime Momento { get; set; } public ModoOperacao Modo { get; set; } + public bool ControleAutomatico { get; set; } public StatusModulo Status { get; set; } public string ErroOperacaoLiberada { get; set; } public bool OperacaoLiberada { get; set; } @@ -2400,7 +2656,7 @@ namespace AgroBase.Models double tmp_max = Math.Max(Variaveis.OperacaoEmAndamento.DadosPerformance?.GPU_temp ?? 0, Variaveis.OperacaoEmAndamento.DadosPerformance?.CPU_temp ?? 0); _DispMvd?.Dados?.AtualizarDadosFreio(); - _DispSen?.Dados?.AtualizarStatusSinaleiros(Variaveis.OperacaoEmAndamento.Modo, Variaveis.OperacaoEmAndamento.StatusAtual); + _DispSen?.Dados?.AtualizarStatusSinaleiros(Variaveis.OperacaoEmAndamento.Parametros?.Modo ?? ModoOperacao.NaoDefinido, Variaveis.OperacaoEmAndamento.StatusAtual); _DispAtu?.Dados?.AtualizaTempoAtuadoGeral(); _Cooler?.Atualizar(tmp_max, DateTime.Now); _Bateria?.AtualizarConsumo(_DispMvd?.Dados?.DistanciaPercorridaTotal ?? 0); @@ -2614,7 +2870,8 @@ namespace AgroBase.Models OperacaoSensoriamentoLogModel dadosAtualizados = new OperacaoSensoriamentoLogModel() { Momento = DateTime.Now, - Modo = Variaveis.OperacaoEmAndamento.Modo, + Modo = Variaveis.OperacaoEmAndamento.Parametros?.Modo ?? ModoOperacao.NaoDefinido, + ControleAutomatico = Variaveis.OperacaoEmAndamento.Parametros?.ControleAutomatico ?? false, Status = Variaveis.OperacaoEmAndamento.Status, OperacaoLiberada = Variaveis.OperacaoEmAndamento.OperacaoLiberada, OperacaoIniciada = Variaveis.OperacaoEmAndamento.Iniciado, @@ -2645,7 +2902,7 @@ namespace AgroBase.Models ModulosSaude = HealthWorkerService.ModulosSaude.ToList(), DispositivosMapeados = new List(SerialService.DispositivosMapeados), ModsCalibragem = new Dictionary>(Variaveis.OperacaoEmAndamento.ModsCalibragem), - Logs = Logs != null ? Logs.Where(x => x.Momento >= UltimoRegistroLog).ToList() : new List(), + Logs = Logs != null ? Logs.Where(x => x?.Momento >= UltimoRegistroLog).ToList() : new List(), CoolerControl = dadosCooler }; @@ -2664,6 +2921,7 @@ namespace AgroBase.Models return new OperacaoSensoriamentoLogModel() { Modo = Modo, + ControleAutomatico = ControleAutomatico, Status = Status, Momento = Momento, ErroOperacaoLiberada = ErroOperacaoLiberada, diff --git a/AgroBase/AgroBase/Models/Operacoes/OperacaoParametrosModel.cs b/AgroBase/AgroBase/Models/Operacoes/OperacaoParametrosModel.cs index 645a76881..4074d0f66 100644 --- a/AgroBase/AgroBase/Models/Operacoes/OperacaoParametrosModel.cs +++ b/AgroBase/AgroBase/Models/Operacoes/OperacaoParametrosModel.cs @@ -68,6 +68,8 @@ namespace AgroBase.Models.Operacoes } } + public bool ControleAutomatico => new List() { ModoOperacao.MapaGPS, ModoOperacao.RetornoBase }.Contains(Modo ?? ModoOperacao.NaoDefinido); + private string _descricao; public string Descricao { @@ -511,7 +513,7 @@ namespace AgroBase.Models.Operacoes Iniciada = op.Iniciado, Liberada = op.OperacaoLiberada, Status = op.StatusAtual, - Modo = op.Modo, + Modo = op.Parametros?.Modo ?? ModoOperacao.NaoDefinido, ImpedimentoErro = op.ErroOperacaoLiberada, TempoAguardandoSegs = op.TempoAguardandoSegs, TempoDecorridoSegs = op.TempoDecorridoSegs, diff --git a/AgroBase/AgroBase/Models/TrajetoriaMapaOperacaoModel.cs b/AgroBase/AgroBase/Models/TrajetoriaMapaOperacaoModel.cs index 21320b9cd..556fa20d0 100644 --- a/AgroBase/AgroBase/Models/TrajetoriaMapaOperacaoModel.cs +++ b/AgroBase/AgroBase/Models/TrajetoriaMapaOperacaoModel.cs @@ -979,7 +979,7 @@ namespace AgroBase.Models public void LoopAtualizaDados() { - if (Variaveis.OperacaoEmAndamento.Modo != ModoOperacao.MapaGPS) + if (!(Variaveis.OperacaoEmAndamento.Parametros?.ControleAutomatico ?? false)) return; AtualizarPropriedadesPontosTrajetoria(); @@ -1778,7 +1778,10 @@ namespace AgroBase.Models if (!valido || pontosRetorno == null || pontosRetorno.Count < 1) Variaveis.OperacaoEmAndamento.Sensoriamento?.InserirLog(T_Code.Trj, StatusModulo.Falha, 0, "Trajetória de retorno inválida."); else + { AplicarTrajetoriaFixaRetorno(pontosRetorno, "RetornoBase"); + AtualizarDadosOperacaoParaRetorno(); + } } private void AplicarTrajetoriaFixaRetorno(List pontos, string motivo) @@ -1827,13 +1830,19 @@ namespace AgroBase.Models _TrajetoriaFixa = traj; Variaveis.OperacaoEmAndamento.Sensoriamento?.InserirLog(T_Code.Trj, StatusModulo.Operante, 100, $"[RETORNO] Trajetória aplicada ({motivo}) - Pontos: {traj.Count}"); + } + private void AtualizarDadosOperacaoParaRetorno() + { AutonomiaCorredor.Parar(); AtualizarDadosTrajetoria(); LoopAtualizaDados(); + var _p = OperacaoModel.CarregarParametrosOperacaoPadrao(ModoOperacao.RetornoBase, false); + Variaveis.OperacaoEmAndamento.Parametros = _p; + if (!Variaveis.OperacaoEmAndamento.Iniciado) { Variaveis.OperacaoEmAndamento.Iniciado = true; diff --git a/AgroBase/AgroBase/Models/Variaveis.cs b/AgroBase/AgroBase/Models/Variaveis.cs index c0e95167e..147cfa68e 100644 --- a/AgroBase/AgroBase/Models/Variaveis.cs +++ b/AgroBase/AgroBase/Models/Variaveis.cs @@ -57,7 +57,7 @@ namespace AgroBase.Models public static string CaminhoParametros { get; } = "Parametros/"; public static string CaminhoModelos { get; } = "C:\\AgroBaseModels\\"; public static List DispositivosConectados { get; set; } = new List(); - public static OperacaoModel OperacaoEmAndamento { get; set; } = new OperacaoModel(ModoOperacao.MapaGPS); + public static OperacaoModel OperacaoEmAndamento { get; set; } = new OperacaoModel(); public static MqttService MqttServiceLocal { get; set; } public static MqttService MqttServiceBase { get; set; } public static LoRaEspService LoraService diff --git a/AgroBase/AgroBase/Services/Operadores/HealthWorkerService.cs b/AgroBase/AgroBase/Services/Operadores/HealthWorkerService.cs index d2951f42a..0a21dda73 100644 --- a/AgroBase/AgroBase/Services/Operadores/HealthWorkerService.cs +++ b/AgroBase/AgroBase/Services/Operadores/HealthWorkerService.cs @@ -261,7 +261,7 @@ namespace AgroBase.Services.Operadores RedisService.AtualizarCampos( CtxKey.DadosOperacao, ("configurado", true), - ("modo", Variaveis.OperacaoEmAndamento.Modo), + ("modo", Variaveis.OperacaoEmAndamento.Parametros?.Modo ?? ModoOperacao.NaoDefinido), ("tempo_aguardar_inicio_operacao", Variaveis.OperacaoEmAndamento.TempoIniciarOperacao), ("modulos_mandatorios", _Parametros.ModulosMandatorios.Where(x => x.Mandatorio && x.Utilizar).Select(x => (int)x.Dispositivo).ToArray()), ("modulos_opcionais", _Parametros.ModulosMandatorios.Where(x => !x.Mandatorio && x.Utilizar).Select(x => (int)x.Dispositivo).ToArray()), @@ -319,7 +319,7 @@ namespace AgroBase.Services.Operadores ) ); - if (Variaveis.OperacaoEmAndamento.Modo == Enums.ModoOperacao.MapaGPS && (Variaveis.OperacaoEmAndamento.Trajetoria?._TrajetoriaFixa?.Any() ?? false)) + if ((Variaveis.OperacaoEmAndamento.Parametros?.ControleAutomatico ?? false) && (Variaveis.OperacaoEmAndamento.Trajetoria?._TrajetoriaFixa?.Any() ?? false)) { var comando = new { diff --git a/AgroBase/AgroBase/Services/SerialService.cs b/AgroBase/AgroBase/Services/SerialService.cs index 70b94f47d..b211799fb 100644 --- a/AgroBase/AgroBase/Services/SerialService.cs +++ b/AgroBase/AgroBase/Services/SerialService.cs @@ -379,7 +379,13 @@ namespace AgroBase.Services }); if (PrimeiraExecucao) { - OperacaoModel.CarregarParametrosOperacaoPadrao(ModoOperacao.MapaGPS, true); + //OperacaoModel.CarregarParametrosOperacaoPadrao(ModoOperacao.MapaGPS, true); + Func func = new Func(() => + { + frmInstancial.frmPrincipal.cmbModoOperacao.SelectedIndex = (int)ModoOperacao.MapaGPS; + return true; + }); + FuncoesGlobais.ExecutarMetodoComVerificacaoCrossThread(frmInstancial.frmPrincipal.cmbModoOperacao, func); } //DispositivosMapeados.ForEach(d => d.AtualizarDados()); diff --git a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/modulos/direcional.py b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/modulos/direcional.py index ace6da613..49c449415 100644 --- a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/modulos/direcional.py +++ b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/modulos/direcional.py @@ -105,7 +105,7 @@ def definir_comando(pid: PIDAdaptativo, envio_necessario: bool): if _tipo_controle == TiposControladorDirecional.MPC: op_modo = ModoOperacao(_operacao.get("modo", ModoOperacao.NaoDefinido.value)) - if op_modo == ModoOperacao.MapaGPS: + if op_modo in [ModoOperacao.MapaGPS, ModoOperacao.RetornoBase]: return _comando_mapa_gps_mpc(contexto) elif op_modo == ModoOperacao.MapeamentoVisual: return _comando_mapeamento_visual(contexto) diff --git a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/modulos/movimentacao.py b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/modulos/movimentacao.py index 7fadcc896..299e12046 100644 --- a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/modulos/movimentacao.py +++ b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/manager_worker/modulos/movimentacao.py @@ -36,7 +36,7 @@ def definir_comando(filtro_vel: FiltroVelocidade, erro_orientacao: float = None) reduzir_para_pulverizar = False pontos_fim_corredor = -1 - if op_modo == ModoOperacao.MapaGPS: + 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) diff --git a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/shared/contexto_global_redis.py b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/shared/contexto_global_redis.py index a55b4d99d..cb03cc862 100644 --- a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/shared/contexto_global_redis.py +++ b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/shared/contexto_global_redis.py @@ -478,7 +478,7 @@ class ContextoGlobalRedis: return # 🔸 Modo MAPA GPS ou IA - if modo in [ModoOperacao.MapaGPS, ModoOperacao.TreinamentoIA, ModoOperacao.MapeamentoVisual]: + if modo in [ModoOperacao.MapaGPS, ModoOperacao.TreinamentoIA, ModoOperacao.MapeamentoVisual, ModoOperacao.RetornoBase]: # Iniciando operacao if (iniciado and not status_iniciado_anterior): cls._iniciar_operacao() diff --git a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/shared/enums.py b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/shared/enums.py index 4ad3ae4f8..2c2ed34e1 100644 --- a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/shared/enums.py +++ b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/shared/enums.py @@ -39,6 +39,7 @@ class ModoOperacao(IntEnum): MapaGPS = 2 TreinamentoIA = 3 MapeamentoVisual = 4 + RetornoBase = 5 class StatusOperacao(IntEnum): NaoIniciado = 0 diff --git a/AgroBase/OperationControl/ViewModels/Views/Operacao/Monitoramento/ControleManualViewModel.cs b/AgroBase/OperationControl/ViewModels/Views/Operacao/Monitoramento/ControleManualViewModel.cs index 55ace7825..ef4cfbc82 100644 --- a/AgroBase/OperationControl/ViewModels/Views/Operacao/Monitoramento/ControleManualViewModel.cs +++ b/AgroBase/OperationControl/ViewModels/Views/Operacao/Monitoramento/ControleManualViewModel.cs @@ -39,10 +39,11 @@ namespace OperationControl.ViewModels.Views.Operacao.Monitoramento OnPropertyChanged(nameof(TextoAjuda)); OnPropertyChanged(nameof(StatusBrush)); - if (VariaveisControleOperacao.RoverEmFoco != null) + var r = VariaveisControleOperacao.RoverEmFoco; + if (r != null) { - VariaveisControleOperacao.RoverEmFoco.Controle.MovimentoAutomatico = !value; - VariaveisControleOperacao.RoverEmFoco.Controle.DirecionalAutomatico = !value; + r.Controle.MovimentoAutomatico = value ? false : r.ControleAutomatico; + r.Controle.DirecionalAutomatico = value ? false : r.ControleAutomatico; VariaveisControleOperacao.EnviarParametrosOperacao(new AgroBase.Models.Operacoes.OperacaoParametrosModel() { Controle = VariaveisControleOperacao.RoverEmFoco?.Controle diff --git a/Mapas/SAO_MANOEL_PIVO/-47.19313E-22.09470N600H.pos b/Mapas/SAO_MANOEL_PIVO/-47.19313E-22.09470N600H.pos new file mode 100644 index 000000000..e69de29bb diff --git a/Mapas/SAO_MANOEL_PIVO/LineFeature.dbf b/Mapas/SAO_MANOEL_PIVO/LineFeature.dbf new file mode 100644 index 0000000000000000000000000000000000000000..0be64ed50bde8fdc41f490dbdf4569c74da0ae50 GIT binary patch literal 5329 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 literal 0 HcmV?d00001 diff --git a/Mapas/SAO_MANOEL_PIVO/LineFeature.shx b/Mapas/SAO_MANOEL_PIVO/LineFeature.shx new file mode 100644 index 0000000000000000000000000000000000000000..235b614f14e26a12d1c161d73109d9c19c771ed1 GIT binary patch literal 228 zcmZQzQ0HR64vJndGcW)VgWbHpI}gurKaiOG^qZ}O*?}`#&b$r+@;~0c+ImRL>;QJ{ zD56FT3``k7JP$&%0__Cx*~=g_=OYNs;|HPnc0p)CH3%&{2||nhgU}LL5L)UQgqC%J Q(DLgbw2~BrR%rv#00EdJ4gdfE literal 0 HcmV?d00001