agrobot_base/AgroBase/AgroBase/Forms/Simuladores/frmSimulacaoMapaGPS.cs

584 lines
24 KiB
C#

using AgroBase.Models;
using AgroBase.Services;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using static AgroBase.Models.Enums;
namespace AgroBase.Forms
{
public partial class frmSimulacaoMapaGPS : Form
{
AsyncTaskTimerModel tmrLeitura;
MapaDinamicoModel MapaDinamico;
bool parar = false;
double tempoGps = (1000.0 / GPSService.TaxaAmostragemHz);
int ticksControleMax = 0;
int ticksControle = 0;
List<GPSModel> passosOperacao = new List<GPSModel>();
int idxPassoOperacao = 0;
double velocidadeCarroMs = 0.0;
DateTime UltimaAtualizacaoGps = DateTime.MinValue;
Queue<double> historicoAngulosControle = new Queue<double>();
GPSModel posicaoAtual = new GPSModel();
List<MPCSimulacaoModel> simulacao = new List<MPCSimulacaoModel>();
public frmSimulacaoMapaGPS()
{
InitializeComponent();
// Ativa o double buffering
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
MapaDinamico = new MapaDinamicoModel(this, pnlZoomMapa);
}
private void frmSimulacaoMapaGPS_Load(object sender, EventArgs e)
{
cmbTipoControleDirecional.Items.Clear();
cmbTipoControleDirecional.Items.AddRange(Enum.GetNames(typeof(Enums.TiposControladorDirecional)));
cmbTipoControleDirecional.SelectedIndex = (int)Variaveis.OperacaoEmAndamento.Parametros.Controle.DirTipoMovimento;
cmbStatusCorredor.Items.Clear();
cmbStatusCorredor.Items.AddRange(Enum.GetNames(typeof(Enums.StatusCarroMapa)));
cmbStatusCorredor.SelectedIndex = (int)StatusCarroMapa.Parado;
Variaveis.OperacaoEmAndamento.ReiniciarSimulacao();
tmrLeitura = new AsyncTaskTimerModel("tmrLeitura", tmrLeitura_Tick, (int)tempoGps, this);
tmrLeitura.Start();
txtTempoGPS.Text = tempoGps.ToString();
Variaveis.OperacaoEmAndamento.Mapa = new MapasModel()
{
pnlMapa = pnlMapa,
};
}
private void frmSimulacaoMapaGPS_FormClosing(object sender, FormClosingEventArgs e)
{
tmrLeitura?.Dispose();
Variaveis.OperacaoEmAndamento.Iniciado = false;
}
DateTime t0 = DateTime.Now;
private async Task tmrLeitura_Tick()
{
double latencia_tick = (DateTime.Now - t0).TotalSeconds;
t0 = DateTime.Now;
int.TryParse(txtTempoGPS.Text, out int tempo);
if (tempo > 0)
{
tempoGps = tempo;
}
if (!AtualizandoTela)
{
Func<bool> funcAtt = new Func<bool>(() =>
{
AtualizarDadosTela();
return true;
});
Task.Run(() => FuncoesGlobais.ExecutarMetodoComVerificacaoCrossThread(this, funcAtt));
}
if (chbAutomatico.Checked)
{
btnAcrescentarGPS_Click(btnAcrescentarGPS, new EventArgs());
}
DateTime t1 = DateTime.Now;
double latencia_exec = (t1 - t0).TotalSeconds;
double frequencia_exec = 1.0 / Math.Max(latencia_exec, 1e-6);
double frequencia_tick = 1.0 / Math.Max(latencia_tick, 1e-6);
//Console.WriteLine($"Tempo por tick GPS: {Math.Round(latencia_exec, 4)} s, Frequencia: {Math.Round(frequencia_exec, 2)} Hz | Tempo entre tick GPS: {Math.Round(latencia_tick, 4)}, Frequencia: {Math.Round(frequencia_tick, 2)} Hz");
double novoDelay = Math.Max(tempoGps - (latencia_exec * 1000.0), 1);
tmrLeitura.SetInterval((int)novoDelay);
}
bool AtualizandoTela = false;
private void AtualizarDadosTela()
{
if (AtualizandoTela)
return;
AtualizandoTela = true;
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
var _Trajetoria = Variaveis.OperacaoEmAndamento.Trajetoria;
if (_Trajetoria == null)
{
AtualizandoTela = false;
return;
}
lblStatusOperacao.Text = $"Operação: {_Sensoriamento.StatusOperacao}";
if (_Sensoriamento.StatusOperacao == StatusOperacao.Aguardando) lblStatusOperacao.Text += $" ({_Sensoriamento.TempoAguardandoSeg:0})";
lblTipoMovimento.Text = (_Sensoriamento.Controle?.TipoMovimento ?? TipoMovimentoDirecional.Diagnostico).ToString();
if (_Trajetoria == null)
{
Variaveis.OperacaoEmAndamento.Mapa.AtualizarRuasSelecionadas();
AtualizandoTela = false;
return;
}
if (_Sensoriamento.Trajetoria == null)
{
AtualizandoTela = false;
return;
}
var h = GPSUtils.DistanciaDoTrecho(simulacao.Select(x => new GPSModel() { Latitude = x.latitude, Longitude = x.longitude, OrientacaoReal = x.orientacao }).ToList());
lblStatus.Text = $"Carro: {_Sensoriamento.Trajetoria.StatusCarro} ({_Sensoriamento.OperadorVisual.Analises.segmentacao.status_corredor})";
lblDirecao.Text = $"Direção: {_Sensoriamento.Trajetoria.DirecaoCaminho}";
lblDistanciaOperacao.Text = $"Distância Operação: {_Sensoriamento.Trajetoria.DistanciaPercorrida:F2} m de {_Sensoriamento.Trajetoria.DistanciaTotal:F2} m";
lblDistanciaFinal.Text = $"Distância Restante: {_Sensoriamento.Trajetoria.DistanciaRestante:F2} m";
//lblDistanciaLateral.Text = $"Esq: {_Sensoriamento.Trajetoria.DistanciaEsquerda:F2} m - Dir: {_Sensoriamento.Trajetoria.DistanciaDireita:F2} m {Variaveis.OperacaoEmAndamento.Controle.ErroLateral:F2} m";
lblDistanciaLateral.Text = $"h: {h:F2} m, p: {_Sensoriamento.Controle.SimulacaoMPC.Count}, s: {_Sensoriamento.Controle.DebugCustoMpc.Count}";
lblRua.Text = $"Corredor: " + (_Sensoriamento.Trajetoria.CorredorAtual.Dentro ? "Dentro" : "Fora");
lblMargem.Text = $"Margem: " + (_Sensoriamento.Trajetoria.NaMargemDoCorredor ? "Sim" : "Não");
lblProximoPonto.Text = $"Próximo Ponto: {_Sensoriamento.Trajetoria.ProximoPonto.idxPonto}";
lblAproximando.Text = (_Sensoriamento.Trajetoria.ProximoPonto.Aproximando ? "Aproximando" : "Afastando");
lblDistProx.Text = $"Distância Próximo Ponto: {_Sensoriamento.Trajetoria.ProximoPonto.DistanciaTrajeto:F2} m";
lblDistAnt.Text = $"Distância Ponto Anterior: {_Sensoriamento.Trajetoria.PontoMaisProximo.DistanciaTrajeto:F2} m";
lblTempoRestante.Text = $"Tempo Restante: {_Sensoriamento.Trajetoria.TempoEstimadoRestante}";
lblTempoOperacao.Text = $"Tempo: " + _Sensoriamento.TempoDecorrido.ToString("HH:mm:ss") + $" de {_Sensoriamento.Trajetoria.TempoEstimadoOperacao}";
lblPercentualRua.Text = $"Rua: {_Sensoriamento.Trajetoria.CorredorAtual.Progresso:F2}%";
lblPercentualOperacao.Text = $"Operação: {_Sensoriamento.Trajetoria.ProgressoTrajeto:F2}%";
pnlOrientacaoTrajeto.Invalidate();
pnlAnguloControle.Invalidate();
pnlOrientacaoCarro.Invalidate();
if (_Sensoriamento.Controle.SimulacaoMPC != null)
{
simulacao = _Sensoriamento.Controle.SimulacaoMPC;
}
else
{
simulacao = new List<MPCSimulacaoModel>();
}
if (_Trajetoria?.CorredorAtual != null || (_Trajetoria?.RetornandoBase ?? false))
{
MapaDinamico.AtualizarDados(
KinectService.Iniciado && KinectService.Leitura.StatusDetecao ? KinectService.Leitura.ObstaculoCritico : null,
(float)_Sensoriamento.Trajetoria.AnguloCaminho,
(float)_Sensoriamento.Gps.AnguloCarroDefinido,
_Sensoriamento.Gps,
_Trajetoria._TrajetoriaDinamica,
_Trajetoria.RetornandoBase ? new List<PontoTrajetoriaModel>() : _Trajetoria.CorredorAtual.Pontos,
Variaveis.OperacaoEmAndamento.GPSTrajetoria,
_Trajetoria.RuasPlantacao,
simulacao
);
}
if (!Variaveis.OperacaoEmAndamento.Iniciado)
{
if (btnIniciarSimulacao.Text.Contains("Parar"))
{
parar = true;
btnIniciarSimulacao_Click(new object(), new EventArgs());
parar = false;
}
Variaveis.OperacaoEmAndamento.Mapa.AtualizarRuasSelecionadas();
}
AtualizandoTela = false;
}
private void btnCarregar_Click(object sender, EventArgs e)
{
Variaveis.OperacaoEmAndamento.Mapa.btnCarregar_Click((Control) sender, e);
}
private void btnIniciarGPS_Click(object sender, EventArgs e)
{
posicaoAtual = new GPSModel()
{
DataHora = DateTime.Now,
Lon0 = double.Parse(txtLongitude.Text.Replace(".", ",")),
LongitudeAnt = double.Parse(txtLongitude.Text.Replace(".", ",")),
Longitude = double.Parse(txtLongitude.Text.Replace(".", ",")),
LatitudeAnt = double.Parse(txtLatitude.Text.Replace(".", ",")),
Lat0 = double.Parse(txtLatitude.Text.Replace(".", ",")),
Latitude = double.Parse(txtLatitude.Text.Replace(".", ",")),
Heartbeat = GPSService.UltimaLeitura.Heartbeat,
OrientacaoReal = double.Parse(txtAnguloGPS.Text.Replace(".", ",")),
};
AtualizarPosicaoGPS();
btnAcrescentarGPS.Enabled = true;
txtAnguloGPS.Enabled = true;
txtDistanciaGPS.Enabled = true;
//btnIniciarGPS.Enabled = false;
//txtLatitude.ReadOnly = true;
//txtLongitude.ReadOnly = true;
}
private void AtualizarPosicaoGPS()
{
GPSService.PenultimaLeitura = new GPSModel()
{
DataHora = GPSService.UltimaLeitura.DataHora,
Longitude = GPSService.UltimaLeitura.Longitude,
LongitudeAnt = GPSService.UltimaLeitura.LongitudeAnt,
Latitude = GPSService.UltimaLeitura.Latitude,
LatitudeAnt = GPSService.UltimaLeitura.LatitudeAnt,
Heartbeat = GPSService.UltimaLeitura.Heartbeat,
OrientacaoReal = GPSService.UltimaLeitura.OrientacaoReal
};
if (!GPSService.Iniciado || (txtLongitude.Text != "" && txtLatitude.Text != ""))
{
GPSService.UltimaLeitura = posicaoAtual;
}
GPSService.AtualizarAtrasoPosicoes(Convert.ToInt32(txtDelayPosicao.Text));
GPSService.AtualizarCoordenadasGPS();
}
private async void btnAcrescentarGPS_Click(object sender, EventArgs e)
{
GPSModel novaPosicao = null;
velocidadeCarroMs = FuncoesMatematicas.CalculaVelocidadeMsPercentual(Variaveis.OperacaoEmAndamento.SimulacaoRpmControle);
if (Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Mov).DirecaoAtual == Direcao.Tras)
velocidadeCarroMs *= -1;
//Console.WriteLine($"RPM SP: {Variaveis.OperacaoEmAndamento.SimulacaoRpmControle} ({velocidadeCarroMs:F2} ms)");
Variaveis.OperacaoEmAndamento.DispMvd.Dados.VelocidadeMedia = velocidadeCarroMs;
double tempoPassado =
!chbAutomatico.Checked || UltimaAtualizacaoGps == DateTime.MinValue ? // esta no modo manual
(tempoGps / 1000.0) : // 1 tick do tempo gps
(DateTime.Now - UltimaAtualizacaoGps).TotalSeconds; // tempo decorrido entre ticks do timer de leitura
// Obtém os parâmetros
double anguloAtual = double.Parse(txtAnguloGPS.Text);
var _Gps = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps;
double anguloControle = 0.0;
TipoMovimentoDirecional tipoMovimento = Variaveis.OperacaoEmAndamento.Controle.TipoMovimento;
double veloccidade = (Variaveis.OperacaoEmAndamento.StatusAtual == StatusOperacao.Concluido || Variaveis.OperacaoEmAndamento.StatusAtual == StatusOperacao.Aguardando) ? 0 : velocidadeCarroMs;
var tipoControle = Variaveis.OperacaoEmAndamento.Parametros.Controle.DirTipoMovimento;
if (passosOperacao.Count > 0 && Variaveis.OperacaoEmAndamento.Simulando)
{
novaPosicao = passosOperacao[Math.Min(passosOperacao.Count - 1, idxPassoOperacao)];
idxPassoOperacao++;
}
else
{
anguloControle = double.Parse(txtAnguloControle.Text);
bool atualizarAnguloControle = (ticksControle >= ticksControleMax);
if (atualizarAnguloControle)
{
ticksControle = 0;
}
else
{
ticksControle++;
}
if (atualizarAnguloControle)
{
btnCalcularAngulo_Click(new object(), new EventArgs());
anguloControle = double.Parse(txtAnguloControle.Text);
}
}
// Calcula a nova posicao do robo
//GPSModel pos = NovaPosicaoSimulacao(velocidadeMs, tempoPassado);
if (novaPosicao == null)
{
novaPosicao = VariaveisEquipamento.SimularNovaPosicao(tipoMovimento, anguloControle, veloccidade, tempoPassado, anguloAtual, _Gps);
}
posicaoAtual = novaPosicao;
//Console.WriteLine($"C#: {DadosPosicao(novaPosicao)}");
//Console.WriteLine($"Py: {DadosPosicao(pos)}");
// Atualiza a interface gráfica
txtAnguloGPS.Text = posicaoAtual.OrientacaoReal.ToString("0.00");
txtVelocidade.Text = veloccidade.ToString("0.00");
txtDistanciaGPS.Text = posicaoAtual.Distancia.ToString("0.0000");
txtLatitude.Text = posicaoAtual.Latitude.ToString();
txtLongitude.Text = posicaoAtual.Longitude.ToString();
UltimaAtualizacaoGps = DateTime.Now;
AtualizarPosicaoGPS();
Variaveis.OperacaoEmAndamento.Sensoriamento.AtualizarDados();
if (!chbAutomatico.Checked)
{
AtualizarDadosTela();
}
}
private GPSModel NovaPosicaoSimulacao(double velocidadeMs, double tempo)
{
if (Variaveis.OperacaoEmAndamento.Controle.SimulacaoMPC.Count() > 1)
{
double distancia = velocidadeMs * tempo;
MPCSimulacaoModel posicao = Variaveis.OperacaoEmAndamento.Controle.SimulacaoMPC[1];
GPSModel novaPosicao = new GPSModel()
{
Latitude = posicao.latitude,
Longitude = posicao.longitude,
OrientacaoReal = posicao.orientacao,
Distancia = distancia,
};
return novaPosicao;
}
return null;
}
private string DadosPosicao(GPSModel pos)
{
if (pos == null) return "";
return $"Lat: {pos.Latitude}, Long: {pos.Longitude}, Theta: {pos.OrientacaoReal}, Distancia: {pos.Distancia}";
}
private void btnIniciarSimulacao_Click(object sender, EventArgs e)
{
if (!Variaveis.OperacaoEmAndamento.Mapa.RuasPercorrer.Any())
{
MessageBox.Show("Selecione as ruas para realizar a operação!");
return;
}
if (!Variaveis.OperacaoEmAndamento.Iniciado && !parar)
{
Variaveis.OperacaoEmAndamento.IniciarSimulacao();
}
btnIniciarSimulacao.Text = Variaveis.OperacaoEmAndamento.Iniciado ? "Parar Simulação" : "Iniciar Simulação";
if (Variaveis.OperacaoEmAndamento.Iniciado)
{
GPSService.PenultimaLeitura.Latitude = GPSService.UltimaLeitura.Latitude;
GPSService.PenultimaLeitura.Longitude = GPSService.UltimaLeitura.Longitude;
//Variaveis.OperacaoEmAndamento.Mapa.GerarTrajetoriaDinamica();
AtualizarDadosTela();
}
}
private void btnCarregarMapa_Click(object sender, EventArgs e)
{
Variaveis.OperacaoEmAndamento.Mapa.btnCarregar_Click((Control)sender, e);
}
private void btnCarregarOperacao_Click(object sender, EventArgs e)
{
passosOperacao = new List<GPSModel>();
txtTempoGPS.Text = tempoGps.ToString();
idxPassoOperacao = 0;
lblCarregado.Text = "Simulador";
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Arquivos de Operação|*.lgop";
ofd.InitialDirectory = Application.StartupPath + "\\" + Variaveis.CaminhoOperacoes;
if (ofd.ShowDialog() == DialogResult.OK)
{
OperacaoDadosModel data = JsonConvert.DeserializeObject<OperacaoDadosModel>(File.ReadAllText(ofd.FileName));
passosOperacao = JsonConvert.DeserializeObject<GPSModel[]>(OperacaoModel.DeserializarDadosOperacao(ofd.FileName, T_Code.Gps.ToString())).ToList();
txtTempoGPS.Text = "1000";
lblCarregado.Text = "Operação";
}
}
private void btnCarregarTrajetoria_Click(object sender, EventArgs e)
{
passosOperacao = new List<GPSModel>();
txtTempoGPS.Text = tempoGps.ToString();
idxPassoOperacao = 0;
lblCarregado.Text = "Simulador";
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Arquivos de Trajetória|*.json";
ofd.InitialDirectory = Application.StartupPath + "\\" + Variaveis.CaminhoMapasConvertidos;
if (ofd.ShowDialog() == DialogResult.OK)
{
var DadosMapa = JsonConvert.DeserializeObject<MapaFeatureCollectionModel>(File.ReadAllText(ofd.FileName));
passosOperacao = DadosMapa.features[0].geometry.coordinates
.Select(x => new GPSModel()
{
Latitude = x[1],
Longitude = x[0]
})
.ToList();
txtTempoGPS.Text = "200";
lblCarregado.Text = "Trajetória";
}
}
private void pnlOrientacaoTrajeto_Paint(object sender, PaintEventArgs e)
{
try
{
//double angulo = Variaveis.OperacaoEmAndamento.Trajetoria.AnguloCaminho;
//double anguloCorredor = Variaveis.OperacaoEmAndamento.Trajetoria.AnguloMedioCorredor;
double angulo = Variaveis.OperacaoEmAndamento.Trajetoria?.ProximoPonto?.Orientacao ?? 0;
double anguloCorredor = Variaveis.OperacaoEmAndamento.Trajetoria?.AnguloCaminho ?? 0;
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90, (float)anguloCorredor);
}
catch { }
}
private void pnlOrientacaoCarro_Paint(object sender, PaintEventArgs e)
{
try
{
double angulo = Variaveis.OperacaoEmAndamento.Sensoriamento?.Gps?.AnguloCarroDefinido ?? 0;
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90);
}
catch { }
}
private void pnlAnguloControle_Paint(object sender, PaintEventArgs e)
{
try
{
double angulo = Variaveis.OperacaoEmAndamento.SimulacaoAnguloControle;
double dif = Variaveis.OperacaoEmAndamento.Sensoriamento?.Trajetoria?.ErroOrientacaoAngularProximoPonto ?? 0;
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90, (float)dif);
}
catch { }
}
private void btnAtualizarLeitura_Click(object sender, EventArgs e)
{
AtualizarDadosTela();
}
private void btnCalcularAngulo_Click(object sender, EventArgs e)
{
historicoAngulosControle.Enqueue(Variaveis.OperacaoEmAndamento.SimulacaoAnguloControle);
int errosConsiderar = int.Parse(txtDelayComando.Text);
while (historicoAngulosControle.Count > 1 && (historicoAngulosControle.Count > errosConsiderar || errosConsiderar == 0))
{
historicoAngulosControle.Dequeue();
}
txtAnguloControle.Text = historicoAngulosControle.Peek().ToString("0.00");
}
private void chbSonarVirando_CheckedChanged(object sender, EventArgs e)
{
}
private void chbAutomatico_CheckedChanged(object sender, EventArgs e)
{
UltimaAtualizacaoGps = DateTime.MinValue;
}
private void btnReiniciar_Click(object sender, EventArgs e)
{
Variaveis.OperacaoEmAndamento.ReiniciarSimulacao();
frmSimulacaoMapaGPS frm = new frmSimulacaoMapaGPS();
frm.Show();
this.Close();
}
private void cmbTipoControleDirecional_SelectedIndexChanged(object sender, EventArgs e)
{
Variaveis.OperacaoEmAndamento.Parametros.Controle.DirTipoMovimento = (TiposControladorDirecional)cmbTipoControleDirecional.SelectedIndex;
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
}
private void cmbStatusCorredor_SelectedIndexChanged(object sender, EventArgs e)
{
var json = RedisService.Get(CtxKey.DadosVisualWorker);
if (string.IsNullOrWhiteSpace(json)) return;
JObject root;
try
{
root = JObject.Parse(json);
}
catch
{
return;
}
long tsUnix = root["ts_analise"]?.Value<long>() ?? 0;
RedisService.AtualizarCampos(
CtxKey.DadosVisualWorker,
("ts_analise", tsUnix + 1),
("segmentacao.status_corredor", cmbStatusCorredor.SelectedIndex)
);
}
private void chbAcompanharCarro_CheckedChanged(object sender, EventArgs e)
{
MapaDinamico.AlterarTravaRover(chbAcompanharCarro.Checked);
}
private void btnRetornarBase_Click(object sender, EventArgs e)
{
//OperacaoModel.CarregarParametrosOperacaoPadrao(ModoOperacao.RetornoBase, true);
Variaveis.OperacaoEmAndamento.Trajetoria.IniciarRetornoBase(VariaveisOperacao.PosicaoBase);
Variaveis.OperacaoEmAndamento.Simulando = true;
}
private void btnFixarBase_Click(object sender, EventArgs e)
{
VariaveisOperacao.PosicaoBase = new GPSModel()
{
DataHora = DateTime.Now,
Lon0 = double.Parse(txtLongitude.Text.Replace(".", ",")),
LongitudeAnt = double.Parse(txtLongitude.Text.Replace(".", ",")),
Longitude = double.Parse(txtLongitude.Text.Replace(".", ",")),
LatitudeAnt = double.Parse(txtLatitude.Text.Replace(".", ",")),
Lat0 = double.Parse(txtLatitude.Text.Replace(".", ",")),
Latitude = double.Parse(txtLatitude.Text.Replace(".", ",")),
Heartbeat = GPSService.UltimaLeitura.Heartbeat,
OrientacaoReal = double.Parse(txtAnguloGPS.Text.Replace(".", ",")),
};
GPSService.EnviarCoordenadasParaMapa(VariaveisOperacao.PosicaoBase.Latitude, VariaveisOperacao.PosicaoBase.Longitude, VariaveisOperacao.PosicaoBase.AnguloCarroDefinido, false, Variaveis.LoraBaseParametros.address);
}
private void btnLiberarCorredor_Click(object sender, EventArgs e)
{
int idx_corredor = (Variaveis.OperacaoEmAndamento.Trajetoria.CorredorAtual?.Idx ?? 0) + (Variaveis.OperacaoEmAndamento.Trajetoria.CorredorAtual?.Concluido ?? false ? 1 : 0);
Variaveis.OperacaoEmAndamento.Trajetoria.AtualizarDadosAutonomiaCorredor(idxCorredor: idx_corredor, bat_liberada: true, herb_liberado: true);
}
}
}