metodo para fixação da base e aplicação de offset global
This commit is contained in:
parent
f3476d6773
commit
a6d9a7271a
|
|
@ -9,8 +9,7 @@ using AgroBase.Models;
|
|||
using static AgroBase.Models.Enums;
|
||||
using OperationControl.Models;
|
||||
using Application = System.Windows.Application;
|
||||
using Mapsui.Animations;
|
||||
using OperationControl.ViewModels;
|
||||
using static OperationControl.Services.BaseFixService;
|
||||
|
||||
namespace OperationControl.Services
|
||||
{
|
||||
|
|
@ -233,7 +232,7 @@ namespace OperationControl.Services
|
|||
private int rtk_timeout = 60;
|
||||
public GPSModel UltimaLeitura = new GPSModel();
|
||||
public BaseFixService BaseFix;
|
||||
private GeoLeverArm LeverArm;
|
||||
public GeoLeverArm LeverArm = new GeoLeverArm();
|
||||
|
||||
private readonly StringBuilder _nmeaBuffer = new();
|
||||
private bool _nmeaInSentence = false;
|
||||
|
|
@ -242,13 +241,14 @@ namespace OperationControl.Services
|
|||
private List<byte> _rtcmMsg = new();
|
||||
private int _rtcmTotalBytes = -1;
|
||||
|
||||
public async Task ConfigurarModulo(bool fixar, MetodoFixacaoBase metodo = MetodoFixacaoBase.Ntrip, double? lat = null, double? lon = null, double? alt = null)
|
||||
public async Task ConfigurarModulo(bool fixar, MetodoFixacaoBase metodo = MetodoFixacaoBase.Ntrip, double? lat = null, double? lon = null, double? alt = null, bool? offset = false)
|
||||
{
|
||||
Models.Variaveis.MostrarLog("Iniciando configuração do módulo GPS...");
|
||||
|
||||
LeverArm = new GeoLeverArm(VariaveisControleOperacao.LeverArmFrontal, VariaveisControleOperacao.LeverArmLateral);
|
||||
|
||||
BaseFix = new BaseFixService(PortaGps, this);
|
||||
if (!(offset ?? false))
|
||||
{
|
||||
BaseFix = new BaseFixService(PortaGps, this);
|
||||
}
|
||||
BaseFix.FixLiberado = fixar;
|
||||
|
||||
string portaUsb = "com3";
|
||||
|
|
@ -268,101 +268,73 @@ namespace OperationControl.Services
|
|||
bool sucesso = false;
|
||||
string mensagem = "";
|
||||
|
||||
|
||||
BaseFix.fimProcesso = null;
|
||||
BaseFix.inicioProcesso = DateTime.UtcNow;
|
||||
BaseFix.inicioFix = DateTime.UtcNow;
|
||||
|
||||
Models.Variaveis.MostrarLog($"Aplicando posição fixa da base com o método {metodo}...");
|
||||
|
||||
switch (metodo)
|
||||
{
|
||||
case MetodoFixacaoBase.Ntrip:
|
||||
{
|
||||
Models.Variaveis.MostrarLog("Tentando fixação da base via NTRIP...");
|
||||
|
||||
sucesso = await BaseFix.FixarBaseViaNtripAsync(
|
||||
portaUsb: portaUsb,
|
||||
portaSaida: portaSaida,
|
||||
portaEntrada: portaEntrada,
|
||||
startNtrip: () =>
|
||||
{
|
||||
Models.Variaveis.MostrarLog("Iniciando correção NTRIP...");
|
||||
CorrecaoRTK_Ntrip = true;
|
||||
_ = Task.Run(async () => await AplicarCorrecaoRTK_Ntrip());
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
stopNtrip: () =>
|
||||
{
|
||||
Models.Variaveis.MostrarLog("Parando correção NTRIP...");
|
||||
CorrecaoRTK_Ntrip = false;
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
segsFixEstavel: TempoSurveryIn
|
||||
);
|
||||
|
||||
if (sucesso)
|
||||
sucesso = await BaseFix.FixarBaseViaNtripAsync(
|
||||
portaUsb: portaUsb,
|
||||
portaSaida: portaSaida,
|
||||
portaEntrada: portaEntrada,
|
||||
startNtrip: () =>
|
||||
{
|
||||
mensagem = "Posição fixada utilizando NTRIP com sucesso!";
|
||||
}
|
||||
else
|
||||
Models.Variaveis.MostrarLog("Iniciando correção NTRIP...");
|
||||
CorrecaoRTK_Ntrip = true;
|
||||
_ = Task.Run(async () => await AplicarCorrecaoRTK_Ntrip());
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
stopNtrip: () =>
|
||||
{
|
||||
Models.Variaveis.MostrarLog("Falha na fixação via NTRIP. Iniciando Survey-In...");
|
||||
|
||||
BaseFix.fimProcesso = null;
|
||||
BaseFix.inicioProcesso = DateTime.UtcNow;
|
||||
BaseFix.inicioFix = DateTime.UtcNow;
|
||||
|
||||
await ConfigurarModuloBase(
|
||||
tempo_fixacao: TempoSurveryIn,
|
||||
porta_usb: portaUsb,
|
||||
porta_saida: portaSaida);
|
||||
|
||||
BaseFix.fimProcesso = DateTime.UtcNow;
|
||||
|
||||
sucesso = true;
|
||||
mensagem = "Posição survery in da base aplicada com sucesso.";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
Models.Variaveis.MostrarLog("Parando correção NTRIP...");
|
||||
CorrecaoRTK_Ntrip = false;
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
segsFixEstavel: TempoSurveryIn
|
||||
);
|
||||
break;
|
||||
|
||||
case MetodoFixacaoBase.SurveyIn:
|
||||
{
|
||||
Models.Variaveis.MostrarLog("Configurando módulo como base em Survey-In...");
|
||||
|
||||
BaseFix.fimProcesso = null;
|
||||
BaseFix.inicioProcesso = DateTime.UtcNow;
|
||||
BaseFix.inicioFix = DateTime.UtcNow;
|
||||
|
||||
await ConfigurarModuloBase(
|
||||
tempo_fixacao: TempoSurveryIn,
|
||||
porta_usb: portaUsb,
|
||||
porta_saida: portaSaida);
|
||||
|
||||
BaseFix.fimProcesso = DateTime.UtcNow;
|
||||
|
||||
sucesso = true;
|
||||
mensagem = "Posição survery in da base aplicada com sucesso.";
|
||||
break;
|
||||
}
|
||||
await ConfigurarModuloBase(tempo_fixacao: TempoSurveryIn, porta_usb: portaUsb, porta_saida: portaSaida);
|
||||
break;
|
||||
|
||||
case MetodoFixacaoBase.Manual:
|
||||
{
|
||||
if (!lat.HasValue || !lon.HasValue || !alt.HasValue)
|
||||
throw new ArgumentException("Latitude, longitude e altitude elipsoidal são obrigatórias no modo manual.");
|
||||
if (lat.HasValue && lon.HasValue && alt.HasValue)
|
||||
await BaseFix.AplicarBaseFixAsync(portaUsb, portaSaida, baseId, lat.Value, lon.Value, alt.Value);
|
||||
break;
|
||||
}
|
||||
|
||||
Models.Variaveis.MostrarLog("Aplicando posição manual fixa da base...");
|
||||
// Aguarda 10 segundos para ver se o UM982 pegou o BaseFix
|
||||
while (sucesso && UltimaLeitura.QualidadeFix != TiposCorrecaoGPS.BaseFix && BaseFix.inicioFix != null && (DateTime.UtcNow - BaseFix.inicioFix).Value.TotalSeconds < 10)
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
|
||||
UltimaLeitura.Latitude = lat.Value;
|
||||
UltimaLeitura.Longitude = lon.Value;
|
||||
AtualizarCoordenadasGPS();
|
||||
BaseFix.fimProcesso = DateTime.UtcNow;
|
||||
BaseFix.FixLiberado = false;
|
||||
|
||||
await BaseFix.AplicarBaseFixAsync(
|
||||
portaUsb,
|
||||
portaSaida,
|
||||
baseId,
|
||||
lat.Value,
|
||||
lon.Value,
|
||||
alt.Value);
|
||||
sucesso = UltimaLeitura.QualidadeFix == TiposCorrecaoGPS.BaseFix;
|
||||
mensagem = sucesso ? $"Posição da base aplicada com sucesso com o método {metodo}." : $"Falha ao aplicar posição da base com o método {metodo}.";
|
||||
|
||||
sucesso = true;
|
||||
mensagem = "Posição manual da base aplicada com sucesso.";
|
||||
break;
|
||||
}
|
||||
if (sucesso && !(offset ?? false))
|
||||
{
|
||||
BaseFix.LatitudeFix = UltimaLeitura.Latitude;
|
||||
BaseFix.LongitudeFix = UltimaLeitura.Longitude;
|
||||
BaseFix.AltitudeElpsoidalFix = UltimaLeitura.AltitudeElipsoidal;
|
||||
BaseFix.OrientacaoFix = UltimaLeitura.OrientacaoReal;
|
||||
|
||||
if (AppShell.Mock)
|
||||
{
|
||||
UltimaLeitura.Latitude = lat.Value;
|
||||
UltimaLeitura.Longitude = lon.Value;
|
||||
UltimaLeitura.AltitudeElipsoidal = alt.Value;
|
||||
AtualizarCoordenadasGPS();
|
||||
}
|
||||
}
|
||||
|
||||
Models.Variaveis.MostrarLog(mensagem);
|
||||
|
|
@ -1304,6 +1276,10 @@ namespace OperationControl.Services
|
|||
public bool CorrecaoAbsoluta = false;
|
||||
public bool CorrecaoEmAndamento = false;
|
||||
public bool FixLiberado = false;
|
||||
public double LatitudeFix { get; set; }
|
||||
public double LongitudeFix { get; set; }
|
||||
public double AltitudeElpsoidalFix { get; set; }
|
||||
public double OrientacaoFix { get; set; }
|
||||
|
||||
public void ReiniciarFix()
|
||||
{
|
||||
|
|
@ -1321,7 +1297,6 @@ namespace OperationControl.Services
|
|||
return false;
|
||||
|
||||
CorrecaoEmAndamento = true;
|
||||
fimProcesso = null;
|
||||
|
||||
segundosFixEstavel = segsFixEstavel;
|
||||
maxJanelaSegundos = maxJanelaSegs;
|
||||
|
|
@ -1349,26 +1324,22 @@ namespace OperationControl.Services
|
|||
{
|
||||
Models.Variaveis.MostrarLog("Poucas amostras de RTK FIX coletadas. Tente aumentar o tempo ou verificar sinais.");
|
||||
CorrecaoAbsoluta = false;
|
||||
FixLiberado = false;
|
||||
return CorrecaoAbsoluta;
|
||||
}
|
||||
|
||||
// 3) Filtro robusto (MAD) + média final
|
||||
var (lat, lon, h, nAmostras) = FiltrarEAgrupar(amostras, madK);
|
||||
var (lat, lon, h, heading, nAmostras) = FiltrarEAgrupar(amostras, madK);
|
||||
|
||||
// 4) Alternar para base FIX + perfil RTCM
|
||||
await AplicarBaseFixAsync(portaUsb, portaSaida, baseId, lat, lon, h);
|
||||
|
||||
Models.Variaveis.MostrarLog($"[BASE/FIX] Coordenadas aplicadas (n={nAmostras}):");
|
||||
Models.Variaveis.MostrarLog($" lat = {lat:0.000000000}, lon = {lon:0.000000000}, h = {h:0.000}");
|
||||
Models.Variaveis.MostrarLog($"[BASE/FIX] Coordenadas aplicadas (n={nAmostras}): lat = {lat:0.000000000}, lon = {lon:0.000000000}, h = {h:0.000}");
|
||||
CorrecaoAbsoluta = true;
|
||||
FixLiberado = false;
|
||||
return CorrecaoAbsoluta;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (stopNtrip != null) await stopNtrip();
|
||||
fimProcesso = DateTime.UtcNow;
|
||||
CorrecaoEmAndamento = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1499,6 +1470,7 @@ namespace OperationControl.Services
|
|||
double lat = ultimaLeitura.Latitude;
|
||||
double lon = ultimaLeitura.Longitude;
|
||||
double altElips = ultimaLeitura.AltitudeElipsoidal; // garanta que já é elipsoidal no parser
|
||||
double heading = ultimaLeitura.OrientacaoReal;
|
||||
var fixQual = ultimaLeitura.QualidadeFix; // enum? ok.
|
||||
|
||||
int hbAfter = ultimaLeitura.Heartbeat;
|
||||
|
|
@ -1515,6 +1487,7 @@ namespace OperationControl.Services
|
|||
latDeg: lat,
|
||||
lonDeg: lon,
|
||||
altElipsoidalM: altElips,
|
||||
headingDeg: heading,
|
||||
fixQuality: fixQual
|
||||
);
|
||||
}
|
||||
|
|
@ -1525,40 +1498,46 @@ namespace OperationControl.Services
|
|||
}
|
||||
|
||||
// ===== 3) Filtro robusto (MAD) + média =====
|
||||
private (double lat, double lon, double h, int n) FiltrarEAgrupar(List<GgaFix> amostras, double madK = 3.5)
|
||||
private (double lat, double lon, double h, double hdg, int n) FiltrarEAgrupar(List<GgaFix> amostras, double madK = 3.5)
|
||||
{
|
||||
Models.Variaveis.MostrarLog("Filtrando dados aferidos...");
|
||||
// Medianas
|
||||
var lats = amostras.Select(a => a.LatDeg).OrderBy(x => x).ToArray();
|
||||
var lons = amostras.Select(a => a.LonDeg).OrderBy(x => x).ToArray();
|
||||
var hs = amostras.Select(a => a.AltElipsoidalM).OrderBy(x => x).ToArray();
|
||||
var hdgs = amostras.Select(a => a.HeadingDeg).OrderBy(x => x).ToArray();
|
||||
|
||||
double medLat = Mediana(lats);
|
||||
double medLon = Mediana(lons);
|
||||
double medH = Mediana(hs);
|
||||
double medHdg = Mediana(hdgs);
|
||||
|
||||
// Desvios absolutos da mediana (MAD)
|
||||
var dLat = amostras.Select(a => Math.Abs(a.LatDeg - medLat)).OrderBy(x => x).ToArray();
|
||||
var dLon = amostras.Select(a => Math.Abs(a.LonDeg - medLon)).OrderBy(x => x).ToArray();
|
||||
var dH = amostras.Select(a => Math.Abs(a.AltElipsoidalM - medH)).OrderBy(x => x).ToArray();
|
||||
var dHdg = amostras.Select(a => Math.Abs(a.HeadingDeg - medH)).OrderBy(x => x).ToArray();
|
||||
|
||||
double madLat = Mediana(dLat) + 1e-12;
|
||||
double madLon = Mediana(dLon) + 1e-12;
|
||||
double madHgt = Mediana(dH) + 1e-12;
|
||||
double madHdg = Mediana(dHdg) + 1e-12;
|
||||
|
||||
// Filtra outliers (|x - med| / MAD <= madK)
|
||||
var filtradas = amostras.Where(a =>
|
||||
(Math.Abs(a.LatDeg - medLat) / madLat) <= madK &&
|
||||
(Math.Abs(a.LonDeg - medLon) / madLon) <= madK &&
|
||||
(Math.Abs(a.AltElipsoidalM - medH) / madHgt) <= madK
|
||||
(Math.Abs(a.AltElipsoidalM - medH) / madHgt) <= madK &&
|
||||
(Math.Abs(a.HeadingDeg - medHdg) / madHdg) <= madK
|
||||
).ToList();
|
||||
|
||||
// Média final
|
||||
double lat = filtradas.Average(a => a.LatDeg);
|
||||
double lon = filtradas.Average(a => a.LonDeg);
|
||||
double h = filtradas.Average(a => a.AltElipsoidalM);
|
||||
double hdg = filtradas.Average(a => a.HeadingDeg);
|
||||
|
||||
return (lat, lon, h, filtradas.Count);
|
||||
return (lat, lon, h, hdg, filtradas.Count);
|
||||
|
||||
double Mediana(double[] arr)
|
||||
{
|
||||
|
|
@ -1618,10 +1597,9 @@ namespace OperationControl.Services
|
|||
|
||||
public enum MetodoFixacaoBase
|
||||
{
|
||||
Automatico = 0,
|
||||
Ntrip = 1,
|
||||
SurveyIn = 2,
|
||||
Manual = 3
|
||||
Ntrip = 0,
|
||||
SurveyIn = 1,
|
||||
Manual = 2
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,20 +1,12 @@
|
|||
using Microsoft.Win32;
|
||||
using OperationControl.Helpers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OperationControl.Helpers;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using static OperationControl.Services.BaseFixService;
|
||||
|
||||
namespace OperationControl.ViewModels
|
||||
{
|
||||
public enum MetodoFixacaoBase
|
||||
{
|
||||
Ntrip = 0,
|
||||
SurveyIn = 1,
|
||||
Manual = 2
|
||||
}
|
||||
|
||||
public class MetodoFixacaoItem
|
||||
{
|
||||
|
|
@ -29,7 +21,9 @@ namespace OperationControl.ViewModels
|
|||
public event Action<string>? CarregarMapaSolicitado;
|
||||
|
||||
// Método, latitude, longitude, altitude, offset frontal cm, offset lateral cm
|
||||
public event Action<MetodoFixacaoBase, double?, double?, double?, double?, double?>? FixarBaseSolicitado;
|
||||
public event Action<MetodoFixacaoBase, double?, double?, double?>? FixarBaseSolicitado;
|
||||
// Offset frontal cm, offset lateral cm
|
||||
public event Action<double?, double?>? AplicarOffsetSolicitado;
|
||||
|
||||
public List<MetodoFixacaoItem> MetodosFixacaoDisponiveis { get; } = new()
|
||||
{
|
||||
|
|
@ -40,11 +34,13 @@ namespace OperationControl.ViewModels
|
|||
|
||||
public ICommand CarregarMapaCommand { get; }
|
||||
public ICommand FixarBaseCommand { get; }
|
||||
public ICommand AplicarOffsetCommand { get; }
|
||||
|
||||
public PreparacaoMapaBottomViewModel()
|
||||
{
|
||||
CarregarMapaCommand = new RelayCommand(_ => ExecutarCarregarMapa(), _ => PodeCarregarMapa);
|
||||
FixarBaseCommand = new RelayCommand(_ => ExecutarFixarBase(), _ => PodeFixarBase);
|
||||
AplicarOffsetCommand = new RelayCommand(_ => ExecutarAplicarOffset(), _ => PodeEditarOffsetBase);
|
||||
|
||||
MetodoFixacaoSelecionado = MetodoFixacaoBase.Ntrip;
|
||||
OffsetFrontalBaseTexto = "0";
|
||||
|
|
@ -121,6 +117,17 @@ namespace OperationControl.ViewModels
|
|||
|
||||
public bool ExibirProgresso => MetodoFixacaoSelecionado != MetodoFixacaoBase.Manual;
|
||||
|
||||
private bool _exibirOffsets;
|
||||
public bool ExibirOffsets
|
||||
{
|
||||
get { return _exibirOffsets; }
|
||||
set
|
||||
{
|
||||
_exibirOffsets = value;
|
||||
OnPropertyChanged(nameof(ExibirOffsets));
|
||||
}
|
||||
}
|
||||
|
||||
public bool PodeFixarBase
|
||||
{
|
||||
get
|
||||
|
|
@ -356,13 +363,7 @@ namespace OperationControl.ViewModels
|
|||
{
|
||||
if (FixacaoEmAndamento)
|
||||
{
|
||||
FixarBaseSolicitado?.Invoke(
|
||||
MetodoFixacaoSelecionado,
|
||||
LatitudeManual,
|
||||
LongitudeManual,
|
||||
AltitudeManual,
|
||||
OffsetFrontalBaseCm,
|
||||
OffsetLateralBaseCm);
|
||||
FixarBaseSolicitado?.Invoke(MetodoFixacaoSelecionado, LatitudeManual, LongitudeManual, AltitudeManual);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -381,13 +382,12 @@ namespace OperationControl.ViewModels
|
|||
StatusTexto = "Pronto para aplicar a posição manual da base.";
|
||||
}
|
||||
|
||||
FixarBaseSolicitado?.Invoke(
|
||||
MetodoFixacaoSelecionado,
|
||||
LatitudeManual,
|
||||
LongitudeManual,
|
||||
AltitudeManual,
|
||||
OffsetFrontalBaseCm,
|
||||
OffsetLateralBaseCm);
|
||||
FixarBaseSolicitado?.Invoke(MetodoFixacaoSelecionado, LatitudeManual, LongitudeManual, AltitudeManual);
|
||||
}
|
||||
|
||||
private void ExecutarAplicarOffset()
|
||||
{
|
||||
AplicarOffsetSolicitado?.Invoke(OffsetFrontalBaseCm, OffsetLateralBaseCm);
|
||||
}
|
||||
|
||||
public void IniciarFixacao()
|
||||
|
|
@ -412,10 +412,9 @@ namespace OperationControl.ViewModels
|
|||
|
||||
public void FinalizarFixacao(bool sucesso, string? mensagem = null)
|
||||
{
|
||||
ExibirOffsets = sucesso;
|
||||
FixacaoEmAndamento = false;
|
||||
|
||||
if (MetodoFixacaoSelecionado != MetodoFixacaoBase.Manual && sucesso)
|
||||
ProgressoFixacao = 100;
|
||||
if (sucesso) ProgressoFixacao = 100;
|
||||
|
||||
StatusTexto = !string.IsNullOrWhiteSpace(mensagem)
|
||||
? mensagem
|
||||
|
|
|
|||
|
|
@ -1,15 +1,19 @@
|
|||
using System.ComponentModel;
|
||||
using System.Windows.Input;
|
||||
using OperationControl.Views;
|
||||
using OperationControl.Helpers;
|
||||
using System.Windows;
|
||||
using OperationControl.Models;
|
||||
using OperationControl.Views.Operacao;
|
||||
using AgroBase.Models.Operacoes;
|
||||
using AgroBase.Models.Operacoes;
|
||||
using AgroBase.Services;
|
||||
using Microsoft.VisualBasic.Logging;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OperationControl.ViewModels.Views.Operacao;
|
||||
using OpenTK.Windowing.Common.Input;
|
||||
using OperationControl.Controls;
|
||||
using OperationControl.Helpers;
|
||||
using OperationControl.Models;
|
||||
using OperationControl.ViewModels.Views.Operacao;
|
||||
using OperationControl.Views;
|
||||
using OperationControl.Views.Operacao;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using static AgroBase.Models.Enums;
|
||||
using static OperationControl.Services.BaseFixService;
|
||||
|
||||
namespace OperationControl.ViewModels
|
||||
{
|
||||
|
|
@ -44,6 +48,7 @@ namespace OperationControl.ViewModels
|
|||
_viewPreparacaoMapaBottom = new PreparacaoMapaBottomView();
|
||||
_viewPreparacaoMapaBottom._vm.CarregarMapaSolicitado += OnCarregarMapaSolicitado;
|
||||
_viewPreparacaoMapaBottom._vm.FixarBaseSolicitado += OnFixarBaseSolicitado;
|
||||
_viewPreparacaoMapaBottom._vm.AplicarOffsetSolicitado += OnAplicarOffsetSolicitado;
|
||||
|
||||
_viewOperacaoTop = new OperacaoTopView();
|
||||
|
||||
|
|
@ -683,8 +688,6 @@ namespace OperationControl.ViewModels
|
|||
if (string.IsNullOrWhiteSpace(linha2))
|
||||
linha2 = "Sem detalhes adicionais.";
|
||||
|
||||
Models.Variaveis.MostrarLog($"LINHA 1: {linha1}");
|
||||
|
||||
// ============================
|
||||
// 8) Atualiza UI
|
||||
// ============================
|
||||
|
|
@ -776,7 +779,7 @@ namespace OperationControl.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
private async void OnFixarBaseSolicitado(MetodoFixacaoBase metodoFix, double? lat, double? lon, double? alt, double? offsetFrontalCm, double? offsetLateralCm)
|
||||
private async void OnFixarBaseSolicitado(MetodoFixacaoBase metodoFix, double? lat, double? lon, double? alt)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -803,14 +806,13 @@ namespace OperationControl.ViewModels
|
|||
if (fixar)
|
||||
{
|
||||
_viewPreparacaoMapaBottom?._vm.IniciarFixacao();
|
||||
await Task.Run(async () => await Variaveis.GpsService.ConfigurarModulo(true, metodoFix, lat, lon, alt));
|
||||
await Variaveis.GpsService.ConfigurarModulo(true, metodoFix, lat, lon, alt);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Variaveis.GpsService.BaseFix.ReiniciarFix();
|
||||
BaseFixada = false;
|
||||
_viewPreparacaoMapaBottom?._vm.CancelarFixacao("Fixação da base interrompida pelo operador.");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -845,6 +847,17 @@ namespace OperationControl.ViewModels
|
|||
}));
|
||||
}
|
||||
|
||||
private async void OnAplicarOffsetSolicitado(double? offsetFrontalCm, double? offsetLateralCm)
|
||||
{
|
||||
if (offsetFrontalCm == null || offsetLateralCm == null) return;
|
||||
|
||||
_viewPreparacaoMapaBottom?._vm.IniciarFixacao();
|
||||
var gps = Variaveis.GpsService;
|
||||
gps.LeverArm = new GeoLeverArm(offsetCampoFrontalCm: offsetFrontalCm.Value, offsetCampoLateralCm: offsetLateralCm.Value);
|
||||
(double lat, double lon) = gps.LeverArm.FixLeverArmLatLon_Fast(gps.BaseFix.LatitudeFix, gps.BaseFix.LongitudeFix, gps.BaseFix.OrientacaoFix);
|
||||
await Variaveis.GpsService.ConfigurarModulo(true, MetodoFixacaoBase.Manual, lat, lon, gps.BaseFix.AltitudeElpsoidalFix, offset: true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region TELA 3
|
||||
|
|
|
|||
|
|
@ -36,90 +36,39 @@
|
|||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="240"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="12"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Botão carregar mapa -->
|
||||
<Button Grid.Column="0"
|
||||
Content="Carregar mapa"
|
||||
Margin="12,12,8,6"
|
||||
Padding="18,10"
|
||||
MinWidth="150"
|
||||
Command="{Binding CarregarMapaCommand}"
|
||||
IsEnabled="{Binding PodeCarregarMapa}"/>
|
||||
<Button Grid.Column="0" Content="Carregar mapa" Margin="12,12,8,6" Padding="18,10" MinWidth="150" Command="{Binding CarregarMapaCommand}" IsEnabled="{Binding PodeCarregarMapa}"/>
|
||||
|
||||
<!-- Combo método -->
|
||||
<ComboBox Grid.Column="1"
|
||||
Margin="8,12,8,6"
|
||||
VerticalContentAlignment="Center"
|
||||
ItemsSource="{Binding MetodosFixacaoDisponiveis}"
|
||||
DisplayMemberPath="Nome"
|
||||
SelectedValuePath="Valor"
|
||||
SelectedValue="{Binding MetodoFixacaoSelecionado, Mode=TwoWay}"
|
||||
IsEnabled="{Binding PodeEditarMetodoFixacao}"/>
|
||||
<ComboBox Grid.Column="1" Margin="8,12,8,6" VerticalContentAlignment="Center" ItemsSource="{Binding MetodosFixacaoDisponiveis}" DisplayMemberPath="Nome" SelectedValuePath="Valor" SelectedValue="{Binding MetodoFixacaoSelecionado, Mode=TwoWay}" IsEnabled="{Binding PodeEditarMetodoFixacao}"/>
|
||||
|
||||
<!-- Botão fixar -->
|
||||
<Button Grid.Column="2"
|
||||
Content="{Binding TextoBotaoFixarBase}"
|
||||
Margin="8,12,12,6"
|
||||
Padding="18,10"
|
||||
MinWidth="180"
|
||||
Command="{Binding FixarBaseCommand}"
|
||||
IsEnabled="{Binding PodeFixarBase}"/>
|
||||
<Button Grid.Column="2" Content="{Binding TextoBotaoFixarBase}" Margin="8,12,12,6" Padding="18,10" MinWidth="180" Command="{Binding FixarBaseCommand}" IsEnabled="{Binding PodeFixarBase}"/>
|
||||
|
||||
<!-- ÁREA DINÂMICA -->
|
||||
<Grid Grid.Column="4" Margin="0,12,12,6">
|
||||
<Grid Grid.Column="3" Margin="0,12,12,6">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Progresso normal + offsets -->
|
||||
<Grid Visibility="{Binding ExibirProgresso, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<!-- Progresso normal -->
|
||||
<Grid Grid.Column="0" Visibility="{Binding ExibirProgresso, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="320"/>
|
||||
<ColumnDefinition Width="70"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="90"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="90"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="50"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<ProgressBar Grid.Column="0"
|
||||
Margin="0,8,8,0"
|
||||
Height="22"
|
||||
Minimum="0"
|
||||
Maximum="100"
|
||||
Value="{Binding ProgressoFixacao}"/>
|
||||
<ProgressBar Grid.Column="0" Margin="0,8,8,0" Height="22" Minimum="0" Maximum="100" Value="{Binding ProgressoFixacao}"/>
|
||||
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{Binding ProgressoFixacaoTexto}"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
Foreground="White"
|
||||
FontWeight="SemiBold"
|
||||
FontSize="14"
|
||||
Margin="0,0,8,0"/>
|
||||
|
||||
<TextBlock Grid.Column="2"
|
||||
Text="Offset frontal (cm):"
|
||||
Style="{StaticResource BottomLabelStyle}"/>
|
||||
|
||||
<TextBox Grid.Column="3"
|
||||
Text="{Binding OffsetFrontalBaseTexto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource BottomTextBoxStyle}"
|
||||
IsEnabled="{Binding PodeEditarOffsetBase}"/>
|
||||
|
||||
<TextBlock Grid.Column="4"
|
||||
Text="Offset lateral (cm):"
|
||||
Style="{StaticResource BottomLabelStyle}"/>
|
||||
|
||||
<TextBox Grid.Column="5"
|
||||
Text="{Binding OffsetLateralBaseTexto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource BottomTextBoxStyle}"
|
||||
IsEnabled="{Binding PodeEditarOffsetBase}"/>
|
||||
<TextBlock Grid.Column="1" Text="{Binding ProgressoFixacaoTexto}" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" FontWeight="SemiBold" FontSize="14" Margin="0,0,8,0"/>
|
||||
</Grid>
|
||||
|
||||
<!-- Campos manuais + offsets -->
|
||||
<Grid Visibility="{Binding ExibirCamposManuais, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<!-- Campos manuais -->
|
||||
<Grid Grid.Column="0" Visibility="{Binding ExibirCamposManuais, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="125"/>
|
||||
|
|
@ -127,108 +76,57 @@
|
|||
<ColumnDefinition Width="125"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="110"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="90"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="90"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="0"
|
||||
Text="Latitude (º):"
|
||||
Style="{StaticResource BottomLabelStyle}"/>
|
||||
<TextBlock Grid.Column="0" Text="Latitude (º):" Style="{StaticResource BottomLabelStyle}"/>
|
||||
|
||||
<TextBox Grid.Column="1"
|
||||
Text="{Binding LatitudeManualTexto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource BottomTextBoxStyle}"
|
||||
IsEnabled="{Binding PodeEditarCoordenadasManuais}"/>
|
||||
<TextBox Grid.Column="1" Text="{Binding LatitudeManualTexto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource BottomTextBoxStyle}" IsEnabled="{Binding PodeEditarCoordenadasManuais}"/>
|
||||
|
||||
<TextBlock Grid.Column="2"
|
||||
Text="Longitude (º):"
|
||||
Style="{StaticResource BottomLabelStyle}"/>
|
||||
<TextBlock Grid.Column="2" Text="Longitude (º):" Style="{StaticResource BottomLabelStyle}"/>
|
||||
|
||||
<TextBox Grid.Column="3"
|
||||
Text="{Binding LongitudeManualTexto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource BottomTextBoxStyle}"
|
||||
IsEnabled="{Binding PodeEditarCoordenadasManuais}"/>
|
||||
<TextBox Grid.Column="3" Text="{Binding LongitudeManualTexto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource BottomTextBoxStyle}" IsEnabled="{Binding PodeEditarCoordenadasManuais}"/>
|
||||
|
||||
<TextBlock Grid.Column="4"
|
||||
Text="Altitude elipsoidal (m):"
|
||||
Style="{StaticResource BottomLabelStyle}"/>
|
||||
<TextBlock Grid.Column="4" Text="Altitude elipsoidal (m):" Style="{StaticResource BottomLabelStyle}"/>
|
||||
|
||||
<TextBox Grid.Column="5"
|
||||
Text="{Binding AltitudeManualTexto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource BottomTextBoxStyle}"
|
||||
IsEnabled="{Binding PodeEditarCoordenadasManuais}"/>
|
||||
|
||||
<TextBlock Grid.Column="6"
|
||||
Text="Offset frontal (cm):"
|
||||
Style="{StaticResource BottomLabelStyle}"/>
|
||||
|
||||
<TextBox Grid.Column="7"
|
||||
Text="{Binding OffsetFrontalBaseTexto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource BottomTextBoxStyle}"
|
||||
IsEnabled="{Binding PodeEditarOffsetBase}"/>
|
||||
|
||||
<TextBlock Grid.Column="8"
|
||||
Text="Offset lateral (cm):"
|
||||
Style="{StaticResource BottomLabelStyle}"/>
|
||||
|
||||
<TextBox Grid.Column="9"
|
||||
Text="{Binding OffsetLateralBaseTexto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource BottomTextBoxStyle}"
|
||||
IsEnabled="{Binding PodeEditarOffsetBase}"/>
|
||||
<TextBox Grid.Column="5" Text="{Binding AltitudeManualTexto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource BottomTextBoxStyle}" IsEnabled="{Binding PodeEditarCoordenadasManuais}"/>
|
||||
</Grid>
|
||||
|
||||
<!-- offsets -->
|
||||
<Grid Grid.Column="1" Visibility="{Binding ExibirOffsets, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="90"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="90"/>
|
||||
<ColumnDefinition Width="150"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="0" Text="Offset frontal (cm):" Style="{StaticResource BottomLabelStyle}"/>
|
||||
|
||||
<TextBox Grid.Column="1" Text="{Binding OffsetFrontalBaseTexto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource BottomTextBoxStyle}" IsEnabled="{Binding PodeEditarOffsetBase}"/>
|
||||
|
||||
<TextBlock Grid.Column="2" Text="Offset lateral (cm):" Style="{StaticResource BottomLabelStyle}"/>
|
||||
|
||||
<TextBox Grid.Column="3" Text="{Binding OffsetLateralBaseTexto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource BottomTextBoxStyle}" IsEnabled="{Binding PodeEditarOffsetBase}"/>
|
||||
|
||||
<Button Grid.Column="4" Content="Aplicar Offset" Margin="12,0,12,0" Padding="5,5" MinWidth="120" Command="{Binding AplicarOffsetCommand}" />
|
||||
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<!-- LINHA 2 -->
|
||||
<Grid Grid.Row="1" Margin="12,4,12,10">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Border Grid.Row="0"
|
||||
Padding="8"
|
||||
Background="#222"
|
||||
CornerRadius="6">
|
||||
<Border Grid.Row="0" Padding="2" Background="#222" CornerRadius="6">
|
||||
|
||||
<Grid>
|
||||
<!-- Status normal -->
|
||||
<StackPanel Visibility="{Binding ExibirStatusNormal, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<TextBlock Text="Status da operação"
|
||||
Foreground="#AAAAAA"
|
||||
FontSize="11"/>
|
||||
<TextBlock Text="{Binding StatusTexto}"
|
||||
Foreground="White"
|
||||
FontSize="14"
|
||||
TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Texto orientativo manual -->
|
||||
<StackPanel Visibility="{Binding ExibirCamposManuais, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<TextBlock Text="Preenchimento manual da base"
|
||||
Foreground="#AAAAAA"
|
||||
FontSize="11"/>
|
||||
<TextBlock Text="Informe latitude, longitude e altitude elipsoidal conhecidas da base para aplicar a posição fixa manualmente."
|
||||
Foreground="White"
|
||||
FontSize="13"
|
||||
TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- Status complementar no manual -->
|
||||
<Border Grid.Row="1"
|
||||
Padding="8,6,8,0"
|
||||
Background="Transparent"
|
||||
Visibility="{Binding ExibirCamposManuais, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<TextBlock Text="{Binding StatusTexto}"
|
||||
Foreground="#D8D8D8"
|
||||
FontSize="12"
|
||||
TextWrapping="Wrap"/>
|
||||
<StackPanel Grid.Column="0" Visibility="{Binding ExibirStatusNormal, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<TextBlock Text="{Binding StatusTexto}" Foreground="White" FontSize="14" TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
|
||||
</Border>
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
@ -16,6 +16,7 @@ using AgroBase.Models.Operadores;
|
|||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Threading;
|
||||
using static OperationControl.Services.BaseFixService;
|
||||
|
||||
namespace OperationControl.Windows
|
||||
{
|
||||
|
|
@ -1725,7 +1726,7 @@ namespace OperationControl.Windows
|
|||
if (fixar)
|
||||
{
|
||||
btnGNSS_FixarBase.Content = "Parar";
|
||||
Task.Run(async () => await Variaveis.GpsService.ConfigurarModulo(true, ViewModels.MetodoFixacaoBase.Ntrip));
|
||||
Task.Run(async () => await Variaveis.GpsService.ConfigurarModulo(true, MetodoFixacaoBase.Ntrip));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
Loading…
Reference in New Issue