Adicionado método de retorno à base por pontos manuais

This commit is contained in:
Diego Freitas 2026-03-26 22:42:40 -03:00
parent e230176950
commit e42e1e6109
7 changed files with 182 additions and 23 deletions

View File

@ -344,6 +344,7 @@ namespace AgroBase.Models
IP = VariaveisEquipamento.Parametros.rover_ip,
RuasPercorrer = null,
Mapa = null,
PontosRetorno = null,
DadosLeitura = new OperacaoParametrosDadosModel(),
};
@ -1130,6 +1131,7 @@ namespace AgroBase.Models
p.QtdCamerasSolo = Parametros.QtdCamerasSolo;
p.Mapa = Parametros.Mapa;
p.RuasPercorrer = Parametros.RuasPercorrer;
p.PontosRetorno = Parametros.PontosRetorno;
p.ModulosMandatorios = Parametros.ModulosMandatorios;
p.ParametrosMandatorios = Parametros.ParametrosMandatorios;
@ -1221,6 +1223,13 @@ namespace AgroBase.Models
Variaveis.OperacaoEmAndamento.Finalizando = false;
Variaveis.OperacaoEmAndamento.Trajetoria?.AutonomiaCorredor?.Parar();
Variaveis.OperacaoEmAndamento.DispSen?.Dados?.ContadorCarga?.FinalizarOperacao();
if (Variaveis.OperacaoEmAndamento.Parametros.Modo == ModoOperacao.RetornoBase)
{
var p = CarregarParametrosOperacaoPadrao(ModoOperacao.MapaGPS, false);
Variaveis.OperacaoEmAndamento.Parametros = p;
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
}
}
public void ReiniciarOperacao(bool daBase)
@ -1835,8 +1844,9 @@ namespace AgroBase.Models
if (controleBase.Dispositivo == T_Code.Trj)
{
var (lat, lon, pontosRetorno) = ((JObject)controleBase._comp_value).ToObject<(double?, double?, List<double[]>)>();
if (lat == null || lon == null) return;
GPSModel posicaoBase = new GPSModel() { Latitude = lat.Value, Longitude = lon.Value };
GPSModel posicaoBase = null;
if (lat != null && lon != null)
posicaoBase = new GPSModel() { Latitude = lat.Value, Longitude = lon.Value };
List<GPSModel> pontosRetornoPos = null;
if (pontosRetorno?.Any() ?? false)
pontosRetornoPos = pontosRetorno.Select(x => new GPSModel() { Latitude = x[0], Longitude = x[1] }).ToList();

View File

@ -148,6 +148,7 @@ namespace AgroBase.Models.Operacoes
public MapaFeatureCollectionModel Mapa { get; set; }
public List<string> RuasPercorrer { get; set; }
public List<double[]> PontosRetorno { get; set; }
public OperacaoParametrosDadosModel DadosLeitura { get; set; }

View File

@ -1752,11 +1752,8 @@ namespace AgroBase.Models
// Retorno a base automatico
public void IniciarRetornoBase(GPSModel baseGps, List<GPSModel> waypointsManual = null)
{
if (baseGps == null)
throw new ArgumentNullException(nameof(baseGps));
bool valido = false;
List<GPSModel> pontosRetorno;
List<GPSModel> pontosRetorno = null;
// =========================
// MODO MANUAL (operador)
@ -1772,7 +1769,8 @@ namespace AgroBase.Models
// =========================
// MODO AUTOMÁTICO
// =========================
(valido, pontosRetorno) = GerarTrajetoriaRetornoAutomatico(baseGps);
if (baseGps != null)
(valido, pontosRetorno) = GerarTrajetoriaRetornoAutomatico(baseGps);
}
if (!valido || pontosRetorno == null || pontosRetorno.Count < 1)

View File

@ -32,6 +32,7 @@ using Mapsui.Extensions;
using OperationControl.Models;
using static AgroBase.Models.Enums;
using System.Windows.Input;
using AgroBase.Models;
namespace OperationControl.Controls
@ -545,6 +546,10 @@ namespace OperationControl.Controls
if (ParametrizandoOperacao)
HighlightRoad(roadFeature);
}
else if (EmModoRetorno)
{
AlternarPontoNoMapa(sp);
}
else
{
OnMarkerClicked(null);
@ -566,6 +571,8 @@ namespace OperationControl.Controls
Mapa.Cursor = System.Windows.Input.Cursors.Hand;
else if (feat != null && info?.Layer == MapaPlantacao_Layer && feat is MIFeature roadFeature && ParametrizandoOperacao)
Mapa.Cursor = System.Windows.Input.Cursors.Hand;
else if (feat != null && info?.Layer == _layerPontosSelecionados && feat is PointFeature pointFeature && EmModoRetorno)
Mapa.Cursor = System.Windows.Input.Cursors.Hand;
else
Mapa.Cursor = System.Windows.Input.Cursors.Arrow;
}
@ -577,6 +584,120 @@ namespace OperationControl.Controls
}
#region RETORNO A BASE MANUAL
private MemoryLayer _layerPontosSelecionados;
public List<GPSModel> _pontosSelecionados = new List<GPSModel>();
double ToleranciaRemocaoMetros = 2.0;
private bool EmModoRetorno =>
!SemRoverFocado &&
!(VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Iniciada ?? false) &&
(VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Status ?? StatusOperacao.NaoIniciado) == StatusOperacao.Parametrizando &&
Models.Variaveis.Dock?._vm?._viewOperacaoRight?._vm?.SecaoAtual == ViewModels.Views.Operacao.SecaoRightBar.Parametrizacao &&
Models.Variaveis.Dock?._vm?._viewOperacaoRight?.areaParametrizacao?._vm?.Parametros?.Modo == ModoOperacao.RetornoBase;
private void AlternarPontoNoMapa(ScreenPosition sp)
{
try
{
// Dependendo da versão do Mapsui, pode ser:
// var world = Mapa.Navigator.Viewport.ScreenToWorld(sp.X, sp.Y);
// ou:
var world = Mapa.Map.Navigator.Viewport.ScreenToWorld(sp.X, sp.Y);
// Normalmente o mapa está em EPSG:3857
var lonLat = Mapsui.Projections.SphericalMercator.ToLonLat(world.X, world.Y);
GPSModel ponto = new GPSModel() { Latitude = lonLat.lat, Longitude = lonLat.lon };
var existente = _pontosSelecionados
.FirstOrDefault(p => GPSUtils.DistanciaEntrePontos(ponto, p) <= ToleranciaRemocaoMetros);
if (existente != null)
{
_pontosSelecionados.Remove(existente);
}
else
{
_pontosSelecionados.Add(ponto);
}
RedesenharPontosSelecionados();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"Erro ao alternar ponto no mapa: {ex.Message}");
}
finally
{
Models.Variaveis.MostrarLog($"Pontos: {_pontosSelecionados.Count}");
}
}
private void RedesenharPontosSelecionados()
{
var features = new List<Mapsui.IFeature>();
for (int i = 0; i < _pontosSelecionados.Count; i++)
{
var p = _pontosSelecionados[i];
var mercator = Mapsui.Projections.SphericalMercator.FromLonLat(p.Longitude, p.Latitude);
var feature = new PointFeature(mercator.x, mercator.y);
// número do ponto
feature["label"] = (i + 1).ToString();
// círculo
feature.Styles.Add(new SymbolStyle
{
SymbolType = SymbolType.Ellipse,
SymbolScale = 1.2,
Fill = new Brush(Color.Red),
Outline = new Pen(Color.White, 2)
});
// texto (número)
feature.Styles.Add(new LabelStyle
{
LabelColumn = "label",
ForeColor = Color.White,
BackColor = null,
HorizontalAlignment = LabelStyle.HorizontalAlignmentEnum.Center,
VerticalAlignment = LabelStyle.VerticalAlignmentEnum.Center,
Offset = new Offset(0, 0),
Font = new Font { Size = 12 }
});
features.Add(feature);
}
if (_layerPontosSelecionados == null)
{
_layerPontosSelecionados = new MemoryLayer
{
Name = "PontosSelecionados"
};
Mapa.Map.Layers.Add(_layerPontosSelecionados);
}
_layerPontosSelecionados.Features = features;
Mapa.Refresh();
}
public void LimparPontosSelecionados()
{
_pontosSelecionados = new List<GPSModel>();
RedesenharPontosSelecionados();
VariaveisControleOperacao.RoverEmFoco.PontosRetorno = null;
}
#endregion
private void EnsureBaseLayer()
{
try
@ -802,7 +923,7 @@ namespace OperationControl.Controls
}
catch (Exception ex)
{
Variaveis.MostrarLog($"Erro ao carregar coordenadas do mapa: {ex.Message}");
Models.Variaveis.MostrarLog($"Erro ao carregar coordenadas do mapa: {ex.Message}");
}
}
@ -915,7 +1036,7 @@ namespace OperationControl.Controls
return _mapa;
}
public void CarregarDadosMapa(AgroBase.Models.MapaFeatureCollectionModel Mapa, List<string> RuasSelecionadas)
public void CarregarDadosMapa(AgroBase.Models.MapaFeatureCollectionModel Mapa, List<string> RuasSelecionadas, List<double[]> pontosSelecionados)
{
if (RuasMapaCarregado.Any())
{
@ -928,6 +1049,8 @@ namespace OperationControl.Controls
AtualizarStylesRuas();
}
_pontosSelecionados = (pontosSelecionados ?? new List<double[]>()).Select(x => new GPSModel() { Latitude = x[0], Longitude = x[1] }).ToList();
RedesenharPontosSelecionados();
}

View File

@ -67,6 +67,7 @@ namespace OperationControl.ViewModels.Views.Operacao.Monitoramento
private void ReiniciarOperacao()
{
VariaveisControleOperacao.EnviarComandoIniciarOperacao(false, false);
Models.Variaveis.Dock?._vm?._viewOperacaoCenter?.Mapa?.LimparPontosSelecionados();
}
public void AtualizarParametros(OperacaoParametrosModel origem)

View File

@ -380,6 +380,7 @@ namespace OperationControl.ViewModels.Views.Operacao
if (System.Windows.MessageBox.Show("Deseja finalizar a operação em andamento?", "Finalizar Operação", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
{
VariaveisControleOperacao.EnviarComandoIniciarOperacao(false);
Models.Variaveis.Dock?._vm?._viewOperacaoCenter?.Mapa?.LimparPontosSelecionados();
}
}

View File

@ -1,8 +1,7 @@
using AgroBase.Models.Operacoes;
using AgroBase.Models;
using AgroBase.Models.Operacoes;
using AgroBase.Services;
using Microsoft.VisualBasic.Logging;
using Newtonsoft.Json.Linq;
using OpenTK.Windowing.Common.Input;
using OperationControl.Controls;
using OperationControl.Helpers;
using OperationControl.Models;
@ -740,7 +739,7 @@ namespace OperationControl.ViewModels
public void AtualizarDadosMapa(OperacaoParametrosModel? dados)
{
_viewOperacaoCenter?.Mapa?.LoadMapFile(_ultimoMapaCarregado);
_viewOperacaoCenter?.Mapa?.CarregarDadosMapa(dados?.Mapa, dados?.RuasPercorrer);
_viewOperacaoCenter?.Mapa?.CarregarDadosMapa(dados?.Mapa, dados?.RuasPercorrer, dados?.PontosRetorno);
}
#region TELA 2
@ -755,9 +754,9 @@ namespace OperationControl.ViewModels
Mapa?.markers?.AddMarker(
markerId,
true,
lat: Variaveis.GpsService?.UltimaLeitura?.Latitude,
lon: Variaveis.GpsService?.UltimaLeitura?.Longitude,
heading: Variaveis.GpsService?.UltimaLeitura?.OrientacaoReal,
lat: Models.Variaveis.GpsService?.UltimaLeitura?.Latitude,
lon: Models.Variaveis.GpsService?.UltimaLeitura?.Longitude,
heading: Models.Variaveis.GpsService?.UltimaLeitura?.OrientacaoReal,
label: "Base"
);
}
@ -783,11 +782,11 @@ namespace OperationControl.ViewModels
{
try
{
if (!(Variaveis.GpsService.BaseFix?.FixLiberado ?? false))
if (!(Models.Variaveis.GpsService.BaseFix?.FixLiberado ?? false))
{
bool fixar = false;
if (Variaveis.GpsService.BaseFix?.PosicaoBaseFixada ?? false)
if (Models.Variaveis.GpsService.BaseFix?.PosicaoBaseFixada ?? false)
{
var res = System.Windows.MessageBox.Show(
"Mudar posição da base?",
@ -806,12 +805,12 @@ namespace OperationControl.ViewModels
if (fixar)
{
_viewPreparacaoMapaBottom?._vm.IniciarFixacao();
await Variaveis.GpsService.ConfigurarModulo(true, metodoFix, lat, lon, alt);
await Models.Variaveis.GpsService.ConfigurarModulo(true, metodoFix, lat, lon, alt);
}
}
else
{
Variaveis.GpsService.BaseFix.ReiniciarFix();
Models.Variaveis.GpsService.BaseFix.ReiniciarFix();
BaseFixada = false;
}
}
@ -852,10 +851,10 @@ namespace OperationControl.ViewModels
if (offsetFrontalCm == null || offsetLateralCm == null) return;
_viewPreparacaoMapaBottom?._vm.IniciarFixacao();
var gps = Variaveis.GpsService;
var gps = Models.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);
await Models.Variaveis.GpsService.ConfigurarModulo(true, MetodoFixacaoBase.Manual, lat, lon, gps.BaseFix.AltitudeElpsoidalFix, offset: true);
}
#endregion
@ -1099,9 +1098,34 @@ namespace OperationControl.ViewModels
}
private void OnSalvarParametrosSolicitado(OperacaoParametrosModel parametros)
{
var rover = VariaveisControleOperacao.RoverEmFoco;
if (parametros.Modo == AgroBase.Models.Enums.ModoOperacao.RetornoBase)
{
var pontos = _viewOperacaoCenter?.Mapa?._pontosSelecionados;
if (!(pontos?.Any() ?? false))
{
System.Windows.MessageBox.Show("Clique no mapa para marcar os pontos por onde o equipamento deve seguir", "Pontos não marcados", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if (System.Windows.MessageBox.Show($"Deseja iniciar a operação de retorno seguindo os {pontos.Count} pontos marcados no mapa, somando em {GPSUtils.DistanciaDoTrecho(pontos):F2} metros?", "Confirmação", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
{
parametros.PontosRetorno = pontos.Select(x => new double[] { x.Latitude, x.Longitude }).ToList();
VariaveisControleOperacao.EnviarComandoRetornoBase(pontosRetorno: parametros.PontosRetorno);
rover.PontosRetorno = parametros.PontosRetorno;
Task.Run(async () =>
{
await Task.Delay(500);
_viewOperacaoRight?._vm?.SelecionarSecao(SecaoRightBar.Resumo);
});
}
return;
}
var dadosMapa = _viewOperacaoCenter?.Mapa?.CriarDadosMapa();
var ruasPercorrer = _viewOperacaoCenter?.Mapa?.RuasMapaCarregado?.Where(x => x.Selected)?.Select(x => x.Id)?.ToList() ?? new List<string>();
var rover = VariaveisControleOperacao.RoverEmFoco;
if (rover?.DadosLeitura?.Operacao?.Modo != parametros.Modo && (rover?.DadosLeitura?.Operacao?.Iniciada ?? false))
{
@ -1283,6 +1307,7 @@ namespace OperationControl.ViewModels
rover.ModulosMandatorios = novosParametros.ModulosMandatorios;
rover.ParametrosMandatorios = novosParametros.ParametrosMandatorios;
rover.RuasPercorrer = novosParametros.RuasPercorrer;
rover.PontosRetorno = novosParametros.PontosRetorno;
rover.Mapa = novosParametros.Mapa;
AtualizarDadosDiagnostico(rover);