iniciado aplicacao de offset na base
This commit is contained in:
parent
09af963498
commit
ae5f8b215b
|
|
@ -1582,12 +1582,8 @@ namespace AgroBase.Models
|
|||
if (controleBase.Dispositivo == T_Code.Gps)
|
||||
{
|
||||
var (la_frontal, la_lateral) = ((JObject)controleBase._comp_value).ToObject<(double?, double?)>();
|
||||
if (la_frontal != null) VariaveisEquipamento.LeverArmFrontal = (double)la_frontal;
|
||||
if (la_lateral != null) VariaveisEquipamento.LeverArmLateral = (double)la_lateral;
|
||||
GPSService.UltimaLeitura.LeverArmFrontal = VariaveisEquipamento.LeverArmFrontal;
|
||||
GPSService.UltimaLeitura.LeverArmLateral = VariaveisEquipamento.LeverArmLateral;
|
||||
if (la_lateral != null || la_frontal != null)
|
||||
GPSService.LeverArm = new GeoLeverArm(VariaveisEquipamento.LeverArmFrontal, VariaveisEquipamento.LeverArmLateral);
|
||||
GPSService.LeverArm = new GeoLeverArm(la_frontal ?? 0, la_lateral ?? 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -449,8 +449,8 @@ namespace AgroBase.Models
|
|||
public static double ComprimentoFrente { get; } = 7.0; // 7
|
||||
public static double ComprimentoTras { get; } = 107.0; // 107
|
||||
public static double DistanciaEntreEixos { get; } = 92.0;
|
||||
public static double LeverArmFrontal { get; set; } = 100.0; // cm
|
||||
public static double LeverArmLateral { get; set; } = 0.0; // cm
|
||||
public static double LeverArmFrontalCm { get; } = 100.0; // cm
|
||||
public static double LeverArmLateralCm { get; } = 0.0; // cm
|
||||
public static double LarguraEquipamentoMm
|
||||
{
|
||||
get
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ namespace AgroBase.Services
|
|||
private static bool LoopRTK_Ntrip = false;
|
||||
public static bool CorrecaoRTK_Ntrip = false;
|
||||
public static DateTime UltimoEnvioCorrecaoRTK = DateTime.MinValue;
|
||||
public static GeoLeverArm LeverArm = new GeoLeverArm(VariaveisEquipamento.LeverArmFrontal, VariaveisEquipamento.LeverArmLateral);
|
||||
public static GeoLeverArm LeverArm = new GeoLeverArm();
|
||||
|
||||
public static void AtualizarPortaCOM(SerialPort Porta)
|
||||
{
|
||||
|
|
@ -969,8 +969,8 @@ namespace AgroBase.Services
|
|||
|
||||
UltimaLeitura.Ntrip_ativado = CorrecaoRTK_Ntrip;
|
||||
UltimaLeitura.Heartbeat = (UltimaLeitura.Heartbeat + 1) % 10;
|
||||
UltimaLeitura.LeverArmFrontal = VariaveisEquipamento.LeverArmFrontal;
|
||||
UltimaLeitura.LeverArmLateral = VariaveisEquipamento.LeverArmLateral;
|
||||
UltimaLeitura.LeverArmFrontal = LeverArm?.FrontalTotalCm ?? 0;
|
||||
UltimaLeitura.LeverArmLateral = LeverArm?.LateralTotalCm ?? 0;
|
||||
|
||||
if (Variaveis.IsAgroMonitor)
|
||||
{
|
||||
|
|
@ -1359,26 +1359,82 @@ namespace AgroBase.Services
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public class GeoLeverArm
|
||||
{
|
||||
public GeoLeverArm(double _xbCm = 0, double _ybCm = 0, bool _invH = false, bool _mirrL = false)
|
||||
// Lever arm físico fixo do equipamento
|
||||
private readonly double xFisico; // +frente (m)
|
||||
private readonly double yFisico; // +direita (m)
|
||||
|
||||
// Offset operacional/de campo
|
||||
private readonly double xCampo; // +frente (m)
|
||||
private readonly double yCampo; // +direita (m)
|
||||
|
||||
private readonly bool invertHeading;
|
||||
private readonly bool mirrorLateral;
|
||||
|
||||
public GeoLeverArm(double offsetCampoFrontalCm = 0, double offsetCampoLateralCm = 0, bool invH = false, bool mirrL = false)
|
||||
{
|
||||
xB = _xbCm / 100.0;
|
||||
yB = _ybCm / 100.0;
|
||||
invertHeading = _invH;
|
||||
mirrorLateral = _mirrL;
|
||||
// fixos do equipamento
|
||||
xFisico = VariaveisEquipamento.LeverArmFrontalCm / 100.0;
|
||||
yFisico = VariaveisEquipamento.LeverArmLateralCm / 100.0;
|
||||
|
||||
// ajustes de campo
|
||||
xCampo = offsetCampoFrontalCm / 100.0;
|
||||
yCampo = offsetCampoLateralCm / 100.0;
|
||||
|
||||
invertHeading = invH;
|
||||
mirrorLateral = mirrL;
|
||||
}
|
||||
|
||||
const double R = 6378137.0; // WGS84
|
||||
private readonly double xB; // +frente (m)
|
||||
private readonly double yB; // +direita (m)
|
||||
private readonly bool invertHeading = false;
|
||||
private readonly bool mirrorLateral = false;
|
||||
|
||||
private double ToRad(double deg) => deg * Math.PI / 180.0;
|
||||
private double ToDeg(double rad) => rad * 180.0 / Math.PI;
|
||||
|
||||
public double FrontalTotalCm => (xFisico + xCampo) * 100.0;
|
||||
public double LateralTotalCm => (yFisico + yCampo) * 100.0;
|
||||
|
||||
/// <summary>
|
||||
/// Convenção:
|
||||
/// - Entrada = posição da antena GNSS
|
||||
/// - Saída = posição corrigida do centro/VRP
|
||||
/// - heading: 0° = Norte, 90° = Leste, sentido horário
|
||||
/// - frontal positivo = antena à frente do centro
|
||||
/// - lateral positivo = antena à direita do centro
|
||||
/// Consequência:
|
||||
/// - frontal positivo desloca a posição corrigida para trás do robô
|
||||
/// - lateral positivo desloca a posição corrigida para a esquerda do robô
|
||||
/// </summary>
|
||||
public (double lat, double lon) FixLeverArmLatLon_Fast(double latAnt_deg, double lonAnt_deg, double headingDeg)
|
||||
{
|
||||
double xTotal = xFisico + xCampo;
|
||||
double yTotal = yFisico + yCampo;
|
||||
|
||||
if (mirrorLateral)
|
||||
yTotal = -yTotal;
|
||||
|
||||
double th = ToRad(headingDeg);
|
||||
if (invertHeading)
|
||||
th = -th;
|
||||
|
||||
// Convenção NAV
|
||||
double fE = Math.Sin(th); // forward east
|
||||
double fN = Math.Cos(th); // forward north
|
||||
|
||||
double rE = fN; // right east
|
||||
double rN = -fE; // right north
|
||||
|
||||
// deslocamento da antena no mundo
|
||||
double dE = xTotal * fE + yTotal * rE;
|
||||
double dN = xTotal * fN + yTotal * rN;
|
||||
|
||||
double latRad = ToRad(latAnt_deg);
|
||||
|
||||
double dLat_deg = (dN / GPSUtils.RaioDaTerra) * 180.0 / Math.PI;
|
||||
double dLon_deg = (dE / (GPSUtils.RaioDaTerra * Math.Cos(latRad))) * 180.0 / Math.PI;
|
||||
|
||||
// retorna o centro/VRP
|
||||
return (latAnt_deg - dLat_deg, lonAnt_deg - dLon_deg);
|
||||
}
|
||||
|
||||
// lat/lon -> ENU (aproximação local, boa para ~km)
|
||||
public (double x, double y) GeodeticToENU(double lat, double lon, double lat0, double lon0)
|
||||
|
|
@ -1386,58 +1442,11 @@ namespace AgroBase.Services
|
|||
double latR = ToRad(lat), lonR = ToRad(lon);
|
||||
double lat0R = ToRad(lat0), lon0R = ToRad(lon0);
|
||||
double dLat = latR - lat0R, dLon = lonR - lon0R;
|
||||
double xEast = dLon * Math.Cos(lat0R) * R;
|
||||
double yNorth = dLat * R;
|
||||
double xEast = dLon * Math.Cos(lat0R) * GPSUtils.RaioDaTerra;
|
||||
double yNorth = dLat * GPSUtils.RaioDaTerra;
|
||||
return (xEast, yNorth);
|
||||
}
|
||||
|
||||
public (double lat, double lon) ENUToGeodetic(double x, double y, double lat0, double lon0)
|
||||
{
|
||||
double lat0R = ToRad(lat0);
|
||||
double dLat = y / R;
|
||||
double dLon = x / (R * Math.Cos(lat0R));
|
||||
double lat = lat0 + ToDeg(dLat);
|
||||
double lon = lon0 + ToDeg(dLon);
|
||||
return (lat, lon);
|
||||
}
|
||||
|
||||
// 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 (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
|
||||
double fx = s, fy = c; // frente
|
||||
double lx = -c, ly = s; // esquerda
|
||||
// vetor centro->antena no mundo
|
||||
double rx = lFwd * fx + lLeft * lx;
|
||||
double ry = lFwd * fy + lLeft * ly;
|
||||
// centro = antena - (centro->antena)
|
||||
return (xAnt - rx, yAnt - ry);
|
||||
}
|
||||
|
||||
public (double lat, double lon) FixLeverArmLatLon_Fast(double latAnt_deg, double lonAnt_deg, double headingDeg)
|
||||
{
|
||||
double _yB = (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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -246,9 +246,7 @@ namespace OperationControl.Services
|
|||
{
|
||||
Models.Variaveis.MostrarLog("Iniciando configuração do módulo GPS...");
|
||||
|
||||
LeverArm = new GeoLeverArm(
|
||||
VariaveisControleOperacao.LeverArmFrontal,
|
||||
VariaveisControleOperacao.LeverArmLateral);
|
||||
LeverArm = new GeoLeverArm(VariaveisControleOperacao.LeverArmFrontal, VariaveisControleOperacao.LeverArmLateral);
|
||||
|
||||
BaseFix = new BaseFixService(PortaGps, this);
|
||||
BaseFix.FixLiberado = fixar;
|
||||
|
|
|
|||
|
|
@ -197,14 +197,10 @@ namespace OperationControl.ViewModels
|
|||
TudoOkChanged?.Invoke(TudoOk);
|
||||
}
|
||||
|
||||
// ====== STATUS INICIAL (fake por enquanto) ======
|
||||
// ====== STATUS INICIAL ======
|
||||
|
||||
public void CarregarStatusInicial()
|
||||
{
|
||||
// aqui você pluga de verdade nos seus serviços:
|
||||
// var statusRede = NetworkService.Get();
|
||||
// var statusGnss = GnssService.Get();
|
||||
|
||||
AtualizarStatusRede();
|
||||
AtualizarStatusGnss();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ namespace OperationControl.ViewModels.Views.Operacao
|
|||
public ICommand AlternarOperacaoCommand { get; }
|
||||
public ICommand ParadaEmergenciaCommand { get; }
|
||||
public ICommand CancelarOperacaoCommand { get; }
|
||||
public ICommand ReconfigurarGnssCommand { get; }
|
||||
private bool _operacaoPausada => (VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Pausa ?? false);
|
||||
private bool _operacaoEmExecucao;
|
||||
public bool OperacaoEmExecucao
|
||||
|
|
@ -42,10 +43,10 @@ namespace OperationControl.ViewModels.Views.Operacao
|
|||
? new SolidColorBrush(Color.FromRgb(120, 88, 20))
|
||||
: new SolidColorBrush(Color.FromRgb(30, 90, 58));
|
||||
|
||||
public System.Windows.Media.Brush BordaBotaoOperacao =>
|
||||
public Brush BordaBotaoOperacao =>
|
||||
OperacaoEmExecucao && !_operacaoPausada
|
||||
? new SolidColorBrush(System.Windows.Media.Color.FromRgb(170, 130, 40))
|
||||
: new SolidColorBrush(System.Windows.Media.Color.FromRgb(74, 138, 91));
|
||||
? new SolidColorBrush(Color.FromRgb(170, 130, 40))
|
||||
: new SolidColorBrush(Color.FromRgb(74, 138, 91));
|
||||
|
||||
|
||||
private bool _roverSelecionado;
|
||||
|
|
@ -60,10 +61,19 @@ namespace OperationControl.ViewModels.Views.Operacao
|
|||
OnPropertyChanged(nameof(RoverSelecionado));
|
||||
OnPropertyChanged(nameof(NomeRover));
|
||||
OnPropertyChanged(nameof(OpacityPainel));
|
||||
OnPropertyChanged(nameof(RoverNaoSelecionado));
|
||||
OnPropertyChanged(nameof(VisibilidadeAcoesRover));
|
||||
OnPropertyChanged(nameof(VisibilidadeConfiguracaoGnss));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool RoverNaoSelecionado => !RoverSelecionado;
|
||||
|
||||
public Visibility VisibilidadeAcoesRover => RoverSelecionado ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
public Visibility VisibilidadeConfiguracaoGnss => !RoverSelecionado ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
private string _nomeRover = "Nenhum rover selecionado";
|
||||
public string NomeRover
|
||||
{
|
||||
|
|
@ -252,6 +262,7 @@ namespace OperationControl.ViewModels.Views.Operacao
|
|||
AlternarOperacaoCommand = new RelayCommand(_ => AlternarOperacao());
|
||||
ParadaEmergenciaCommand = new RelayCommand(_ => ExecutarParadaEmergencia());
|
||||
CancelarOperacaoCommand = new RelayCommand(_ => CancelarOperacao());
|
||||
ReconfigurarGnssCommand = new RelayCommand(_ => ReconfigurarGnss());
|
||||
|
||||
DefinirSemRover();
|
||||
}
|
||||
|
|
@ -372,6 +383,10 @@ namespace OperationControl.ViewModels.Views.Operacao
|
|||
}
|
||||
}
|
||||
|
||||
private void ReconfigurarGnss()
|
||||
{
|
||||
Variaveis.Dock._vm.CurrentStep = DockStep.PreparacaoMapa;
|
||||
}
|
||||
|
||||
|
||||
private string ValorOuTracos(string valor) => RoverSelecionado ? valor : "--";
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using OperationControl.Helpers;
|
||||
using Microsoft.Win32;
|
||||
using OperationControl.Helpers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
|
@ -26,7 +27,9 @@ namespace OperationControl.ViewModels
|
|||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
public event Action<string>? CarregarMapaSolicitado;
|
||||
public event Action<MetodoFixacaoBase, double?, double?, double?>? FixarBaseSolicitado;
|
||||
|
||||
// Método, latitude, longitude, altitude, offset frontal cm, offset lateral cm
|
||||
public event Action<MetodoFixacaoBase, double?, double?, double?, double?, double?>? FixarBaseSolicitado;
|
||||
|
||||
public List<MetodoFixacaoItem> MetodosFixacaoDisponiveis { get; } = new()
|
||||
{
|
||||
|
|
@ -35,45 +38,18 @@ namespace OperationControl.ViewModels
|
|||
new MetodoFixacaoItem { Valor = MetodoFixacaoBase.Manual, Nome = "Preenchimento manual" }
|
||||
};
|
||||
|
||||
private bool _fixacaoEmAndamento;
|
||||
public bool FixacaoEmAndamento
|
||||
public ICommand CarregarMapaCommand { get; }
|
||||
public ICommand FixarBaseCommand { get; }
|
||||
|
||||
public PreparacaoMapaBottomViewModel()
|
||||
{
|
||||
get => _fixacaoEmAndamento;
|
||||
set
|
||||
{
|
||||
if (_fixacaoEmAndamento != value)
|
||||
{
|
||||
_fixacaoEmAndamento = value;
|
||||
OnPropertyChanged(nameof(FixacaoEmAndamento));
|
||||
OnPropertyChanged(nameof(PodeCarregarMapa));
|
||||
OnPropertyChanged(nameof(PodeFixarBase));
|
||||
OnPropertyChanged(nameof(PodeEditarMetodoFixacao));
|
||||
OnPropertyChanged(nameof(PodeEditarCoordenadasManuais));
|
||||
}
|
||||
}
|
||||
}
|
||||
CarregarMapaCommand = new RelayCommand(_ => ExecutarCarregarMapa(), _ => PodeCarregarMapa);
|
||||
FixarBaseCommand = new RelayCommand(_ => ExecutarFixarBase(), _ => PodeFixarBase);
|
||||
|
||||
public bool PodeCarregarMapa => !FixacaoEmAndamento;
|
||||
|
||||
public bool PodeEditarMetodoFixacao => !FixacaoEmAndamento;
|
||||
|
||||
public bool PodeEditarCoordenadasManuais =>
|
||||
!FixacaoEmAndamento && MetodoFixacaoSelecionado == MetodoFixacaoBase.Manual;
|
||||
|
||||
public bool PodeFixarBase
|
||||
{
|
||||
get
|
||||
{
|
||||
if (FixacaoEmAndamento)
|
||||
return true; // permite "Parar"
|
||||
|
||||
if (MetodoFixacaoSelecionado != MetodoFixacaoBase.Manual)
|
||||
return true;
|
||||
|
||||
return LatitudeManual.HasValue &&
|
||||
LongitudeManual.HasValue &&
|
||||
AltitudeManual.HasValue;
|
||||
}
|
||||
MetodoFixacaoSelecionado = MetodoFixacaoBase.Ntrip;
|
||||
OffsetFrontalBaseTexto = "0";
|
||||
OffsetLateralBaseTexto = "0";
|
||||
StatusTexto = "Pronto para carregar o mapa e fixar a base.";
|
||||
}
|
||||
|
||||
private MetodoFixacaoBase _metodoFixacaoSelecionado = MetodoFixacaoBase.Ntrip;
|
||||
|
|
@ -88,7 +64,6 @@ namespace OperationControl.ViewModels
|
|||
|
||||
OnPropertyChanged(nameof(MetodoFixacaoSelecionado));
|
||||
OnPropertyChanged(nameof(ExibirCamposManuais));
|
||||
OnPropertyChanged(nameof(ExibirStatusNormal));
|
||||
OnPropertyChanged(nameof(ExibirProgresso));
|
||||
OnPropertyChanged(nameof(PodeEditarCoordenadasManuais));
|
||||
OnPropertyChanged(nameof(PodeFixarBase));
|
||||
|
|
@ -112,10 +87,69 @@ namespace OperationControl.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
private bool _fixacaoEmAndamento;
|
||||
public bool FixacaoEmAndamento
|
||||
{
|
||||
get => _fixacaoEmAndamento;
|
||||
set
|
||||
{
|
||||
if (_fixacaoEmAndamento != value)
|
||||
{
|
||||
_fixacaoEmAndamento = value;
|
||||
|
||||
OnPropertyChanged(nameof(FixacaoEmAndamento));
|
||||
OnPropertyChanged(nameof(PodeCarregarMapa));
|
||||
OnPropertyChanged(nameof(PodeEditarMetodoFixacao));
|
||||
OnPropertyChanged(nameof(PodeEditarCoordenadasManuais));
|
||||
OnPropertyChanged(nameof(PodeEditarOffsetBase));
|
||||
OnPropertyChanged(nameof(PodeFixarBase));
|
||||
OnPropertyChanged(nameof(TextoBotaoFixarBase));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool PodeCarregarMapa => !FixacaoEmAndamento;
|
||||
|
||||
public bool PodeEditarMetodoFixacao => !FixacaoEmAndamento;
|
||||
|
||||
public bool PodeEditarCoordenadasManuais =>
|
||||
!FixacaoEmAndamento && MetodoFixacaoSelecionado == MetodoFixacaoBase.Manual;
|
||||
|
||||
public bool PodeEditarOffsetBase => !FixacaoEmAndamento;
|
||||
|
||||
public bool ExibirCamposManuais => MetodoFixacaoSelecionado == MetodoFixacaoBase.Manual;
|
||||
public bool ExibirStatusNormal => MetodoFixacaoSelecionado != MetodoFixacaoBase.Manual;
|
||||
|
||||
public bool ExibirProgresso => MetodoFixacaoSelecionado != MetodoFixacaoBase.Manual;
|
||||
|
||||
public bool PodeFixarBase
|
||||
{
|
||||
get
|
||||
{
|
||||
if (FixacaoEmAndamento)
|
||||
return true; // botão vira "Parar"
|
||||
|
||||
if (MetodoFixacaoSelecionado != MetodoFixacaoBase.Manual)
|
||||
return true;
|
||||
|
||||
return LatitudeManual.HasValue &&
|
||||
LongitudeManual.HasValue &&
|
||||
AltitudeManual.HasValue;
|
||||
}
|
||||
}
|
||||
|
||||
public string TextoBotaoFixarBase
|
||||
{
|
||||
get
|
||||
{
|
||||
if (FixacaoEmAndamento)
|
||||
return "Parar";
|
||||
|
||||
return MetodoFixacaoSelecionado == MetodoFixacaoBase.Manual
|
||||
? "Aplicar posição manual"
|
||||
: "Fixar posição da base";
|
||||
}
|
||||
}
|
||||
|
||||
private double? _latitudeManual;
|
||||
public double? LatitudeManual
|
||||
{
|
||||
|
|
@ -171,6 +205,7 @@ namespace OperationControl.ViewModels
|
|||
{
|
||||
_latitudeManualTexto = value;
|
||||
LatitudeManual = TryParseDouble(value);
|
||||
|
||||
OnPropertyChanged(nameof(LatitudeManualTexto));
|
||||
OnPropertyChanged(nameof(PodeFixarBase));
|
||||
}
|
||||
|
|
@ -187,6 +222,7 @@ namespace OperationControl.ViewModels
|
|||
{
|
||||
_longitudeManualTexto = value;
|
||||
LongitudeManual = TryParseDouble(value);
|
||||
|
||||
OnPropertyChanged(nameof(LongitudeManualTexto));
|
||||
OnPropertyChanged(nameof(PodeFixarBase));
|
||||
}
|
||||
|
|
@ -203,12 +239,73 @@ namespace OperationControl.ViewModels
|
|||
{
|
||||
_altitudeManualTexto = value;
|
||||
AltitudeManual = TryParseDouble(value);
|
||||
|
||||
OnPropertyChanged(nameof(AltitudeManualTexto));
|
||||
OnPropertyChanged(nameof(PodeFixarBase));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double? _offsetFrontalBaseCm;
|
||||
public double? OffsetFrontalBaseCm
|
||||
{
|
||||
get => _offsetFrontalBaseCm;
|
||||
private set
|
||||
{
|
||||
if (_offsetFrontalBaseCm != value)
|
||||
{
|
||||
_offsetFrontalBaseCm = value;
|
||||
OnPropertyChanged(nameof(OffsetFrontalBaseCm));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double? _offsetLateralBaseCm;
|
||||
public double? OffsetLateralBaseCm
|
||||
{
|
||||
get => _offsetLateralBaseCm;
|
||||
private set
|
||||
{
|
||||
if (_offsetLateralBaseCm != value)
|
||||
{
|
||||
_offsetLateralBaseCm = value;
|
||||
OnPropertyChanged(nameof(OffsetLateralBaseCm));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string _offsetFrontalBaseTexto = "0";
|
||||
public string OffsetFrontalBaseTexto
|
||||
{
|
||||
get => _offsetFrontalBaseTexto;
|
||||
set
|
||||
{
|
||||
if (_offsetFrontalBaseTexto != value)
|
||||
{
|
||||
_offsetFrontalBaseTexto = value;
|
||||
OffsetFrontalBaseCm = TryParseDouble(value);
|
||||
|
||||
OnPropertyChanged(nameof(OffsetFrontalBaseTexto));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string _offsetLateralBaseTexto = "0";
|
||||
public string OffsetLateralBaseTexto
|
||||
{
|
||||
get => _offsetLateralBaseTexto;
|
||||
set
|
||||
{
|
||||
if (_offsetLateralBaseTexto != value)
|
||||
{
|
||||
_offsetLateralBaseTexto = value;
|
||||
OffsetLateralBaseCm = TryParseDouble(value);
|
||||
|
||||
OnPropertyChanged(nameof(OffsetLateralBaseTexto));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double _progressoFixacao;
|
||||
public double ProgressoFixacao
|
||||
{
|
||||
|
|
@ -226,7 +323,7 @@ namespace OperationControl.ViewModels
|
|||
|
||||
public string ProgressoFixacaoTexto => $"{ProgressoFixacao:F0}%";
|
||||
|
||||
private string _statusTexto = "Pronto para carregar o mapa e fixar a base.";
|
||||
private string _statusTexto = string.Empty;
|
||||
public string StatusTexto
|
||||
{
|
||||
get => _statusTexto;
|
||||
|
|
@ -240,37 +337,15 @@ namespace OperationControl.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
public string TextoBotaoFixarBase
|
||||
{
|
||||
get
|
||||
{
|
||||
if (FixacaoEmAndamento)
|
||||
return "Parar";
|
||||
|
||||
return MetodoFixacaoSelecionado == MetodoFixacaoBase.Manual
|
||||
? "Aplicar posição manual"
|
||||
: "Fixar posição da base";
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand CarregarMapaCommand { get; }
|
||||
public ICommand FixarBaseCommand { get; }
|
||||
|
||||
public PreparacaoMapaBottomViewModel()
|
||||
{
|
||||
CarregarMapaCommand = new RelayCommand(_ => ExecutarCarregarMapa(), _ => PodeCarregarMapa);
|
||||
FixarBaseCommand = new RelayCommand(_ => ExecutarFixarBase(), _ => PodeFixarBase);
|
||||
}
|
||||
|
||||
private void ExecutarCarregarMapa()
|
||||
{
|
||||
var dlg = new OpenFileDialog
|
||||
var dlg = new Microsoft.Win32.OpenFileDialog
|
||||
{
|
||||
Filter = "Arquivos de mapa|*.geojson;*.json;*.shp",
|
||||
Title = "Selecione o arquivo de mapa"
|
||||
};
|
||||
|
||||
if (dlg.ShowDialog() == DialogResult.OK)
|
||||
if (dlg.ShowDialog() == true)
|
||||
{
|
||||
StatusTexto = $"Mapa selecionado: {System.IO.Path.GetFileName(dlg.FileName)}";
|
||||
CarregarMapaSolicitado?.Invoke(dlg.FileName);
|
||||
|
|
@ -285,7 +360,9 @@ namespace OperationControl.ViewModels
|
|||
MetodoFixacaoSelecionado,
|
||||
LatitudeManual,
|
||||
LongitudeManual,
|
||||
AltitudeManual);
|
||||
AltitudeManual,
|
||||
OffsetFrontalBaseCm,
|
||||
OffsetLateralBaseCm);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -308,19 +385,14 @@ namespace OperationControl.ViewModels
|
|||
MetodoFixacaoSelecionado,
|
||||
LatitudeManual,
|
||||
LongitudeManual,
|
||||
AltitudeManual);
|
||||
}
|
||||
|
||||
public void AtualizarProgresso(double progresso, string status)
|
||||
{
|
||||
ProgressoFixacao = progresso;
|
||||
StatusTexto = status;
|
||||
AltitudeManual,
|
||||
OffsetFrontalBaseCm,
|
||||
OffsetLateralBaseCm);
|
||||
}
|
||||
|
||||
public void IniciarFixacao()
|
||||
{
|
||||
FixacaoEmAndamento = true;
|
||||
OnPropertyChanged(nameof(TextoBotaoFixarBase));
|
||||
ProgressoFixacao = 0;
|
||||
|
||||
StatusTexto = MetodoFixacaoSelecionado switch
|
||||
|
|
@ -332,31 +404,29 @@ namespace OperationControl.ViewModels
|
|||
};
|
||||
}
|
||||
|
||||
public void AtualizarProgresso(double progresso, string status)
|
||||
{
|
||||
ProgressoFixacao = progresso;
|
||||
StatusTexto = status;
|
||||
}
|
||||
|
||||
public void FinalizarFixacao(bool sucesso, string? mensagem = null)
|
||||
{
|
||||
FixacaoEmAndamento = false;
|
||||
OnPropertyChanged(nameof(TextoBotaoFixarBase));
|
||||
|
||||
if (MetodoFixacaoSelecionado != MetodoFixacaoBase.Manual)
|
||||
ProgressoFixacao = sucesso ? 100 : ProgressoFixacao;
|
||||
if (MetodoFixacaoSelecionado != MetodoFixacaoBase.Manual && sucesso)
|
||||
ProgressoFixacao = 100;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(mensagem))
|
||||
{
|
||||
StatusTexto = mensagem;
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusTexto = sucesso
|
||||
StatusTexto = !string.IsNullOrWhiteSpace(mensagem)
|
||||
? mensagem
|
||||
: sucesso
|
||||
? "Fixação da base concluída com sucesso."
|
||||
: "Fixação da base encerrada.";
|
||||
}
|
||||
}
|
||||
|
||||
public void CancelarFixacao(string? mensagem = null)
|
||||
{
|
||||
FixacaoEmAndamento = false;
|
||||
OnPropertyChanged(nameof(TextoBotaoFixarBase));
|
||||
|
||||
StatusTexto = mensagem ?? "Fixação da base cancelada.";
|
||||
}
|
||||
|
||||
|
|
@ -378,14 +448,8 @@ namespace OperationControl.ViewModels
|
|||
|
||||
texto = texto.Trim().Replace(",", ".");
|
||||
|
||||
if (double.TryParse(
|
||||
texto,
|
||||
NumberStyles.Any,
|
||||
CultureInfo.InvariantCulture,
|
||||
out var valor))
|
||||
{
|
||||
if (double.TryParse(texto, NumberStyles.Any, CultureInfo.InvariantCulture, out var valor))
|
||||
return valor;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -776,7 +776,7 @@ namespace OperationControl.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
private async void OnFixarBaseSolicitado(MetodoFixacaoBase metodoFix, double? lat, double? lon, double? alt)
|
||||
private async void OnFixarBaseSolicitado(MetodoFixacaoBase metodoFix, double? lat, double? lon, double? alt, double? offsetFrontalCm, double? offsetLateralCm)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
|
|||
|
|
@ -26,12 +26,8 @@
|
|||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="8">
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="8">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
|
|
@ -40,12 +36,7 @@
|
|||
</UserControl.Resources>
|
||||
|
||||
<Grid Background="#181818">
|
||||
<Border Margin="10"
|
||||
Padding="12"
|
||||
CornerRadius="10"
|
||||
Background="#202020"
|
||||
BorderBrush="#343434"
|
||||
BorderThickness="1">
|
||||
<Border Margin="10" Padding="12" CornerRadius="10" Background="#202020" BorderBrush="#343434" BorderThickness="1">
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
|
|
@ -54,24 +45,11 @@
|
|||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- CONTEÚDO SUPERIOR -->
|
||||
<ScrollViewer Grid.Row="0"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
HorizontalScrollBarVisibility="Disabled">
|
||||
<ScrollViewer Grid.Row="0" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
|
||||
<StackPanel Opacity="{Binding OpacityPainel}">
|
||||
<TextBlock Text="Operação em Andamento"
|
||||
FontSize="18"
|
||||
FontWeight="Bold"
|
||||
Foreground="White"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,0,0,6"/>
|
||||
<TextBlock Text="Operação em Andamento" FontSize="18" FontWeight="Bold" Foreground="White" HorizontalAlignment="Center" Margin="0,0,0,6"/>
|
||||
|
||||
<TextBlock Text="{Binding NomeRover}"
|
||||
FontSize="14"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="#D0D0D0"
|
||||
HorizontalAlignment="Center"
|
||||
TextAlignment="Center"
|
||||
Margin="0,0,0,14"/>
|
||||
<TextBlock Text="{Binding NomeRover}" FontSize="14" FontWeight="SemiBold" Foreground="#D0D0D0" HorizontalAlignment="Center" TextAlignment="Center" Margin="0,0,0,14"/>
|
||||
|
||||
<Border Style="{StaticResource LeftInfoCardStyle}">
|
||||
<Grid>
|
||||
|
|
@ -193,41 +171,25 @@
|
|||
</ScrollViewer>
|
||||
|
||||
<!-- RODAPÉ FIXO -->
|
||||
<Border Grid.Row="1"
|
||||
Margin="0,12,0,0"
|
||||
Padding="10"
|
||||
CornerRadius="10"
|
||||
Background="#1A1A1A"
|
||||
BorderBrush="#343434"
|
||||
BorderThickness="1"
|
||||
IsEnabled="{Binding RoverSelecionado}"
|
||||
Opacity="{Binding OpacityPainel}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Ações principais"
|
||||
Foreground="#CFCFCF"
|
||||
FontSize="13"
|
||||
FontWeight="SemiBold"
|
||||
Margin="0,0,0,10"/>
|
||||
<Border Grid.Row="1" Margin="0,12,0,0" Padding="10" CornerRadius="10" Background="#1A1A1A" BorderBrush="#343434" BorderThickness="1">
|
||||
|
||||
<Button Content="{Binding TextoBotaoOperacao}"
|
||||
Command="{Binding AlternarOperacaoCommand}"
|
||||
Style="{StaticResource LeftActionButtonStyle}"
|
||||
Background="{Binding CorBotaoOperacao}"
|
||||
BorderBrush="{Binding BordaBotaoOperacao}"/>
|
||||
<Grid>
|
||||
<StackPanel Visibility="{Binding VisibilidadeAcoesRover}">
|
||||
<TextBlock Text="Ações principais" Foreground="#CFCFCF" FontSize="13" FontWeight="SemiBold" Margin="0,0,0,10"/>
|
||||
|
||||
<Button Content="⛔ Parada de Emergência"
|
||||
Command="{Binding ParadaEmergenciaCommand}"
|
||||
Style="{StaticResource LeftActionButtonStyle}"
|
||||
Background="#7A1E1E"
|
||||
BorderBrush="#B83A3A"/>
|
||||
<Button Content="{Binding TextoBotaoOperacao}" Command="{Binding AlternarOperacaoCommand}" Style="{StaticResource LeftActionButtonStyle}" Background="{Binding CorBotaoOperacao}" BorderBrush="{Binding BordaBotaoOperacao}"/>
|
||||
|
||||
<Button Content="✖ Finalizar Operação"
|
||||
Command="{Binding CancelarOperacaoCommand}"
|
||||
Style="{StaticResource LeftActionButtonStyle}"
|
||||
Background="#3A3A3A"
|
||||
BorderBrush="#666666"
|
||||
Margin="0,0,0,0"/>
|
||||
</StackPanel>
|
||||
<Button Content="⛔ Parada de Emergência" Command="{Binding ParadaEmergenciaCommand}" Style="{StaticResource LeftActionButtonStyle}" Background="#7A1E1E" BorderBrush="#B83A3A"/>
|
||||
|
||||
<Button Content="✖ Finalizar Operação" Command="{Binding CancelarOperacaoCommand}" Style="{StaticResource LeftActionButtonStyle}" Background="#3A3A3A" BorderBrush="#666666" Margin="0,0,0,0"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Visibility="{Binding VisibilidadeConfiguracaoGnss}">
|
||||
<TextBlock Text="Configuração" Foreground="#CFCFCF" FontSize="13" FontWeight="SemiBold" Margin="0,0,0,10"/>
|
||||
|
||||
<Button Content="📡 Reconfigurar GNSS" Command="{Binding ReconfigurarGnssCommand}" Style="{StaticResource LeftActionButtonStyle}" Background="#1F3A5F" BorderBrush="#4F7DB8"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
</Grid>
|
||||
|
|
|
|||
|
|
@ -37,68 +37,88 @@
|
|||
<ColumnDefinition Width="240"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="12"/>
|
||||
|
||||
<!-- Área dinâmica -->
|
||||
<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}"/>
|
||||
|
||||
<!-- 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}"/>
|
||||
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}"/>
|
||||
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}"/>
|
||||
|
||||
<!-- ÁREA DINÂMICA -->
|
||||
<Grid Grid.Column="4" Margin="0,12,12,6">
|
||||
|
||||
<!-- Progresso normal -->
|
||||
<!-- Progresso normal + offsets -->
|
||||
<Grid 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="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<ProgressBar Grid.Column="0"
|
||||
Margin="0,8,8,0"
|
||||
Height="22"
|
||||
Minimum="0"
|
||||
Maximum="100"
|
||||
Value="{Binding ProgressoFixacao}"/>
|
||||
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"/>
|
||||
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}"/>
|
||||
</Grid>
|
||||
|
||||
<!-- Campos manuais -->
|
||||
<!-- Campos manuais + offsets -->
|
||||
<Grid Visibility="{Binding ExibirCamposManuais, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
|
|
@ -107,35 +127,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}"/>
|
||||
Text="Latitude (º):"
|
||||
Style="{StaticResource BottomLabelStyle}"/>
|
||||
|
||||
<TextBox Grid.Column="1"
|
||||
Text="{Binding LatitudeManualTexto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource BottomTextBoxStyle}"
|
||||
IsEnabled="{Binding PodeEditarCoordenadasManuais}"/>
|
||||
Text="{Binding LatitudeManualTexto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource BottomTextBoxStyle}"
|
||||
IsEnabled="{Binding PodeEditarCoordenadasManuais}"/>
|
||||
|
||||
<TextBlock Grid.Column="2"
|
||||
Text="Longitude (º):"
|
||||
Style="{StaticResource BottomLabelStyle}"/>
|
||||
Text="Longitude (º):"
|
||||
Style="{StaticResource BottomLabelStyle}"/>
|
||||
|
||||
<TextBox Grid.Column="3"
|
||||
Text="{Binding LongitudeManualTexto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource BottomTextBoxStyle}"
|
||||
IsEnabled="{Binding PodeEditarCoordenadasManuais}"/>
|
||||
Text="{Binding LongitudeManualTexto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource BottomTextBoxStyle}"
|
||||
IsEnabled="{Binding PodeEditarCoordenadasManuais}"/>
|
||||
|
||||
<TextBlock Grid.Column="4"
|
||||
Text="Altitude elipsoidal (m)"
|
||||
Style="{StaticResource BottomLabelStyle}"/>
|
||||
Text="Altitude elipsoidal (m):"
|
||||
Style="{StaticResource BottomLabelStyle}"/>
|
||||
|
||||
<TextBox Grid.Column="5"
|
||||
Text="{Binding AltitudeManualTexto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource BottomTextBoxStyle}"
|
||||
IsEnabled="{Binding PodeEditarCoordenadasManuais}"/>
|
||||
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}"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
|
|
|||
Loading…
Reference in New Issue