ajustado pesos do MPC

This commit is contained in:
Diego Freitas 2025-09-25 16:05:45 -03:00
parent c3f72fc7df
commit 914f838482
54 changed files with 640 additions and 236 deletions

Binary file not shown.

View File

@ -439,6 +439,13 @@
this.cmbCameras_Filtro = new System.Windows.Forms.ComboBox();
this.label131 = new System.Windows.Forms.Label();
this.chartCameras = new System.Windows.Forms.DataVisualization.Charting.Chart();
this.tabComandos = new System.Windows.Forms.TabPage();
this.label138 = new System.Windows.Forms.Label();
this.dtComandosAtu = new System.Windows.Forms.DataGridView();
this.label137 = new System.Windows.Forms.Label();
this.dtComandosDir = new System.Windows.Forms.DataGridView();
this.label100 = new System.Windows.Forms.Label();
this.dtComandosMov = new System.Windows.Forms.DataGridView();
this.panel6 = new System.Windows.Forms.Panel();
this.pnlInformacoesOperacao = new System.Windows.Forms.Panel();
this.label134 = new System.Windows.Forms.Label();
@ -500,6 +507,8 @@
this.label36 = new System.Windows.Forms.Label();
this.txtMomento = new System.Windows.Forms.TextBox();
this.btnPlay = new System.Windows.Forms.Button();
this.tabMPC = new System.Windows.Forms.TabPage();
this.tvwMPC = new System.Windows.Forms.TreeView();
((System.ComponentModel.ISupportInitialize)(this.trbMomento)).BeginInit();
this.panel1.SuspendLayout();
this.tabControl4.SuspendLayout();
@ -567,9 +576,14 @@
this.gpbCameras_Analise.SuspendLayout();
this.gpbCameras_Filtro.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.chartCameras)).BeginInit();
this.tabComandos.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.dtComandosAtu)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.dtComandosDir)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.dtComandosMov)).BeginInit();
this.panel6.SuspendLayout();
this.pnlInformacoesOperacao.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picCameraCaminho)).BeginInit();
this.tabMPC.SuspendLayout();
this.SuspendLayout();
//
// trbMomento
@ -960,6 +974,8 @@
this.tabControl1.Controls.Add(this.tabSegmentacao);
this.tabControl1.Controls.Add(this.tabCPU);
this.tabControl1.Controls.Add(this.tabCameras);
this.tabControl1.Controls.Add(this.tabComandos);
this.tabControl1.Controls.Add(this.tabMPC);
this.tabControl1.Location = new System.Drawing.Point(2, 2);
this.tabControl1.Margin = new System.Windows.Forms.Padding(2);
this.tabControl1.Name = "tabControl1";
@ -4886,6 +4902,74 @@
this.chartCameras.TabIndex = 137;
this.chartCameras.Text = "chart1";
//
// tabComandos
//
this.tabComandos.AutoScroll = true;
this.tabComandos.Controls.Add(this.label138);
this.tabComandos.Controls.Add(this.dtComandosAtu);
this.tabComandos.Controls.Add(this.label137);
this.tabComandos.Controls.Add(this.dtComandosDir);
this.tabComandos.Controls.Add(this.label100);
this.tabComandos.Controls.Add(this.dtComandosMov);
this.tabComandos.Location = new System.Drawing.Point(4, 22);
this.tabComandos.Name = "tabComandos";
this.tabComandos.Padding = new System.Windows.Forms.Padding(3);
this.tabComandos.Size = new System.Drawing.Size(496, 522);
this.tabComandos.TabIndex = 12;
this.tabComandos.Text = "Comandos";
this.tabComandos.UseVisualStyleBackColor = true;
//
// label138
//
this.label138.AutoSize = true;
this.label138.Location = new System.Drawing.Point(6, 341);
this.label138.Name = "label138";
this.label138.Size = new System.Drawing.Size(44, 13);
this.label138.TabIndex = 5;
this.label138.Text = "Atuador";
//
// dtComandosAtu
//
this.dtComandosAtu.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dtComandosAtu.Location = new System.Drawing.Point(6, 357);
this.dtComandosAtu.Name = "dtComandosAtu";
this.dtComandosAtu.Size = new System.Drawing.Size(465, 150);
this.dtComandosAtu.TabIndex = 4;
//
// label137
//
this.label137.AutoSize = true;
this.label137.Location = new System.Drawing.Point(6, 172);
this.label137.Name = "label137";
this.label137.Size = new System.Drawing.Size(54, 13);
this.label137.TabIndex = 3;
this.label137.Text = "Direcional";
//
// dtComandosDir
//
this.dtComandosDir.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dtComandosDir.Location = new System.Drawing.Point(6, 188);
this.dtComandosDir.Name = "dtComandosDir";
this.dtComandosDir.Size = new System.Drawing.Size(465, 150);
this.dtComandosDir.TabIndex = 2;
//
// label100
//
this.label100.AutoSize = true;
this.label100.Location = new System.Drawing.Point(6, 3);
this.label100.Name = "label100";
this.label100.Size = new System.Drawing.Size(77, 13);
this.label100.TabIndex = 1;
this.label100.Text = "Movimentação";
//
// dtComandosMov
//
this.dtComandosMov.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dtComandosMov.Location = new System.Drawing.Point(6, 19);
this.dtComandosMov.Name = "dtComandosMov";
this.dtComandosMov.Size = new System.Drawing.Size(465, 150);
this.dtComandosMov.TabIndex = 0;
//
// panel6
//
this.panel6.Controls.Add(this.pnlInformacoesOperacao);
@ -5539,6 +5623,25 @@
this.btnPlay.UseVisualStyleBackColor = true;
this.btnPlay.Click += new System.EventHandler(this.btnPlay_Click);
//
// tabMPC
//
this.tabMPC.Controls.Add(this.tvwMPC);
this.tabMPC.Location = new System.Drawing.Point(4, 22);
this.tabMPC.Name = "tabMPC";
this.tabMPC.Padding = new System.Windows.Forms.Padding(3);
this.tabMPC.Size = new System.Drawing.Size(496, 522);
this.tabMPC.TabIndex = 13;
this.tabMPC.Text = "MPC";
this.tabMPC.UseVisualStyleBackColor = true;
//
// tvwMPC
//
this.tvwMPC.Dock = System.Windows.Forms.DockStyle.Fill;
this.tvwMPC.Location = new System.Drawing.Point(3, 3);
this.tvwMPC.Name = "tvwMPC";
this.tvwMPC.Size = new System.Drawing.Size(490, 516);
this.tvwMPC.TabIndex = 0;
//
// frmResultadosOperacao
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -5655,10 +5758,16 @@
this.gpbCameras_Filtro.ResumeLayout(false);
this.gpbCameras_Filtro.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.chartCameras)).EndInit();
this.tabComandos.ResumeLayout(false);
this.tabComandos.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.dtComandosAtu)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.dtComandosDir)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.dtComandosMov)).EndInit();
this.panel6.ResumeLayout(false);
this.pnlInformacoesOperacao.ResumeLayout(false);
this.pnlInformacoesOperacao.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.picCameraCaminho)).EndInit();
this.tabMPC.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
@ -6113,5 +6222,14 @@
private System.Windows.Forms.TabPage tabSonarDeteccoes;
private System.Windows.Forms.Panel pnlSonarDeteccoes;
private System.Windows.Forms.CheckBox chbSonarDeteccoes;
private System.Windows.Forms.TabPage tabComandos;
private System.Windows.Forms.Label label137;
private System.Windows.Forms.DataGridView dtComandosDir;
private System.Windows.Forms.Label label100;
private System.Windows.Forms.DataGridView dtComandosMov;
private System.Windows.Forms.Label label138;
private System.Windows.Forms.DataGridView dtComandosAtu;
private System.Windows.Forms.TabPage tabMPC;
private System.Windows.Forms.TreeView tvwMPC;
}
}

View File

@ -9,10 +9,13 @@ using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Threading.Tasks;
using System.Windows.Forms;
using static AgroBase.Models.Enums;
namespace AgroBase.Forms.Operacoes
{
@ -201,6 +204,7 @@ namespace AgroBase.Forms.Operacoes
InicializarGraficos();
InicializarCombosBusca();
InicializarGridsComandos();
AtualizarDadosMomento();
@ -857,6 +861,24 @@ namespace AgroBase.Forms.Operacoes
}
private void InicializarGridsComandos()
{
dtComandosMov.Columns.Clear();
dtComandosMov.Columns.Add("clDirecao", "Direção");
dtComandosMov.Columns.Add("clRPMSP", "RPM SP");
dtComandosDir.Columns.Clear();
dtComandosDir.Columns.Add("clDirecao", "Direção");
dtComandosDir.Columns.Add("clAnguloSP", "Angulo SP");
dtComandosDir.Columns.Add("clTipoMovimento", "Tipo Movimento");
dtComandosAtu.Columns.Clear();
dtComandosAtu.Columns.Add("clB0", "B0");
dtComandosAtu.Columns.Add("clB1", "B1");
dtComandosAtu.Columns.Add("clB2", "B2");
dtComandosAtu.Columns.Add("clB3", "B3");
}
private void InicializarCombosBusca()
{
CarregarInformacoesBusca(gpbMOV_Alimentacao_Filtro, graficoMovAlimentacao.Series.Select(x => x.Titulo).ToArray());
@ -1072,6 +1094,10 @@ namespace AgroBase.Forms.Operacoes
AtualizarInformacoesSonar();
AtualizarInformacoesCPU();
AtualizarInformacoesComandos();
AtualizarInformacoesMPC();
}
private void AtualizarInformacoesOperacao()
@ -1106,8 +1132,8 @@ namespace AgroBase.Forms.Operacoes
txtVelocidadeControle.Text = ((Log.Controle?.PercentualVelocidadeSP ?? 0) / VariaveisEquipamento.RPM_Max_Roda * 100).ToString() + " rpm";
txtErvasIdentificadas.Text = $"{totalAtuacoes}";
txtDistanciasLaterais.Text = Log.Trajetoria.DistanciaEsquerda.ToString("0.00") + " m / " + Log.Trajetoria.DistanciaDireita.ToString("0.00") + " m";
txtErroLateral.Text = Log.Controle.ErroLateral.ToString("0.00") + " m";
txtDistanciasLaterais.Text = (Log.Trajetoria.DistanciaEsquerda * 100.0).ToString("0.00") + " cm / " + (Log.Trajetoria.DistanciaDireita * 100.0).ToString("0.00") + " cm";
txtErroLateral.Text = (Log.Controle.ErroLateral * 100.0).ToString("0.00") + " cm";
txtNaMargem.Text = Log.Trajetoria.NaMargemDoCorredor ? "Sim" : "Não";
lblPercentualOperacao.Text = $"Operação {Log.Trajetoria.ProgressoTrajeto.ToString("0.00")}%";
@ -1528,6 +1554,115 @@ namespace AgroBase.Forms.Operacoes
}
}
private void AtualizarInformacoesComandos()
{
var Log = LogsOperacao[idxMomentoAtual].Controle;
foreach (var controle in Log.TiposControle)
{
DataGridView dt = FuncoesGlobais.FindControlRecursive<DataGridView>(tabComandos, "dtComandos" + controle.Tipo.ToString());
dt.Rows.Clear();
foreach (var comando in controle.Comandos)
{
dt.Rows.Add(comando.Split(';'));
}
}
}
private void AtualizarInformacoesMPC()
{
bool ordenarPorCustoTotal = true;
Dictionary<string, ManagerWorkerMessageResponseDebugCustoModel> dict = LogsOperacao[idxMomentoAtual].Controle.DebugCustoMpc;
TreeView tv = tvwMPC;
tv.BeginUpdate();
tv.Nodes.Clear();
// rank global e margem (diferença p/ o próximo)
var ordered = dict
.Select(kv => new {
kv.Key,
Cost = ordenarPorCustoTotal ? kv.Value.custo_total : kv.Value.custo_map
})
.OrderBy(x => x.Cost)
.ToList();
var rank = new Dictionary<string, (int rank, double cost, double margin)>();
for (int i = 0; i < ordered.Count; i++)
{
double margin = (i < ordered.Count - 1) ? (ordered[i + 1].Cost - ordered[i].Cost) : 0.0;
rank[ordered[i].Key] = (i + 1, ordered[i].Cost, margin);
}
// agrupar por tipo
var porTipo = dict.GroupBy(kv => CandMpcKey.ParseKey(kv.Key).Tipo);
foreach (var g in porTipo.OrderBy(gr => gr.Key.ToString()))
{
var tipoNode = tv.Nodes.Add(g.Key.ToString());
// ordenar ângulos
foreach (var kv in g.OrderBy(kv => CandMpcKey.ParseKey(kv.Key).AngDeg))
{
var k = CandMpcKey.ParseKey(kv.Key);
var m = kv.Value;
var r = rank[kv.Key];
string angleTxt = k.AngDeg.ToString("+0.00;-0.00;0.00", CultureInfo.InvariantCulture);
string yLabel = ordenarPorCustoTotal ? "ctot" : "cmap";
double yVal = ordenarPorCustoTotal ? m.custo_total : m.custo_map;
// nó do ângulo (resumo compacto)
var angNode = tipoNode.Nodes.Add(
$"ang {angleTxt}° #{r.rank} Δ={r.margin:0.000} {yLabel}={yVal:0.0000}");
angNode.Tag = kv.Key;
// destaque visual
if (r.rank == 1)
{
angNode.NodeFont = new Font(tv.Font, FontStyle.Bold);
angNode.ForeColor = Color.ForestGreen;
}
else if (r.rank == 2)
{
angNode.ForeColor = Color.DarkOrange;
}
// ---- Subgrupos
var pose = angNode.Nodes.Add("Pose/Alvo");
pose.Nodes.Add($"x={m.x_sim:0.3} y={m.y_sim:0.3} θ={m.theta_sim:0.00}");
pose.Nodes.Add($"alvo: x={m.x_alvo:0.3} y={m.y_alvo:0.3}");
var errs = angNode.Nodes.Add("Erros");
errs.Nodes.Add($"epos={m.erro_posicao:0.3} eposn={m.erro_posicao_n:0.3}");
errs.Nodes.Add($"eori={m.erro_orientacao:0.3} eorin={m.erro_orientacao_n:0.4}");
errs.Nodes.Add($"elat={m.erro_lateral:0.3} elatn={m.erro_lateral_n:0.4}");
errs.Nodes.Add($"ere={m.erro_re:0.3}");
var costs = angNode.Nodes.Add("Custos");
costs.Nodes.Add($"cpos={m.custo_posicao:0.4} cori={m.custo_orientacao:0.4}");
costs.Nodes.Add($"csua={m.custo_suavizacao:0.4} cre={m.custo_re:0.4}");
costs.Nodes.Add($"clat={m.custo_lateral:0.4} clatd={m.custo_lateral_d:0.4}");
costs.Nodes.Add($"cvw={m.custo_visual_worker:0.4}");
costs.Nodes.Add($"cmap={m.custo_map:0.4} ctot={m.custo_total:0.4}");
var pesos = angNode.Nodes.Add("Pesos");
pesos.Nodes.Add($"pos={m.peso_posicao:0.2} ori={m.peso_orientacao:0.2}");
pesos.Nodes.Add($"suav={m.peso_suavizacao:0.2} re={m.peso_re:0.2} ideal={m.peso_ideal:0.2}");
pesos.Nodes.Add($"lat={m.peso_lateral:0.2}");
if (m.peso_tipo_movimento != null)
{
var ptip = pesos.Nodes.Add("tipo_mov");
foreach (var kvp in m.peso_tipo_movimento)
ptip.Nodes.Add($"{kvp.Key}: {kvp.Value:0.2}");
}
}
}
tv.ExpandAll(); // ou deixe colapsado se preferir
tv.EndUpdate();
}
private void pnlOrientacaoDirecional_Paint(object sender, PaintEventArgs e)
@ -1535,10 +1670,10 @@ namespace AgroBase.Forms.Operacoes
var LogOp = LogsOperacao.FirstOrDefault(x => x.Momento == MomentoAtual);
double Angulo = LogOp?.Controle?.Angulo ?? 0;
Enums.Direcao direcaoControle = (LogOp?.Controle.TiposControle?.FirstOrDefault(x => x.Tipo == Enums.T_Code.Dir).UltimaDirecao ?? Enums.Direcao.Parado);
Angulo *=
direcaoControle == Enums.Direcao.Esquerda ? -1 :
direcaoControle == Enums.Direcao.Direita ? 1 :
0;
//Angulo *=
// direcaoControle == Enums.Direcao.Esquerda ? -1 :
// direcaoControle == Enums.Direcao.Direita ? 1 :
// 0;
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)Angulo, 90);
}

View File

@ -41,6 +41,7 @@ namespace AgroBase.Models
/// Verifica se o timer foi criado, mas ainda não foi iniciado.
/// </summary>
public bool IsCreated => _state == TimerState.Created;
public bool IsDisposed => _state == TimerState.Disposed;
private CancellationTokenSource _cancellationTokenSource;
private Func<Task> _taskToExecute;
@ -92,6 +93,7 @@ namespace AgroBase.Models
_timer.Interval = interval;
_timer.AutoReset = false;
_timer.Elapsed += _timer_Elapsed;
_timer.Disposed += _timer_Disposed;
lock (_timersLock)
{
@ -99,10 +101,15 @@ namespace AgroBase.Models
}
}
private void _timer_Disposed(object sender, EventArgs e)
{
_state = TimerState.Disposed;
}
private async void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
System.Timers.Timer tmr = sender as System.Timers.Timer;
if (VerificaDisposed()) return;
if (IsDisposed) return;
tmr.Stop();
if (_Ticking)
@ -157,9 +164,9 @@ namespace AgroBase.Models
finally
{
_Ticking = false;
if (!VerificaDisposed() && _state == TimerState.Running)
if (_state == TimerState.Running)
{
tmr.Start();
if (!IsDisposed) tmr.Start();
}
}
}

View File

@ -1056,7 +1056,7 @@ namespace AgroBase.Models
Protocolos = new List<string>()
{
_Controle.Direcao.ToString() + ";" + _Controle.Angulo.ToString()
_Controle.Direcao.ToString() + ";" + _Controle.Angulo.ToString() + ";" + _Controle.TipoMovimento.ToString()
};
break;
}
@ -1635,6 +1635,7 @@ namespace AgroBase.Models
public List<MPCSimulacaoModel> SimulacaoMPC { get; set; } = new List<MPCSimulacaoModel>();
public double Latencia { get; set; }
public double ErroLateral { get; set; } = 0.0;
public Dictionary<string, ManagerWorkerMessageResponseDebugCustoModel> DebugCustoMpc { get; set; } = new Dictionary<string, ManagerWorkerMessageResponseDebugCustoModel>();
public OperacaoControleModel Clone()
{
@ -1665,7 +1666,8 @@ namespace AgroBase.Models
ticks_sem_resposta = ticks_sem_resposta,
Latencia = Latencia,
EmFreio = EmFreio,
ErroLateral = ErroLateral
ErroLateral = ErroLateral,
DebugCustoMpc = new Dictionary<string, ManagerWorkerMessageResponseDebugCustoModel>(DebugCustoMpc ?? new Dictionary<string, ManagerWorkerMessageResponseDebugCustoModel>()),
};
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using static AgroBase.Models.Enums;
namespace AgroBase.Models.Operadores
@ -55,6 +56,59 @@ namespace AgroBase.Models.Operadores
public int heartbeat { get; set; }
public double latencia { get; set; }
public double erro_lateral { get; set; }
public Dictionary<string, ManagerWorkerMessageResponseDebugCustoModel> debug_custo { get; set; }
}
public class ManagerWorkerMessageResponseDebugCustoModel
{
public double angulo { get; set; }
public TipoMovimentoDirecional tipo { get; set; }
public double omega { get; set; }
public double x_sim { get; set; }
public double y_sim { get; set; }
public double theta_sim { get; set; }
public double x_alvo { get; set; }
public double y_alvo { get; set; }
public double peso_posicao { get; set; }
public double peso_orientacao { get; set; }
public double peso_suavizacao { get; set; }
public double peso_re { get; set; }
public double peso_ideal { get; set; }
public double peso_lateral { get; set; }
public Dictionary<TipoMovimentoDirecional, double> peso_tipo_movimento { get; set; }
public double erro_posicao { get; set; }
public double erro_posicao_n { get; set; }
public double erro_orientacao { get; set; }
public double erro_orientacao_n { get; set; }
public double erro_suavizacao { get; set; }
public double erro_re { get; set; }
public double erro_lateral { get; set; }
public double erro_lateral_n { get; set; }
public double custo_posicao { get; set; }
public double custo_orientacao { get; set; }
public double custo_suavizacao { get; set; }
public double custo_tipo_movimento { get; set; }
public double custo_re { get; set; }
public double custo_lateral { get; set; }
public double custo_lateral_d { get; set; }
public double custo_flip { get; set; }
public double custo_visual_worker { get; set; }
public double custo_map { get; set; }
public double custo_total { get; set; }
}
public class CandMpcKey
{
public TipoMovimentoDirecional Tipo { get; set; }
public double AngDeg { get; set; }
public static CandMpcKey ParseKey(string k)
{
var partes = k.Split('_');
TipoMovimentoDirecional tipo = (TipoMovimentoDirecional)(Convert.ToInt32(partes[0]));
double ang = (Convert.ToDouble(partes[1].Replace(".", ",")));
return new CandMpcKey() { Tipo = tipo, AngDeg = ang };
}
}
public class ManagerWorkerMessageResponseModulosPendentesModel

View File

@ -771,6 +771,7 @@ namespace AgroBase.Models
dictParams.TryGetValue("heartbeat", out var _heartbeat);
dictParams.TryGetValue("latencia", out var _latencia);
dictParams.TryGetValue("erro_lateral", out var _erro_lateral);
dictParams.TryGetValue("debug_custo", out var _debug_custo);
novoComando = new ManagerWorkerMessageResponseComandoModel()
{
angulo = Convert.ToDouble(_angulo),
@ -781,6 +782,7 @@ namespace AgroBase.Models
heartbeat = Convert.ToInt32(_heartbeat),
latencia = Convert.ToDouble(_latencia.ToString().Replace(".", ",")),
erro_lateral = Convert.ToDouble(_erro_lateral.ToString().Replace(".", ",")),
debug_custo = JsonConvert.DeserializeObject<Dictionary<string, ManagerWorkerMessageResponseDebugCustoModel>>(_debug_custo.ToString()),
};
}
catch (Exception ex)
@ -792,7 +794,7 @@ namespace AgroBase.Models
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
bool comandoMudou = novoComando != null && (_Controle.Angulo != novoComando.angulo || _Controle.PercentualVelocidadeSP != novoComando.percentual_velocidade || _Controle.TipoMovimento != novoComando.tipo_movimento || _Controle.EmFreio != novoComando.em_freio);
bool mangerDestravou = (_Controle.ticks_sem_resposta.AddMilliseconds(min_ticks_sem_resposta) < agora && novoComando.heartbeat != _Controle.heartbeat);
bool mangerDestravou = novoComando != null && (_Controle.ticks_sem_resposta.AddMilliseconds(min_ticks_sem_resposta) < agora && novoComando.heartbeat != _Controle.heartbeat);
if (novoComando != null && (comandoMudou || mangerDestravou))
{
_Controle.Angulo = novoComando.angulo;
@ -802,10 +804,11 @@ namespace AgroBase.Models
_Controle.SimulacaoMPC = novoComando.simulacao?.Select(x => new MPCSimulacaoModel() { latitude = x[0], longitude = x[1], orientacao = x[2] }).ToList() ?? new List<MPCSimulacaoModel>();
_Controle.Latencia = novoComando.latencia;
_Controle.ErroLateral = novoComando.erro_lateral;
_Controle.DebugCustoMpc = novoComando.debug_custo;
Variaveis.OperacaoEmAndamento.AtualizaInformacoesControleOperacao();
}
if (novoComando.heartbeat == _Controle.heartbeat)
if (novoComando != null && novoComando.heartbeat == _Controle.heartbeat)
{
if (_Controle.ticks_sem_resposta == DateTime.MinValue)
{
@ -816,7 +819,8 @@ namespace AgroBase.Models
{
_Controle.ticks_sem_resposta = DateTime.MinValue;
}
_Controle.heartbeat = novoComando.heartbeat;
if (novoComando != null)
_Controle.heartbeat = novoComando.heartbeat;
if (_Controle.ticks_sem_resposta != DateTime.MinValue)
{
if (_Controle.ticks_sem_resposta.AddMilliseconds(max_ticks_sem_resposta) < agora)

View File

@ -1 +0,0 @@
1.A99D66CFCE8CA170740CE0403956F4DFAF4683829A89F4B7AD9C95303871E284

View File

@ -1,5 +0,0 @@
{
"description" : "AutoLaunch Protocols Preregistration",
"name" : "Protocol Preregistration",
"version" : "1.0.0.9"
}

View File

@ -1,118 +0,0 @@
{
"allow": [
{
"origins": [
"https://.get.microsoft.com",
"https://.apps.microsoft.com"
],
"protocol": "ms-windows-store"
},
{
"origins": [
"https://.onedrive.com",
"https://.onedrive.live.com",
"https://sharepoint.com"
],
"protocol": "ms-word"
},
{
"origins": [
"https://[a-z1-9-]*word-edit.officeapps.live.com",
"https://[a-z1-9-]*word-view.officeapps.live.com",
"https://[a-z1-9-]*onenote.officeapps.live.com",
"https://[a-z1-9-]*eap.officeapps.live.com",
"https://[a-z1-9-]*shared.officeapps.live.com",
"https://[a-z1-9-]*afhs.officeapps.live.com",
"https://[a-z1-9-]*vhs.officeapps.live.com",
"https://[a-z1-9-]*optin.online.office.com"
],
"use_regex": true,
"protocol": "ms-word"
},
{
"origins": [
"https://.onedrive.com",
"https://.onedrive.live.com",
"https://sharepoint.com"
],
"protocol": "ms-excel"
},
{
"origins": [
"https://[a-z1-9-]*excel.officeapps.live.com",
"https://[a-z1-9-]*onenote.officeapps.live.com",
"https://[a-z1-9-]*eap.officeapps.live.com",
"https://[a-z1-9-]*shared.officeapps.live.com",
"https://[a-z1-9-]*afhs.officeapps.live.com",
"https://[a-z1-9-]*vhs.officeapps.live.com",
"https://[a-z1-9-]*optin.online.office.com"
],
"use_regex": true,
"protocol": "ms-excel"
},
{
"origins": [
"https://.onedrive.com",
"https://.onedrive.live.com",
"https://sharepoint.com"
],
"protocol": "ms-powerpoint"
},
{
"origins": [
"https://[a-z1-9-]*powerpoint.officeapps.live.com",
"https://[a-z1-9-]*onenote.officeapps.live.com",
"https://[a-z1-9-]*eap.officeapps.live.com",
"https://[a-z1-9-]*shared.officeapps.live.com",
"https://[a-z1-9-]*afhs.officeapps.live.com",
"https://[a-z1-9-]*vhs.officeapps.live.com",
"https://[a-z1-9-]*optin.online.office.com"
],
"use_regex": true,
"protocol": "ms-powerpoint"
},
{
"origins": [
"https://.onedrive.com",
"https://.onedrive.live.com",
"https://sharepoint.com"
],
"protocol": "ms-visio"
},
{
"origins": [
"https://[a-z1-9-]*visio.officeapps.live.com",
"https://[a-z1-9-]*onenote.officeapps.live.com",
"https://[a-z1-9-]*eap.officeapps.live.com",
"https://[a-z1-9-]*shared.officeapps.live.com",
"https://[a-z1-9-]*afhs.officeapps.live.com",
"https://[a-z1-9-]*vhs.officeapps.live.com",
"https://[a-z1-9-]*optin.online.office.com"
],
"use_regex": true,
"protocol": "ms-visio"
},
{
"origins": [
"https://www.microsoft.com"
],
"protocol": "ms-copilot"
}
],
"warn": [
{
"origins": [
"*"
],
"protocol": "ms-test-warn"
}
],
"block": [
{
"origins": [
"*"
],
"protocol": "ms-test-block"
}
]
}

View File

@ -29,5 +29,5 @@
"top_topics_and_observing_domains": [ ]
} ],
"hex_encoded_hmac_key": "40F346D3248C3AFDF2BEE1FE496DBD32F7CED6E5AE98B881ABC421AA7E7B5642",
"next_scheduled_calculation_time": "13403636820469815"
"next_scheduled_calculation_time": "13403636820470311"
}

View File

@ -1,3 +1,3 @@
2025/09/24-10:46:59.725 4b24 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/09/24-10:46:59.737 4b24 Recovering log #3
2025/09/24-10:46:59.741 4b24 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log
2025/09/25-16:03:01.465 6fbc Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/09/25-16:03:01.473 6fbc Recovering log #3
2025/09/25-16:03:01.476 6fbc 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/09/24-10:35:30.569 5054 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/09/24-10:35:30.580 5054 Recovering log #3
2025/09/24-10:35:30.583 5054 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log
2025/09/25-15:43:45.802 6e20 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/09/25-15:43:45.810 6e20 Recovering log #3
2025/09/25-15:43:45.813 6e20 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":"13403281624997146","port":443,"protocol_str":"quic"}],"anonymization":["DAAAAAcAAABmaWxlOi8vAA==",false,0],"network_stats":{"srtt":16178},"server":"https://tile.openstreetmap.org","supports_spdy":true}],"supports_quic":{"address":"2804:d78:67d:1400:d0b1:309d:2180:66eb","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":"13403386981816386","port":443,"protocol_str":"quic"}],"anonymization":["DAAAAAcAAABmaWxlOi8vAA==",false,0],"network_stats":{"srtt":16615},"server":"https://tile.openstreetmap.org","supports_spdy":true}],"supports_quic":{"address":"2804:d78:67d:1400:b1d8:f114:3804:472c","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":1790250106.627238,"host":"bWGAftl61rqoc0YzqPncsLvQQh/iC2Bdp3ejUeGC83w=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1758714106.62724}],"version":2}
{"sts":[{"expiry":1790355489.322402,"host":"bWGAftl61rqoc0YzqPncsLvQQh/iC2Bdp3ejUeGC83w=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1758819489.322412}],"version":2}

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,3 @@
2025/09/24-10:48:23.768 4b24 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/09/24-10:48:23.769 4b24 Recovering log #3
2025/09/24-10:48:23.773 4b24 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log
2025/09/25-16:03:05.668 6fbc Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/09/25-16:03:05.669 6fbc Recovering log #3
2025/09/25-16:03:05.677 6fbc 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/09/24-10:43:41.339 5054 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/09/24-10:43:41.340 5054 Recovering log #3
2025/09/24-10:43:41.343 5054 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log
2025/09/25-15:44:11.254 6e20 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/09/25-15:44:11.256 6e20 Recovering log #3
2025/09/25-15:44:11.259 6e20 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/09/24-10:46:59.643 5da4 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/09/24-10:46:59.646 5da4 Recovering log #7
2025/09/24-10:46:59.647 5da4 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log
2025/09/25-16:03:01.394 423c Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/09/25-16:03:01.396 423c Recovering log #7
2025/09/25-16:03:01.397 423c 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/09/24-10:35:30.498 35a4 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/09/24-10:35:30.500 35a4 Recovering log #7
2025/09/24-10:35:30.500 35a4 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log
2025/09/25-15:43:45.734 4d14 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/09/25-15:43:45.736 4d14 Recovering log #7
2025/09/25-15:43:45.737 4d14 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"hashes":{"00AF3F07B5ABB71F6D30337E1EEF62FA280F06EF19485C0CF6B72171F92CCC0A":{"appid":"kpfehajjjbbcifeehjgfgnabifknmdad","fp":"1.00AF3F07B5ABB71F6D30337E1EEF62FA280F06EF19485C0CF6B72171F92CCC0A"},"452064dcff76e03e0e81b4bb3c48ab1c432e040094f7546c7261a90d4a1c1bbf":{"appid":"fgbafbciocncjfbbonhocjaohoknlaco","fp":""},"4B81B4DF3AD971287E1AE02C449344FCFA5D20431DE17B2BA8854CC9CDCE4089":{"appid":"ahmaebgpfccdhgidjaidaoojjcijckba","fp":"1.4B81B4DF3AD971287E1AE02C449344FCFA5D20431DE17B2BA8854CC9CDCE4089"},"89f43cb3df807293de2772d5f01ac2fc1482b38ccc8fdaee859b80642b7a0487":{"appid":"pghocgajpebopihickglahgebcmkcekh","fp":""},"95FD9D48E4FC245A3F3A99A3A16ECD1355050BA3F4AFC555F19A97C7F9B49677":{"appid":"ohckeflnhegojcjlcpbfpciadgikcohk","fp":"1.95FD9D48E4FC245A3F3A99A3A16ECD1355050BA3F4AFC555F19A97C7F9B49677"},"A81D1959892AE4180554347DF1B97834ABBA2E1A5E6B9AEBA000ECEA26EABECC":{"appid":"fppmbhmldokgmleojlplaaodlkibgikh","fp":"1.A81D1959892AE4180554347DF1B97834ABBA2E1A5E6B9AEBA000ECEA26EABECC"},"A99D66CFCE8CA170740CE0403956F4DFAF4683829A89F4B7AD9C95303871E284":{"appid":"eeobbhfgfagbclfofmgbdfoicabjdbkn","fp":"1.A99D66CFCE8CA170740CE0403956F4DFAF4683829A89F4B7AD9C95303871E284"},"b987bdc4f2ad2a409b964921d4a5db1cdbe07f9c98f868293b4cc32acdc42cec":{"appid":"alpjnmnfbgfkmmpcfpejmmoebdndedno","fp":""},"bcb93cba8636743d1fbd32be3bd8ce8ff602323895bf4d136c26b9bc64b0a6a4":{"appid":"ndikpojcjlepofdkaaldkinkjbeeebkl","fp":""},"fa29a6d5775ff340900a65b39b02fc8b4b77d403c048d8debf22f2f5d09c61a0":{"appid":"oankkpibpaokgecfckkdkgaoafllipag","fp":""},"ff87fddb54d7bdc8ab8c2697bc92337c914803fb22cd32e445389e8042159ce9":{"appid":"jbfaflocpnkhbgcijpkiafdpbjkedane","fp":""}}}
{"hashes":{"000ac7dc9366969db9d1e41810a3a27c747a7623535d856eecc2de86cfed80c7":{"appid":"eeobbhfgfagbclfofmgbdfoicabjdbkn","fp":""},"00AF3F07B5ABB71F6D30337E1EEF62FA280F06EF19485C0CF6B72171F92CCC0A":{"appid":"kpfehajjjbbcifeehjgfgnabifknmdad","fp":"1.00AF3F07B5ABB71F6D30337E1EEF62FA280F06EF19485C0CF6B72171F92CCC0A"},"452064dcff76e03e0e81b4bb3c48ab1c432e040094f7546c7261a90d4a1c1bbf":{"appid":"fgbafbciocncjfbbonhocjaohoknlaco","fp":""},"4B81B4DF3AD971287E1AE02C449344FCFA5D20431DE17B2BA8854CC9CDCE4089":{"appid":"ahmaebgpfccdhgidjaidaoojjcijckba","fp":"1.4B81B4DF3AD971287E1AE02C449344FCFA5D20431DE17B2BA8854CC9CDCE4089"},"89f43cb3df807293de2772d5f01ac2fc1482b38ccc8fdaee859b80642b7a0487":{"appid":"pghocgajpebopihickglahgebcmkcekh","fp":""},"95FD9D48E4FC245A3F3A99A3A16ECD1355050BA3F4AFC555F19A97C7F9B49677":{"appid":"ohckeflnhegojcjlcpbfpciadgikcohk","fp":"1.95FD9D48E4FC245A3F3A99A3A16ECD1355050BA3F4AFC555F19A97C7F9B49677"},"A81D1959892AE4180554347DF1B97834ABBA2E1A5E6B9AEBA000ECEA26EABECC":{"appid":"fppmbhmldokgmleojlplaaodlkibgikh","fp":"1.A81D1959892AE4180554347DF1B97834ABBA2E1A5E6B9AEBA000ECEA26EABECC"},"b987bdc4f2ad2a409b964921d4a5db1cdbe07f9c98f868293b4cc32acdc42cec":{"appid":"alpjnmnfbgfkmmpcfpejmmoebdndedno","fp":""},"bcb93cba8636743d1fbd32be3bd8ce8ff602323895bf4d136c26b9bc64b0a6a4":{"appid":"ndikpojcjlepofdkaaldkinkjbeeebkl","fp":""},"fa29a6d5775ff340900a65b39b02fc8b4b77d403c048d8debf22f2f5d09c61a0":{"appid":"oankkpibpaokgecfckkdkgaoafllipag","fp":""},"ff87fddb54d7bdc8ab8c2697bc92337c914803fb22cd32e445389e8042159ce9":{"appid":"jbfaflocpnkhbgcijpkiafdpbjkedane","fp":""}}}

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

@ -1 +1 @@
{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"Id":"1","Name":"CidadeJardimCerto","Length":18.438211678884382,"Dist1":18.438211678884382,"Dist2":0.0},"geometry":{"id":null,"type":"LineString","coordinates":[[-47.3952092235,-22.172566764333332],[-47.395214685166664,-22.172591648666668],[-47.395217691333336,-22.1726149115],[-47.39522120783333,-22.172638106166666],[-47.395224592333335,-22.172662264666666],[-47.395227536833332,-22.172683503833333],[-47.395231278833336,-22.172709659],[-47.3952341445,-22.1727307235]]}},{"type":"Feature","properties":{"Id":"2","Name":"CidadeJardimCerto","Length":18.304756653641313,"Dist1":18.438211678884382,"Dist2":0.0},"geometry":{"id":null,"type":"LineString","coordinates":[[-47.395219567666665,-22.172731676],[-47.3952166705,-22.172709694166667],[-47.395212956833333,-22.1726860135],[-47.395209649833333,-22.172662382166667],[-47.3952061285,-22.172638539666668],[-47.395203071333334,-22.172615091],[-47.395199642,-22.172589946333332],[-47.39519637716667,-22.172568656333333]]}},{"type":"Feature","properties":{"Id":"3","Name":"CidadeJardimCerto","Length":18.204085527823089,"Dist1":18.438211678884382,"Dist2":0.0},"geometry":{"id":null,"type":"LineString","coordinates":[[-47.395182856666665,-22.172571987333335],[-47.395186353666666,-22.172596904666666],[-47.3951894365,-22.1726195275],[-47.395192361833331,-22.172642871333334],[-47.3951957415,-22.1726662635],[-47.3951991415,-22.1726895815],[-47.395202583833331,-22.172713842],[-47.395205228833333,-22.172734196333334]]}},{"type":"Feature","properties":{"Id":"4","Name":"CidadeJardimCerto","Length":18.206275148810604,"Dist1":18.438211678884382,"Dist2":0.0},"geometry":{"id":null,"type":"LineString","coordinates":[[-47.3951911205,-22.172735722833334],[-47.395187572,-22.172712241833334],[-47.3951841675,-22.1726893895],[-47.395179907166664,-22.1726651245],[-47.3951765075,-22.172642284833334],[-47.395173248666666,-22.1726180985],[-47.395169798666664,-22.172594096166666],[-47.395167092166666,-22.172573705666668]]}},{"type":"Feature","properties":{"Id":"5","Name":"CidadeJardimCerto","Length":18.067139082589541,"Dist1":18.438211678884382,"Dist2":0.0},"geometry":{"id":null,"type":"LineString","coordinates":[[-47.395153470333334,-22.172576570833332],[-47.395156353166669,-22.172600550333332],[-47.395159992333333,-22.172624829333333],[-47.395162920833336,-22.172647923333333],[-47.39516644,-22.172671954333332],[-47.395169917833336,-22.1726952245],[-47.3951736845,-22.172721525666667],[-47.395175992333336,-22.172737516833333]]}}]}
{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"Id":"1","Name":"CidadeJardimCerto","Length":18.438211678884382,"Dist1":18.438211678884382,"Dist2":0.0},"geometry":{"id":"0","type":"LineString","coordinates":[[-47.3952092235,-22.172566764333332],[-47.395214685166664,-22.172591648666668],[-47.395217691333336,-22.1726149115],[-47.39522120783333,-22.172638106166666],[-47.395224592333335,-22.172662264666666],[-47.395227536833332,-22.172683503833333],[-47.395231278833336,-22.172709659],[-47.3952341445,-22.1727307235]]}},{"type":"Feature","properties":{"Id":"2","Name":"CidadeJardimCerto","Length":18.304756653641313,"Dist1":18.438211678884382,"Dist2":0.0},"geometry":{"id":"1","type":"LineString","coordinates":[[-47.395219567666665,-22.172731676],[-47.3952166705,-22.172709694166667],[-47.395212956833333,-22.1726860135],[-47.395209649833333,-22.172662382166667],[-47.3952061285,-22.172638539666668],[-47.395203071333334,-22.172615091],[-47.395199642,-22.172589946333332],[-47.39519637716667,-22.172568656333333]]}},{"type":"Feature","properties":{"Id":"3","Name":"CidadeJardimCerto","Length":18.204085527823089,"Dist1":18.438211678884382,"Dist2":0.0},"geometry":{"id":"2","type":"LineString","coordinates":[[-47.395182856666665,-22.172571987333335],[-47.395186353666666,-22.172596904666666],[-47.3951894365,-22.1726195275],[-47.395192361833331,-22.172642871333334],[-47.3951957415,-22.1726662635],[-47.3951991415,-22.1726895815],[-47.395202583833331,-22.172713842],[-47.395205228833333,-22.172734196333334]]}},{"type":"Feature","properties":{"Id":"4","Name":"CidadeJardimCerto","Length":18.206275148810604,"Dist1":18.438211678884382,"Dist2":0.0},"geometry":{"id":"3","type":"LineString","coordinates":[[-47.3951911205,-22.172735722833334],[-47.395187572,-22.172712241833334],[-47.3951841675,-22.1726893895],[-47.395179907166664,-22.1726651245],[-47.3951765075,-22.172642284833334],[-47.395173248666666,-22.1726180985],[-47.395169798666664,-22.172594096166666],[-47.395167092166666,-22.172573705666668]]}},{"type":"Feature","properties":{"Id":"5","Name":"CidadeJardimCerto","Length":18.067139082589541,"Dist1":18.438211678884382,"Dist2":0.0},"geometry":{"id":"4","type":"LineString","coordinates":[[-47.395153470333334,-22.172576570833332],[-47.395156353166669,-22.172600550333332],[-47.395159992333333,-22.172624829333333],[-47.395162920833336,-22.172647923333333],[-47.39516644,-22.172671954333332],[-47.395169917833336,-22.1726952245],[-47.3951736845,-22.172721525666667],[-47.395175992333336,-22.172737516833333]]}}]}

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_8ba568814c3b3735ef0f7d202c8c9f5e {
#map_f63c9a42b387b7620b9c3dbf34b83eee {
position: relative;
width: 100.0%;
height: 100.0%;
@ -54,14 +54,14 @@
<body>
<div class="folium-map" id="map_8ba568814c3b3735ef0f7d202c8c9f5e" ></div>
<div class="folium-map" id="map_f63c9a42b387b7620b9c3dbf34b83eee" ></div>
</body>
<script>
var map_8ba568814c3b3735ef0f7d202c8c9f5e = L.map(
"map_8ba568814c3b3735ef0f7d202c8c9f5e",
var map_f63c9a42b387b7620b9c3dbf34b83eee = L.map(
"map_f63c9a42b387b7620b9c3dbf34b83eee",
{
center: [0.0, 0.0],
crs: L.CRS.EPSG3857,
@ -77,26 +77,6 @@
var tile_layer_ae18c2d43f153eef1ccf5ccb4165855e = L.tileLayer(
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
{
"minZoom": 0,
"maxZoom": 19,
"maxNativeZoom": 19,
"noWrap": false,
"attribution": "\u0026copy; \u003ca href=\"https://www.openstreetmap.org/copyright\"\u003eOpenStreetMap\u003c/a\u003e contributors",
"subdomains": "abc",
"detectRetina": false,
"tms": false,
"opacity": 1,
}
);
tile_layer_ae18c2d43f153eef1ccf5ccb4165855e.addTo(map_8ba568814c3b3735ef0f7d202c8c9f5e);
</script>
<script>
@ -116,7 +96,7 @@
}
trajeto_json_add({"features": []});
trajeto_json.addTo(map_8ba568814c3b3735ef0f7d202c8c9f5e);
trajeto_json.addTo(map_f63c9a42b387b7620b9c3dbf34b83eee);
function adicionarGeometria(novaGeometria) {
trajeto_json.addData(novaGeometria);
@ -179,9 +159,9 @@
var marcadorEquipamento = L.marker([0, 0], {
icon: customIcon
}).addTo(map_8ba568814c3b3735ef0f7d202c8c9f5e);
}).addTo(map_f63c9a42b387b7620b9c3dbf34b83eee);
var marcadorBase = L.marker([0, 0], {}).addTo(map_8ba568814c3b3735ef0f7d202c8c9f5e);
var marcadorBase = L.marker([0, 0], {}).addTo(map_f63c9a42b387b7620b9c3dbf34b83eee);
var icon = L.AwesomeMarkers.icon(
{"extraClasses": "fa-rotate-0", "icon": "info-sign", "iconColor": "white", "markerColor": "red", "prefix": "glyphicon"}
);
@ -246,7 +226,7 @@
}
if (foco) {
map_8ba568814c3b3735ef0f7d202c8c9f5e.setView(novaPosicao, map_8ba568814c3b3735ef0f7d202c8c9f5e.getZoom());
map_f63c9a42b387b7620b9c3dbf34b83eee.setView(novaPosicao, map_f63c9a42b387b7620b9c3dbf34b83eee.getZoom());
}
}
@ -268,7 +248,7 @@
marcadorDinamico.setRotationAngle(angulo);
adicionarCoordenada("Tj", [novaLongitude, novaLatitude]);
map_8ba568814c3b3735ef0f7d202c8c9f5e.setView(novaPosicao, map_8ba568814c3b3735ef0f7d202c8c9f5e.getZoom());*/
map_f63c9a42b387b7620b9c3dbf34b83eee.setView(novaPosicao, map_f63c9a42b387b7620b9c3dbf34b83eee.getZoom());*/
});
function calcularOrientacao(P1latitude, P1longitude, P2latitude, P2longitude) {

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_e9b1b3ee64db174d6f4543ce38e0b5e1 {
#map_c4ba79c1d98f5ccc1d268b643fbb7abb {
position: relative;
width: 100.0%;
height: 100.0%;
@ -54,14 +54,14 @@
<body>
<div class="folium-map" id="map_e9b1b3ee64db174d6f4543ce38e0b5e1" ></div>
<div class="folium-map" id="map_c4ba79c1d98f5ccc1d268b643fbb7abb" ></div>
</body>
<script>
var map_e9b1b3ee64db174d6f4543ce38e0b5e1 = L.map(
"map_e9b1b3ee64db174d6f4543ce38e0b5e1",
var map_c4ba79c1d98f5ccc1d268b643fbb7abb = L.map(
"map_c4ba79c1d98f5ccc1d268b643fbb7abb",
{
center: [-22.17265214058333, -47.39519380741667],
crs: L.CRS.EPSG3857,
@ -78,7 +78,7 @@
var tile_layer_507a582c5bc0aa807282907c2bc3275c = L.tileLayer(
var tile_layer_4debaf03661fab35c7f05f9165d16413 = L.tileLayer(
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
{
"minZoom": 0,
@ -95,7 +95,7 @@
);
tile_layer_507a582c5bc0aa807282907c2bc3275c.addTo(map_e9b1b3ee64db174d6f4543ce38e0b5e1);
tile_layer_4debaf03661fab35c7f05f9165d16413.addTo(map_c4ba79c1d98f5ccc1d268b643fbb7abb);
@ -111,7 +111,7 @@
}*/
});
}
function geo_json_b7203db4da92fe2236826b29ddbfaf68_onEachFeature(feature, layer) {
function geo_json_9f5502753d57522086d0216c6c3a7f99_onEachFeature(feature, layer) {
layer.on({
@ -148,23 +148,23 @@
}*/
});
};
var geo_json_b7203db4da92fe2236826b29ddbfaf68 = L.geoJson(null, {
onEachFeature: geo_json_b7203db4da92fe2236826b29ddbfaf68_onEachFeature,
var geo_json_9f5502753d57522086d0216c6c3a7f99 = L.geoJson(null, {
onEachFeature: geo_json_9f5502753d57522086d0216c6c3a7f99_onEachFeature,
...{
}
});
function geo_json_b7203db4da92fe2236826b29ddbfaf68_add (data) {
geo_json_b7203db4da92fe2236826b29ddbfaf68
function geo_json_9f5502753d57522086d0216c6c3a7f99_add (data) {
geo_json_9f5502753d57522086d0216c6c3a7f99
.addData(data);
}
geo_json_b7203db4da92fe2236826b29ddbfaf68_add({"features": [{"geometry": {"coordinates": [[-47.3952092235, -22.172566764333332], [-47.395214685166664, -22.172591648666668], [-47.395217691333336, -22.1726149115], [-47.39522120783333, -22.172638106166666], [-47.395224592333335, -22.172662264666666], [-47.39522753683333, -22.172683503833333], [-47.395231278833336, -22.172709659], [-47.3952341445, -22.1727307235]], "id": null, "type": "LineString"}, "id": 0, "properties": {"Dist1": 18.438211678884382, "Dist2": 0.0, "Id": "1", "Length": 18.438211678884382, "Name": "CidadeJardimCerto"}, "type": "Feature"}, {"geometry": {"coordinates": [[-47.395219567666665, -22.172731676], [-47.3952166705, -22.172709694166667], [-47.39521295683333, -22.1726860135], [-47.39520964983333, -22.172662382166667], [-47.3952061285, -22.172638539666668], [-47.395203071333334, -22.172615091], [-47.395199642, -22.172589946333332], [-47.39519637716667, -22.172568656333333]], "id": null, "type": "LineString"}, "id": 1, "properties": {"Dist1": 18.438211678884382, "Dist2": 0.0, "Id": "2", "Length": 18.304756653641313, "Name": "CidadeJardimCerto"}, "type": "Feature"}, {"geometry": {"coordinates": [[-47.395182856666665, -22.172571987333335], [-47.395186353666666, -22.172596904666666], [-47.3951894365, -22.1726195275], [-47.39519236183333, -22.172642871333334], [-47.3951957415, -22.1726662635], [-47.3951991415, -22.1726895815], [-47.39520258383333, -22.172713842], [-47.39520522883333, -22.172734196333334]], "id": null, "type": "LineString"}, "id": 2, "properties": {"Dist1": 18.438211678884382, "Dist2": 0.0, "Id": "3", "Length": 18.20408552782309, "Name": "CidadeJardimCerto"}, "type": "Feature"}, {"geometry": {"coordinates": [[-47.3951911205, -22.172735722833334], [-47.395187572, -22.172712241833334], [-47.3951841675, -22.1726893895], [-47.395179907166664, -22.1726651245], [-47.3951765075, -22.172642284833334], [-47.395173248666666, -22.1726180985], [-47.395169798666664, -22.172594096166666], [-47.395167092166666, -22.172573705666668]], "id": null, "type": "LineString"}, "id": 3, "properties": {"Dist1": 18.438211678884382, "Dist2": 0.0, "Id": "4", "Length": 18.206275148810604, "Name": "CidadeJardimCerto"}, "type": "Feature"}, {"geometry": {"coordinates": [[-47.395153470333334, -22.172576570833332], [-47.39515635316667, -22.172600550333332], [-47.39515999233333, -22.172624829333333], [-47.395162920833336, -22.172647923333333], [-47.39516644, -22.17267195433333], [-47.395169917833336, -22.1726952245], [-47.3951736845, -22.172721525666667], [-47.395175992333336, -22.172737516833333]], "id": null, "type": "LineString"}, "id": 4, "properties": {"Dist1": 18.438211678884382, "Dist2": 0.0, "Id": "5", "Length": 18.06713908258954, "Name": "CidadeJardimCerto"}, "type": "Feature"}], "type": "FeatureCollection"});
geo_json_b7203db4da92fe2236826b29ddbfaf68.setStyle(function(feature) {return feature.properties.style;});
geo_json_9f5502753d57522086d0216c6c3a7f99_add({"features": [{"geometry": {"coordinates": [[-47.3952092235, -22.172566764333332], [-47.395214685166664, -22.172591648666668], [-47.395217691333336, -22.1726149115], [-47.39522120783333, -22.172638106166666], [-47.395224592333335, -22.172662264666666], [-47.39522753683333, -22.172683503833333], [-47.395231278833336, -22.172709659], [-47.3952341445, -22.1727307235]], "id": "0", "type": "LineString"}, "id": 0, "properties": {"Dist1": 18.438211678884382, "Dist2": 0.0, "Id": "1", "Length": 18.438211678884382, "Name": "CidadeJardimCerto"}, "type": "Feature"}, {"geometry": {"coordinates": [[-47.395219567666665, -22.172731676], [-47.3952166705, -22.172709694166667], [-47.39521295683333, -22.1726860135], [-47.39520964983333, -22.172662382166667], [-47.3952061285, -22.172638539666668], [-47.395203071333334, -22.172615091], [-47.395199642, -22.172589946333332], [-47.39519637716667, -22.172568656333333]], "id": "1", "type": "LineString"}, "id": 1, "properties": {"Dist1": 18.438211678884382, "Dist2": 0.0, "Id": "2", "Length": 18.304756653641313, "Name": "CidadeJardimCerto"}, "type": "Feature"}, {"geometry": {"coordinates": [[-47.395182856666665, -22.172571987333335], [-47.395186353666666, -22.172596904666666], [-47.3951894365, -22.1726195275], [-47.39519236183333, -22.172642871333334], [-47.3951957415, -22.1726662635], [-47.3951991415, -22.1726895815], [-47.39520258383333, -22.172713842], [-47.39520522883333, -22.172734196333334]], "id": "2", "type": "LineString"}, "id": 2, "properties": {"Dist1": 18.438211678884382, "Dist2": 0.0, "Id": "3", "Length": 18.20408552782309, "Name": "CidadeJardimCerto"}, "type": "Feature"}, {"geometry": {"coordinates": [[-47.3951911205, -22.172735722833334], [-47.395187572, -22.172712241833334], [-47.3951841675, -22.1726893895], [-47.395179907166664, -22.1726651245], [-47.3951765075, -22.172642284833334], [-47.395173248666666, -22.1726180985], [-47.395169798666664, -22.172594096166666], [-47.395167092166666, -22.172573705666668]], "id": "3", "type": "LineString"}, "id": 3, "properties": {"Dist1": 18.438211678884382, "Dist2": 0.0, "Id": "4", "Length": 18.206275148810604, "Name": "CidadeJardimCerto"}, "type": "Feature"}, {"geometry": {"coordinates": [[-47.395153470333334, -22.172576570833332], [-47.39515635316667, -22.172600550333332], [-47.39515999233333, -22.172624829333333], [-47.395162920833336, -22.172647923333333], [-47.39516644, -22.17267195433333], [-47.395169917833336, -22.1726952245], [-47.3951736845, -22.172721525666667], [-47.395175992333336, -22.172737516833333]], "id": "4", "type": "LineString"}, "id": 4, "properties": {"Dist1": 18.438211678884382, "Dist2": 0.0, "Id": "5", "Length": 18.06713908258954, "Name": "CidadeJardimCerto"}, "type": "Feature"}], "type": "FeatureCollection"});
geo_json_9f5502753d57522086d0216c6c3a7f99.setStyle(function(feature) {return feature.properties.style;});
geo_json_b7203db4da92fe2236826b29ddbfaf68.addTo(map_e9b1b3ee64db174d6f4543ce38e0b5e1);
geo_json_9f5502753d57522086d0216c6c3a7f99.addTo(map_c4ba79c1d98f5ccc1d268b643fbb7abb);
</script>
@ -185,7 +185,7 @@
}
trajeto_json_add({"features": []});
trajeto_json.addTo(map_e9b1b3ee64db174d6f4543ce38e0b5e1);
trajeto_json.addTo(map_c4ba79c1d98f5ccc1d268b643fbb7abb);
function adicionarGeometria(novaGeometria) {
trajeto_json.addData(novaGeometria);
@ -243,7 +243,7 @@
}
trajeto_dinamico_json_add({"features": []});
trajeto_dinamico_json.addTo(map_e9b1b3ee64db174d6f4543ce38e0b5e1);
trajeto_dinamico_json.addTo(map_c4ba79c1d98f5ccc1d268b643fbb7abb);
function adicionarGeometriaDinamica(novaGeometria) {
trajeto_dinamico_json.addData(novaGeometria);
@ -296,9 +296,9 @@
var marcadorEquipamento = L.marker([0, 0], {
icon: customIcon
}).addTo(map_e9b1b3ee64db174d6f4543ce38e0b5e1);
}).addTo(map_c4ba79c1d98f5ccc1d268b643fbb7abb);
var marcadorBase = L.marker([0, 0], {}).addTo(map_e9b1b3ee64db174d6f4543ce38e0b5e1);
var marcadorBase = L.marker([0, 0], {}).addTo(map_c4ba79c1d98f5ccc1d268b643fbb7abb);
var icon = L.AwesomeMarkers.icon(
{"extraClasses": "fa-rotate-0", "icon": "info-sign", "iconColor": "white", "markerColor": "red", "prefix": "glyphicon"}
);
@ -380,7 +380,7 @@
}
if (foco) {
map_e9b1b3ee64db174d6f4543ce38e0b5e1.setView(novaPosicao, map_e9b1b3ee64db174d6f4543ce38e0b5e1.getZoom());
map_c4ba79c1d98f5ccc1d268b643fbb7abb.setView(novaPosicao, map_c4ba79c1d98f5ccc1d268b643fbb7abb.getZoom());
}
}
@ -397,7 +397,7 @@
function atualizarSelecaoRuas(selecionadas) {
selecionadas = JSON.parse(selecionadas);
RuasSelecionadas = Array.isArray(selecionadas) ? [...selecionadas] : [];
geo_json_b7203db4da92fe2236826b29ddbfaf68.eachLayer(function (layer) {
geo_json_9f5502753d57522086d0216c6c3a7f99.eachLayer(function (layer) {
if (RuasSelecionadas.includes(parseInt(layer.feature.id))) {
layer.setStyle({ color: 'blue' });
} else {

View File

@ -416,12 +416,12 @@ class ControladorMPC:
manobrando = CARRO.get("ManobrandoEntreRuas", False)
velocidade = CARRO.get("Velocidade", self.velocidade_min)
peso_erro_pos = 1.2 # 0
peso_erro_ori = 1.0 # 1
peso_suavidade = 1.5 # 2
peso_fator_re = 0.2 # 3
peso_ideal = 0.4 # 4
peso_lateral = 1.8 if dentro else 0.0 # 5
peso_erro_pos = 1.2 # 0
peso_erro_ori = 4.5 # 1
peso_suavidade = 0.2 # 2
peso_fator_re = 0.05 # 3
peso_ideal = 0.4 # 4
peso_lateral = 3.8 if dentro else 0.0 # 5
# Penalidade proporcional à velocidade
penalidade_por_velocidade = (velocidade / self.velocidade_max) / 10.0
@ -1067,6 +1067,7 @@ class ControladorMPC:
angulo_anterior = np.radians(comando_anterior.get("angulo", 0.0))
tipo_anterior = TipoMovimentoDirecional(comando_anterior.get("tipo", TipoMovimentoDirecional.RodasDianteiras.value))
simulacao_latlon = []
debug_custo = {}
ultimo_ponto = idx_proximo_ponto_real >= len(self.pontos_info)
if ultimo_ponto:
@ -1085,6 +1086,7 @@ class ControladorMPC:
#mostrar_log(f"idx_proximo_ponto_C#: {idx_proximo_ponto_real}, idx_ponto_alvo_C#: {idx_ponto_alvo}, idx_proximo_ponto_Python: {idx_alvo_correcao}")
# Loop de K comandos (receding); cada comando simula dt_pred com v_sim
#print("COMENCANDO")
for passo in range(self.qtd_comandos_sucessivos):
if ms_left() <= 0:
break
@ -1164,15 +1166,18 @@ class ControladorMPC:
t_c_ini = now()
try:
# >>> CHANGED: passa dt_pred e v_sim para a simulação de um PASSO
custo, sim, valido, visitados_sim = self._simular_passo(
custo, sim, valido, visitados_sim, _debug_custo = self._simular_passo(
x_atual, y_atual, theta_atual,
tipo_k, ang_k,
custos_candidatos,
cmd_anterior_local, contexto,
visitados,
dt_pred=dt_pred, # <-- NOVO
v_planejado=v_sim # <-- NOVO
v_planejado=v_sim, # <-- NOVO
passo=passo
)
if passo == 0:
debug_custo[f"{tipo_k.value}_{np.degrees(ang_k):.2f}"] = _debug_custo
if valido:
x_f, y_f, theta_f = sim[-1]
novo = {
@ -1239,7 +1244,8 @@ class ControladorMPC:
"angulo": float(round(np.degrees(angulo_final), 2)),
"tipo": tipo_final.value,
"simulacao": simulacao_latlon,
"erro_lateral": erro_lateral
"erro_lateral": erro_lateral,
"debug_custo": debug_custo
}
# -------------------- Debug opcional da matriz de custo --------------------
@ -1553,6 +1559,9 @@ class ControladorMPC:
if deadline is None:
return 1e9
return (deadline - now()) * 1000.0
def ang_err(a, b):
return abs(self._wrap_pi(a - b)) # menor distância angular em rad
# estimadores adaptativos
if not hasattr(self, "_t_est_candidato_ms"):
@ -1576,7 +1585,7 @@ class ControladorMPC:
# fallback sem matriz ou sem tempo
if (not filtrar_matriz) or (custo_grid is None) or (np.size(custo_grid) == 0) or (ms_left() <= 0.0):
custos_candidatos = {}
erro = np.abs(angulos_rad - float(angulo_ideal_rad))
erro = ang_err(angulos_rad, float(angulo_ideal_rad)) / np.pi
custo_ideal = peso_angulo_ideal * erro
for tipo in tipos:
for g2, c in zip(graus_2c, custo_ideal):
@ -2053,13 +2062,7 @@ class ControladorMPC:
mostrar_log(f"❌ Erro ao filtrar por margem angular: {e}")
return candidatos
def _simular_passo(
self, x, y, theta,
tipo, angulo_testado,
custos_candidatos, comando_anterior,
contexto, visitados,
dt_pred, v_planejado
):
def _simular_passo_old(self, x, y, theta, tipo, angulo_testado, custos_candidatos, comando_anterior, contexto, visitados, dt_pred, v_planejado):
"""
Simula UM 'passo' do receding (um comando) cobrindo dt_pred de tempo,
subdividido em passos menores (sub_dt) para estabilidade geométrica.
@ -2156,6 +2159,228 @@ class ControladorMPC:
mostrar_log(f"Erro ao simular passo para {tipo.name} | angulo: {np.degrees(angulo_testado):.2f}: {e}")
return float('inf'), [(0.0, 0.0, 0.0)], False, visitados
def _simular_passo(self, x, y, theta, tipo, angulo_testado, custos_candidatos, comando_anterior, contexto, visitados, dt_pred, v_planejado, passo=-1):
"""
Simula UM 'passo' do receding cobrindo dt_pred, subdividido em subpassos.
O custo é acumulado 'por metro' (multiplicando por v_planejado * sub_dt).
"""
try:
arr_custos = []
custo_total = 0.0
x_sim, y_sim, theta_sim = x, y, theta
self.x_ant, self.y_ant = 0.0, 0.0
# chave para custo heurístico vindo do VisualWorker (por ângulo/tipo)
chave = (tipo.value, round(float(np.degrees(angulo_testado)), 2))
custo_visual_worker = float(custos_candidatos.get(chave, 0.0))
simulacoes = []
prev_ang = float(comando_anterior.get("angulo", 0.0))
prev_tipo = comando_anterior.get("tipo", TipoMovimentoDirecional.RodasDianteiras.value)
pontos_visitados = visitados.copy()
# Contexto usado no custo (mantido)
angulo_caminho = np.radians(contexto.get("Carro", {}).get("AnguloCaminho", 0.0))
status_carro = StatusCarroMapa(contexto.get("Carro", {}).get("Status", StatusCarroMapa.Parado.value))
dentro_corredor = bool(contexto.get("Carro", {}).get("DentroCorredor", False))
# omega e sub-stepping
omega_const = self.gps_handler.calcular_omega(v_planejado, angulo_testado, tipo)
passos_local = max(1, int(getattr(self, "passos_horizonte_local", 1)))
dt_total = float(dt_pred) * passos_local
SUB_MAX = float(getattr(self, "_dt_sub_max", 0.15)) # ~150 ms por subpasso (ajuste teu comentário)
n_subs = max(1, int(math.ceil(dt_total / SUB_MAX)))
sub_dt = dt_total / n_subs
dist_sub = v_planejado * sub_dt # custo por metro
# --- PATCH: estado local p/ amortecimento e anti-chatter
e_lat_prev_local = None
side_mem_local = 0 # -1 direita, +1 esquerda, 0 centro
for n_sub in range(n_subs):
# IMPORTANTE: _nova_posicao precisa aceitar dt opcional
x_sim, y_sim, theta_sim = self._nova_posicao(
x_sim, y_sim, theta_sim,
omega_const, v_planejado, # (omega, v, tipo, angulo)
tipo, angulo_testado,
dt=sub_dt
)
simulacoes.append((x_sim, y_sim, theta_sim))
# alvo mais próximo após avançar (mantido)
idx_alvo_sim = self._corrigir_pontos_visitados(
x_sim, y_sim, pontos_visitados,
velocidade=v_planejado, dt=sub_dt
)
ponto_alvo_sim = self.pontos_info[idx_alvo_sim]["xy"]
# --------------------------
# ERROS / CUSTOS
# --------------------------
# posição (mantido)
D_sat = 10.0 # metros (ajuste)
erro_pos = float(np.hypot(x_sim - ponto_alvo_sim[0], y_sim - ponto_alvo_sim[1]))
d_norm = np.clip(erro_pos / D_sat, 0.0, 1.0)
# --- PATCH A: usa theta do CAMINHO (segmento projetado) como referência
# e usa também margem local pra normalização do custo lateral
e_lat, _, _, _, theta_path, margem = self.cross_track_error_point(x_sim, y_sim)
# erro de orientação: referência = theta_path (não o bearing ao alvo)
# (manter 'peso_erro_orientacao_caminho' se você usa em pesos dinâmicos)
peso_erro_orientacao_pp = 1.0 # 0.6 if (status_carro == StatusCarroMapa.CaminhandoRua and dentro_corredor) else 0.4
orient_sim = self.gps_handler.calcular_orientacao((x_sim, y_sim), ponto_alvo_sim)
orient_sim = (orient_sim + np.pi) % (2 * np.pi)
# erros
#erro_ori_sim = self.gps_handler.erro_angular(orient_sim, theta_sim, theta_path, peso_erro_orientacao_pp)
erro_ori_sim = abs(self._wrap_pi(orient_sim - theta_sim))
o_norm = np.clip(abs(erro_ori_sim) / np.pi, 0.0, 1.0)
#erro_ori_sim = self._wrap_pi(theta_path - theta_sim)
# pesos dinâmicos (mantido)
pesos = self._calcular_pesos_movimento(contexto, erro_ori_sim)
(peso_erro_pos, peso_erro_ori, peso_suavidade, peso_fator_re, peso_ideal, peso_lateral, peso_movimento) = pesos
# ângulo relativo ao alvo e suavidade (parcialmente mantido)
vetor_alvo = np.array(ponto_alvo_sim) - np.array([x_sim, y_sim])
vetor_alvo_norm = vetor_alvo / (np.linalg.norm(vetor_alvo) + 1e-9)
vetor_movel = np.array([np.cos(theta_sim), np.sin(theta_sim)])
cos_delta = float(np.dot(vetor_movel, vetor_alvo_norm))
delta_angulo = abs(angulo_testado - prev_ang)
# --------------------------
# COMPONENTES DE CUSTO
# --------------------------
# posição (mantido)
#custo_pos = erro_pos * peso_erro_pos
custo_pos = d_norm * peso_erro_pos
# --- PATCH B: custo de orientação desacoplado de erro_pos e quadrático
#custo_ori = erro_ori_sim * peso_erro_ori
custo_ori = o_norm * peso_erro_ori
# --- PATCH C: suavidade SEM depender de erro_pos + piso
base_suav = 0.25 # piso de penalização (0.250.5)
erro_suavidade = ((base_suav + 1.0) * (abs(delta_angulo) / np.pi) * erro_pos)
custo_suavidade = erro_suavidade * peso_suavidade
# tipo de movimento (mantido)
custo_tipo_movimento = float(peso_movimento[tipo])
# fator "re" (mantido como estava)
erro_re = -cos_delta # já está em [-1, +1]
custo_re = erro_re * peso_fator_re # aplica peso normalmente
# --- PATCH D: custo lateral com deadband + quadrático + normalização
dead = 0.0 # 512 cm
half = max(float(margem), 0.20) # meia-largura mínima
e_eff = max(0.0, abs(e_lat) - dead)
l_norm = np.clip(e_eff / half, 0.0, 1.0) ** 2
#custo_lateral = (((e_eff / half) ** 2) * erro_pos) * peso_lateral
custo_lateral = l_norm * peso_lateral
# --- PATCH E: amortecimento por derivada do erro lateral (m/s)
if e_lat_prev_local is not None:
de = (e_lat - e_lat_prev_local) / max(sub_dt, 1e-6) # m/s
peso_lat_der = 0.1 * float(peso_lateral) # ganho pequeno
custo_lat_der = (de ** 2) * peso_lat_der
else:
custo_lat_der = 0.0
e_lat_prev_local = e_lat
# --- PATCH F: anti-chatter (histerese) perto do centro
band = 0.10 # 812 cm
side_now = 0 if abs(e_lat) < band else (1 if e_lat > 0 else -1)
flip_pen = 0.0
if abs(e_lat) < band and side_mem_local != 0 and side_now != side_mem_local:
flip_pen = 0.12 * float(peso_suavidade) # 0.080.20
side_mem_local = side_now
# soma local (heurística do visual + demais) e NORMALIZA por metro
custo_mapa = (
custo_pos + custo_ori + custo_suavidade +
custo_tipo_movimento + custo_re + custo_lateral +
custo_lat_der + flip_pen + custo_visual_worker
)
custo_total += custo_mapa * dist_sub # custo POR METRO
# debug opcional:
arr_custos.append((x_sim, y_sim, theta_sim, ponto_alvo_sim[0], ponto_alvo_sim[1], erro_pos, d_norm, erro_ori_sim, o_norm, erro_suavidade, erro_re, abs(e_lat), l_norm, custo_pos, custo_ori, custo_suavidade, custo_tipo_movimento, custo_re, custo_lateral, custo_lat_der, flip_pen, custo_visual_worker, custo_mapa, custo_total))
prev_ang = angulo_testado
prev_tipo = tipo
debug_custo = {}
if passo == 0:
arr_np = np.array(arr_custos) # shape = (n_subs, 23)
somas = arr_np.sum(axis=0) # soma coluna a coluna
medias = arr_np.mean(axis=0) # média coluna a coluna
finais = arr_np[-1] # último subpasso (se quiser estado final)
print(
f"ang:{np.degrees(angulo_testado):.2f} "
f"tipo:{tipo.name} omg:{omega_const:.3f} "
f"xsim:{finais[0]:.5f} ysim:{finais[1]:.5f} tsim:{finais[2]:.5f} "
f"xalv:{finais[3]:.5f} yalv:{finais[4]:.5f} "
f"epos:{somas[5]:.4f} eposn:{somas[6]:.4f} "
f"eori:{np.degrees(somas[7]):.4f} eorin:{somas[8]:.4f} "
f"esua:{somas[9]:.4f} ere:{somas[10]:.4f} "
f"elat:{somas[11]:.4f} elatn:{somas[12]:.4f} "
f"cpos:{somas[13]:.4f} cori:{somas[14]:.4f} "
f"csua:{somas[15]:.4f} ctmv:{somas[16]:.4f} "
f"cre:{somas[17]:.4f} clat:{somas[18]:.4f} "
f"clatd:{somas[19]:.4f} flpp:{somas[20]:.4f} "
f"cvw:{somas[21]:.4f} cmap:{somas[22]:.4f} "
f"ctot:{finais[23]:.4f}"
)
debug_custo = {
"angulo": np.degrees(angulo_testado),
"tipo": tipo.value,
"omega": omega_const,
"x_sim": finais[0],
"y_sim": finais[1],
"theta_sim": finais[2],
"x_alvo": finais[3],
"y_alvo": finais[4],
"peso_posicao": peso_erro_pos,
"peso_orientacao": peso_erro_ori,
"peso_suavizacao": peso_suavidade,
"peso_re": peso_fator_re,
"peso_ideal": peso_ideal,
"peso_lateral": peso_lateral,
"peso_tipo_movimento": peso_movimento,
"erro_posicao": somas[5],
"erro_posicao_n": somas[6],
"erro_orientacao": somas[7],
"erro_orientacao_n": somas[8],
"erro_suavizacao": somas[9],
"erro_re": somas[10],
"erro_lateral": somas[11],
"erro_lateral_n": somas[12],
"custo_posicao": somas[13],
"custo_orientacao": somas[14],
"custo_suavizacao": somas[15],
"custo_tipo_movimento": somas[16],
"custo_re": somas[17],
"custo_lateral": somas[18],
"custo_lateral_d": somas[19],
"custo_flip": somas[20],
"custo_visual_worker": somas[21],
"custo_map": somas[22],
"custo_total": finais[23]
}
#print(custo_visual_worker)
return float(custo_total), simulacoes, True, pontos_visitados, debug_custo
except Exception as e:
mostrar_log(f"Erro ao simular passo para {tipo.name} | angulo: {np.degrees(angulo_testado):.2f}: {e}")
return float('inf'), [(0.0, 0.0, 0.0)], False, visitados
def _nova_posicao(self, x, y, theta, omega, velocidade, tipo, angulo_rad, dt=None):
"""
Atualiza a pose integrando por 'dt' (se None, cai em self.dt).

View File

@ -40,7 +40,8 @@ class ProcessadorEmAndamento(ProcessadorBase):
simulacao=comando_dir.get("simulacao"),
erro=comando_dir.get("erro", False),
latencia=comando_dir.get("latencia", 0.0),
erro_lateral=comando_dir.get("erro_lateral", 0.0)
erro_lateral=comando_dir.get("erro_lateral", 0.0),
debug_custo=comando_dir.get("debug_custo", {})
)
except Exception as e:
print(f"Erro no processador EmAndamento: {e}")

View File

@ -3,7 +3,7 @@ from shared.enums import ModoOperacao, StatusOperacao
from manager_worker.config import mostrar_log
from shared.contexto_global_redis import ContextoGlobalRedis, CtxKey
def comando_controle(percentual_velocidade: float, frear: bool, angulo: float, tipo_movimento: int, simulacao = [], erro: bool = False, latencia: float = 0.0, erro_lateral: float = 0.0):
def comando_controle(percentual_velocidade: float, frear: bool, angulo: float, tipo_movimento: int, simulacao = [], erro: bool = False, latencia: float = 0.0, erro_lateral: float = 0.0, debug_custo: dict = {}):
hb_atual = ContextoGlobalRedis.get_controle().get("heartbeat", 0)
if erro == False:
try:
@ -21,7 +21,8 @@ def comando_controle(percentual_velocidade: float, frear: bool, angulo: float, t
simulacao=simulacao,
heartbeat=hb_atual,
latencia=latencia,
erro_lateral=erro_lateral
erro_lateral=erro_lateral,
debug_custo=debug_custo
)
return {
"velocidade_sp": percentual_velocidade,
@ -31,7 +32,8 @@ def comando_controle(percentual_velocidade: float, frear: bool, angulo: float, t
"simulacao": simulacao,
"heartbeat": hb_atual,
"latencia": latencia,
"erro_lateral": erro_lateral
"erro_lateral": erro_lateral,
"debug_custo": debug_custo
}
def comando_parado():