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 000000000..0be64ed50 Binary files /dev/null and b/Mapas/SAO_MANOEL_PIVO/LineFeature.dbf differ diff --git a/Mapas/SAO_MANOEL_PIVO/LineFeature.shp b/Mapas/SAO_MANOEL_PIVO/LineFeature.shp new file mode 100644 index 000000000..98727f6f4 Binary files /dev/null and b/Mapas/SAO_MANOEL_PIVO/LineFeature.shp differ diff --git a/Mapas/SAO_MANOEL_PIVO/LineFeature.shx b/Mapas/SAO_MANOEL_PIVO/LineFeature.shx new file mode 100644 index 000000000..235b614f1 Binary files /dev/null and b/Mapas/SAO_MANOEL_PIVO/LineFeature.shx differ