agrobot_base/AgroBase/AgroBase/Forms/IHM/frmDialogoMapa.cs

553 lines
23 KiB
C#

using AgroBase.Models;
using AgroBase.Models.Components;
using AgroBase.Services;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AgroBase.Forms.IHM
{
public partial class frmDialogoMapa : Form
{
AsyncTaskTimerModel tmrLeitura;
MapaDinamicoModel MapaDinamico;
private ulong CodigoFalha = 0;
public frmDialogoMapa()
{
InitializeComponent();
// Ativa o double buffering
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
pnlJoystick.GetType().GetMethod("SetStyle", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).Invoke(pnlJoystick, new object[] { ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true });
pnlFreio.GetType().GetMethod("SetStyle", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).Invoke(pnlFreio, new object[] { ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true });
cmbModoControle.Items.Clear();
cmbModoControle.Items.AddRange(Enum.GetNames(typeof(Enums.TipoMovimentoDirecional)));
cmbModoControle.SelectedIndexChanged += CmbModoControle_SelectedIndexChanged;
AtualizarElementosModoManual();
MapaDinamico = new MapaDinamicoModel(this, pnlMapaDinamico);
FuncoesGlobais.DefinirEventosPicBtn(picFechar, "", async () =>
{
if (Variaveis.OperacaoEmAndamento.Iniciado)
{
var res = CustomDialog.ShowDialog(
"Interromper Operação",
"Tem certeza que deseja interromper a operação em andamento?",
MessageBoxIcon.Question,
new Dictionary<(string, DialogResult?), Action>()
{
{ ("Sim", DialogResult.Yes), () => { } },
{ ("Não", DialogResult.No), () => { } },
}
);
if (res == DialogResult.Yes)
{
await Variaveis.OperacaoEmAndamento.FinalizarOperacao();
if (Variaveis.OperacaoEmAndamento.Modo == Enums.ModoOperacao.Manual)
{
this.Close();
}
}
}
else
{
this.Hide();
}
});
}
private void frmDialogoMapa_Load(object sender, EventArgs e)
{
tmrLeitura?.Dispose();
tmrLeitura = new AsyncTaskTimerModel("tmrLeitura", tmrLeitura_Tick, 500, this);
tmrLeitura.Start();
tkbAnguloDirecional.Minimum = 0;
tkbAnguloDirecional.Maximum = Convert.ToInt32(Variaveis.OperacaoEmAndamento.Controle.Angulo_Max);
if (!Variaveis.OperacaoEmAndamento.Controle.SegmentacaoSemantica && KinectService.Iniciado)
{
PictureBox picRgb = new PictureBox();
picRgb.SizeMode = PictureBoxSizeMode.StretchImage;
picRgb.Dock = DockStyle.Fill;
KinectService.picRGB = picRgb;
pnlCameraCaminho.Controls.Add(picRgb);
}
}
private void frmDialogoMapa_FormClosing(object sender, FormClosingEventArgs e)
{
tmrLeitura.Dispose();
Variaveis.OperacaoEmAndamento.DesligarCameras();
}
public async Task AtualizarRuasSelecionadas(List<string> ruasSelecionadas)
{
Variaveis.OperacaoEmAndamento.AtualizaListaCameras(new List<Panel>() { pnlCameraCaminho }, new List<Panel>(){ pnlCameraSoloE, pnlCameraSoloD }, true);
await Task.Delay(1000);
GPSService.AtualizarRuasSelecionadas(ruasSelecionadas);
}
public void IniciarOperacao()
{
Task.Run(async () => {
await Variaveis.OperacaoEmAndamento.IniciarOperacao();
//InicializarModoManual();
});
}
public void AtualizarMapaDinamico()
{
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
var _Trajetoria = Variaveis.OperacaoEmAndamento.Trajetoria;
MapaDinamico.AtualizarDados(
KinectService.Iniciado && KinectService.Leitura.StatusDetecao ? KinectService.Leitura.ObstaculoCritico : null,
(float)_Sensoriamento.Trajetoria.AnguloCaminho,
(float)_Sensoriamento.Gps.AnguloCarroDefinido,
_Sensoriamento.Gps,
_Trajetoria._TrajetoriaDinamica,
_Trajetoria.CorredorAtual.Pontos,
Variaveis.OperacaoEmAndamento.GPSTrajetoria,
_Trajetoria.RuasPlantacao
);
}
private async Task tmrLeitura_Tick()
{
pnlOrientacao.Invalidate();
pnlInclinacao.Invalidate();
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
var ultimaLeitura = Variaveis.OperacaoEmAndamento.CamerasSolo.OrderByDescending(x => x.Leitura.timestamp).FirstOrDefault();
if (ultimaLeitura != null)
{
lblUltimaLeituraSolo.Text = "Última Leitura Solo: " + FuncoesGlobais.TimestampToDate(ultimaLeitura.Leitura.timestamp);
}
if (Variaveis.OperacaoEmAndamento.CameraCaminho != null)
{
lblUltimaLeituraCaminho.Text = "Última Leitura Caminho: " + FuncoesGlobais.TimestampToDate(Variaveis.OperacaoEmAndamento.CameraCaminho.Leitura.timestamp);
}
lblPerformance.Text = _Sensoriamento.DadosPerformance.PerformanceStr;
lblMapaCarregado.Text = "Operação: " + Variaveis.OperacaoEmAndamento.Descricao;
txtModoOperacao.Text = Variaveis.OperacaoEmAndamento.Modo.ToString();
bool opLiberada = _Sensoriamento.OperacaoLiberada;
txtOperacaoLiberada.Text = opLiberada ? "Sim" : "Não";
txtOperacaoLiberada.ForeColor = opLiberada ? Color.Black : Color.Red;
CodigoFalha = _Sensoriamento.CodigoFalha;
btnCodFalha.Text = CodigoFalha.ToString();
txtStatusAtual.Text = _Sensoriamento.StatusOperacao.ToString();
txtIniciadoEm.Text = _Sensoriamento.DataInicio == DateTime.MinValue ? "Aguardando" : _Sensoriamento.DataInicio.ToString("dd/MM HH:mm:ss");
txtConcluidoEm.Text = _Sensoriamento.DataFim == DateTime.MinValue ? "-" : _Sensoriamento.DataFim.ToString("dd/MM HH:mm:ss");
txtDistanciaPercorrida.Text = _Sensoriamento.Trajetoria.DistanciaPercorrida.ToString("0.00") + " m";
txtTempoOperacao.Text = _Sensoriamento.TempoDecorrido.ToString("HH:mm:ss");
txtErvasIdentificadas.Text = _Sensoriamento.Atuador.QtdErvasIdentificadas.ToString();
txtHerbicidaAplicado.Text = _Sensoriamento.Atuador.HerbicidaConsumido.ToString("0.000") + " L";
txtBateriaConsumida.Text = _Sensoriamento.Bateria.BateriaConsumida.ToString("0.00") + " %";
FuncoesGlobais.PreencheValorProgressBar(pgbReservatorio, _Sensoriamento.Atuador.PercentualReservatorio);
lblReservatorio.Text = "Reservatório: " + _Sensoriamento.Atuador.PercentualReservatorio.ToString("0.00") + "%";
FuncoesGlobais.PreencheValorProgressBar(pgbBateria, _Sensoriamento.Bateria.PorcentagemBateria);
lblBateria.Text = "Bateria: " + _Sensoriamento.Bateria.TensaoInstantanea.ToString("0.00") + "v " + _Sensoriamento.Bateria.CorrenteInstantanea.ToString("0.00") + "A " + _Sensoriamento.Bateria.PorcentagemBateria.ToString("0.00") + "%";
FuncoesGlobais.PreencheValorProgressBar(pgbOperacao, _Sensoriamento.Trajetoria.ProgressoTrajeto);
lblOperacao.Text = "Operação: " + _Sensoriamento.Trajetoria.ProgressoTrajeto.ToString("0.00") + "%";
FuncoesGlobais.PreencheValorProgressBar(pgbRuaAtual, _Sensoriamento.Trajetoria.CorredorAtual.Progresso);
lblRuaAtual.Text = "Rua Atual: " + _Sensoriamento.Trajetoria.CorredorAtual.Progresso.ToString("0.00") + "%";
lblCorrecaoGPS.Text = _Sensoriamento.Gps.QualidadeFix.ToString();
lblPrecisaoGPS.Text = $"Precisão: {_Sensoriamento.Gps.PrecisaoCm.ToString("0.00")} cm";
bool automatico = Variaveis.OperacaoEmAndamento.Modo != Enums.ModoOperacao.Manual;
cmbModoControle.Enabled = !automatico;
tkbVelocidade.Enabled = !automatico;
tkbAnguloDirecional.Enabled = !automatico;
pnlFreio.Enabled = !automatico;
if (automatico)
{
cmbModoControle.SelectedIndex = (int)_Sensoriamento.Controle.TipoMovimento;
tkbVelocidade.Value = Convert.ToInt32(_Sensoriamento.Controle.PercentualVelocidadeSP);
tkbAnguloDirecional.Value = Math.Abs(Convert.ToInt32(_Sensoriamento.Controle.Angulo));
}
txtDistanciasEsqDir.Text = _Sensoriamento.Trajetoria.DistanciaEsquerda.ToString("0.00") + " / " + _Sensoriamento.Trajetoria.DistanciaDireita.ToString("0.00");
txtDentroCorredor.Text = _Sensoriamento.Trajetoria.CorredorAtual.Dentro ? "Sim" : "Não";
txtMargemCorredor.Text = _Sensoriamento.Trajetoria.NaMargemDoCorredor ? "Sim" : "Não";
txtStatusCarro.Text = _Sensoriamento.Trajetoria.StatusCarro.ToString();
var ModET = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.FirstOrDefault(x => x.Modulo_ID == "ET");
txtET.Text = (ModET?.MovMotor?.Corrente_Motor ?? 0).ToString("0.00");
lblET.ForeColor = (ModET?.Conectado ?? false) ? Color.Green : Color.Red;
var ModDT = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.FirstOrDefault(x => x.Modulo_ID == "DT");
txtDT.Text = (ModDT?.MovMotor?.Corrente_Motor ?? 0).ToString("0.00");
lblDT.ForeColor = (ModDT?.Conectado ?? false) ? Color.Green : Color.Red;
var ModEF = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.FirstOrDefault(x => x.Modulo_ID == "EF");
txtEF.Text = (ModEF?.MovMotor?.Corrente_Motor ?? 0).ToString("0.00");
lblEF.ForeColor = (ModEF?.Conectado ?? false) ? Color.Green : Color.Red;
var ModDF = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.FirstOrDefault(x => x.Modulo_ID == "DF");
txtDF.Text = (ModDF?.MovMotor?.Corrente_Motor ?? 0).ToString("0.00");
lblDF.ForeColor = (ModDF?.Conectado ?? false) ? Color.Green : Color.Red;
if (!Variaveis.Producao)
{
AtualizarMapaDinamico();
}
}
private void pnlOrientacao_Paint(object sender, PaintEventArgs e)
{
try
{
double angulo = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.AnguloCarroDefinido;
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90, (float)Variaveis.OperacaoEmAndamento.Sensoriamento.Trajetoria.AnguloCaminho);
}
catch { }
}
private void pnlInclinacao_Paint(object sender, PaintEventArgs e)
{
try
{
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)(Variaveis.OperacaoEmAndamento.Controle.Angulo), 90);
}
catch { }
}
#region MODO MANUAL
private Point joystickCenter;
private bool isDragging = false;
private Keys prevMovKey = Keys.None;
private Keys prevDirKey = Keys.None;
private int joystickRadius;
private Point joystickPosition;
private Point freioPosition;
private Point freioStartPosition;
private bool isDraggingFreio = false;
private bool isBrakeLocked = false;
private void AtualizarElementosModoManual()
{
cmbModoControle.Enabled = false;
tkbAnguloDirecional.Enabled = false;
tkbVelocidade.Enabled = false;
pnlJoystick.Visible = false;
cmbModoControle.SelectedIndex = (int)Variaveis.OperacaoEmAndamento.Controle.TipoMovimento;
FuncoesGlobais.PreencheValorTrackBar(tkbAnguloDirecional, Variaveis.OperacaoEmAndamento.Controle.Angulo);
FuncoesGlobais.PreencheValorTrackBar(tkbVelocidade, Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP);
tkbVelocidade_Scroll(null, null);
tkbAnguloDirecional_Scroll(null, null);
}
public void InicializarModoManual()
{
AtualizarElementosModoManual();
Variaveis.OperacaoEmAndamento.Mapa = new MapasModel()
{
pnlMapa = pnlMapa,
lblMapa = lblMapaCarregado
};
Variaveis.OperacaoEmAndamento.Mapa.CarregarMapaGPS();
cmbModoControle.Enabled = true;
tkbVelocidade.Enabled = true;
tkbAnguloDirecional.Enabled = true;
pnlJoystick.Visible = true;
pnlFreio.Visible = true;
// Configurar o painel do joystick
pnlJoystick.BackColor = Color.LightGray; // Fundo semitransparente
// Definir região circular para o painel
System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();
path.AddEllipse(0, 0, pnlJoystick.Width, pnlJoystick.Height);
pnlJoystick.Region = new Region(path);
// Calcular o centro do joystick
joystickCenter = new Point(pnlJoystick.Width / 2, pnlJoystick.Height / 2);
// Definir o raio do joystick
joystickRadius = pnlJoystick.Width / 4;
joystickPosition = joystickCenter;
// Evento de pintura do painel
pnlJoystick.Paint += PanelJoystickBack_Paint;
// Eventos de toque/mouse
pnlJoystick.MouseDown += PanelJoystickBack_MouseDown;
pnlJoystick.MouseMove += PanelJoystickBack_MouseMove;
pnlJoystick.MouseUp += PanelJoystickBack_MouseUp;
pnlFreio.BackColor = Color.LightGray;
pnlFreio.BorderStyle = BorderStyle.FixedSingle;
// Eventos de toque/pressão
pnlFreio.Paint += BrakePanel_Paint;
pnlFreio.MouseDown += BrakePanel_MouseDown;
pnlFreio.MouseMove += BrakePanel_MouseMove;
pnlFreio.MouseUp += BrakePanel_MouseUp;
// Configuração inicial do freio
freioStartPosition = new Point(pnlFreio.Width / 2 - 20, 10);
freioPosition = freioStartPosition;
Variaveis.OperacaoEmAndamento.AtualizaListaCameras(new List<Panel>() { pnlCameraCaminho }, new List<Panel>() { pnlCameraSoloE, pnlCameraSoloD }, true);
IniciarOperacao();
}
#region JOYSTICK
private void PanelJoystickBack_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
e.Graphics.FillEllipse(Brushes.Red, joystickPosition.X - joystickRadius, joystickPosition.Y - joystickRadius, joystickRadius * 2, joystickRadius * 2);
}
private void PanelJoystickBack_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
}
private void PanelJoystickBack_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
// Calcula a nova posição do joystick
var mouseX = e.X;
var mouseY = e.Y;
var deltaX = mouseX - joystickCenter.X;
var deltaY = mouseY - joystickCenter.Y;
// Limitar o movimento do joystick ao círculo do painel
var distance = Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
var maxDistance = pnlJoystick.Width / 2;
if (distance > maxDistance)
{
deltaX = (int)(deltaX / distance * maxDistance);
deltaY = (int)(deltaY / distance * maxDistance);
}
joystickPosition = new Point(joystickCenter.X + deltaX, joystickCenter.Y + deltaY);
pnlJoystick.Invalidate(); // Redesenha o painel
// Enviar comandos de movimento ao robô
SendMovementCommand(deltaX, deltaY);
}
}
private void PanelJoystickBack_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
// Retorna o joystick ao centro
joystickPosition = joystickCenter;
pnlJoystick.Invalidate(); // Redesenha o painel
// Enviar comando de parada ao robô
SendMovementCommand(0, 0);
}
private void SendMovementCommand(int deltaX, int deltaY)
{
Keys MovKey = Keys.Escape;
if (deltaY < -10) MovKey = Keys.Up;
else if (deltaY > 10) MovKey = Keys.Down;
Keys DirKey = Keys.Escape;
if (deltaX < -10) DirKey = Keys.Left;
else if (deltaX > 10) DirKey = Keys.Right;
// Verifica se o estado da tecla de movimento mudou
if (MovKey != prevMovKey)
{
// Lógica para enviar comando ao robô baseado em MovKey
Console.WriteLine($"Movimento: MovKey={MovKey}");
GeneralJoystick.EnviaComandoMotor(MovKey, Enums.T_Code.Mov);
prevMovKey = MovKey; // Atualiza o estado anterior
}
// Verifica se o estado da tecla de direção mudou
if (DirKey != prevDirKey)
{
// Lógica para enviar comando ao robô baseado em DirKey
Console.WriteLine($"Direção: DirKey={DirKey}");
GeneralJoystick.EnviaComandoMotor(DirKey, Enums.T_Code.Dir);
prevDirKey = DirKey; // Atualiza o estado anterior
}
}
#endregion
#region FREIO
// Desenho do trilho e trava no painel do freio
private void BrakePanel_Paint(object sender, PaintEventArgs e)
{
Panel panel = sender as Panel;
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
// Desenhar trilha do freio (trajetória vertical)
e.Graphics.DrawLine(new Pen(Color.Black, 5), panel.Width / 2, 10, panel.Width / 2, panel.Height - 50);
// Desenhar a área de trava (na lateral direita)
e.Graphics.DrawRectangle(new Pen(Color.Blue, 3), panel.Width - 30, panel.Height - 60, 20, 40);
// Desenhar o botão de freio atual
e.Graphics.FillEllipse(Brushes.Red, freioPosition.X, freioPosition.Y, 40, 40);
}
// Iniciar o arraste
private void BrakePanel_MouseDown(object sender, MouseEventArgs e)
{
if (Variaveis.OperacaoEmAndamento.Modo != Enums.ModoOperacao.Manual)
{
return;
}
if (new Rectangle(freioPosition.X, freioPosition.Y, 40, 40).Contains(e.Location))
{
isDraggingFreio = true;
}
}
// Movimentar o botão de freio
private void BrakePanel_MouseMove(object sender, MouseEventArgs e)
{
if (Variaveis.OperacaoEmAndamento.Modo != Enums.ModoOperacao.Manual)
{
return;
}
if (isDraggingFreio)
{
// Calcula a posição ao arrastar
int deltaY = e.Y - freioPosition.Y;
int newPosX = freioPosition.X;
int newPosY = freioPosition.Y + deltaY;
// Limitar o movimento do freio ao trilho e destravar se o usuário mover para fora da trava
if (!isBrakeLocked || (isBrakeLocked && e.X < pnlFreio.Width - 30))
{
isBrakeLocked = false; // Destrava o freio se mover para fora
// Restringe o movimento vertical dentro da área do trilho
if (newPosY >= 10 && newPosY <= pnlFreio.Height - 50)
{
freioPosition = new Point(newPosX, newPosY);
pnlFreio.Invalidate(); // Redesenha o painel
// Enviar comando de freio
GeneralJoystick.EnviaComandoMotor(Keys.Space, Enums.T_Code.Mov);
}
}
// Verifica se o usuário está na área de trava
if (freioPosition.Y >= pnlFreio.Height - 90 && e.X >= pnlFreio.Width - 30)
{
isBrakeLocked = true; // Freio travado
freioPosition = new Point(pnlFreio.Width - 40, pnlFreio.Height - 60); // Posiciona o freio na trava
pnlFreio.Invalidate();
}
}
}
// Soltar o botão de freio
private void BrakePanel_MouseUp(object sender, MouseEventArgs e)
{
if (Variaveis.OperacaoEmAndamento.Modo != Enums.ModoOperacao.Manual)
{
return;
}
isDraggingFreio = false;
if (!isBrakeLocked)
{
// Se o freio não estiver travado, retorna à posição inicial
freioPosition = freioStartPosition;
pnlFreio.Invalidate(); // Redesenha o painel
// Enviar comando para desativar o freio
GeneralJoystick.EnviaComandoMotor(Keys.Escape, Enums.T_Code.Mov);
}
else
{
// Freio travado, mantém travado
GeneralJoystick.EnviaComandoMotor(Keys.Space, Enums.T_Code.Mov);
}
}
#endregion
private void CmbModoControle_SelectedIndexChanged(object sender, EventArgs e)
{
Variaveis.OperacaoEmAndamento.Controle.TipoMovimento = (Enums.TipoMovimentoDirecional)cmbModoControle.SelectedIndex;
}
private void tkbVelocidade_Scroll(object sender, EventArgs e)
{
Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP = tkbVelocidade.Value;
double Velocidade = FuncoesMatematicas.ConverteMsParaKmh(FuncoesMatematicas.CalculaVelocidadeMsPercentual(tkbVelocidade.Value));
lblVelocidade.Text = $"Velocidade: {tkbVelocidade.Value}% {Velocidade.ToString("0.00")} km/h";
}
private void tkbAnguloDirecional_Scroll(object sender, EventArgs e)
{
Variaveis.OperacaoEmAndamento.Controle.Angulo = tkbAnguloDirecional.Value;
lblAnguloDirecional.Text = $"Ângulo Direcional: {tkbAnguloDirecional.Value}°";
}
#endregion
private void btnCodFalha_Click(object sender, EventArgs e)
{
string DescricaoFalha = OperacaoModel.DescricaoCodigoFalha(CodigoFalha);
CustomDialog.ShowDialog(
"Código de Falha",
$"{DescricaoFalha}",
MessageBoxIcon.Question,
new Dictionary<(string, dynamic), Action>()
{
{ ("OK", null), () => { } },
}
);
}
}
}