361 lines
12 KiB
C#
361 lines
12 KiB
C#
using OperationControl.Models;
|
|
using System.ComponentModel;
|
|
using System.Windows.Media;
|
|
using static AgroBase.Models.Enums;
|
|
using Brush = System.Windows.Media.Brush;
|
|
using Color = System.Windows.Media.Color;
|
|
using Key = System.Windows.Input.Key;
|
|
|
|
namespace OperationControl.ViewModels.Views.Operacao.Monitoramento
|
|
{
|
|
public class ControleManualViewModel : INotifyPropertyChanged
|
|
{
|
|
private bool _habilitado;
|
|
private double _velocidadePercentual = 40;
|
|
private double _anguloDirecional = 10;
|
|
private TipoMovimentoDirecional _tipoMovimentoSelecionado = TipoMovimentoDirecional.RodasDianteiras;
|
|
|
|
private bool _wPressionado;
|
|
private bool _aPressionado;
|
|
private bool _sPressionado;
|
|
private bool _dPressionado;
|
|
private bool _fPressionado;
|
|
|
|
private readonly HashSet<Key> _pressedKeys = new();
|
|
|
|
private Direcao _lastMovKey = Direcao.Parado;
|
|
private Direcao _lastDirKey = Direcao.Parado;
|
|
private bool _lastFreio = false;
|
|
|
|
public bool Habilitado
|
|
{
|
|
get => _habilitado;
|
|
set
|
|
{
|
|
if (_habilitado != value)
|
|
{
|
|
_habilitado = value;
|
|
OnPropertyChanged(nameof(StatusTexto));
|
|
OnPropertyChanged(nameof(TextoAjuda));
|
|
OnPropertyChanged(nameof(StatusBrush));
|
|
|
|
if (VariaveisControleOperacao.RoverEmFoco != null)
|
|
{
|
|
VariaveisControleOperacao.RoverEmFoco.Controle.MovimentoAutomatico = !value;
|
|
VariaveisControleOperacao.RoverEmFoco.Controle.DirecionalAutomatico = !value;
|
|
VariaveisControleOperacao.EnviarParametrosOperacao(new AgroBase.Models.Operacoes.OperacaoParametrosModel()
|
|
{
|
|
Controle = VariaveisControleOperacao.RoverEmFoco?.Controle
|
|
});
|
|
}
|
|
|
|
if (!value)
|
|
{
|
|
LimparTeclas();
|
|
EnviarNeutros();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public double VelocidadePercentual
|
|
{
|
|
get => _velocidadePercentual;
|
|
set
|
|
{
|
|
if (_velocidadePercentual != value)
|
|
{
|
|
_velocidadePercentual = value;
|
|
OnPropertyChanged(nameof(VelocidadePercentualTexto));
|
|
|
|
if (Habilitado)
|
|
RecalcularComandos();
|
|
}
|
|
}
|
|
}
|
|
|
|
public string VelocidadePercentualTexto => $"{VelocidadePercentual:0}%";
|
|
|
|
public double AnguloDirecional
|
|
{
|
|
get => _anguloDirecional;
|
|
set
|
|
{
|
|
if (_anguloDirecional != value)
|
|
{
|
|
_anguloDirecional = value;
|
|
OnPropertyChanged(nameof(AnguloTexto));
|
|
|
|
if (Habilitado)
|
|
RecalcularComandos();
|
|
}
|
|
}
|
|
}
|
|
|
|
public string AnguloTexto => $"{AnguloDirecional:+0;-0;0}°";
|
|
|
|
public TipoMovimentoDirecional TipoMovimentoSelecionado
|
|
{
|
|
get => _tipoMovimentoSelecionado;
|
|
set
|
|
{
|
|
if (_tipoMovimentoSelecionado != value)
|
|
{
|
|
_tipoMovimentoSelecionado = value;
|
|
if (Habilitado)
|
|
RecalcularComandos();
|
|
}
|
|
}
|
|
}
|
|
|
|
public List<TipoMovimentoDirecional> TiposMovimento { get; } =
|
|
Enum.GetValues(typeof(TipoMovimentoDirecional))
|
|
.Cast<TipoMovimentoDirecional>()
|
|
.ToList();
|
|
|
|
public bool WPressionado
|
|
{
|
|
get => _wPressionado;
|
|
private set
|
|
{
|
|
if (_wPressionado != value)
|
|
{
|
|
_wPressionado = value;
|
|
OnPropertyChanged(nameof(TeclaWBackground));
|
|
OnPropertyChanged(nameof(TeclaWBorder));
|
|
OnPropertyChanged(nameof(MovimentoAtualTexto));
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool APressionado
|
|
{
|
|
get => _aPressionado;
|
|
private set
|
|
{
|
|
if (_aPressionado != value)
|
|
{
|
|
_aPressionado = value;
|
|
OnPropertyChanged(nameof(TeclaABackground));
|
|
OnPropertyChanged(nameof(TeclaABorder));
|
|
OnPropertyChanged(nameof(DirecaoAtualTexto));
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool SPressionado
|
|
{
|
|
get => _sPressionado;
|
|
private set
|
|
{
|
|
if (_sPressionado != value)
|
|
{
|
|
_sPressionado = value;
|
|
OnPropertyChanged(nameof(TeclaSBackground));
|
|
OnPropertyChanged(nameof(TeclaSBorder));
|
|
OnPropertyChanged(nameof(MovimentoAtualTexto));
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool DPressionado
|
|
{
|
|
get => _dPressionado;
|
|
private set
|
|
{
|
|
if (_dPressionado != value)
|
|
{
|
|
_dPressionado = value;
|
|
OnPropertyChanged(nameof(TeclaDBackground));
|
|
OnPropertyChanged(nameof(TeclaDBorder));
|
|
OnPropertyChanged(nameof(DirecaoAtualTexto));
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool FPressionado
|
|
{
|
|
get => _fPressionado;
|
|
private set
|
|
{
|
|
if (_fPressionado != value)
|
|
{
|
|
_fPressionado = value;
|
|
OnPropertyChanged(nameof(TeclaFBackground));
|
|
OnPropertyChanged(nameof(TeclaFBorder));
|
|
OnPropertyChanged(nameof(FreioAtivoTexto));
|
|
OnPropertyChanged(nameof(FreioCardBackground));
|
|
OnPropertyChanged(nameof(FreioCardBorder));
|
|
OnPropertyChanged(nameof(MovimentoAtualTexto));
|
|
}
|
|
}
|
|
}
|
|
|
|
public Brush TeclaWBackground => WPressionado ? BrushFrom("#1D4ED8") : BrushFrom("#2D2D2D");
|
|
public Brush TeclaWBorder => WPressionado ? BrushFrom("#60A5FA") : BrushFrom("#555555");
|
|
|
|
public Brush TeclaABackground => APressionado ? BrushFrom("#1D4ED8") : BrushFrom("#2D2D2D");
|
|
public Brush TeclaABorder => APressionado ? BrushFrom("#60A5FA") : BrushFrom("#555555");
|
|
|
|
public Brush TeclaSBackground => SPressionado ? BrushFrom("#B45309") : BrushFrom("#2D2D2D");
|
|
public Brush TeclaSBorder => SPressionado ? BrushFrom("#F59E0B") : BrushFrom("#555555");
|
|
|
|
public Brush TeclaDBackground => DPressionado ? BrushFrom("#1D4ED8") : BrushFrom("#2D2D2D");
|
|
public Brush TeclaDBorder => DPressionado ? BrushFrom("#60A5FA") : BrushFrom("#555555");
|
|
|
|
public Brush TeclaFBackground => FPressionado ? BrushFrom("#7A2323") : BrushFrom("#2D2D2D");
|
|
public Brush TeclaFBorder => FPressionado ? BrushFrom("#D35B5B") : BrushFrom("#555555");
|
|
|
|
public Brush FreioCardBackground => FPressionado ? BrushFrom("#7A2323") : BrushFrom("#2B2B2B");
|
|
public Brush FreioCardBorder => FPressionado ? BrushFrom("#D35B5B") : BrushFrom("#555555");
|
|
|
|
public string MovimentoAtualTexto
|
|
{
|
|
get
|
|
{
|
|
if (FPressionado)
|
|
return "Freado";
|
|
|
|
if (WPressionado && !SPressionado) return "Frente";
|
|
if (SPressionado && !WPressionado) return "Ré";
|
|
if (WPressionado && SPressionado) return "Conflito";
|
|
return "Parado";
|
|
}
|
|
}
|
|
|
|
public string DirecaoAtualTexto
|
|
{
|
|
get
|
|
{
|
|
if (APressionado && !DPressionado) return "Esquerda";
|
|
if (DPressionado && !APressionado) return "Direita";
|
|
if (APressionado && DPressionado) return "Conflito";
|
|
return "Centralizado";
|
|
}
|
|
}
|
|
|
|
public string FreioAtivoTexto => FPressionado ? "Freio Ativo" : "Freio Inativo";
|
|
|
|
public string StatusTexto => !Habilitado ? "INATIVO" : "PRONTO";
|
|
|
|
public string TextoAjuda => !Habilitado
|
|
? "Habilite o controle por teclado para começar."
|
|
: "Clique na tela de operação e use W, A, S, D e F para controlar o rover.";
|
|
|
|
public Brush StatusBrush => !Habilitado ? BrushFrom("#6B7280") : BrushFrom("#22C55E");
|
|
|
|
public void HandleKeyDown(Key key)
|
|
{
|
|
if (!Habilitado)
|
|
return;
|
|
|
|
if (_pressedKeys.Contains(key))
|
|
return;
|
|
|
|
_pressedKeys.Add(key);
|
|
AtualizarEstadoTeclas();
|
|
RecalcularComandos();
|
|
}
|
|
|
|
public void HandleKeyUp(Key key)
|
|
{
|
|
if (_pressedKeys.Remove(key))
|
|
{
|
|
AtualizarEstadoTeclas();
|
|
RecalcularComandos();
|
|
}
|
|
}
|
|
|
|
public void LimparTeclas()
|
|
{
|
|
_pressedKeys.Clear();
|
|
AtualizarEstadoTeclas();
|
|
}
|
|
|
|
private void AtualizarEstadoTeclas()
|
|
{
|
|
WPressionado = _pressedKeys.Contains(Key.W) || _pressedKeys.Contains(Key.Up);
|
|
APressionado = _pressedKeys.Contains(Key.A) || _pressedKeys.Contains(Key.Left);
|
|
SPressionado = _pressedKeys.Contains(Key.S) || _pressedKeys.Contains(Key.Down);
|
|
DPressionado = _pressedKeys.Contains(Key.D) || _pressedKeys.Contains(Key.Right);
|
|
FPressionado = _pressedKeys.Contains(Key.F) || _pressedKeys.Contains(Key.Space);
|
|
}
|
|
|
|
private void RecalcularComandos()
|
|
{
|
|
var dir = ObterDirecaoDirecional();
|
|
var mov = ObterDirecaoMovimentacao();
|
|
var freio = FPressionado;
|
|
|
|
if (_lastDirKey != dir)
|
|
{
|
|
VariaveisControleOperacao.EnviarComandoDirecionalUDP(dir, Convert.ToInt32(AnguloDirecional), TipoMovimentoSelecionado);
|
|
|
|
_lastDirKey = dir;
|
|
}
|
|
|
|
if (_lastMovKey != mov || _lastFreio != freio)
|
|
{
|
|
VariaveisControleOperacao.EnviarComandoMovimentacaoUDP(mov, Convert.ToInt32(VelocidadePercentual), freio);
|
|
|
|
_lastMovKey = mov;
|
|
_lastFreio = freio;
|
|
}
|
|
}
|
|
|
|
private Direcao ObterDirecaoDirecional()
|
|
{
|
|
if (APressionado && !DPressionado)
|
|
return Direcao.Esquerda;
|
|
|
|
if (DPressionado && !APressionado)
|
|
return Direcao.Direita;
|
|
|
|
return Direcao.Parado;
|
|
}
|
|
|
|
private Direcao ObterDirecaoMovimentacao()
|
|
{
|
|
if (FPressionado)
|
|
return Direcao.Parado;
|
|
|
|
if (WPressionado && !SPressionado)
|
|
return Direcao.Cima;
|
|
|
|
if (SPressionado && !WPressionado)
|
|
return Direcao.Baixo;
|
|
|
|
return Direcao.Parado;
|
|
}
|
|
|
|
private void EnviarNeutros()
|
|
{
|
|
if (_lastDirKey != Direcao.Parado)
|
|
{
|
|
VariaveisControleOperacao.EnviarComandoDirecionalUDP(Direcao.Parado, Convert.ToInt32(AnguloDirecional), TipoMovimentoSelecionado);
|
|
|
|
_lastDirKey = Direcao.Parado;
|
|
}
|
|
|
|
if (_lastMovKey != Direcao.Parado || _lastFreio)
|
|
{
|
|
VariaveisControleOperacao.EnviarComandoMovimentacaoUDP(Direcao.Parado, 0, false);
|
|
|
|
_lastMovKey = Direcao.Parado;
|
|
_lastFreio = false;
|
|
}
|
|
}
|
|
|
|
private Brush BrushFrom(string hex)
|
|
{
|
|
return new SolidColorBrush((Color)System.Windows.Media.ColorConverter.ConvertFromString(hex));
|
|
}
|
|
|
|
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
private void OnPropertyChanged(string nome)
|
|
{
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome));
|
|
}
|
|
}
|
|
} |