ajustes plot antenas

This commit is contained in:
Diego Freitas 2025-09-29 10:26:07 -03:00
parent 9b6dbf7890
commit 5ad682f7fe
36 changed files with 264 additions and 90 deletions

Binary file not shown.

View File

@ -166,7 +166,7 @@ namespace AgroBase.Models
_Ticking = false;
if (_state == TimerState.Running)
{
if (!IsDisposed) tmr.Start();
try { if (!IsDisposed) tmr.Start(); } catch { }
}
}
}

View File

@ -157,28 +157,53 @@ namespace AgroBase.Models
// Desenha a posição atual do robô (ponto vermelho)
//float PxToCm = DrawRobot(g, centerX, centerY, Color.Red, Color.Red, (float)VariaveisEquipamento.LarguraEsquerda, (float)VariaveisEquipamento.LarguraDireita, (float)VariaveisEquipamento.ComprimentoFrente, (float)VariaveisEquipamento.ComprimentoTras, AnguloCarro);
// === NOVO: pega pixels do CENTRO (corrigido) e da ANTENA (bruto) ===
// Use sua própria função de conversão se já tiver.
PointF pCtr = LatLonToPanel(_posicaoAtual.Latitude, _posicaoAtual.Longitude, centerX, centerY);
PointF pAnt = LatLonToPanel(_posicaoAtual.LatitudeAnt, _posicaoAtual.LongitudeAnt, centerX, centerY);
//PointF pCtr = LatLonToPanel(_posicaoAtual.Latitude, _posicaoAtual.Longitude, centerX, centerY);
//PointF pAnt = LatLonToPanel(_posicaoAtual.LatitudeAnt, _posicaoAtual.LongitudeAnt, centerX, centerY);
// desenha o robô centrado no ponto corrigido e marca a antena bruta
float PxToCm = DrawRobotNew(
//float PxToCm = DrawRobotNew(
// g,
// pCtr.X, pCtr.Y,
// Color.ForestGreen, // cor do contorno do corpo
// (float)VariaveisEquipamento.LarguraEsquerda,
// (float)VariaveisEquipamento.LarguraDireita,
// (float)VariaveisEquipamento.ComprimentoFrente,
// (float)VariaveisEquipamento.ComprimentoTras,
// AnguloCarro, // em rad
// pAnt.X, pAnt.Y, // antena "bruta" (opcional)
// desenharAntenaEsperada: true // mostra também a antena “prevista”
//);
// 1) centro em pixels (seu “centro de giro” no painel)
PointF pCtr = LatLonToPanel(_posicaoAtual.Latitude, _posicaoAtual.Longitude, centerX, centerY);
// 2) antenas (corrigida e bruta)
double latCorr = _posicaoAtual.Latitude; // já com lever arm aplicado
double lonCorr = _posicaoAtual.Longitude;
double latBrut = _posicaoAtual.LatitudeAnt; // GNGGA bruto
double lonBrut = _posicaoAtual.LongitudeAnt;
AntenaDiagPx diag = DrawRobotAndAntennaDiagnostics(
g,
pCtr.X, pCtr.Y,
Color.ForestGreen, // cor do contorno do corpo
(float)VariaveisEquipamento.LarguraEsquerda,
(float)VariaveisEquipamento.LarguraDireita,
(float)VariaveisEquipamento.ComprimentoFrente,
(float)VariaveisEquipamento.ComprimentoTras,
AnguloCarro, // em rad
pAnt.X, pAnt.Y, // antena "bruta" (opcional)
desenharAntenaEsperada: true // mostra também a antena “prevista”
AnguloCarro, // em rad conforme seu desenho
(lat, lon) => LatLonToPanel(lat, lon, centerX, centerY),
latCorr, lonCorr,
latBrut, lonBrut,
Color.ForestGreen
);
// Se quiser logar os offsets em px:
var offPrev_vs_Corr = new PointF(diag.Corrigida.X - diag.Prevista.X, diag.Corrigida.Y - diag.Prevista.Y);
var offPrev_vs_Brut = new PointF(diag.Bruta.X - diag.Prevista.X, diag.Bruta.Y - diag.Prevista.Y);
if (obstaculoDetectado != null)
{
DrawObstacle(g, centerX, centerY, Color.Cyan, Color.Cyan, AnguloCaminho - (float)obstaculoDetectado.AnguloParaDesvio, obstaculoDetectado, PxToCm);
//DrawObstacle(g, centerX, centerY, Color.Cyan, Color.Cyan, AnguloCaminho - (float)obstaculoDetectado.AnguloParaDesvio, obstaculoDetectado, PxToCm);
}
// Desenha a simulação do MPC (linha tracejada verde-limão)
@ -406,6 +431,111 @@ namespace AgroBase.Models
return pxToCm;
}
// Opcional: um contêiner simples para você logar os pixels depois
public struct AntenaDiagPx
{
public PointF Centro; // centro do robô (retângulo)
public PointF Prevista; // antena prevista a partir do centro (pelas medidas)
public PointF Corrigida; // antena corrigida (lever arm aplicado)
public PointF Bruta; // antena bruta (GNGGA)
}
// ===================== MÉTODO PRINCIPAL =====================
public AntenaDiagPx DrawRobotAndAntennaDiagnostics(
Graphics g,
float xCtrPx, float yCtrPx, // centro do robô em pixels (centro de giro)
float angleRad, // heading (mesmo sistema do seu desenho: 0°=N, Y para "frente" = -Y)
Func<double, double, PointF> latlonToPanel, // conversor lat/lon -> pixels
double latAntCorr, double lonAntCorr, // antena corrigida (lever arm já aplicado)
double latAntBruta, double lonAntBruta, // antena bruta (GNGGA)
Color corBordaRobo
)
{
// --- 1) Dimensões vindas do seu equipamento (em cm) ---
float L_esq_cm = (float)VariaveisEquipamento.LarguraEsquerda;
float L_dir_cm = (float)VariaveisEquipamento.LarguraDireita;
float F_cm = (float)VariaveisEquipamento.ComprimentoFrente;
float T_cm = (float)VariaveisEquipamento.ComprimentoTras;
float larguraTotalCm = L_esq_cm + L_dir_cm;
float comprimentoTotalCm = F_cm + T_cm;
// --- 2) Conversão cm -> px (mesma convenção que você já usa) ---
float zoom = (float)_zoom;
float cmToPx = zoom / 1e7f;
float larguraPx = Math.Max(1e-6f, larguraTotalCm * cmToPx);
float comprimentoPx = Math.Max(1e-6f, comprimentoTotalCm * cmToPx);
// --- 3) Desenhar o retângulo do robô centrado no (xCtrPx, yCtrPx) ---
PointF[] corners = new PointF[4];
corners[0] = CalcularPontoRotacionado(xCtrPx, yCtrPx, -larguraPx / 2f, -comprimentoPx / 2f, angleRad);
corners[1] = CalcularPontoRotacionado(xCtrPx, yCtrPx, +larguraPx / 2f, -comprimentoPx / 2f, angleRad);
corners[2] = CalcularPontoRotacionado(xCtrPx, yCtrPx, +larguraPx / 2f, +comprimentoPx / 2f, angleRad);
corners[3] = CalcularPontoRotacionado(xCtrPx, yCtrPx, -larguraPx / 2f, +comprimentoPx / 2f, angleRad);
using (var penBody = new Pen(corBordaRobo, 2f))
g.DrawPolygon(penBody, corners);
// Seta da frente (opcional)
float frenteLenPx = F_cm * cmToPx;
PointF pontaFrente = CalcularPontoRotacionado(xCtrPx, yCtrPx, 0f, -frenteLenPx, angleRad);
using (var penFront = new Pen(corBordaRobo, 2f))
g.DrawLine(penFront, xCtrPx, yCtrPx, pontaFrente.X, pontaFrente.Y);
// --- 4) Antena PREVISTA a partir do centro (onde deveria estar na carcaça) ---
// Offsets CENTRO -> ANTENA em cm:
// +dx = esquerda, -dx = direita ; +dy = trás, -dy = frente
float dxCm = (larguraTotalCm / 2f) - L_dir_cm;
float dyCm = (comprimentoTotalCm / 2f) - F_cm;
// Para a tela: "frente" é -dy (mesma convenção do seu código)
float dxPx = dxCm * cmToPx;
float dyPx = dyCm * cmToPx;
PointF antenaPrevistaPx = CalcularPontoRotacionado(xCtrPx, yCtrPx, dxPx, -dyPx, angleRad);
// --- 5) Antena CORRIGIDA (lat/lon após lever arm) ---
PointF antenaCorrigidaPx = latlonToPanel(latAntCorr, lonAntCorr);
// --- 6) Antena BRUTA (lat/lon direto do GNGGA) ---
PointF antenaBrutaPx = latlonToPanel(latAntBruta, lonAntBruta);
// --- 7) Plots e ligações (cores distintas) ---
// Centro
DrawPoint(g, xCtrPx, yCtrPx, Color.WhiteSmoke);
// Antena prevista (onde deveria estar fisicamente)
DrawPoint(g, antenaPrevistaPx.X, antenaPrevistaPx.Y, Color.DeepSkyBlue);
using (var linkPrev = new Pen(Color.DeepSkyBlue, 1.5f) { DashStyle = System.Drawing.Drawing2D.DashStyle.Dash })
g.DrawLine(linkPrev, xCtrPx, yCtrPx, antenaPrevistaPx.X, antenaPrevistaPx.Y);
// Antena corrigida (o que você "quer atingir" após correção)
DrawPoint(g, antenaCorrigidaPx.X, antenaCorrigidaPx.Y, Color.LimeGreen);
using (var linkCorr = new Pen(Color.LimeGreen, 1.5f))
g.DrawLine(linkCorr, xCtrPx, yCtrPx, antenaCorrigidaPx.X, antenaCorrigidaPx.Y);
// Antena bruta (de onde realmente vem o GNGGA)
DrawPoint(g, antenaBrutaPx.X, antenaBrutaPx.Y, Color.OrangeRed);
using (var linkBruta = new Pen(Color.OrangeRed, 1.0f) { DashStyle = System.Drawing.Drawing2D.DashStyle.Dot })
g.DrawLine(linkBruta, xCtrPx, yCtrPx, antenaBrutaPx.X, antenaBrutaPx.Y);
// Opcional: linhas entre prevista x corrigida x bruta (comparação direta)
using (var penPC = new Pen(Color.MediumPurple, 1.0f) { DashStyle = System.Drawing.Drawing2D.DashStyle.Dash })
g.DrawLine(penPC, antenaPrevistaPx, antenaCorrigidaPx);
using (var penPB = new Pen(Color.SandyBrown, 1.0f) { DashStyle = System.Drawing.Drawing2D.DashStyle.Dash })
g.DrawLine(penPB, antenaPrevistaPx, antenaBrutaPx);
// --- 8) Retornar as posições para log/depuração ---
return new AntenaDiagPx
{
Centro = new PointF(xCtrPx, yCtrPx),
Prevista = antenaPrevistaPx,
Corrigida = antenaCorrigidaPx,
Bruta = antenaBrutaPx
};
}
private PointF CalcularPontoRotacionado(float centroX, float centroY, float offsetX, float offsetY, float angle)
{
// Converter o ângulo para radianos

View File

@ -400,16 +400,19 @@ namespace AgroBase.Models
double dLat = (dy / R_earth) * 180.0 / Math.PI;
double dLon = (dx / (R_earth * Math.Cos(pos.Latitude * Math.PI / 180.0))) * 180.0 / Math.PI;
double latitude = pos.Latitude + dLat;
double longitude = pos.Longitude + dLon;
GPSModel ultimaPosicao = GPSService.historicoPosicao.Peek();
GPSModel novaPosicao = new GPSModel
{
Momento = DateTime.Now,
Lat0 = GPSService.UltimaLeitura.Lat0,
Lon0 = GPSService.UltimaLeitura.Lon0,
Latitude = pos.Latitude + dLat,
LatitudeAnt = pos.Latitude + dLat,
Longitude = pos.Longitude + dLon,
LongitudeAnt = pos.Longitude + dLon,
Latitude = latitude,
LatitudeAnt = latitude,
Longitude = longitude,
LongitudeAnt = longitude,
OrientacaoReal = GPSUtils.NormalizarAngulo(theta * 180.0 / Math.PI),
Distancia = velocidadeMs * tempoDelta,
Velocidade = velocidadeMs,
@ -418,6 +421,10 @@ namespace AgroBase.Models
TimestampPos = ultimaPosicao.TimestampPos.Clone(),
};
//(double latCor, double lonCorr) = GeoLeverArm.FixLeverArmLatLon_Fast(latitude, longitude, novaPosicao.OrientacaoReal);
//novaPosicao.Latitude = latCor;
//novaPosicao.Longitude = lonCorr;
novaPosicao.TimestampOri.valor = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
novaPosicao.TimestampPos.valor = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;

View File

@ -484,7 +484,7 @@ namespace AgroBase.Services
}
// 2) se já temos origem e um heading válido, aplica lever arm
if (UltimaLeitura.EnuOriginSet)
if (UltimaLeitura.EnuOriginSet && false)
{
// a) antena -> ENU
var (xAnt, yAnt) = GeoLeverArm.GeodeticToENU(latitude, longitude, UltimaLeitura.Lat0, UltimaLeitura.Lon0);
@ -516,6 +516,14 @@ namespace AgroBase.Services
// UltimaLeitura.Latitude = latCtr;
// UltimaLeitura.Longitude = lonCtr;
}
if (UltimaLeitura.EnuOriginSet)
{
(double latCor, double lonCorr) = GeoLeverArm.FixLeverArmLatLon_Fast(latitude, longitude, UltimaLeitura.OrientacaoReal);
UltimaLeitura.Latitude = latCor;
UltimaLeitura.Longitude = lonCorr;
}
}
private static void ProcessarGNRMC(string sentenca)
@ -1698,6 +1706,10 @@ namespace AgroBase.Services
public class GeoLeverArm
{
const double R = 6378137.0; // WGS84
public static double xB = 0.0; // +frente (m)
public static double yB = 0.2; // +direita (m)
public static bool invertHeading = true;
public static bool mirrorLateral = true;
static double ToRad(double deg) => deg * Math.PI / 180.0;
static double ToDeg(double rad) => rad * 180.0 / Math.PI;
@ -1725,8 +1737,7 @@ namespace AgroBase.Services
// Aplica lever arm: retorna o CENTRO dado ANTENA + heading.
// Convenção: θ=0 norte; +horário→leste (igual ao seu modelo: x+=sinθ, y+=cosθ).
public static (double xCtr, double yCtr) ApplyLeverArmENU(
double xAnt, double yAnt, double thetaRad, double lFwd, double lLeft)
public static (double xCtr, double yCtr) ApplyLeverArmENU(double xAnt, double yAnt, double thetaRad, double lFwd, double lLeft)
{
double s = Math.Sin(thetaRad), c = Math.Cos(thetaRad);
// vetores no mundo
@ -1738,6 +1749,32 @@ namespace AgroBase.Services
// centro = antena - (centro->antena)
return (xAnt - rx, yAnt - ry);
}
public static (double lat, double lon) FixLeverArmLatLon_Fast(double latAnt_deg, double lonAnt_deg, double headingDeg)
{
invertHeading = false;
mirrorLateral = false;
if (mirrorLateral) yB = -yB; // espelha lateral (D<->E)
double th = headingDeg * Math.PI / 180.0;
if (invertHeading) th = -th; // inverte sentido do ângulo
// Convenção NAV: 0°=Norte, cresce horário
double fE = Math.Sin(th), fN = Math.Cos(th); // forward (E,N)
double rE = fN, rN = -fE; // right (E,N)
double dE = xB * fE + yB * rE; // body -> ENU
double dN = xB * fN + yB * rN;
const double R = 6378137.0;
double latRad = latAnt_deg * Math.PI / 180.0;
double dLat_deg = (dN / R) * 180.0 / Math.PI;
double dLon_deg = (dE / (R * Math.Cos(latRad))) * 180.0 / Math.PI;
// antena -> VRP (subtrai o offset da antena)
return (latAnt_deg - dLat_deg, lonAnt_deg - dLon_deg);
}
}
}

View File

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

View File

@ -1,3 +1,3 @@
2025/09/26-14:06:14.063 3ac0 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/09/26-14:06:14.074 3ac0 Recovering log #3
2025/09/26-14:06:14.077 3ac0 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log
2025/09/29-10:01:16.906 2c18 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/09/29-10:01:16.915 2c18 Recovering log #3
2025/09/29-10:01:16.918 2c18 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/26-14:03:00.019 39e4 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/09/26-14:03:00.029 39e4 Recovering log #3
2025/09/26-14:03:00.033 39e4 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log
2025/09/29-09:56:13.780 6138 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/09/29-09:56:13.789 6138 Recovering log #3
2025/09/29-09:56:13.792 6138 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":"13403466393568231","port":443,"protocol_str":"quic"}],"anonymization":["DAAAAAcAAABmaWxlOi8vAA==",false,0],"network_stats":{"srtt":14687},"server":"https://tile.openstreetmap.org","supports_spdy":true}],"supports_quic":{"address":"2804:d78:67d:1400:2c66:7456:c2f:b6e6","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":"13403710893015464","port":443,"protocol_str":"quic"}],"anonymization":["DAAAAAcAAABmaWxlOi8vAA==",false,0],"network_stats":{"srtt":159598},"server":"https://tile.openstreetmap.org","supports_spdy":true}],"supports_quic":{"address":"2804:d78:678:7800:a470:6a2a:c4f8:2741","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":1790441947.398009,"host":"bWGAftl61rqoc0YzqPncsLvQQh/iC2Bdp3ejUeGC83w=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1758905947.398017}],"version":2}
{"sts":[{"expiry":1790686574.188502,"host":"bWGAftl61rqoc0YzqPncsLvQQh/iC2Bdp3ejUeGC83w=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1759150574.18851}],"version":2}

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,3 @@
2025/09/26-14:13:03.573 3ac0 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/09/26-14:13:03.574 3ac0 Recovering log #3
2025/09/26-14:13:03.577 3ac0 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log
2025/09/29-10:23:05.989 2c18 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/09/29-10:23:05.991 2c18 Recovering log #3
2025/09/29-10:23:05.995 2c18 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/26-14:04:37.387 39e4 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/09/26-14:04:37.389 39e4 Recovering log #3
2025/09/26-14:04:37.393 39e4 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log
2025/09/29-10:00:49.743 6138 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/09/29-10:00:49.744 6138 Recovering log #3
2025/09/29-10:00:49.747 6138 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/26-14:06:13.990 27dc Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/09/26-14:06:13.993 27dc Recovering log #7
2025/09/26-14:06:13.993 27dc Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log
2025/09/29-10:01:16.830 1b54 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/09/29-10:01:16.833 1b54 Recovering log #7
2025/09/29-10:01:16.833 1b54 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/26-14:02:59.941 4510 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/09/26-14:02:59.944 4510 Recovering log #7
2025/09/26-14:02:59.944 4510 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log
2025/09/29-09:56:13.706 272c Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/09/29-09:56:13.708 272c Recovering log #7
2025/09/29-09:56:13.708 272c 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

@ -17,7 +17,7 @@
<meta name="viewport" content="width=device-width,
initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<style>
#map_de13db2dddfa8d44afb0c6dc4a7b2662 {
#map_902dcfb9bc1908cefaeb7f1e3b6836f6 {
position: relative;
width: 100.0%;
height: 100.0%;
@ -54,14 +54,14 @@
<body>
<div class="folium-map" id="map_de13db2dddfa8d44afb0c6dc4a7b2662" ></div>
<div class="folium-map" id="map_902dcfb9bc1908cefaeb7f1e3b6836f6" ></div>
</body>
<script>
var map_de13db2dddfa8d44afb0c6dc4a7b2662 = L.map(
"map_de13db2dddfa8d44afb0c6dc4a7b2662",
var map_902dcfb9bc1908cefaeb7f1e3b6836f6 = L.map(
"map_902dcfb9bc1908cefaeb7f1e3b6836f6",
{
center: [-22.17265214058333, -47.39519380741667],
crs: L.CRS.EPSG3857,
@ -78,7 +78,7 @@
var tile_layer_0d4b83a132c0a3275ab44552f768a22b = L.tileLayer(
var tile_layer_6b1f102283a7b99d35116ac10e2a6478 = L.tileLayer(
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
{
"minZoom": 0,
@ -95,7 +95,7 @@
);
tile_layer_0d4b83a132c0a3275ab44552f768a22b.addTo(map_de13db2dddfa8d44afb0c6dc4a7b2662);
tile_layer_6b1f102283a7b99d35116ac10e2a6478.addTo(map_902dcfb9bc1908cefaeb7f1e3b6836f6);
@ -111,7 +111,7 @@
}*/
});
}
function geo_json_77371c1eaf1e6144b4deabe3ab1e0927_onEachFeature(feature, layer) {
function geo_json_f1ae38900c23f5c586be86538d71abd1_onEachFeature(feature, layer) {
layer.on({
@ -148,23 +148,23 @@
}*/
});
};
var geo_json_77371c1eaf1e6144b4deabe3ab1e0927 = L.geoJson(null, {
onEachFeature: geo_json_77371c1eaf1e6144b4deabe3ab1e0927_onEachFeature,
var geo_json_f1ae38900c23f5c586be86538d71abd1 = L.geoJson(null, {
onEachFeature: geo_json_f1ae38900c23f5c586be86538d71abd1_onEachFeature,
...{
}
});
function geo_json_77371c1eaf1e6144b4deabe3ab1e0927_add (data) {
geo_json_77371c1eaf1e6144b4deabe3ab1e0927
function geo_json_f1ae38900c23f5c586be86538d71abd1_add (data) {
geo_json_f1ae38900c23f5c586be86538d71abd1
.addData(data);
}
geo_json_77371c1eaf1e6144b4deabe3ab1e0927_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_77371c1eaf1e6144b4deabe3ab1e0927.setStyle(function(feature) {return feature.properties.style;});
geo_json_f1ae38900c23f5c586be86538d71abd1_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_f1ae38900c23f5c586be86538d71abd1.setStyle(function(feature) {return feature.properties.style;});
geo_json_77371c1eaf1e6144b4deabe3ab1e0927.addTo(map_de13db2dddfa8d44afb0c6dc4a7b2662);
geo_json_f1ae38900c23f5c586be86538d71abd1.addTo(map_902dcfb9bc1908cefaeb7f1e3b6836f6);
</script>
@ -185,7 +185,7 @@
}
trajeto_json_add({"features": []});
trajeto_json.addTo(map_de13db2dddfa8d44afb0c6dc4a7b2662);
trajeto_json.addTo(map_902dcfb9bc1908cefaeb7f1e3b6836f6);
function adicionarGeometria(novaGeometria) {
trajeto_json.addData(novaGeometria);
@ -243,7 +243,7 @@
}
trajeto_dinamico_json_add({"features": []});
trajeto_dinamico_json.addTo(map_de13db2dddfa8d44afb0c6dc4a7b2662);
trajeto_dinamico_json.addTo(map_902dcfb9bc1908cefaeb7f1e3b6836f6);
function adicionarGeometriaDinamica(novaGeometria) {
trajeto_dinamico_json.addData(novaGeometria);
@ -296,9 +296,9 @@
var marcadorEquipamento = L.marker([0, 0], {
icon: customIcon
}).addTo(map_de13db2dddfa8d44afb0c6dc4a7b2662);
}).addTo(map_902dcfb9bc1908cefaeb7f1e3b6836f6);
var marcadorBase = L.marker([0, 0], {}).addTo(map_de13db2dddfa8d44afb0c6dc4a7b2662);
var marcadorBase = L.marker([0, 0], {}).addTo(map_902dcfb9bc1908cefaeb7f1e3b6836f6);
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_de13db2dddfa8d44afb0c6dc4a7b2662.setView(novaPosicao, map_de13db2dddfa8d44afb0c6dc4a7b2662.getZoom());
map_902dcfb9bc1908cefaeb7f1e3b6836f6.setView(novaPosicao, map_902dcfb9bc1908cefaeb7f1e3b6836f6.getZoom());
}
}
@ -397,7 +397,7 @@
function atualizarSelecaoRuas(selecionadas) {
selecionadas = JSON.parse(selecionadas);
RuasSelecionadas = Array.isArray(selecionadas) ? [...selecionadas] : [];
geo_json_77371c1eaf1e6144b4deabe3ab1e0927.eachLayer(function (layer) {
geo_json_f1ae38900c23f5c586be86538d71abd1.eachLayer(function (layer) {
if (RuasSelecionadas.includes(parseInt(layer.feature.id))) {
layer.setStyle({ color: 'blue' });
} else {

View File

@ -457,13 +457,12 @@ class ControladorMPC:
calc_omega_fn=None # opcional: fn(tipo, angulo_rad, v) -> omega
):
"""
Propaga (x,y,theta) por 'latency_s' usando 'nova_posicao_fn' que depende de self.dt.
Propaga (x, y, theta) por 'latency_s' usando 'nova_posicao_fn' que depende de self.dt.
Retorna (x, y, theta) estimados no presente.
"""
visitados_copy = visitados.copy()
latency_s = max(0.0, float(latency_s))
if latency_s == 0.0:
return x, y, theta, visitados_copy
return x, y, theta, visitados
# --- constrói sequência efetiva de comandos ---
if not cmd_seq:
@ -505,15 +504,15 @@ class ControladorMPC:
for _ in range(n):
if time_left_ms() <= 0.0:
return x, y, theta, visitados_copy
return x, y, theta, visitados
x, y, theta = aplicar_passo_dt(x, y, theta, u, dt_eff)
idx_alvo = self._corrigir_pontos_visitados(x, y, visitados_copy)
idx_alvo = self._corrigir_pontos_visitados(x, y, visitados)
t_rem -= seg
# normaliza theta se quiser
# theta = (theta + np.pi) % (2*np.pi) - np.pi
return x, y, theta, visitados_copy
return x, y, theta, visitados
def d_look_ahead_m(self, velocidade, dt: float = None):
"""
@ -1002,6 +1001,9 @@ class ControladorMPC:
idx_ponto_alvo = contexto.get("Carro", {}).get("IdxPontoAlvo", 0)
Nmax = 20 if status_carro == StatusCarroMapa.CaminhandoRua.value else 60
self.tempo_execucao_local = contexto.get("Carro", {}).get("TempoEntreComandos", 0.5)
self.passos_horizonte_local = max(1, math.floor(1 / self.tempo_execucao_local))
# -------------------- Correção por latência (vida real) --------------------
# Mantém correção com 'self.dt' e 'velocidade' REAIS
u_hold = {
@ -1017,7 +1019,7 @@ class ControladorMPC:
cmd_seq = None
x, y, theta, self.visitados_execucao = self.corrigir_pose_por_latencia(
x, y, theta, self.visitados_execucao,
latency_s=min(pos_latencia, LAT_MAX),
0.0, #latency_s=min(pos_latencia + self.tempo_execucao_local, LAT_MAX),
dt=self.dt,
nova_posicao_fn=self._nova_posicao,
u_hold=u_hold,
@ -1059,8 +1061,6 @@ class ControladorMPC:
dt_pred = (S_ALVO / (v_sim * K))
dt_pred = max(DT_MIN, min(dt_pred, DT_MAX))
self.tempo_execucao_local = contexto.get("Carro", {}).get("TempoEntreComandos", 0.5)
self.passos_horizonte_local = max(1, math.floor(1 / self.tempo_execucao_local))
self.qtd_comandos_sucessivos = K
# -------------------- Seleção do comando --------------------
@ -1086,7 +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("COMECANDO...")
#print("COMECANDO...")
for passo in range(self.qtd_comandos_sucessivos):
if ms_left() <= 0:
break
@ -2328,22 +2328,22 @@ class ControladorMPC:
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}"
)
#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,