interligado telas da ihm Mov, Atu, Nav e Parametrizacao

This commit is contained in:
Diego Freitas 2026-07-21 15:20:08 -03:00
parent 6337847fce
commit ac2a8e249c
29 changed files with 1268 additions and 1078 deletions

View File

@ -513,6 +513,7 @@
<Compile Include="Forms\IHM\frmOperacao.Designer.cs"> <Compile Include="Forms\IHM\frmOperacao.Designer.cs">
<DependentUpon>frmOperacao.cs</DependentUpon> <DependentUpon>frmOperacao.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Forms\IHM\FuncoesIHM.cs" />
<Compile Include="Forms\IHM\Operacao\HmiCompactMetricCard.cs"> <Compile Include="Forms\IHM\Operacao\HmiCompactMetricCard.cs">
<SubType>UserControl</SubType> <SubType>UserControl</SubType>
</Compile> </Compile>

View File

@ -1,4 +1,5 @@
using AgroBase.Forms.IHM.Controls; using AgroBase.Forms.IHM.Controls;
using AgroBase.Models;
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
@ -13,7 +14,7 @@ namespace AgroBase.Forms.IHM.Operacao.Parametros.Controls
private readonly Button _btnContinuo; private readonly Button _btnContinuo;
private readonly Button _btnIntermitente; private readonly Button _btnIntermitente;
private string _selectedMode = "Continuo"; private Enums.ModoAgitadorCalda _selectedMode = Enums.ModoAgitadorCalda.SemAgitacao;
public event EventHandler SelectedModeChanged; public event EventHandler SelectedModeChanged;
@ -50,9 +51,9 @@ namespace AgroBase.Forms.IHM.Operacao.Parametros.Controls
Controls.Add(layout); Controls.Add(layout);
_btnSemAgitacao.Click += delegate { SelectedMode = "SemAgitacao"; }; _btnSemAgitacao.Click += delegate { SelectedMode = Enums.ModoAgitadorCalda.SemAgitacao; };
_btnContinuo.Click += delegate { SelectedMode = "Continuo"; }; _btnContinuo.Click += delegate { SelectedMode = Enums.ModoAgitadorCalda.Continuo; };
_btnIntermitente.Click += delegate { SelectedMode = "Intermitente"; }; _btnIntermitente.Click += delegate { SelectedMode = Enums.ModoAgitadorCalda.Intermitente; };
AtualizarAparencia(); AtualizarAparencia();
} }
@ -80,9 +81,9 @@ namespace AgroBase.Forms.IHM.Operacao.Parametros.Controls
private void AtualizarAparencia() private void AtualizarAparencia()
{ {
AplicarEstado(_btnSemAgitacao, _selectedMode == "SemAgitacao"); AplicarEstado(_btnSemAgitacao, _selectedMode == Enums.ModoAgitadorCalda.SemAgitacao);
AplicarEstado(_btnContinuo, _selectedMode == "Continuo"); AplicarEstado(_btnContinuo, _selectedMode == Enums.ModoAgitadorCalda.Continuo);
AplicarEstado(_btnIntermitente, _selectedMode == "Intermitente"); AplicarEstado(_btnIntermitente, _selectedMode == Enums.ModoAgitadorCalda.Intermitente);
} }
private static void AplicarEstado(Button button, bool selecionado) private static void AplicarEstado(Button button, bool selecionado)
@ -103,24 +104,15 @@ namespace AgroBase.Forms.IHM.Operacao.Parametros.Controls
[Category("Dados")] [Category("Dados")]
[DefaultValue("Continuo")] [DefaultValue("Continuo")]
public string SelectedMode public Enums.ModoAgitadorCalda SelectedMode
{ {
get { return _selectedMode; } get { return _selectedMode; }
set set
{ {
string novo; if (_selectedMode == value)
if (string.Equals(value, "SemAgitacao", StringComparison.OrdinalIgnoreCase))
novo = "SemAgitacao";
else if (string.Equals(value, "Intermitente", StringComparison.OrdinalIgnoreCase))
novo = "Intermitente";
else
novo = "Continuo";
if (_selectedMode == novo)
return; return;
_selectedMode = novo; _selectedMode = value;
AtualizarAparencia(); AtualizarAparencia();
if (SelectedModeChanged != null) if (SelectedModeChanged != null)

View File

@ -1,4 +1,5 @@
using AgroBase.Forms.IHM.Controls; using AgroBase.Forms.IHM.Controls;
using AgroBase.Models;
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
@ -11,7 +12,7 @@ namespace AgroBase.Forms.IHM.Operacao.Parametros.Controls
{ {
private readonly Button _btnMpc; private readonly Button _btnMpc;
private readonly Button _btnPid; private readonly Button _btnPid;
private string _selectedMode = "MPC"; private Enums.TiposControladorDirecional _selectedMode = Enums.TiposControladorDirecional.MPC;
public event EventHandler SelectedModeChanged; public event EventHandler SelectedModeChanged;
@ -60,8 +61,8 @@ namespace AgroBase.Forms.IHM.Operacao.Parametros.Controls
Controls.Add(root); Controls.Add(root);
_btnMpc.Click += delegate { SelectedMode = "MPC"; }; _btnMpc.Click += delegate { SelectedMode = Enums.TiposControladorDirecional.MPC; };
_btnPid.Click += delegate { SelectedMode = "PID"; }; _btnPid.Click += delegate { SelectedMode = Enums.TiposControladorDirecional.PID; };
AtualizarAparencia(); AtualizarAparencia();
} }
@ -90,8 +91,8 @@ namespace AgroBase.Forms.IHM.Operacao.Parametros.Controls
private void AtualizarAparencia() private void AtualizarAparencia()
{ {
AplicarEstado(_btnMpc, _selectedMode == "MPC"); AplicarEstado(_btnMpc, _selectedMode == Enums.TiposControladorDirecional.MPC);
AplicarEstado(_btnPid, _selectedMode == "PID"); AplicarEstado(_btnPid, _selectedMode == Enums.TiposControladorDirecional.PID);
} }
private static void AplicarEstado(Button button, bool selected) private static void AplicarEstado(Button button, bool selected)
@ -112,19 +113,15 @@ namespace AgroBase.Forms.IHM.Operacao.Parametros.Controls
[Category("Dados")] [Category("Dados")]
[DefaultValue("MPC")] [DefaultValue("MPC")]
public string SelectedMode public Enums.TiposControladorDirecional SelectedMode
{ {
get { return _selectedMode; } get { return _selectedMode; }
set set
{ {
string novo = string.Equals(value, "PID", StringComparison.OrdinalIgnoreCase) if (_selectedMode == value)
? "PID"
: "MPC";
if (_selectedMode == novo)
return; return;
_selectedMode = novo; _selectedMode = value;
AtualizarAparencia(); AtualizarAparencia();
if (SelectedModeChanged != null) if (SelectedModeChanged != null)

View File

@ -15,6 +15,7 @@ namespace AgroBase.Forms.IHM.Controls.Operacao
DoubleBuffered = true; DoubleBuffered = true;
BackColor = HmiTheme.Surface; BackColor = HmiTheme.Surface;
Height = 24; Height = 24;
Width = 72;
MinimumSize = new Size(105, 22); MinimumSize = new Size(105, 22);
Margin = Padding.Empty; Margin = Padding.Empty;
Padding = new Padding(2, 0, 2, 1); Padding = new Padding(2, 0, 2, 1);
@ -77,5 +78,13 @@ namespace AgroBase.Forms.IHM.Controls.Operacao
get { return _lblValor.ForeColor; } get { return _lblValor.ForeColor; }
set { _lblValor.ForeColor = value; } set { _lblValor.ForeColor = value; }
} }
[Category("Layout")]
[DefaultValue(72)]
public int LarguraValor
{
get { return _lblValor.Width; }
set { _lblValor.Width = System.Math.Max(35, value); }
}
} }
} }

View File

@ -27,12 +27,7 @@ namespace AgroBase.Forms.IHM.Controls.Operacao
public HmiNozzleCard() public HmiNozzleCard()
{ {
SetStyle( SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);
ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.ResizeRedraw,
true);
DoubleBuffered = true; DoubleBuffered = true;
BackColor = HmiTheme.SurfaceRaised; BackColor = HmiTheme.SurfaceRaised;
@ -109,12 +104,7 @@ namespace AgroBase.Forms.IHM.Controls.Operacao
_nozzleGlyph.Click += HandleClick; _nozzleGlyph.Click += HandleClick;
} }
private static Label MakeLabel( private static Label MakeLabel(string text, float size, FontStyle style, Color color, ContentAlignment align)
string text,
float size,
FontStyle style,
Color color,
ContentAlignment align)
{ {
return new Label return new Label
{ {
@ -146,50 +136,16 @@ namespace AgroBase.Forms.IHM.Controls.Operacao
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
Color border = GetStateColor(_state); Color border = FuncoesIHM.CorPorStatusModulo(_state);
using (Pen glow = new Pen( using (Pen glow = new Pen(Color.FromArgb(45, border.R, border.G, border.B), 4F))
Color.FromArgb(45, border.R, border.G, border.B),
4F))
{ {
e.Graphics.DrawRectangle( e.Graphics.DrawRectangle(glow, 2, 2, Math.Max(1, Width - 5), Math.Max(1, Height - 5));
glow,
2,
2,
Math.Max(1, Width - 5),
Math.Max(1, Height - 5));
} }
using (Pen pen = new Pen(border, 1.3F)) using (Pen pen = new Pen(border, 1.3F))
{ {
e.Graphics.DrawRectangle( e.Graphics.DrawRectangle(pen, 0, 0, Math.Max(1, Width - 1), Math.Max(1, Height - 1));
pen,
0,
0,
Math.Max(1, Width - 1),
Math.Max(1, Height - 1));
}
}
private static Color GetStateColor(StatusModulo state)
{
switch (state)
{
case StatusModulo.Desconectado:
return HmiTheme.TextMuted;
case StatusModulo.Conectado:
return HmiTheme.Info;
case StatusModulo.Falha:
return HmiTheme.Danger;
case StatusModulo.Alerta:
return HmiTheme.Warning;
case StatusModulo.Operante:
default:
return HmiTheme.Success;
} }
} }

View File

@ -11,11 +11,13 @@ namespace AgroBase.Forms.IHM.Controls.Operacao
{ {
private readonly Label _lblTitulo; private readonly Label _lblTitulo;
private readonly Label _lblDirTitulo;
private readonly CheckBox _chkDir; private readonly CheckBox _chkDir;
private readonly Label _lblDirSp; private readonly Label _lblDirSp;
private readonly Label _lblDirAtual; private readonly Label _lblDirAtual;
private readonly Label _lblDirStatus; private readonly Label _lblDirStatus;
private readonly Label _lblMovTitulo;
private readonly CheckBox _chkMov; private readonly CheckBox _chkMov;
private readonly Label _lblMovSp; private readonly Label _lblMovSp;
private readonly Label _lblMovAtual; private readonly Label _lblMovAtual;
@ -25,13 +27,7 @@ namespace AgroBase.Forms.IHM.Controls.Operacao
public HmiWheelStatusCard() public HmiWheelStatusCard()
{ {
SetStyle( SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);
ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.ResizeRedraw,
true
);
DoubleBuffered = true; DoubleBuffered = true;
BackColor = HmiTheme.SurfaceRaised; BackColor = HmiTheme.SurfaceRaised;
@ -50,26 +46,11 @@ namespace AgroBase.Forms.IHM.Controls.Operacao
Padding = Padding.Empty Padding = Padding.Empty
}; };
root.ColumnStyles.Add( root.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
new ColumnStyle(SizeType.Percent, 100F) root.RowStyles.Add(new RowStyle(SizeType.Absolute, 18F));
); root.RowStyles.Add(new RowStyle(SizeType.Absolute, 1F));
root.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
// Título pequeno, liberando espaço para os dados. root.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
root.RowStyles.Add(
new RowStyle(SizeType.Absolute, 18F)
);
root.RowStyles.Add(
new RowStyle(SizeType.Absolute, 1F)
);
root.RowStyles.Add(
new RowStyle(SizeType.Percent, 50F)
);
root.RowStyles.Add(
new RowStyle(SizeType.Percent, 50F)
);
_lblTitulo = new Label _lblTitulo = new Label
{ {
@ -81,11 +62,7 @@ namespace AgroBase.Forms.IHM.Controls.Operacao
BackColor = Color.FromArgb(28, 34, 38), BackColor = Color.FromArgb(28, 34, 38),
ForeColor = HmiTheme.Text, ForeColor = HmiTheme.Text,
Font = new Font( Font = new Font("Segoe UI", 7.8F, FontStyle.Bold),
"Segoe UI",
7.8F,
FontStyle.Bold
),
Text = "EF", Text = "EF",
TextAlign = ContentAlignment.MiddleCenter, TextAlign = ContentAlignment.MiddleCenter,
@ -101,7 +78,7 @@ namespace AgroBase.Forms.IHM.Controls.Operacao
Margin = Padding.Empty Margin = Padding.Empty
}; };
var pnlDir = CriarBloco( (Panel pnlDir, Label lblDir) = CriarBloco(
"DIR", "DIR",
HmiTheme.Manual, HmiTheme.Manual,
out _chkDir, out _chkDir,
@ -110,7 +87,7 @@ namespace AgroBase.Forms.IHM.Controls.Operacao
out _lblDirStatus out _lblDirStatus
); );
var pnlMov = CriarBloco( (Panel pnlMov, Label lblMov) = CriarBloco(
"MOV", "MOV",
HmiTheme.Info, HmiTheme.Info,
out _chkMov, out _chkMov,
@ -119,11 +96,13 @@ namespace AgroBase.Forms.IHM.Controls.Operacao
out _lblMovStatus out _lblMovStatus
); );
_lblDirTitulo = lblDir;
_lblDirSp.Text = "SP +0,0°"; _lblDirSp.Text = "SP +0,0°";
_lblDirAtual.Text = "AT +0,0°"; _lblDirAtual.Text = "AT +0,0°";
_lblDirStatus.Text = "Parado"; _lblDirStatus.Text = "Parado";
_lblDirStatus.ForeColor = HmiTheme.Success; _lblDirStatus.ForeColor = HmiTheme.Success;
_lblMovTitulo = lblMov;
_lblMovSp.Text = "SP 0 rpm"; _lblMovSp.Text = "SP 0 rpm";
_lblMovAtual.Text = "AT 0 rpm"; _lblMovAtual.Text = "AT 0 rpm";
_lblMovStatus.Text = "Sem freio"; _lblMovStatus.Text = "Sem freio";
@ -142,13 +121,7 @@ namespace AgroBase.Forms.IHM.Controls.Operacao
_chkMov.BringToFront(); _chkMov.BringToFront();
} }
private static Panel CriarBloco( private static (Panel, Label) CriarBloco(string titulo, Color corTitulo, out CheckBox check, out Label lblSp, out Label lblAtual, out Label lblStatus)
string titulo,
Color corTitulo,
out CheckBox check,
out Label lblSp,
out Label lblAtual,
out Label lblStatus)
{ {
var panel = new Panel var panel = new Panel
{ {
@ -168,25 +141,11 @@ namespace AgroBase.Forms.IHM.Controls.Operacao
Padding = Padding.Empty Padding = Padding.Empty
}; };
layout.ColumnStyles.Add( layout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
new ColumnStyle(SizeType.Percent, 100F) layout.RowStyles.Add(new RowStyle(SizeType.Absolute, 18F));
); layout.RowStyles.Add(new RowStyle(SizeType.Percent, 30F));
layout.RowStyles.Add(new RowStyle(SizeType.Percent, 30F));
layout.RowStyles.Add( layout.RowStyles.Add(new RowStyle(SizeType.Percent, 40F));
new RowStyle(SizeType.Absolute, 18F)
);
layout.RowStyles.Add(
new RowStyle(SizeType.Percent, 30F)
);
layout.RowStyles.Add(
new RowStyle(SizeType.Percent, 30F)
);
layout.RowStyles.Add(
new RowStyle(SizeType.Percent, 40F)
);
var header = new Panel var header = new Panel
{ {
@ -203,11 +162,7 @@ namespace AgroBase.Forms.IHM.Controls.Operacao
BackColor = Color.Transparent, BackColor = Color.Transparent,
ForeColor = corTitulo, ForeColor = corTitulo,
Font = new Font( Font = new Font("Segoe UI", 6.6F, FontStyle.Bold),
"Segoe UI",
6.6F,
FontStyle.Bold
),
Text = titulo, Text = titulo,
TextAlign = ContentAlignment.MiddleLeft, TextAlign = ContentAlignment.MiddleLeft,
@ -231,11 +186,7 @@ namespace AgroBase.Forms.IHM.Controls.Operacao
lblAtual = CriarLabelDado("AT 0"); lblAtual = CriarLabelDado("AT 0");
lblStatus = CriarLabelDado("Parado"); lblStatus = CriarLabelDado("Parado");
lblStatus.Font = new Font( lblStatus.Font = new Font("Segoe UI", 5.8F, FontStyle.Bold);
"Segoe UI",
5.8F,
FontStyle.Bold
);
layout.Controls.Add(header, 0, 0); layout.Controls.Add(header, 0, 0);
layout.Controls.Add(lblSp, 0, 1); layout.Controls.Add(lblSp, 0, 1);
@ -244,7 +195,7 @@ namespace AgroBase.Forms.IHM.Controls.Operacao
panel.Controls.Add(layout); panel.Controls.Add(layout);
return panel; return (panel, lblTitulo);
} }
private static Label CriarLabelDado(string texto) private static Label CriarLabelDado(string texto)
@ -333,20 +284,24 @@ namespace AgroBase.Forms.IHM.Controls.Operacao
public void AtualizarDados( public void AtualizarDados(
bool dir_em_uso, bool dir_em_uso,
StatusModulo dir_status,
double dir_ang_sp, double dir_ang_sp,
double dir_ang_at, double dir_ang_at,
Sentido dir_sentido, Sentido dir_sentido,
bool mov_em_uso, bool mov_em_uso,
StatusModulo mov_status,
double mov_vel_sp, double mov_vel_sp,
double mov_vel_at, double mov_vel_at,
bool mov_freio bool mov_freio
) )
{ {
_lblDirTitulo.ForeColor = FuncoesIHM.CorPorStatusModulo(dir_status);
CheckDir.Checked = dir_em_uso; CheckDir.Checked = dir_em_uso;
DirecionalSp = $"{dir_ang_sp}"; DirecionalSp = $"{dir_ang_sp}";
DirecionalAtual = $"{dir_ang_at}"; DirecionalAtual = $"{dir_ang_at}";
StatusDirecional = $"{dir_sentido}"; StatusDirecional = $"{dir_sentido}";
_lblMovTitulo.ForeColor = FuncoesIHM.CorPorStatusModulo(mov_status);
CheckMov.Checked = mov_em_uso; CheckMov.Checked = mov_em_uso;
MovimentoSp = $"{mov_vel_sp}"; MovimentoSp = $"{mov_vel_sp}";
MovimentoAtual = $"{mov_vel_at}"; MovimentoAtual = $"{mov_vel_at}";

View File

@ -0,0 +1,355 @@
using AgroBase.Forms.IHM.Controls;
using AgroBase.Models;
using System;
using System.Drawing;
using static AgroBase.Models.Enums;
namespace AgroBase.Forms.IHM
{
public class FuncoesIHM
{
public static Color MisturarCores(Color baseColor, Color accentColor, float pesoAccent)
{
pesoAccent = Math.Max(0F, Math.Min(1F, pesoAccent));
float pesoBase = 1F - pesoAccent;
return Color.FromArgb(
(int)(baseColor.R * pesoBase + accentColor.R * pesoAccent),
(int)(baseColor.G * pesoBase + accentColor.G * pesoAccent),
(int)(baseColor.B * pesoBase + accentColor.B * pesoAccent)
);
}
public static Color CorPorPercentual(double percentual)
{
percentual = Limitar(percentual, 0, 100);
if (percentual <= 50)
{
double fator = percentual / 50.0;
return InterpolarCor(HmiTheme.Danger, HmiTheme.Warning, fator);
}
double fatorVerde = (percentual - 50) / 50.0;
return InterpolarCor(HmiTheme.Warning, HmiTheme.Success, fatorVerde);
}
public static Color CorPorValorESaude(double valor, double saude)
{
double notaFinal = Math.Min(Limitar(valor, 0, 100), Limitar(saude, 0, 100));
return CorPorPercentual(notaFinal);
}
public static Color CorTemperatura(double temperatura, double saudeModulo)
{
Color corTemperatura;
if (temperatura <= 45)
{
corTemperatura = HmiTheme.Success;
}
else if (temperatura <= 60)
{
double fator = (temperatura - 45) / (60 - 45);
corTemperatura = InterpolarCor(HmiTheme.Success, HmiTheme.Warning, fator);
}
else if (temperatura <= 75)
{
double fator = (temperatura - 60) / (75 - 60);
corTemperatura = InterpolarCor(HmiTheme.Warning, HmiTheme.Danger, fator);
}
else
{
corTemperatura = HmiTheme.Danger;
}
Color corSaude = CorPorPercentual(saudeModulo);
/*
* Se a saúde estiver muito baixa,
* ela prevalece sobre a temperatura.
*/
if (saudeModulo < 40)
return corSaude;
return corTemperatura;
}
public static Color CorDistanciaBase(double distanciaMetros, double distanciaMaximaMetros)
{
if (double.IsNaN(distanciaMetros) || double.IsInfinity(distanciaMetros) || distanciaMetros < 0)
{
return HmiTheme.Danger;
}
double percentualSaudavel = 100 - (distanciaMetros / distanciaMaximaMetros * 100);
return CorPorPercentual(percentualSaudavel);
}
public static Color InterpolarCor(Color inicial, Color final, double fator)
{
fator = Limitar(fator, 0, 1);
int r = (int)Math.Round(inicial.R + (final.R - inicial.R) * fator);
int g = (int)Math.Round(inicial.G + (final.G - inicial.G) * fator);
int b = (int)Math.Round(inicial.B + (final.B - inicial.B) * fator);
return Color.FromArgb(r, g, b);
}
public static Color CorPorStatusModulo(StatusModulo state)
{
switch (state)
{
case StatusModulo.Desconectado:
return HmiTheme.TextMuted;
case StatusModulo.Conectado:
return HmiTheme.Info;
case StatusModulo.Falha:
return HmiTheme.Danger;
case StatusModulo.Alerta:
return HmiTheme.Warning;
case StatusModulo.Operante:
default:
return HmiTheme.Success;
}
}
public static Color CorPorAutonomia(double distanciaCapaz, double distanciaNecessaria, double limiar)
{
StatusModulo status = CalcularStatusAutonomiaCorredor(distanciaCapaz, distanciaNecessaria, limiar);
switch (status)
{
case StatusModulo.Operante:
return HmiTheme.Success;
case StatusModulo.Alerta:
return HmiTheme.Warning;
case StatusModulo.Falha:
return HmiTheme.Danger;
default:
return HmiTheme.Disabled;
}
}
public static Color CorPorErroNumerico(double atual, double sp, double limiarWarning, double limiarDanger)
{
double erro = Math.Abs(atual - sp);
if (erro >= Math.Abs(limiarDanger))
return HmiTheme.Danger;
if (erro >= Math.Abs(limiarWarning))
return HmiTheme.Warning;
return HmiTheme.Success;
}
public static Color CorPorErroAngular(double atual, double sp, double limiarWarning, double limiarDanger)
{
double erro = Math.Abs(CalcularErroAngular(atual, sp));
if (erro >= Math.Abs(limiarDanger))
return HmiTheme.Danger;
if (erro >= Math.Abs(limiarWarning))
return HmiTheme.Warning;
return HmiTheme.Success;
}
public static double NotaQualidadeGnss(TiposCorrecaoGPS qualidade)
{
switch (qualidade)
{
case TiposCorrecaoGPS.RTKFixo:
return 100;
case TiposCorrecaoGPS.BaseFix:
return 100;
case TiposCorrecaoGPS.RTKFlutuante:
return 78;
case TiposCorrecaoGPS.PPS:
return 65;
case TiposCorrecaoGPS.DGPS:
return 58;
case TiposCorrecaoGPS.DeadReckoing:
return 35;
case TiposCorrecaoGPS.Autonomo:
return 22;
case TiposCorrecaoGPS.SemCorrecao:
default:
return 0;
}
}
public static double NotaPrecisaoGnss(double precisaoCm)
{
if (precisaoCm <= 2)
return 100;
if (precisaoCm <= 5)
return InterpolarValor(precisaoCm, 2, 5, 100, 90);
if (precisaoCm <= 10)
return InterpolarValor(precisaoCm, 5, 10, 90, 75);
if (precisaoCm <= 30)
return InterpolarValor(precisaoCm, 10, 30, 75, 50);
if (precisaoCm <= 100)
return InterpolarValor(precisaoCm, 30, 100, 50, 20);
return 5;
}
public static double CalcularNotaGnss(TiposCorrecaoGPS qualidade, double precisaoCm, double saudeModulo)
{
double notaFix = NotaQualidadeGnss(qualidade);
double notaPrecisao = NotaPrecisaoGnss(precisaoCm);
/*
* O pior dos três critérios define a cor.
*
* RTK Fixo com saúde ruim não fica verde.
* Saúde boa com modo autônomo também não.
*/
return Math.Min(notaFix, Math.Min(notaPrecisao, Limitar(saudeModulo, 0, 100)));
}
public static StatusModulo CalcularStatusAutonomiaCorredor(double distanciaCapaz, double distanciaNecessaria, double limiar)
{
StatusModulo status =
distanciaNecessaria > (distanciaCapaz + limiar) ? StatusModulo.Operante :
distanciaNecessaria > (distanciaCapaz - limiar) ? StatusModulo.Alerta :
StatusModulo.Falha;
return status;
}
public static double CalcularErroAngular(double atual, double sp)
{
double erro = (atual - sp) % 360.0;
if (erro > 180.0)
erro -= 360.0;
else if (erro < -180.0)
erro += 360.0;
return erro;
}
public static string FormatarQualidadeGnss(TiposCorrecaoGPS qualidade)
{
switch (qualidade)
{
case Enums.TiposCorrecaoGPS.SemCorrecao:
return "Sem correção";
case Enums.TiposCorrecaoGPS.Autonomo:
return "Autônomo";
case Enums.TiposCorrecaoGPS.DGPS:
return "DGPS";
case Enums.TiposCorrecaoGPS.PPS:
return "PPS";
case Enums.TiposCorrecaoGPS.RTKFixo:
return "RTK Fixo";
case Enums.TiposCorrecaoGPS.RTKFlutuante:
return "RTK Flutuante";
case Enums.TiposCorrecaoGPS.DeadReckoing:
return "Dead Reckoning";
case Enums.TiposCorrecaoGPS.BaseFix:
return "Base Fix";
default:
return "Desconhecido";
}
}
public static string FormatarDistancia(double distanciaMetros)
{
if (double.IsNaN(distanciaMetros) || double.IsInfinity(distanciaMetros) || distanciaMetros < 0)
{
return "Indisponível";
}
if (distanciaMetros >= 1000)
{
return $"{distanciaMetros / 1000.0:0.00} km";
}
return $"{distanciaMetros:0.0} m";
}
public static string FormatarTempo(TimeSpan tempo)
{
if (tempo < TimeSpan.Zero)
tempo = TimeSpan.Zero;
int horasTotais = (int)tempo.TotalHours;
return string.Format(
"{0:00}:{1:00}:{2:00}",
horasTotais,
tempo.Minutes,
tempo.Seconds
);
}
public static double InterpolarValor(double valor, double origemMinima, double origemMaxima, double destinoInicial, double destinoFinal)
{
if (origemMaxima <= origemMinima)
return destinoInicial;
double fator = (valor - origemMinima) / (origemMaxima - origemMinima);
fator = Limitar(fator, 0, 1);
return destinoInicial + (destinoFinal - destinoInicial) * fator;
}
public static double Limitar(double valor, double minimo, double maximo)
{
return Math.Max(minimo, Math.Min(maximo, valor));
}
public static void AplicarEstadoPainel(HmiRoundedPanel panel, Color color)
{
panel.BorderColor = color;
panel.Invalidate();
}
}
}

View File

@ -1,4 +1,6 @@
namespace AgroBase.Forms.IHM.Operacao.Parametros using AgroBase.Models;
namespace AgroBase.Forms.IHM.Operacao.Parametros
{ {
partial class ucParametrosAtuador partial class ucParametrosAtuador
{ {
@ -106,7 +108,7 @@
this.seletorModoAgitador.Margin = new System.Windows.Forms.Padding(0, 3, 0, 5); this.seletorModoAgitador.Margin = new System.Windows.Forms.Padding(0, 3, 0, 5);
this.seletorModoAgitador.MinimumSize = new System.Drawing.Size(0, 40); this.seletorModoAgitador.MinimumSize = new System.Drawing.Size(0, 40);
this.seletorModoAgitador.Name = "seletorModoAgitador"; this.seletorModoAgitador.Name = "seletorModoAgitador";
this.seletorModoAgitador.SelectedMode = "Continuo"; this.seletorModoAgitador.SelectedMode = Enums.ModoAgitadorCalda.SemAgitacao;
this.seletorModoAgitador.Size = new System.Drawing.Size(282, 42); this.seletorModoAgitador.Size = new System.Drawing.Size(282, 42);
this.seletorModoAgitador.TabIndex = 2; this.seletorModoAgitador.TabIndex = 2;
// //

View File

@ -1,36 +1,20 @@
using System; using AgroBase.Models;
using System;
using System.Windows.Forms; using System.Windows.Forms;
namespace AgroBase.Forms.IHM.Operacao.Parametros namespace AgroBase.Forms.IHM.Operacao.Parametros
{ {
public partial class ucParametrosAtuador : UserControl public partial class ucParametrosAtuador : UserControl
{ {
public event EventHandler ParametrosAlterados; private OperacaoModel op;
private bool _carregandoDados;
public ucParametrosAtuador() public ucParametrosAtuador()
{ {
InitializeComponent(); InitializeComponent();
ConfigurarEstadoInicial();
VincularEventos(); VincularEventos();
} }
private void ConfigurarEstadoInicial()
{
seletorModoAgitador.SelectedMode = "Continuo";
paramKp.Value = 1.00M;
paramKi.Value = 0.10M;
paramKd.Value = 0.00M;
paramBicosEmUso.Value = 7M;
paramPressaoLinha.Value = 18M;
paramInicioTela.Value = 85M;
paramAlturaArea.Value = 15M;
paramErvasOn.Value = 25M;
paramErvasOff.Value = 15M;
}
private void VincularEventos() private void VincularEventos()
{ {
seletorModoAgitador.SelectedModeChanged += Controle_Alterado; seletorModoAgitador.SelectedModeChanged += Controle_Alterado;
@ -47,70 +31,63 @@ namespace AgroBase.Forms.IHM.Operacao.Parametros
paramErvasOff.ValueChanged += Controle_Alterado; paramErvasOff.ValueChanged += Controle_Alterado;
} }
public void DefinirOperacao(OperacaoModel operacao)
{
op = operacao;
CarregarDadosTela();
}
private void CarregarDadosTela()
{
try
{
var parametros = op?.Parametros?.Controle;
var agitador = op?.DispAtu?.Dados?.AgitadorDeCalda?.Controle;
seletorModoAgitador.SelectedMode = parametros?.AtuAgitadorModo ?? Enums.ModoAgitadorCalda.SemAgitacao;
paramKp.Value = (decimal)(agitador?.Kp ?? 0);
paramKi.Value = (decimal)(agitador?.Ki ?? 0);
paramKd.Value = (decimal)(agitador?.Kd ?? 0);
paramBicosEmUso.Value = op?.Parametros?.QtdBicos ?? 0;
paramPressaoLinha.Value = (decimal)(parametros?.AtuPressaoLinha ?? 0);
paramInicioTela.Value = (decimal)(parametros?.AtuPercentualInicioPulverizacao ?? 0);
paramAlturaArea.Value = (decimal)(parametros?.AtuAlturaAreaPulverizacao ?? 0);
paramErvasOn.Value = (decimal)(parametros?.AtuPercentualErvasBicoOn ?? 0);
paramErvasOff.Value = (decimal)(parametros?.AtuPercentualErvasBicoOff ?? 0);
}
finally
{
_carregandoDados = false;
}
}
private void Controle_Alterado(object sender, EventArgs e) private void Controle_Alterado(object sender, EventArgs e)
{ {
if (ParametrosAlterados != null) if (_carregandoDados)
ParametrosAlterados(this, EventArgs.Empty); return;
}
public string ModoAgitador var parametros = op?.Parametros?.Controle;
{ var agitador = op?.DispAtu?.Dados?.AgitadorDeCalda?.Controle;
get { return seletorModoAgitador.SelectedMode; }
set { seletorModoAgitador.SelectedMode = value; }
}
public decimal KpAgitador if (parametros == null)
{ return;
get { return paramKp.Value; }
set { paramKp.Value = value; }
}
public decimal KiAgitador parametros.AtuAgitadorModo = seletorModoAgitador.SelectedMode;
{
get { return paramKi.Value; }
set { paramKi.Value = value; }
}
public decimal KdAgitador agitador.Kp = (double)paramKp.Value;
{ agitador.Ki = (double)paramKi.Value;
get { return paramKd.Value; } agitador.Kd = (double)paramKd.Value;
set { paramKd.Value = value; }
}
public int QuantidadeBicosEmUso op.Parametros.QtdBicos = (int)paramBicosEmUso.Value;
{ parametros.AtuPressaoLinha = (double)paramPressaoLinha.Value;
get { return Convert.ToInt32(paramBicosEmUso.Value); }
set { paramBicosEmUso.Value = value; }
}
public decimal PressaoLinhaPsi parametros.AtuPercentualInicioPulverizacao = (double)paramInicioTela.Value;
{ parametros.AtuAlturaAreaPulverizacao = (double)paramAlturaArea.Value;
get { return paramPressaoLinha.Value; } parametros.AtuPercentualErvasBicoOn = (double)paramErvasOn.Value;
set { paramPressaoLinha.Value = value; } parametros.AtuPercentualErvasBicoOff = (double)paramErvasOff.Value;
}
public int PercentualInicioTela
{
get { return Convert.ToInt32(paramInicioTela.Value); }
set { paramInicioTela.Value = value; }
}
public int PercentualAlturaArea
{
get { return Convert.ToInt32(paramAlturaArea.Value); }
set { paramAlturaArea.Value = value; }
}
public decimal PercentualErvasOn
{
get { return paramErvasOn.Value; }
set { paramErvasOn.Value = value; }
}
public decimal PercentualErvasOff
{
get { return paramErvasOff.Value; }
set { paramErvasOff.Value = value; }
} }
} }
} }

View File

@ -1,4 +1,6 @@
namespace AgroBase.Forms.IHM.Operacao.Parametros using AgroBase.Models;
namespace AgroBase.Forms.IHM.Operacao.Parametros
{ {
partial class ucParametrosDirecional partial class ucParametrosDirecional
{ {
@ -180,7 +182,7 @@
this.seletorModoControle.Dock = System.Windows.Forms.DockStyle.Fill; this.seletorModoControle.Dock = System.Windows.Forms.DockStyle.Fill;
this.seletorModoControle.Margin = new System.Windows.Forms.Padding(0, 1, 3, 0); this.seletorModoControle.Margin = new System.Windows.Forms.Padding(0, 1, 3, 0);
this.seletorModoControle.MinimumSize = System.Drawing.Size.Empty; this.seletorModoControle.MinimumSize = System.Drawing.Size.Empty;
this.seletorModoControle.SelectedMode = "MPC"; this.seletorModoControle.SelectedMode = Enums.TiposControladorDirecional.MPC;
this.parametroHorizonte.Dock = System.Windows.Forms.DockStyle.Fill; this.parametroHorizonte.Dock = System.Windows.Forms.DockStyle.Fill;
this.parametroHorizonte.Margin = new System.Windows.Forms.Padding(3, 1, 3, 0); this.parametroHorizonte.Margin = new System.Windows.Forms.Padding(3, 1, 3, 0);

View File

@ -1,38 +1,20 @@
using System; using AgroBase.Models;
using System;
using System.Windows.Forms; using System.Windows.Forms;
namespace AgroBase.Forms.IHM.Operacao.Parametros namespace AgroBase.Forms.IHM.Operacao.Parametros
{ {
public partial class ucParametrosDirecional : UserControl public partial class ucParametrosDirecional : UserControl
{ {
public event EventHandler ParametrosAlterados; private OperacaoModel op;
private bool _carregandoDados;
public ucParametrosDirecional() public ucParametrosDirecional()
{ {
InitializeComponent(); InitializeComponent();
ConfigurarEstadoInicial();
VincularEventos(); VincularEventos();
} }
private void ConfigurarEstadoInicial()
{
checkDirecionalAutomatico.Checked = true;
checkAssistidoSonar.Checked = true;
checkAssistidoImu.Checked = true;
checkImuPrefereArco.Checked = false;
sliderAnguloMaximo.Value = 45;
sliderAnguloMaximo.VelocidadeMaximaKmh = 0D;
sliderVelocidadeDirecional.Value = 60;
sliderVelocidadeDirecional.VelocidadeMaximaKmh = 0D;
seletorModoControle.SelectedMode = "MPC";
parametroHorizonte.Value = 4M;
parametroDistanciaSaida.Value = 5M;
}
private void VincularEventos() private void VincularEventos()
{ {
checkDirecionalAutomatico.CheckedChanged += Controle_Alterado; checkDirecionalAutomatico.CheckedChanged += Controle_Alterado;
@ -48,64 +30,63 @@ namespace AgroBase.Forms.IHM.Operacao.Parametros
parametroDistanciaSaida.ValueChanged += Controle_Alterado; parametroDistanciaSaida.ValueChanged += Controle_Alterado;
} }
public void DefinirOperacao(OperacaoModel operacao)
{
op = operacao;
CarregarDadosTela();
}
private void CarregarDadosTela()
{
_carregandoDados = true;
try
{
var parametros = op?.Parametros?.Controle;
checkDirecionalAutomatico.Checked = parametros?.DirecionalAutomatico ?? false;
checkAssistidoSonar.Checked = parametros?.DirAuxilioSonar ?? false;
checkAssistidoImu.Checked = parametros?.ImuAuxilioDirecional ?? false;
checkImuPrefereArco.Checked = parametros?.ImuDirecionalPreferirArco ?? false;
sliderAnguloMaximo.Value = parametros?.DirAnguloMaximo ?? 0;
sliderVelocidadeDirecional.Value = (int)(parametros?.DirVelocidadeMovimento ?? 0);
seletorModoControle.SelectedMode = parametros?.DirTipoMovimento ?? Enums.TiposControladorDirecional.MPC;
parametroHorizonte.Value = (decimal)(parametros?.MpcHorizonte ?? 0);
parametroDistanciaSaida.Value = (decimal)(parametros?.DistanciaManobra ?? 0);
}
finally
{
_carregandoDados = false;
}
}
private void Controle_Alterado(object sender, EventArgs e) private void Controle_Alterado(object sender, EventArgs e)
{ {
if (ParametrosAlterados != null) if (_carregandoDados)
ParametrosAlterados(this, EventArgs.Empty); return;
}
public bool DirecionalAutomatico var parametros = op?.Parametros?.Controle;
{
get { return checkDirecionalAutomatico.Checked; }
set { checkDirecionalAutomatico.Checked = value; }
}
public bool AssistidoPorSonar if (parametros == null)
{ return;
get { return checkAssistidoSonar.Checked; }
set { checkAssistidoSonar.Checked = value; }
}
public bool AssistidoPorImu parametros.DirecionalAutomatico = checkDirecionalAutomatico.Checked;
{ parametros.DirAuxilioSonar = checkAssistidoSonar.Checked;
get { return checkAssistidoImu.Checked; } parametros.ImuAuxilioDirecional = checkAssistidoImu.Checked;
set { checkAssistidoImu.Checked = value; } parametros.ImuDirecionalPreferirArco = checkImuPrefereArco.Checked;
}
public bool ImuPrefereArco parametros.DirAnguloMaximo = sliderAnguloMaximo.Value;
{
get { return checkImuPrefereArco.Checked; }
set { checkImuPrefereArco.Checked = value; }
}
public int AnguloMaximo parametros.DirVelocidadeMovimento = sliderVelocidadeDirecional.Value;
{
get { return sliderAnguloMaximo.Value; }
set { sliderAnguloMaximo.Value = value; }
}
public int VelocidadeDirecionalPercentual parametros.DirTipoMovimento = seletorModoControle.SelectedMode;
{
get { return sliderVelocidadeDirecional.Value; }
set { sliderVelocidadeDirecional.Value = value; }
}
public string ModoControle parametros.MpcHorizonte = (double)parametroHorizonte.Value;
{ parametros.DistanciaManobra = (double)parametroDistanciaSaida.Value;
get { return seletorModoControle.SelectedMode; }
set { seletorModoControle.SelectedMode = value; }
}
public decimal HorizontePredicaoMetros
{
get { return parametroHorizonte.Value; }
set { parametroHorizonte.Value = value; }
}
public decimal DistanciaSaidaCorredorMetros
{
get { return parametroDistanciaSaida.Value; }
set { parametroDistanciaSaida.Value = value; }
} }
} }
} }

View File

@ -1,20 +1,67 @@
using System; using AgroBase.Models;
using System.Collections.Generic; using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
namespace AgroBase.Forms.IHM.Operacao.Parametros namespace AgroBase.Forms.IHM.Operacao.Parametros
{ {
public partial class ucParametrosMapa : UserControl public partial class ucParametrosMapa : UserControl
{ {
private OperacaoModel op;
private bool _carregandoDados;
public ucParametrosMapa() public ucParametrosMapa()
{ {
InitializeComponent(); InitializeComponent();
VincularEventos();
}
private void VincularEventos()
{
seletorModoAgitador.SelectedModeChanged += Controle_Alterado;
paramKp.ValueChanged += Controle_Alterado;
paramKi.ValueChanged += Controle_Alterado;
paramKd.ValueChanged += Controle_Alterado;
paramBicosEmUso.ValueChanged += Controle_Alterado;
paramPressaoLinha.ValueChanged += Controle_Alterado;
paramInicioTela.ValueChanged += Controle_Alterado;
paramAlturaArea.ValueChanged += Controle_Alterado;
paramErvasOn.ValueChanged += Controle_Alterado;
paramErvasOff.ValueChanged += Controle_Alterado;
}
public void DefinirOperacao(OperacaoModel operacao)
{
op = operacao;
CarregarDadosTela();
}
private void CarregarDadosTela()
{
try
{
var parametros = op?.Parametros?.Controle;
// preenchimento dos dados
}
finally
{
_carregandoDados = false;
}
}
private void Controle_Alterado(object sender, EventArgs e)
{
if (_carregandoDados)
return;
var parametros = op?.Parametros?.Controle;
if (parametros == null)
return;
// definicao dos parametros
} }
} }
} }

View File

@ -1,4 +1,4 @@
using AgroBase.Forms.IHM.Operacao.Parametros.Controls; using AgroBase.Models;
using System; using System;
using System.Windows.Forms; using System.Windows.Forms;
@ -6,31 +6,15 @@ namespace AgroBase.Forms.IHM.Operacao.Parametros
{ {
public partial class ucParametrosMovimento : UserControl public partial class ucParametrosMovimento : UserControl
{ {
public event EventHandler ParametrosAlterados; private OperacaoModel op;
private bool _carregandoDados;
public ucParametrosMovimento() public ucParametrosMovimento()
{ {
InitializeComponent(); InitializeComponent();
ConfigurarEstadoInicial();
VincularEventos(); VincularEventos();
} }
private void ConfigurarEstadoInicial()
{
checkMovimentoAutomatico.Checked = true;
checkAssistidoSonar.Checked = true;
checkParadaObstaculo.Checked = true;
checkAssistidoImu.Checked = true;
checkParadaInclinacao.Checked = true;
checkFrenagemParar.Checked = true;
sliderSemErvas.Value = 68;
sliderSemErvas.VelocidadeMaximaKmh = 5D;
sliderComErvas.Value = 45;
sliderComErvas.VelocidadeMaximaKmh = 5D;
}
private void VincularEventos() private void VincularEventos()
{ {
checkMovimentoAutomatico.CheckedChanged += Controle_Alterado; checkMovimentoAutomatico.CheckedChanged += Controle_Alterado;
@ -44,68 +28,58 @@ namespace AgroBase.Forms.IHM.Operacao.Parametros
sliderComErvas.ValueChanged += Controle_Alterado; sliderComErvas.ValueChanged += Controle_Alterado;
} }
public void DefinirOperacao(OperacaoModel operacao)
{
op = operacao;
CarregarDadosTela();
}
private void CarregarDadosTela()
{
_carregandoDados = true;
try
{
var parametros = op?.Parametros?.Controle;
checkMovimentoAutomatico.Checked = parametros?.MovimentoAutomatico ?? false;
checkAssistidoSonar.Checked = parametros?.MovAuxilioSonar ?? false;
checkParadaObstaculo.Checked = parametros?.OakParadaPorObstaculo ?? false;
checkAssistidoImu.Checked = parametros?.ImuAuxilioMovimento ?? false;
checkParadaInclinacao.Checked = parametros?.ImuParadaPorInclinacao ?? false;
checkFrenagemParar.Checked = parametros?.FrenagemAutomaticaAoParar ?? false;
sliderSemErvas.VelocidadeMaximaKmh = FuncoesMatematicas.CalculaVelocidadeRPM(VariaveisEquipamento.RPM_Max_Roda);
sliderComErvas.VelocidadeMaximaKmh = FuncoesMatematicas.CalculaVelocidadeRPM(VariaveisEquipamento.RPM_Max_Roda);
sliderSemErvas.Value = parametros?.MovVelocidadeSErvasPercent ?? 0;
sliderComErvas.Value = parametros?.MovVelocidadeCErvasPercent ?? 0;
}
finally
{
_carregandoDados = false;
}
}
private void Controle_Alterado(object sender, EventArgs e) private void Controle_Alterado(object sender, EventArgs e)
{ {
if (ParametrosAlterados != null) if (_carregandoDados)
ParametrosAlterados(this, EventArgs.Empty); return;
}
public bool MovimentoAutomatico var parametros = op?.Parametros?.Controle;
{
get { return checkMovimentoAutomatico.Checked; }
set { checkMovimentoAutomatico.Checked = value; }
}
public bool AssistidoPorSonar if (parametros == null)
{ return;
get { return checkAssistidoSonar.Checked; }
set { checkAssistidoSonar.Checked = value; }
}
public bool ParadaPorObstaculo parametros.MovimentoAutomatico = checkMovimentoAutomatico.Checked;
{ parametros.MovAuxilioSonar = checkAssistidoSonar.Checked;
get { return checkParadaObstaculo.Checked; } parametros.OakParadaPorObstaculo = checkParadaObstaculo.Checked;
set { checkParadaObstaculo.Checked = value; } parametros.ImuAuxilioMovimento = checkAssistidoImu.Checked;
} parametros.ImuParadaPorInclinacao = checkParadaInclinacao.Checked;
parametros.FrenagemAutomaticaAoParar = checkFrenagemParar.Checked;
public bool AssistidoPorImu parametros.MovVelocidadeSErvasPercent = sliderSemErvas.Value;
{ parametros.MovVelocidadeCErvasPercent = sliderComErvas.Value;
get { return checkAssistidoImu.Checked; }
set { checkAssistidoImu.Checked = value; }
}
public bool ParadaPorInclinacao
{
get { return checkParadaInclinacao.Checked; }
set { checkParadaInclinacao.Checked = value; }
}
public bool FrenagemAoParar
{
get { return checkFrenagemParar.Checked; }
set { checkFrenagemParar.Checked = value; }
}
public int VelocidadeSemErvasPercentual
{
get { return sliderSemErvas.Value; }
set { sliderSemErvas.Value = value; }
}
public int VelocidadeComErvasPercentual
{
get { return sliderComErvas.Value; }
set { sliderComErvas.Value = value; }
}
public double VelocidadeMaximaEquipamentoKmh
{
get { return sliderSemErvas.VelocidadeMaximaKmh; }
set
{
sliderSemErvas.VelocidadeMaximaKmh = value;
sliderComErvas.VelocidadeMaximaKmh = value;
}
} }
} }
} }

View File

@ -22,7 +22,7 @@ namespace AgroBase.Forms.IHM.Operacao
private bool _atualizandoSlider = false; private bool _atualizandoSlider = false;
private bool _requisitandoCameraFrame; private bool _requisitandoCameraFrame;
private bool _controleDescartado; private bool _controleDescartado;
OperacaoModel op => Variaveis.OperacaoEmAndamento; private OperacaoModel op => Variaveis.OperacaoEmAndamento;
public ucOperacaoMovimentacao() public ucOperacaoMovimentacao()
{ {
@ -236,6 +236,8 @@ namespace AgroBase.Forms.IHM.Operacao
AtualizarDadosImu(dados.IMU); AtualizarDadosImu(dados.IMU);
AtualizarDadosTelemetria(dados); AtualizarDadosTelemetria(dados);
AtualizarSaudeModulos();
} }
public void AtualizarDadosControle(OperacaoControleModel controle, OperacaoParametrosControleModel parametros) public void AtualizarDadosControle(OperacaoControleModel controle, OperacaoParametrosControleModel parametros)
@ -246,9 +248,9 @@ namespace AgroBase.Forms.IHM.Operacao
return; return;
sliderVelocidadeMax.VelocidadeMaximaKmh = FuncoesMatematicas.CalculaVelocidadeRPM(VariaveisEquipamento.RPM_Max_Roda); sliderVelocidadeMax.VelocidadeMaximaKmh = FuncoesMatematicas.CalculaVelocidadeRPM(VariaveisEquipamento.RPM_Max_Roda);
sliderVelocidadeMax.Value = (int)Limitar(controle?.PercentualVelocidadeSP ?? 0, sliderVelocidadeMax.Minimum, sliderVelocidadeMax.Maximum); sliderVelocidadeMax.Value = (int)FuncoesIHM.Limitar(controle?.PercentualVelocidadeSP ?? 0, sliderVelocidadeMax.Minimum, sliderVelocidadeMax.Maximum);
sliderAngulo.Value = (int)Limitar(controle?.Angulo ?? 0, sliderAngulo.Minimum, sliderAngulo.Maximum); sliderAngulo.Value = (int)FuncoesIHM.Limitar(controle?.Angulo ?? 0, sliderAngulo.Minimum, sliderAngulo.Maximum);
sliderVelocidadeDir.Value = (int)Limitar(parametros?.DirVelocidadeMovimento ?? 0, sliderVelocidadeDir.Minimum, sliderVelocidadeDir.Maximum); sliderVelocidadeDir.Value = (int)FuncoesIHM.Limitar(parametros?.DirVelocidadeMovimento ?? 0, sliderVelocidadeDir.Minimum, sliderVelocidadeDir.Maximum);
} }
private void AtualizarListaJoysticks() private void AtualizarListaJoysticks()
@ -294,15 +296,20 @@ namespace AgroBase.Forms.IHM.Operacao
if (_modoManualAtivado && !forcar) if (_modoManualAtivado && !forcar)
return; return;
var saude_dir = op?.Sensoriamento?.OperadorSaude?.ModulosSaude?.FirstOrDefault(x => x.modulo == T_Code.Dir)?.saude_individual?.FirstOrDefault(x => x.id == card.Tag.ToString());
var saude_mov = op?.Sensoriamento?.OperadorSaude?.ModulosSaude?.FirstOrDefault(x => x.modulo == T_Code.Mov)?.saude_individual?.FirstOrDefault(x => x.id == card.Tag.ToString());
var Dir = Mods.FirstOrDefault(x => x.Modulo_ID == card.Tag.ToString())?.DirMotor; var Dir = Mods.FirstOrDefault(x => x.Modulo_ID == card.Tag.ToString())?.DirMotor;
var Mov = Mods.FirstOrDefault(x => x.Modulo_ID == card.Tag.ToString())?.MovMotor; var Mov = Mods.FirstOrDefault(x => x.Modulo_ID == card.Tag.ToString())?.MovMotor;
card.AtualizarDados( card.AtualizarDados(
dir_em_uso: Dir?.Comandar ?? false, dir_em_uso: Dir?.Comandar ?? false,
dir_status: saude_dir?.status ?? StatusModulo.Desconectado,
dir_ang_sp: Dir?.Angulo_SP ?? 0, dir_ang_sp: Dir?.Angulo_SP ?? 0,
dir_ang_at: Dir?.AnguloReal ?? 0, dir_ang_at: Dir?.AnguloReal ?? 0,
dir_sentido: Dir?.SentidoReal ?? Sentido.Parado, dir_sentido: Dir?.SentidoReal ?? Sentido.Parado,
mov_em_uso: Mov?.Comandar ?? false, mov_em_uso: Mov?.Comandar ?? false,
mov_status: saude_mov?.status ?? StatusModulo.Desconectado,
mov_vel_sp: Mov?.RPM_SP ?? 0, mov_vel_sp: Mov?.RPM_SP ?? 0,
mov_vel_at: Mov?.RPM_Roda ?? 0, mov_vel_at: Mov?.RPM_Roda ?? 0,
mov_freio: Mov?.UltimoFreioSP ?? false mov_freio: Mov?.UltimoFreioSP ?? false
@ -438,11 +445,17 @@ namespace AgroBase.Forms.IHM.Operacao
} }
private void AtualizarSaudeModulos()
private static double Limitar(double valor, double minimo, double maximo)
{ {
return Math.Max(minimo, Math.Min(maximo, valor)); var saude_m = op?.Sensoriamento?.OperadorSaude?.ModulosSaude;
var saudeCamera = saude_m?.FirstOrDefault(x => x.modulo == T_Code.Snr)?.status ?? StatusModulo.Desconectado;
var saudeImu = saude_m?.FirstOrDefault(x => x.modulo == T_Code.Imu)?.status ?? StatusModulo.Desconectado;
FuncoesIHM.AplicarEstadoPainel(pnlCamera, FuncoesIHM.CorPorStatusModulo(saudeCamera));
FuncoesIHM.AplicarEstadoPainel(pnlRadar, FuncoesIHM.CorPorStatusModulo(saudeCamera));
FuncoesIHM.AplicarEstadoPainel(pnlImu, FuncoesIHM.CorPorStatusModulo(saudeImu));
} }
} }
} }

View File

@ -30,7 +30,8 @@ namespace AgroBase.Forms.IHM.Operacao
this.btnMapaWeb = new System.Windows.Forms.Button(); this.btnMapaWeb = new System.Windows.Forms.Button();
this.btnMapaDinamico = new System.Windows.Forms.Button(); this.btnMapaDinamico = new System.Windows.Forms.Button();
this.pnlMapaVisual = new AgroBase.Forms.IHM.Controls.HmiRoundedPanel(); this.pnlMapaVisual = new AgroBase.Forms.IHM.Controls.HmiRoundedPanel();
this.lblMapaPlaceholder = new System.Windows.Forms.Label(); this.pnlMapaWeb = new System.Windows.Forms.Panel();
this.pnlMapaDinamico = new System.Windows.Forms.Panel();
this.rightTopLayout = new System.Windows.Forms.TableLayoutPanel(); this.rightTopLayout = new System.Windows.Forms.TableLayoutPanel();
@ -166,21 +167,21 @@ namespace AgroBase.Forms.IHM.Operacao
SetupMapButton(this.btnMapaDinamico, "Trajetória"); SetupMapButton(this.btnMapaDinamico, "Trajetória");
this.pnlMapaVisual.BorderColor = AgroBase.Forms.IHM.Controls.HmiTheme.Border; this.pnlMapaVisual.BorderColor = AgroBase.Forms.IHM.Controls.HmiTheme.Border;
this.pnlMapaVisual.Controls.Add(this.lblMapaPlaceholder);
this.pnlMapaVisual.CornerRadius = 8; this.pnlMapaVisual.CornerRadius = 8;
this.pnlMapaVisual.Dock = System.Windows.Forms.DockStyle.Fill; this.pnlMapaVisual.Dock = System.Windows.Forms.DockStyle.Fill;
this.pnlMapaVisual.FillColor = System.Drawing.Color.FromArgb(18, 29, 22); this.pnlMapaVisual.FillColor = System.Drawing.Color.FromArgb(18, 29, 22);
this.pnlMapaVisual.Controls.Add(this.pnlMapaWeb);
this.pnlMapaVisual.Controls.Add(this.pnlMapaDinamico);
this.lblMapaPlaceholder.Dock = System.Windows.Forms.DockStyle.Fill; this.pnlMapaWeb.Dock = DockStyle.Fill;
this.lblMapaPlaceholder.BackColor = System.Drawing.Color.Transparent; this.pnlMapaWeb.Margin = Padding.Empty;
this.lblMapaPlaceholder.ForeColor = AgroBase.Forms.IHM.Controls.HmiTheme.Success; this.pnlMapaWeb.Padding = Padding.Empty;
this.lblMapaPlaceholder.Font = new System.Drawing.Font("Consolas", 9F, System.Drawing.FontStyle.Bold); this.pnlMapaWeb.BackColor = Color.Black;
this.lblMapaPlaceholder.Text =
"MAPA / TRAJETÓRIA\n\n" + this.pnlMapaDinamico.Dock = DockStyle.Fill;
"Rua atual: 12 / 35\n\n" + this.pnlMapaDinamico.Margin = Padding.Empty;
" ○ 125\n │\n ○ 126\n │\n [ROVER]\n │\n ○ 127\n\n" + this.pnlMapaDinamico.Padding = Padding.Empty;
"Coordenadas: -23.5621, -46.6542\nAltitude: 812 m"; this.pnlMapaDinamico.BackColor = HmiTheme.Text;
this.lblMapaPlaceholder.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.rightTopLayout.ColumnCount = 2; this.rightTopLayout.ColumnCount = 2;
this.rightTopLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 54F)); this.rightTopLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 54F));
@ -235,10 +236,10 @@ namespace AgroBase.Forms.IHM.Operacao
this.orientationValuesLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 18F)); this.orientationValuesLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 18F));
this.orientationValuesLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 32F)); this.orientationValuesLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 32F));
SetupHeadingTitle(this.lblRoverTitulo, "Rover", AgroBase.Forms.IHM.Controls.HmiTheme.Success); SetupHeadingTitle(this.lblRoverTitulo, "Rover", AgroBase.Forms.IHM.Controls.HmiTheme.Text);
SetupHeadingValue(this.lblRoverValor, "128°", AgroBase.Forms.IHM.Controls.HmiTheme.Success); SetupHeadingValue(this.lblRoverValor, "128°", AgroBase.Forms.IHM.Controls.HmiTheme.Success);
SetupHeadingTitle(this.lblTrajetoriaTitulo, "Trajetória", AgroBase.Forms.IHM.Controls.HmiTheme.Warning); SetupHeadingTitle(this.lblTrajetoriaTitulo, "Trajetória", AgroBase.Forms.IHM.Controls.HmiTheme.Text);
SetupHeadingValue(this.lblTrajetoriaValor, "136°", AgroBase.Forms.IHM.Controls.HmiTheme.Warning); SetupHeadingValue(this.lblTrajetoriaValor, "136°", AgroBase.Forms.IHM.Controls.HmiTheme.Manual);
ConfigurePanel(this.pnlGnss, this.gnssLayout); ConfigurePanel(this.pnlGnss, this.gnssLayout);
this.pnlGnss.Padding = new Padding(6, 4, 6, 4); this.pnlGnss.Padding = new Padding(6, 4, 6, 4);
@ -253,16 +254,16 @@ namespace AgroBase.Forms.IHM.Operacao
this.gnssLayout.Dock = System.Windows.Forms.DockStyle.Fill; this.gnssLayout.Dock = System.Windows.Forms.DockStyle.Fill;
this.gnssLayout.RowCount = 6; this.gnssLayout.RowCount = 6;
this.gnssLayout.RowStyles.Clear(); this.gnssLayout.RowStyles.Clear();
for (int i = 0; i < 6; i++) for (int i = 0; i < this.gnssLayout.RowCount; i++)
this.gnssLayout.RowStyles.Add(new RowStyle(SizeType.Percent, 16.6667F)); this.gnssLayout.RowStyles.Add(new RowStyle(SizeType.Percent, 100F / this.gnssLayout.RowCount));
//SetupTitle(this.lblGnssTitulo, "GNSS"); //SetupTitle(this.lblGnssTitulo, "GNSS");
SetupMetric(this.metricSatelites, "Satélites", "18"); SetupMetric(this.metricSatelites, "Satélites", "18", 65);
SetupMetric(this.metricPrecisao, "Precisão", "0,8 cm"); SetupMetric(this.metricPrecisao, "Precisão", "0,8 cm", 72);
SetupMetric(this.metricIdadeCorrecao, "Idade correção", "1,2 s"); SetupMetric(this.metricIdadeCorrecao, "Idade correção", "1,2 s", 72);
SetupMetric(this.metricAltitude, "Altitude", "812 m"); SetupMetric(this.metricAltitude, "Altitude", "812 m", 72);
SetupMetric(this.metricVelocidade, "Velocidade", "3,4 km/h"); SetupMetric(this.metricVelocidade, "Velocidade", "3,4 km/h", 82);
SetupMetric(this.metricHeading, "Heading", "128°"); SetupMetric(this.metricHeading, "Heading", "128°", 65);
ConfigurePanel(this.pnlTrajetoria, this.trajectoryLayout); ConfigurePanel(this.pnlTrajetoria, this.trajectoryLayout);
this.trajectoryLayout.ColumnCount = 1; this.trajectoryLayout.ColumnCount = 1;
@ -310,6 +311,7 @@ namespace AgroBase.Forms.IHM.Operacao
this.progressRua.Value = 65; this.progressRua.Value = 65;
this.progressRua.Margin = new System.Windows.Forms.Padding(1, 1, 1, 1); this.progressRua.Margin = new System.Windows.Forms.Padding(1, 1, 1, 1);
this.progressRua.CornerRadius = 5; this.progressRua.CornerRadius = 5;
this.progressRua.BarColor = HmiTheme.Info;
SetupProgressHeader( SetupProgressHeader(
this.progressGeralHeader, this.progressGeralHeader,
@ -323,6 +325,7 @@ namespace AgroBase.Forms.IHM.Operacao
this.progressGeral.Value = 38; this.progressGeral.Value = 38;
this.progressGeral.Margin = new System.Windows.Forms.Padding(1, 1, 1, 1); this.progressGeral.Margin = new System.Windows.Forms.Padding(1, 1, 1, 1);
this.progressGeral.CornerRadius = 5; this.progressGeral.CornerRadius = 5;
this.progressGeral.BarColor = HmiTheme.Success;
this.trajectoryBottomLayout.Controls.Clear(); this.trajectoryBottomLayout.Controls.Clear();
this.trajectoryBottomLayout.ColumnCount = 2; this.trajectoryBottomLayout.ColumnCount = 2;
@ -456,9 +459,7 @@ namespace AgroBase.Forms.IHM.Operacao
this.ResumeLayout(false); this.ResumeLayout(false);
} }
private static void ConfigurePanel( private static void ConfigurePanel(AgroBase.Forms.IHM.Controls.HmiRoundedPanel panel, System.Windows.Forms.Control child)
AgroBase.Forms.IHM.Controls.HmiRoundedPanel panel,
System.Windows.Forms.Control child)
{ {
panel.BorderColor = AgroBase.Forms.IHM.Controls.HmiTheme.Border; panel.BorderColor = AgroBase.Forms.IHM.Controls.HmiTheme.Border;
panel.Controls.Add(child); panel.Controls.Add(child);
@ -469,9 +470,7 @@ namespace AgroBase.Forms.IHM.Operacao
panel.Padding = new System.Windows.Forms.Padding(7); panel.Padding = new System.Windows.Forms.Padding(7);
} }
private static void SetupTitle( private static void SetupTitle(System.Windows.Forms.Label label, string text)
System.Windows.Forms.Label label,
string text)
{ {
label.Dock = System.Windows.Forms.DockStyle.Fill; label.Dock = System.Windows.Forms.DockStyle.Fill;
label.BackColor = System.Drawing.Color.Transparent; label.BackColor = System.Drawing.Color.Transparent;
@ -482,9 +481,7 @@ namespace AgroBase.Forms.IHM.Operacao
label.AutoEllipsis = true; label.AutoEllipsis = true;
} }
private static void SetupMapButton( private static void SetupMapButton(System.Windows.Forms.Button button, string text)
System.Windows.Forms.Button button,
string text)
{ {
button.Dock = System.Windows.Forms.DockStyle.Fill; button.Dock = System.Windows.Forms.DockStyle.Fill;
button.Text = text; button.Text = text;
@ -496,10 +493,7 @@ namespace AgroBase.Forms.IHM.Operacao
button.Margin = new System.Windows.Forms.Padding(2); button.Margin = new System.Windows.Forms.Padding(2);
} }
private static void SetupHeadingTitle( private static void SetupHeadingTitle(System.Windows.Forms.Label label, string text, System.Drawing.Color color)
System.Windows.Forms.Label label,
string text,
System.Drawing.Color color)
{ {
label.Dock = System.Windows.Forms.DockStyle.Fill; label.Dock = System.Windows.Forms.DockStyle.Fill;
label.BackColor = System.Drawing.Color.Transparent; label.BackColor = System.Drawing.Color.Transparent;
@ -511,10 +505,7 @@ namespace AgroBase.Forms.IHM.Operacao
label.AutoEllipsis = true; label.AutoEllipsis = true;
} }
private static void SetupHeadingValue( private static void SetupHeadingValue(System.Windows.Forms.Label label, string text, System.Drawing.Color color)
System.Windows.Forms.Label label,
string text,
System.Drawing.Color color)
{ {
label.Dock = System.Windows.Forms.DockStyle.Fill; label.Dock = System.Windows.Forms.DockStyle.Fill;
label.BackColor = System.Drawing.Color.Transparent; label.BackColor = System.Drawing.Color.Transparent;
@ -525,14 +516,13 @@ namespace AgroBase.Forms.IHM.Operacao
label.Padding = new Padding(2, 0, 0, 0); label.Padding = new Padding(2, 0, 0, 0);
} }
private static void SetupMetric( private static void SetupMetric(AgroBase.Forms.IHM.Controls.Operacao.HmiNavigationMetric metric, string title, string value, int largura)
AgroBase.Forms.IHM.Controls.Operacao.HmiNavigationMetric metric,
string title,
string value)
{ {
metric.Dock = System.Windows.Forms.DockStyle.Fill; metric.Dock = System.Windows.Forms.DockStyle.Fill;
metric.Titulo = title; metric.Titulo = title;
metric.Valor = value; metric.Valor = value;
metric.LarguraValor = largura;
metric.CorValor = HmiTheme.Success;
} }
private static void SetupInfoBox(Label label, string text, Color color) private static void SetupInfoBox(Label label, string text, Color color)
@ -567,12 +557,7 @@ namespace AgroBase.Forms.IHM.Operacao
label.Padding = Padding.Empty; label.Padding = Padding.Empty;
} }
private static void SetupProgressHeader( private static void SetupProgressHeader(System.Windows.Forms.TableLayoutPanel layout, System.Windows.Forms.Label title, System.Windows.Forms.Label value, string titleText, string valueText)
System.Windows.Forms.TableLayoutPanel layout,
System.Windows.Forms.Label title,
System.Windows.Forms.Label value,
string titleText,
string valueText)
{ {
layout.ColumnCount = 2; layout.ColumnCount = 2;
layout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 45F)); layout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 45F));
@ -598,11 +583,7 @@ namespace AgroBase.Forms.IHM.Operacao
value.AutoEllipsis = true; value.AutoEllipsis = true;
} }
private static void SetupAction( private static void SetupAction(AgroBase.Forms.IHM.Controls.HmiSidebarButton button, string text, string icon, System.Drawing.Color accent)
AgroBase.Forms.IHM.Controls.HmiSidebarButton button,
string text,
string icon,
System.Drawing.Color accent)
{ {
button.Dock = System.Windows.Forms.DockStyle.Fill; button.Dock = System.Windows.Forms.DockStyle.Fill;
button.Text = text; button.Text = text;
@ -616,11 +597,7 @@ namespace AgroBase.Forms.IHM.Operacao
} }
private static void SetupStatusAutonomiaLabel( private static void SetupStatusAutonomiaLabel(Label label, string text, Color color, bool bold)
Label label,
string text,
Color color,
bool bold)
{ {
label.Dock = DockStyle.Fill; label.Dock = DockStyle.Fill;
label.AutoSize = false; label.AutoSize = false;
@ -628,13 +605,7 @@ namespace AgroBase.Forms.IHM.Operacao
label.BackColor = HmiTheme.SurfaceRaised; label.BackColor = HmiTheme.SurfaceRaised;
label.ForeColor = color; label.ForeColor = color;
label.Font = new Font( label.Font = new Font("Segoe UI", 6.8F, bold ? FontStyle.Bold : FontStyle.Regular);
"Segoe UI",
6.8F,
bold
? FontStyle.Bold
: FontStyle.Regular
);
label.Text = text; label.Text = text;
label.TextAlign = ContentAlignment.MiddleCenter; label.TextAlign = ContentAlignment.MiddleCenter;
@ -658,11 +629,7 @@ namespace AgroBase.Forms.IHM.Operacao
label.BackColor = Color.Transparent; label.BackColor = Color.Transparent;
label.ForeColor = accent; label.ForeColor = accent;
label.Font = new Font( label.Font = new Font("Segoe UI", 5.8F, FontStyle.Bold);
"Segoe UI",
5.8F,
FontStyle.Bold
);
label.TextAlign = ContentAlignment.MiddleCenter; label.TextAlign = ContentAlignment.MiddleCenter;
label.Margin = Padding.Empty; label.Margin = Padding.Empty;
@ -683,7 +650,8 @@ namespace AgroBase.Forms.IHM.Operacao
private System.Windows.Forms.Button btnMapaWeb; private System.Windows.Forms.Button btnMapaWeb;
private System.Windows.Forms.Button btnMapaDinamico; private System.Windows.Forms.Button btnMapaDinamico;
private AgroBase.Forms.IHM.Controls.HmiRoundedPanel pnlMapaVisual; private AgroBase.Forms.IHM.Controls.HmiRoundedPanel pnlMapaVisual;
private System.Windows.Forms.Label lblMapaPlaceholder; private System.Windows.Forms.Panel pnlMapaWeb;
private System.Windows.Forms.Panel pnlMapaDinamico;
private System.Windows.Forms.TableLayoutPanel rightTopLayout; private System.Windows.Forms.TableLayoutPanel rightTopLayout;

View File

@ -1,5 +1,5 @@
using AgroBase.Forms.IHM.Controls; using AgroBase.Forms.IHM.Controls;
using AgroBase.Forms.IHM.Controls.Operacao; using AgroBase.Models;
using System; using System;
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
@ -9,117 +9,125 @@ namespace AgroBase.Forms.IHM.Operacao
public partial class ucOperacaoNavegacao : UserControl public partial class ucOperacaoNavegacao : UserControl
{ {
private bool _alertaAutonomiaVisivel; private bool _alertaAutonomiaVisivel;
private MapaDinamicoModel _mapaDinamico;
private bool _mapasInicializados;
private bool _exibindoMapaDinamico = true;
private OperacaoModel op => Variaveis.OperacaoEmAndamento;
public ucOperacaoNavegacao() public ucOperacaoNavegacao()
{ {
InitializeComponent(); InitializeComponent();
ConfigurarEstadoInicial();
VincularEventos(); VincularEventos();
MostrarStatusAutonomia(); MostrarStatusAutonomia();
this.Load += ucOperacaoNavegacao_Load;
} }
private void ConfigurarEstadoInicial() private void ucOperacaoNavegacao_Load(object sender, EventArgs e)
{ {
SelecionarMapa(btnMapaDinamico); InicializarMapas();
MostrarMapaDinamico();
}
compassControl.RoverHeading = 128D; private void InicializarMapas()
compassControl.TrajectoryHeading = 136D; {
if (_mapasInicializados)
return;
metricSatelites.CorValor = HmiTheme.Success; Form formPai = FindForm();
metricPrecisao.CorValor = HmiTheme.Success;
metricIdadeCorrecao.CorValor = HmiTheme.Success;
metricAltitude.CorValor = HmiTheme.Success;
metricVelocidade.CorValor = HmiTheme.Success;
metricHeading.CorValor = HmiTheme.Success;
progressRua.Value = 65; if (formPai == null)
progressRua.BarColor = HmiTheme.Info; return;
progressGeral.Value = 38; _mapasInicializados = true;
progressGeral.BarColor = HmiTheme.Success; _mapaDinamico = new MapaDinamicoModel(formPai, pnlMapaDinamico);
autonomiaBateria.AccentColor = HmiTheme.Warning; if (op == null)
autonomiaHerbicida.AccentColor = HmiTheme.Danger; return;
if (op?.Mapa == null)
op.Mapa = new MapasModel();
op.Mapa.pnlMapa = pnlMapaWeb;
CarregarMapaWeb();
}
private void CarregarMapaWeb()
{
var mapa = op?.Mapa;
if (mapa == null)
return;
//mapa.btnCarregar_Click(sender as Control, e);
mapa.CarregarMapaGPS();
MostrarMapaWeb();
}
private void MostrarMapaWeb()
{
_exibindoMapaDinamico = false;
pnlMapaWeb.Visible = true;
pnlMapaDinamico.Visible = true;
pnlMapaWeb.BringToFront();
AtualizarEstadoBotoesMapa(mapaWebSelecionado: true);
}
private void MostrarMapaDinamico()
{
_exibindoMapaDinamico = true;
pnlMapaWeb.Visible = true;
pnlMapaDinamico.Visible = true;
pnlMapaDinamico.BringToFront();
AtualizarEstadoBotoesMapa(mapaWebSelecionado: false);
} }
private void VincularEventos() private void VincularEventos()
{ {
btnMapaWeb.Click += delegate btnMapaWeb.Click += btnMapaWeb_Click;
{ btnMapaDinamico.Click += btnMapaDinamico_Click;
SelecionarMapa(btnMapaWeb);
};
btnMapaDinamico.Click += delegate
{
SelecionarMapa(btnMapaDinamico);
};
btnAtualizarAutonomia.Click += btnAtualizarAutonomia_Click; btnAtualizarAutonomia.Click += btnAtualizarAutonomia_Click;
btnLiberarSupervisao.Click += btnLiberarSupervisao_Click; btnLiberarSupervisao.Click += btnLiberarSupervisao_Click;
} }
private void SelecionarMapa(Button selecionado) private void btnMapaWeb_Click(object sender, EventArgs e)
{ {
AplicarEstiloMapa(btnMapaWeb, false); MostrarMapaWeb();
AplicarEstiloMapa(btnMapaDinamico, false);
AplicarEstiloMapa(selecionado, true);
} }
private static void AplicarEstiloMapa( private void btnMapaDinamico_Click(object sender, EventArgs e)
Button button,
bool selecionado)
{ {
if (selecionado) MostrarMapaDinamico();
{
button.BackColor = Color.FromArgb(31, 91, 43);
button.ForeColor = HmiTheme.Text;
button.FlatAppearance.BorderColor = HmiTheme.Success;
}
else
{
button.BackColor = HmiTheme.SurfaceRaised;
button.ForeColor = HmiTheme.TextMuted;
button.FlatAppearance.BorderColor = HmiTheme.Border;
}
} }
public void AtualizarOrientacao( private void AtualizarEstadoBotoesMapa(bool mapaWebSelecionado)
double headingRover,
double headingTrajetoria,
bool possuiTrajetoria)
{ {
compassControl.RoverHeading = headingRover; AplicarEstadoBotaoMapa(btnMapaWeb, mapaWebSelecionado);
compassControl.TrajectoryHeading = headingTrajetoria;
compassControl.ShowTrajectory = possuiTrajetoria;
lblRoverValor.Text = AplicarEstadoBotaoMapa(btnMapaDinamico, !mapaWebSelecionado);
headingRover.ToString("0") + "°";
lblTrajetoriaValor.Text =
possuiTrajetoria
? headingTrajetoria.ToString("0") + "°"
: "--";
} }
public void AtualizarProgresso( private static void AplicarEstadoBotaoMapa(Button button, bool selecionado)
int percentualRua,
string detalheRua,
int percentualGeral,
string detalheGeral)
{ {
progressRua.Value = percentualRua; button.BackColor = selecionado
? HmiTheme.SurfaceRaised
: HmiTheme.Surface;
lblProgressoRuaValor.Text = button.ForeColor = selecionado
percentualRua + ? HmiTheme.Info
"% · " + : HmiTheme.TextMuted;
(detalheRua ?? string.Empty);
progressGeral.Value = percentualGeral; button.FlatAppearance.BorderColor = selecionado
? HmiTheme.Info
lblProgressoGeralValor.Text = : HmiTheme.Border;
percentualGeral +
"% · " +
(detalheGeral ?? string.Empty);
} }
@ -143,7 +151,6 @@ namespace AgroBase.Forms.IHM.Operacao
pnlAlertaAutonomia.BringToFront(); pnlAlertaAutonomia.BringToFront();
} }
private void RecalcularAutonomia() private void RecalcularAutonomia()
{ {
@ -194,31 +201,14 @@ namespace AgroBase.Forms.IHM.Operacao
); );
} }
private void AtualizarStatusAutonomia( private void AtualizarStatusAutonomia(string bateria, Color corBateria, string herbicida, Color corHerbicida, string corredor, Color corCorredor)
string bateria,
Color corBateria,
string herbicida,
Color corHerbicida,
string corredor,
Color corCorredor)
{ {
lblStatusBateria.Text = lblStatusBateria.Text = bateria;
bateria; lblStatusBateria.ForeColor = corBateria;
lblStatusHerbicida.Text = herbicida;
lblStatusBateria.ForeColor = lblStatusHerbicida.ForeColor = corHerbicida;
corBateria; lblStatusCorredor.Text = corredor;
lblStatusCorredor.ForeColor = corCorredor;
lblStatusHerbicida.Text =
herbicida;
lblStatusHerbicida.ForeColor =
corHerbicida;
lblStatusCorredor.Text =
corredor;
lblStatusCorredor.ForeColor =
corCorredor;
} }
public void AtualizarBloqueioAutonomia(bool corredorBloqueado, bool liberadoManualmente) public void AtualizarBloqueioAutonomia(bool corredorBloqueado, bool liberadoManualmente)
@ -232,5 +222,218 @@ namespace AgroBase.Forms.IHM.Operacao
MostrarStatusAutonomia(); MostrarStatusAutonomia();
} }
public void AtualizarDadosTela()
{
var dados = op?.Sensoriamento;
AtualizarDadosMapa();
AtualizarDadosAutonomia(dados);
AtualizarDadosOrientacao(dados);
AtualizarDadosGnss(dados?.Gps);
AtualizarDadosCorredor(dados);
AtualizarDadosTelemetria(dados?.Trajetoria?.AutonomiaCorredor);
}
private void AtualizarDadosMapa()
{
AtualizarMapaDinamico();
}
private void AtualizarMapaDinamico()
{
if (!_exibindoMapaDinamico)
return;
var _Sensoriamento = op?.Sensoriamento;
var _Trajetoria = op?.Trajetoria;
if (_Trajetoria != null && _Trajetoria?.CorredorAtual != null)
{
_mapaDinamico.AtualizarDados(
null,
(float)_Trajetoria.AnguloCaminho,
(float)_Sensoriamento.Gps.AnguloCarroDefinido,
_Sensoriamento.Gps,
_Trajetoria._TrajetoriaDinamica,
_Trajetoria.CorredorAtual.Pontos,
op.GPSTrajetoria,
_Trajetoria.RuasPlantacao,
op.Controle.SimulacaoMPC
);
}
}
private void AtualizarDadosAutonomia(OperacaoSensoriamentoConjuntoModel dados)
{
double limiar = 20.0;
double distanciaCorredor = dados?.Trajetoria?.CorredorAtual?.DistanciaTotal ?? 0;
double distanciaBateria = dados?.Bateria?.DistanciaEstimadaRestanteMetros ?? 0;
TimeSpan tempoBateria = TimeSpan.FromMinutes(Math.Max(0, dados?.Bateria?.TempoEstimadoRestanteMinutos ?? 0));
double distanciaHerbicida = dados?.Atuador?.DistanciaEstimadaRestanteMetros ?? 0;
TimeSpan tempoHerbicida = TimeSpan.FromMinutes(Math.Max(0, dados?.Atuador?.TempoEstimadoRestanteMinutos ?? 0));
autonomiaBateria.Distancia = distanciaBateria.ToString("F2") + " m";
autonomiaBateria.Tempo = FuncoesIHM.FormatarTempo(tempoBateria);
autonomiaBateria.AccentColor = FuncoesIHM.CorPorAutonomia(distanciaCorredor, distanciaBateria, limiar);
autonomiaHerbicida.Distancia = distanciaHerbicida.ToString("F2") + " m";
autonomiaHerbicida.Tempo = FuncoesIHM.FormatarTempo(tempoHerbicida);
autonomiaHerbicida.AccentColor = FuncoesIHM.CorPorAutonomia(distanciaCorredor, distanciaHerbicida, limiar);
}
private void AtualizarDadosOrientacao(OperacaoSensoriamentoConjuntoModel dados)
{
double headingCarro = dados?.Gps?.OrientacaoReal ?? 0;
double headingCaminho = dados?.Trajetoria?.AnguloCaminho ?? 0;
bool possuiTrajetoria = dados?.Trajetoria?.QtdPontos > 0;
lblRoverValor.Text = $"{headingCarro:F2}°";
lblRoverValor.ForeColor =
possuiTrajetoria ? FuncoesIHM.CorPorErroAngular(headingCarro, headingCaminho, 5.0, 15.0) :
HmiTheme.Success;
compassControl.RoverHeading = headingCarro;
compassControl.ShowTrajectory = possuiTrajetoria;
lblTrajetoriaValor.Text = possuiTrajetoria ? $"{headingCaminho:F2}°" : "--";
compassControl.TrajectoryHeading = headingCaminho;
}
private void AtualizarDadosGnss(GPSModel dados)
{
metricSatelites.Valor = (dados?.NumeroSatelites ?? 0).ToString();
metricPrecisao.Valor = (dados?.PrecisaoCm ?? 0).ToString();
metricIdadeCorrecao.Valor = ((dados?.Ntrip_ativado ?? false) ? "N" : "B") + " " + (dados?.IdadeCorrecao ?? 0).ToString("F1") + " s";
metricAltitude.Valor = (dados?.Altitude ?? 0).ToString("F2") + " m";
metricVelocidade.Valor = (dados?.Velocidade ?? 0).ToString("F2") + " km/h";
metricHeading.Valor = (dados?.OrientacaoReal ?? 0).ToString("F2") + "°";
}
private void AtualizarDadosCorredor(OperacaoSensoriamentoConjuntoModel dados)
{
var trajetoria = dados?.Trajetoria;
lblRuaAtual.Text = $"Rua {trajetoria?.IdxRuaAtual ?? 0} / {op?.Mapa?.RuasPercorrer?.Count ?? 0}";
lblDentroCorredor.Text = ((trajetoria?.CorredorAtual?.Dentro ?? false) ? "Dentro do Corredor" : "Fora do Corredor");
lblProximoPonto.Text = $"Ponto {trajetoria?.PontoAtual?.idxPonto ?? 0} / {trajetoria?.QtdPontos ?? 0}";
double _progressoRua = trajetoria?.CorredorAtual?.Progresso ?? 0;
double _distanciaPercorridaRua = trajetoria?.CorredorAtual?.DistanciaPercorridaTotal ?? 0;
double _distanciaTotalRua = trajetoria?.CorredorAtual?.DistanciaTotal ?? 0;
lblProgressoRuaValor.Text = $"{_progressoRua:F2}% · {_distanciaPercorridaRua:F2} / {_distanciaTotalRua:F2} m";
progressRua.Value = (int)_progressoRua;
double _progressoGeral = trajetoria?.ProgressoTrajeto ?? 0;
double _distanciaPercorridaGeral = trajetoria?.DistanciaPercorrida ?? 0;
double _distanciaTotalGeral = trajetoria?.DistanciaTotal ?? 0;
progressGeral.Value = (int)_progressoGeral;
lblProgressoGeralValor.Text = $"{_progressoGeral:F2}% · {_distanciaPercorridaGeral:F2} / {_distanciaTotalGeral:F2} m";
string _tempoEstimado = string.IsNullOrEmpty(trajetoria?.TempoEstimadoOperacao) ? "00:00:00" : trajetoria?.TempoEstimadoOperacao;
lblStatusMapa.Text = (trajetoria?.StatusCarro ?? Enums.StatusCarroMapa.Parado).ToString();
lblTempoOperacao.Text = dados?.Operacao?.TempoDecorrido.ToString("HH:mm:ss") + " / " + _tempoEstimado;
lblDistanciaEsq.Text = $"Esquerda {trajetoria?.DistanciaEsquerda ?? 0:F2} m";
lblDistanciaDir.Text = $"Direita {trajetoria?.DistanciaDireita ?? 0:F2} m";
}
private void AtualizarDadosTelemetria(AutonomiaCorredorModel dados)
{
lblStatusBateria.Text = MontarStatusBateria(dados);
lblStatusHerbicida.Text = MontarStatusHerbicida(dados);
lblStatusCorredor.Text = MontarStatusCorredor(dados);
lblStatusAvaliacao.Text = MontarStatusAvaliacao(dados);
}
private static string MontarStatusBateria(AutonomiaCorredorModel autonomia)
{
if (autonomia == null)
return "Bateria: autonomia indisponível";
if (!autonomia.DadosBateriaValidos)
return "Bateria: autonomia indisponível";
if (autonomia.BateriaOverrideAplicado)
{
return string.Format("Bateria: liberada pelo operador · folga {0:F1} m", autonomia.FolgaBateria_m);
}
if (autonomia.BateriaSuficiente)
{
return string.Format("Bateria: suficiente · folga {0:F1} m", autonomia.FolgaBateria_m);
}
return string.Format("Bateria: insuficiente · faltam {0:F1} m", Math.Abs(autonomia.FolgaBateria_m));
}
private static string MontarStatusHerbicida(AutonomiaCorredorModel autonomia)
{
if (autonomia == null)
return "Herbicida: não exigido neste corredor";
if (!autonomia.PulverizacaoExigida)
return "Herbicida: não exigido neste corredor";
if (!autonomia.DadosHerbicidaValidos)
return "Herbicida: autonomia indisponível";
if (autonomia.HerbicidaOverrideAplicado)
{
return string.Format("Herbicida: liberado pelo operador · folga {0:F1} m", autonomia.FolgaHerbicida_m);
}
if (autonomia.HerbicidaSuficiente)
{
return string.Format("Herbicida: suficiente · folga {0:F1} m", autonomia.FolgaHerbicida_m);
}
return string.Format("Herbicida: insuficiente · faltam {0:F1} m", Math.Abs(autonomia.FolgaHerbicida_m));
}
private static string MontarStatusCorredor(AutonomiaCorredorModel autonomia)
{
if (autonomia == null)
return "Corredor: avaliação inativa";
if (!autonomia.Iniciado)
return "Corredor: avaliação inativa";
if (autonomia.ConfirmadoParaEntrada)
return "Corredor: entrada confirmada";
if (autonomia.Liberado)
return "Corredor: liberado";
switch (autonomia.Status)
{
case AutonomiaCorredorStatus.AguardandoLiberacaoManual:
return "Corredor: aguardando liberação manual";
case AutonomiaCorredorStatus.Critico:
return "Corredor: bloqueado por autonomia";
default:
return "Corredor: não liberado";
}
}
private static string MontarStatusAvaliacao(AutonomiaCorredorModel autonomia)
{
if (!string.IsNullOrWhiteSpace(autonomia?.Motivo))
return autonomia.Motivo;
if (autonomia?.Avisos != null && autonomia?.Avisos?.Count > 0)
{
return autonomia.Avisos[0];
}
return "Nova avaliação na próxima troca de rua";
}
} }
} }

View File

@ -1,5 +1,6 @@
using AgroBase.Forms.IHM.Controls; using AgroBase.Forms.IHM.Controls;
using AgroBase.Forms.IHM.Operacao.Parametros; using AgroBase.Forms.IHM.Operacao.Parametros;
using AgroBase.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
@ -18,10 +19,7 @@ namespace AgroBase.Forms.IHM.Operacao
private readonly ucParametrosAtuador _ucAtuador; private readonly ucParametrosAtuador _ucAtuador;
private readonly ucParametrosMapa _ucMapa; private readonly ucParametrosMapa _ucMapa;
public event EventHandler RedefinirSolicitado; private OperacaoModel operacaoParametrizando;
public event EventHandler SalvarSolicitado;
public event EventHandler ModoOperacaoAlterado;
public event EventHandler RegistrarPosProcessamentoAlterado;
public ucOperacaoParametros() public ucOperacaoParametros()
{ {
@ -39,8 +37,8 @@ namespace AgroBase.Forms.IHM.Operacao
_abas.Add(TipoAbaParametros.Mapa, _ucMapa); _abas.Add(TipoAbaParametros.Mapa, _ucMapa);
ConfigurarSubControles(); ConfigurarSubControles();
ConfigurarEstadoInicial();
VincularEventos(); VincularEventos();
ConfigurarEstadoInicial();
} }
private void ConfigurarSubControles() private void ConfigurarSubControles()
@ -59,11 +57,7 @@ namespace AgroBase.Forms.IHM.Operacao
cmbModoOperacao.Items.Clear(); cmbModoOperacao.Items.Clear();
cmbModoOperacao.Items.AddRange(Enum.GetNames(typeof(ModoOperacao))); cmbModoOperacao.Items.AddRange(Enum.GetNames(typeof(ModoOperacao)));
if (cmbModoOperacao.Items.Count > 1) cmbModoOperacao.SelectedIndex = (int)(Variaveis.OperacaoEmAndamento?.Sensoriamento?.Operacao?.Modo ?? ModoOperacao.NaoDefinido);
cmbModoOperacao.SelectedIndex = 1;
checkPosProcessamento.Checked = true;
AtualizarAparenciaCheck(checkPosProcessamento);
AbrirAba(TipoAbaParametros.Movimento); AbrirAba(TipoAbaParametros.Movimento);
} }
@ -75,33 +69,45 @@ namespace AgroBase.Forms.IHM.Operacao
btnAbaAtuador.Click += delegate { AbrirAba(TipoAbaParametros.Atuador); }; btnAbaAtuador.Click += delegate { AbrirAba(TipoAbaParametros.Atuador); };
btnAbaMapa.Click += delegate { AbrirAba(TipoAbaParametros.Mapa); }; btnAbaMapa.Click += delegate { AbrirAba(TipoAbaParametros.Mapa); };
btnRedefinir.Click += delegate btnRedefinir.Click += BtnRedefinir_Click;
{ btnSalvar.Click += BtnSalvar_Click;
if (RedefinirSolicitado != null) cmbModoOperacao.SelectedIndexChanged += CmbModoOperacao_SelectedIndexChanged;
RedefinirSolicitado(this, EventArgs.Empty);
};
btnSalvar.Click += delegate
{
if (SalvarSolicitado != null)
SalvarSolicitado(this, EventArgs.Empty);
};
cmbModoOperacao.SelectedIndexChanged += delegate
{
if (ModoOperacaoAlterado != null)
ModoOperacaoAlterado(this, EventArgs.Empty);
};
checkPosProcessamento.CheckedChanged += delegate
{
AtualizarAparenciaCheck(checkPosProcessamento);
if (RegistrarPosProcessamentoAlterado != null)
RegistrarPosProcessamentoAlterado(this, EventArgs.Empty);
};
} }
private void DefinirOperacaoParametrizando(OperacaoModel operacao)
{
operacaoParametrizando = operacao;
_ucMovimento.DefinirOperacao(operacaoParametrizando);
_ucDirecional.DefinirOperacao(operacaoParametrizando);
_ucAtuador.DefinirOperacao(operacaoParametrizando);
_ucMapa.DefinirOperacao(operacaoParametrizando);
}
private void CmbModoOperacao_SelectedIndexChanged(object sender, EventArgs e)
{
ModoOperacao modo = (ModoOperacao)cmbModoOperacao.SelectedIndex;
OperacaoModel novaOperacao = OperacaoModel.CarregarParametrosOperacaoPadrao(modo, true);
DefinirOperacaoParametrizando(novaOperacao);
}
private void BtnSalvar_Click(object sender, EventArgs e)
{
if (operacaoParametrizando == null)
return;
OperacaoModel.CarregarParamerosOperacaoBase(operacaoParametrizando.Parametros);
}
private void BtnRedefinir_Click(object sender, EventArgs e)
{
ModoOperacao modo = (ModoOperacao)cmbModoOperacao.SelectedIndex;
OperacaoModel novaOperacao = OperacaoModel.CarregarParametrosOperacaoPadrao(modo, true);
DefinirOperacaoParametrizando(novaOperacao);
}
private void AbrirAba(TipoAbaParametros aba) private void AbrirAba(TipoAbaParametros aba)
{ {
_abaAtual = aba; _abaAtual = aba;
@ -162,68 +168,7 @@ namespace AgroBase.Forms.IHM.Operacao
} }
} }
private static void AtualizarAparenciaCheck(CheckBox check)
{
if (check.Checked)
{
check.Text = "✓";
check.ForeColor = HmiTheme.Success;
check.BackColor = Color.FromArgb(30, 90, 46);
check.FlatAppearance.BorderColor = HmiTheme.Success;
}
else
{
check.Text = "×";
check.ForeColor = HmiTheme.Danger;
check.BackColor = HmiTheme.Surface;
check.FlatAppearance.BorderColor = HmiTheme.Danger;
}
}
public string ModoOperacaoSelecionado
{
get { return Convert.ToString(cmbModoOperacao.SelectedItem); }
set
{
if (string.IsNullOrWhiteSpace(value))
return;
int index = cmbModoOperacao.FindStringExact(value);
if (index >= 0)
cmbModoOperacao.SelectedIndex = index;
}
}
public bool RegistrarPosProcessamento
{
get { return checkPosProcessamento.Checked; }
set { checkPosProcessamento.Checked = value; }
}
public TipoAbaParametros AbaAtual
{
get { return _abaAtual; }
}
public ucParametrosMovimento Movimento
{
get { return _ucMovimento; }
}
public ucParametrosDirecional Direcional
{
get { return _ucDirecional; }
}
public ucParametrosAtuador Atuador
{
get { return _ucAtuador; }
}
public ucParametrosMapa Mapa
{
get { return _ucMapa; }
}
} }
public enum TipoAbaParametros public enum TipoAbaParametros

View File

@ -2,8 +2,8 @@
using AgroBase.Forms.IHM.Controls.Operacao; using AgroBase.Forms.IHM.Controls.Operacao;
using AgroBase.Models; using AgroBase.Models;
using AgroBase.Models.Operadores; using AgroBase.Models.Operadores;
using AgroBase.Services;
using AgroBase.Services.Operadores; using AgroBase.Services.Operadores;
using Assimp.Unmanaged;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
@ -19,9 +19,14 @@ namespace AgroBase.Forms.IHM.Operacao
private bool _requisitandoCameraFrame; private bool _requisitandoCameraFrame;
private bool _controleDescartado; private bool _controleDescartado;
OperacaoModel op => Variaveis.OperacaoEmAndamento; private OperacaoModel op => Variaveis.OperacaoEmAndamento;
private readonly List<HmiNozzleCard> _bicos = new List<HmiNozzleCard>(); private readonly List<HmiNozzleCard> _bicos = new List<HmiNozzleCard>();
public IList<HmiNozzleCard> Bicos
{
get { return _bicos.AsReadOnly(); }
}
public ucOperacaoPulverizador() public ucOperacaoPulverizador()
{ {
@ -66,44 +71,41 @@ namespace AgroBase.Forms.IHM.Operacao
private void AtualizarSaudeModulos() private void AtualizarSaudeModulos()
{ {
var saude_m = op?.Sensoriamento?.OperadorSaude?.ModulosSaude; var saude_m = op?.Sensoriamento?.OperadorSaude?.ModulosSaude;
var saude_i = saude_m?.FirstOrDefault(x => x.modulo == Enums.T_Code.Atu)?.saude_individual; var saude_i = saude_m?.FirstOrDefault(x => x.modulo == T_Code.Atu)?.saude_individual;
var saudeBomba = saude_i?.FirstOrDefault(x => x.label == op?.DispAtu?.Dados?.BombaPressurizadora?.ID); var saudeBomba = saude_i?.FirstOrDefault(x => x.label == op?.DispAtu?.Dados?.BombaPressurizadora?.ID);
var saudeAgitador = saude_i?.FirstOrDefault(x => x.label == op?.DispAtu?.Dados?.AgitadorDeCalda?.ID); var saudeAgitador = saude_i?.FirstOrDefault(x => x.label == op?.DispAtu?.Dados?.AgitadorDeCalda?.ID);
var saudeSensores = saude_i?.Where(x => op?.DispAtu?.Dados?.Sensores?.Where(y => y.Aferir)?.Select(y => y.ID).Contains(x.label) ?? false)?.ToList(); var saudeSensores = saude_i?.Where(x => op?.DispAtu?.Dados?.Sensores?.Where(y => y.Aferir)?.Select(y => y.ID).Contains(x.label) ?? false)?.ToList();
var saudeBicos = saude_i?.Where(x => op?.DispAtu?.Dados?.BicosPulverizadores?.Where(y => y.Comandar)?.Select(y => y.ID).Contains(x.label) ?? false)?.ToList(); var saudeBicos = saude_i?.Where(x => op?.DispAtu?.Dados?.BicosPulverizadores?.Where(y => y.Comandar)?.Select(y => y.ID).Contains(x.label) ?? false)?.ToList();
var saudeCamera = saude_m?.FirstOrDefault(x => x.modulo == Enums.T_Code.Cam); var saudeCamera = saude_m?.FirstOrDefault(x => x.modulo == T_Code.Cam);
var saudeSensoresMedia = saudeSensores?.Average(x => x.saude) ?? 0; var saudeSensoresMedia = saudeSensores?.Average(x => x.saude) ?? 0;
Enums.StatusModulo saudeSensoresStatus = StatusModulo saudeSensoresStatus =
saudeSensoresMedia >= 80 ? Enums.StatusModulo.Operante : saudeSensoresMedia >= 80 ? StatusModulo.Operante :
saudeSensoresMedia <= 0 ? Enums.StatusModulo.Falha : saudeSensoresMedia <= 0 ? StatusModulo.Falha :
Enums.StatusModulo.Alerta; StatusModulo.Alerta;
var saudeBicosMedia = saudeBicos?.Average(x => x.saude) ?? 0; var saudeBicosMedia = saudeBicos?.Average(x => x.saude) ?? 0;
Enums.StatusModulo saudeBicosStatus = StatusModulo saudeBicosStatus =
saudeBicosMedia >= 80 ? Enums.StatusModulo.Operante : saudeBicosMedia >= 80 ? StatusModulo.Operante :
saudeBicosMedia <= 0 ? Enums.StatusModulo.Falha : saudeBicosMedia <= 0 ? StatusModulo.Falha :
Enums.StatusModulo.Alerta; StatusModulo.Alerta;
void DefinirSaudeModulo(HmiSprayerModuleHealthRow card, double saude, Enums.StatusModulo status) void DefinirSaudeModulo(HmiSprayerModuleHealthRow card, HmiRoundedPanel pnl, double saude, StatusModulo status)
{ {
card.Saude = saude.ToString("F0") + "%"; card.Saude = saude.ToString("F0") + "%";
card.Status = status.ToString(); card.Status = status.ToString();
card.StatusColor = card.StatusColor = FuncoesIHM.CorPorStatusModulo(status);
status == Enums.StatusModulo.Operante ? HmiTheme.Success :
status == Enums.StatusModulo.Alerta ? HmiTheme.Warning : if (pnl != null)
status == Enums.StatusModulo.Falha ? HmiTheme.Danger : FuncoesIHM.AplicarEstadoPainel(pnl, card.StatusColor);
status == Enums.StatusModulo.Desconectado ? HmiTheme.Disabled :
status == Enums.StatusModulo.Conectado ? HmiTheme.Info :
HmiTheme.Disabled;
} }
DefinirSaudeModulo(healthBomba, saudeBomba?.saude ?? 0, saudeBomba?.status ?? Enums.StatusModulo.Desconectado); DefinirSaudeModulo(healthBomba, pnlBomba, saudeBomba?.saude ?? 0, saudeBomba?.status ?? StatusModulo.Desconectado);
DefinirSaudeModulo(healthAgitador, saudeAgitador?.saude ?? 0, saudeAgitador?.status ?? Enums.StatusModulo.Desconectado); DefinirSaudeModulo(healthAgitador, pnlAgitador, saudeAgitador?.saude ?? 0, saudeAgitador?.status ?? StatusModulo.Desconectado);
DefinirSaudeModulo(healthSensores, saudeSensoresMedia, saudeSensoresStatus); DefinirSaudeModulo(healthSensores, pnlTelemetria, saudeSensoresMedia, saudeSensoresStatus);
DefinirSaudeModulo(healthBicos, saudeBicosMedia, saudeBicosStatus); DefinirSaudeModulo(healthBicos, pnlBicos, saudeBicosMedia, saudeBicosStatus);
DefinirSaudeModulo(healthCamera, saudeCamera?.saude ?? 0, saudeCamera?.status ?? Enums.StatusModulo.Desconectado); DefinirSaudeModulo(healthCamera, pnlVideo, saudeCamera?.saude ?? 0, saudeCamera?.status ?? StatusModulo.Desconectado);
} }
public async void AtualizarDadosCamera(CameraWorkerItemModel dados, double saude) public async void AtualizarDadosCamera(CameraWorkerItemModel dados, double saude)
@ -222,11 +224,11 @@ namespace AgroBase.Forms.IHM.Operacao
telemetryPressaoSensor.Valor = (dados?.PressaoSensor ?? 0).ToString("F1") + " psi"; telemetryPressaoSensor.Valor = (dados?.PressaoSensor ?? 0).ToString("F1") + " psi";
telemetryPressaoBomba.Valor = (dados?.PressaoAtualBomba ?? 0).ToString("F1") + " psi"; telemetryPressaoBomba.Valor = (dados?.PressaoAtualBomba ?? 0).ToString("F1") + " psi";
telemetryAutonomiaM.Valor = (dados?.DistanciaEstimadaRestanteMetros ?? 0).ToString("F1") + " m"; telemetryAutonomiaM.Valor = (dados?.DistanciaEstimadaRestanteMetros ?? 0).ToString("F1") + " m";
telemetryAutonomiaTempo.Valor = FormatarTempo(tempoAutonomia); telemetryAutonomiaTempo.Valor = FuncoesIHM.FormatarTempo(tempoAutonomia);
telemetryVolumeAplicado.Valor = (dados?.VolumeVazaoML ?? 0).ToString("F1") + " L"; telemetryVolumeAplicado.Valor = (dados?.VolumeVazaoML ?? 0).ToString("F1") + " L";
telemetryLitroMetro.Valor = (dados?.LPorMetro ?? 0).ToString("F1") + " L/m"; telemetryLitroMetro.Valor = (dados?.LPorMetro ?? 0).ToString("F1") + " L/m";
telemetryInfestacao.Valor = (dados?.PercentualErvasTerreno ?? 0).ToString("F1") + "% · Baixa"; telemetryInfestacao.Valor = (dados?.PercentualErvasTerreno ?? 0).ToString("F1") + "% · Baixa";
telemetryTempoLigado.Valor = FormatarTempo(tempoPulverizador); telemetryTempoLigado.Valor = FuncoesIHM.FormatarTempo(tempoPulverizador);
} }
@ -256,15 +258,90 @@ namespace AgroBase.Forms.IHM.Operacao
telemetryLitroMetro.CorValor = HmiTheme.Info; telemetryLitroMetro.CorValor = HmiTheme.Info;
telemetryInfestacao.CorValor = HmiTheme.Success; telemetryInfestacao.CorValor = HmiTheme.Success;
telemetryTempoLigado.CorValor = HmiTheme.Manual; telemetryTempoLigado.CorValor = HmiTheme.Manual;
AplicarEstadoPainel(pnlBomba, HmiTheme.Warning);
AplicarEstadoPainel(pnlAgitador, HmiTheme.Success);
} }
private void VincularEventos() private void VincularEventos()
{ {
foreach (HmiNozzleCard card in _bicos) foreach (HmiNozzleCard card in _bicos)
card.NozzleClick += NozzleCard_Click; card.NozzleClick += NozzleCard_Click;
btnDesligarAgitador.Click += BtnDesligarAgitador_Click;
btnLigarAgitador.Click += BtnLigarAgitador_Click;
btnDesligarBomba.Click += BtnDesligarBomba_Click;
btnLigarBomba.Click += BtnLigarBomba_Click;
}
private void BtnLigarBomba_Click(object sender, EventArgs e)
{
var Bomba = op?.DispAtu?.Dados?.BombaPressurizadora;
if (Bomba != null)
{
op?.DispAtu?.Dados?.EnviarComandoFisicoBomba(
Bomba,
CanMessagePosicaoDados.Command2,
setarControle: true,
status: true
);
op?.DispAtu?.Dados?.EnviarComandoFisicoBomba(
Bomba,
CanMessagePosicaoDados.Command1,
setarControle: true,
status: true
);
}
}
private void BtnDesligarBomba_Click(object sender, EventArgs e)
{
var Bomba = op?.DispAtu?.Dados?.BombaPressurizadora;
if (Bomba != null)
op?.DispAtu?.Dados?.EnviarComandoFisicoBomba(
Bomba,
CanMessagePosicaoDados.Command1,
setarControle: true,
status: false
);
}
private void BtnLigarAgitador_Click(object sender, EventArgs e)
{
var Agitador = op?.DispAtu?.Dados?.AgitadorDeCalda;
if (Agitador != null)
{
op.Parametros.Controle.AtuAgitadorModo = ModoAgitadorCalda.Manual;
op?.DispAtu?.Dados?.EnviarComandoFisicoBomba(
Agitador,
CanMessagePosicaoDados.Command2,
setarControle: true,
status: true
);
op?.DispAtu?.Dados?.EnviarComandoFisicoBomba(
Agitador,
CanMessagePosicaoDados.Command1,
setarControle: true,
status: true
);
}
}
private void BtnDesligarAgitador_Click(object sender, EventArgs e)
{
if (!(op?.Parametros?.Controle?.ControleManualAcionado ?? false))
return;
op.Parametros.Controle.AtuAgitadorModo = ModoAgitadorCalda.SemAgitacao;
var Agitador = op?.DispAtu?.Dados?.AgitadorDeCalda;
if (Agitador != null)
op?.DispAtu?.Dados?.EnviarComandoFisicoBomba(
Agitador,
CanMessagePosicaoDados.Command1,
setarControle: true,
status: false
);
} }
private void NozzleCard_Click(object sender, EventArgs e) private void NozzleCard_Click(object sender, EventArgs e)
@ -273,36 +350,28 @@ namespace AgroBase.Forms.IHM.Operacao
if (card == null) if (card == null)
return; return;
if (!(op?.Parametros?.Controle?.ControleManualAcionado ?? false))
return;
var bico = op?.DispAtu?.Dados?.BicosPulverizadores?.FirstOrDefault(x => x.ID == card.Codigo);
if (bico == null)
return;
card.CommandOn = !card.CommandOn; card.CommandOn = !card.CommandOn;
}
private static void AplicarEstadoPainel(HmiRoundedPanel panel, Color color) op?.DispAtu?.Dados?.EnviarComandoFisicoBico(
{ bico,
panel.BorderColor = color; CanMessagePosicaoDados.Command1,
panel.Invalidate(); setarControle: true,
} status:
card.CommandOn
public IList<HmiNozzleCard> Bicos
{
get { return _bicos.AsReadOnly(); }
}
private static string FormatarTempo(TimeSpan tempo)
{
if (tempo < TimeSpan.Zero)
tempo = TimeSpan.Zero;
int horasTotais = (int)tempo.TotalHours;
return string.Format(
"{0:00}:{1:00}:{2:00}",
horasTotais,
tempo.Minutes,
tempo.Seconds
); );
} }
} }
} }

View File

@ -260,31 +260,31 @@ namespace AgroBase.Forms.IHM
// ========================================================= // =========================================================
double bateria = operacao?.Sensoriamento?.Bateria?.PercentualBateria ?? 0; double bateria = operacao?.Sensoriamento?.Bateria?.PercentualBateria ?? 0;
double bateriaSaude = ObterSaudeModulo(saudeModulos, Enums.T_Code.Bat); double bateriaSaude = ObterSaudeModulo(saudeModulos, Enums.T_Code.Bat);
Color corBateria = CorPorValorESaude(bateria, bateriaSaude); Color corBateria = FuncoesIHM.CorPorValorESaude(bateria, bateriaSaude);
AtualizarBateria($"{Limitar(bateria, 0, 100):0}%", corBateria); AtualizarBateria($"{FuncoesIHM.Limitar(bateria, 0, 100):0}%", corBateria);
// ========================================================= // =========================================================
// RESERVATÓRIO // RESERVATÓRIO
// ========================================================= // =========================================================
double reservatorio = operacao?.Sensoriamento?.Atuador?.PercentualReservatorio ?? 0; double reservatorio = operacao?.Sensoriamento?.Atuador?.PercentualReservatorio ?? 0;
double atuadorSaude = ObterSaudeModulo(saudeModulos, Enums.T_Code.Atu); double atuadorSaude = ObterSaudeModulo(saudeModulos, Enums.T_Code.Atu);
Color corReservatorio = CorPorValorESaude(reservatorio, atuadorSaude); Color corReservatorio = FuncoesIHM.CorPorValorESaude(reservatorio, atuadorSaude);
AtualizarReservatorio($"{Limitar(reservatorio, 0, 100):0}%", corReservatorio); AtualizarReservatorio($"{FuncoesIHM.Limitar(reservatorio, 0, 100):0}%", corReservatorio);
// ========================================================= // =========================================================
// TEMPERATURA // TEMPERATURA
// ========================================================= // =========================================================
double temperatura = operacao?.Sensoriamento?.CoolerControl?.Temperatura ?? 0; double temperatura = operacao?.Sensoriamento?.CoolerControl?.Temperatura ?? 0;
double temperaturaSaude = ObterSaudeModulo(saudeModulos, Enums.T_Code.Npc); double temperaturaSaude = ObterSaudeModulo(saudeModulos, Enums.T_Code.Npc);
Color corTemperatura = CorTemperatura(temperatura, temperaturaSaude); Color corTemperatura = FuncoesIHM.CorTemperatura(temperatura, temperaturaSaude);
AtualizarTemperatura($"{temperatura:0.#} °C", corTemperatura); AtualizarTemperatura($"{temperatura:0.#} °C", corTemperatura);
// ========================================================= // =========================================================
// REDE / IPB // REDE / IPB
// ========================================================= // =========================================================
double redeSaude = ObterSaudeModulo(saudeModulos, Enums.T_Code.Ipb); double redeSaude = ObterSaudeModulo(saudeModulos, Enums.T_Code.Ipb);
Color corRede = CorPorPercentual(redeSaude); Color corRede = FuncoesIHM.CorPorPercentual(redeSaude);
AtualizarRede($"{Limitar(redeSaude, 0, 100):0}%", corRede); AtualizarRede($"{FuncoesIHM.Limitar(redeSaude, 0, 100):0}%", corRede);
// ========================================================= // =========================================================
// GNSS // GNSS
@ -300,9 +300,9 @@ namespace AgroBase.Forms.IHM
{ {
Enums.TiposCorrecaoGPS qualidadeFix = gnss.QualidadeFix; Enums.TiposCorrecaoGPS qualidadeFix = gnss.QualidadeFix;
double precisaoCm = Math.Max(0, gnss.PrecisaoCm); double precisaoCm = Math.Max(0, gnss.PrecisaoCm);
double notaGnss = CalcularNotaGnss(qualidadeFix, precisaoCm, gnssSaude); double notaGnss = FuncoesIHM.CalcularNotaGnss(qualidadeFix, precisaoCm, gnssSaude);
Color corGnss = CorPorPercentual(notaGnss); Color corGnss = FuncoesIHM.CorPorPercentual(notaGnss);
string textoGnss = $"{FormatarQualidadeGnss(qualidadeFix)} " + $"{precisaoCm:0.##} cm"; string textoGnss = $"{FuncoesIHM.FormatarQualidadeGnss(qualidadeFix)} " + $"{precisaoCm:0.##} cm";
AtualizarGnss(textoGnss, corGnss); AtualizarGnss(textoGnss, corGnss);
} }
@ -317,8 +317,8 @@ namespace AgroBase.Forms.IHM
else else
{ {
double distanciaBase = GPSUtils.DistanciaEntrePontos(gnss, VariaveisOperacao.PosicaoBase); double distanciaBase = GPSUtils.DistanciaEntrePontos(gnss, VariaveisOperacao.PosicaoBase);
Color corBase = CorDistanciaBase(distanciaBase, 1000); Color corBase = FuncoesIHM.CorDistanciaBase(distanciaBase, 1000);
string distanciaTexto = FormatarDistancia(distanciaBase); string distanciaTexto = FuncoesIHM.FormatarDistancia(distanciaBase);
AtualizarDistanciaBase(distanciaTexto, corBase); AtualizarDistanciaBase(distanciaTexto, corBase);
} }
@ -392,7 +392,7 @@ namespace AgroBase.Forms.IHM
lblIndicadorStatus.ForeColor = corStatus; lblIndicadorStatus.ForeColor = corStatus;
pnlStatusOperacao.AccentColor = corStatus; pnlStatusOperacao.AccentColor = corStatus;
pnlStatusOperacao.BorderColor = MisturarCores(HmiTheme.BorderSoft, corStatus, 0.35F); pnlStatusOperacao.BorderColor = FuncoesIHM.MisturarCores(HmiTheme.BorderSoft, corStatus, 0.35F);
}); });
} }
@ -511,205 +511,7 @@ namespace AgroBase.Forms.IHM
acao(); acao();
} }
private static Color MisturarCores(Color baseColor, Color accentColor, float pesoAccent)
{
pesoAccent = Math.Max(0F, Math.Min(1F, pesoAccent));
float pesoBase = 1F - pesoAccent;
return Color.FromArgb(
(int)(baseColor.R * pesoBase + accentColor.R * pesoAccent),
(int)(baseColor.G * pesoBase + accentColor.G * pesoAccent),
(int)(baseColor.B * pesoBase + accentColor.B * pesoAccent)
);
}
private static Color CorPorPercentual(double percentual)
{
percentual = Limitar(percentual, 0, 100);
if (percentual <= 50)
{
double fator = percentual / 50.0;
return InterpolarCor(HmiTheme.Danger, HmiTheme.Warning, fator);
}
double fatorVerde = (percentual - 50) / 50.0;
return InterpolarCor(HmiTheme.Warning, HmiTheme.Success, fatorVerde);
}
private static Color CorPorValorESaude(double valor, double saude)
{
double notaFinal = Math.Min(Limitar(valor, 0, 100), Limitar(saude, 0, 100));
return CorPorPercentual(notaFinal);
}
private static Color CorTemperatura(double temperatura, double saudeModulo)
{
Color corTemperatura;
if (temperatura <= 45)
{
corTemperatura = HmiTheme.Success;
}
else if (temperatura <= 60)
{
double fator = (temperatura - 45) / (60 - 45);
corTemperatura = InterpolarCor(HmiTheme.Success, HmiTheme.Warning, fator);
}
else if (temperatura <= 75)
{
double fator = (temperatura - 60) / (75 - 60);
corTemperatura = InterpolarCor(HmiTheme.Warning, HmiTheme.Danger, fator);
}
else
{
corTemperatura = HmiTheme.Danger;
}
Color corSaude = CorPorPercentual(saudeModulo);
/*
* Se a saúde estiver muito baixa,
* ela prevalece sobre a temperatura.
*/
if (saudeModulo < 40)
return corSaude;
return corTemperatura;
}
private static double NotaQualidadeGnss(Enums.TiposCorrecaoGPS qualidade)
{
switch (qualidade)
{
case Enums.TiposCorrecaoGPS.RTKFixo:
return 100;
case Enums.TiposCorrecaoGPS.BaseFix:
return 100;
case Enums.TiposCorrecaoGPS.RTKFlutuante:
return 78;
case Enums.TiposCorrecaoGPS.PPS:
return 65;
case Enums.TiposCorrecaoGPS.DGPS:
return 58;
case Enums.TiposCorrecaoGPS.DeadReckoing:
return 35;
case Enums.TiposCorrecaoGPS.Autonomo:
return 22;
case Enums.TiposCorrecaoGPS.SemCorrecao:
default:
return 0;
}
}
private static double NotaPrecisaoGnss(double precisaoCm)
{
if (precisaoCm <= 2)
return 100;
if (precisaoCm <= 5)
return InterpolarValor(precisaoCm, 2, 5, 100, 90);
if (precisaoCm <= 10)
return InterpolarValor(precisaoCm, 5, 10, 90, 75);
if (precisaoCm <= 30)
return InterpolarValor(precisaoCm, 10, 30, 75, 50);
if (precisaoCm <= 100)
return InterpolarValor(precisaoCm, 30, 100, 50, 20);
return 5;
}
private static double CalcularNotaGnss(Enums.TiposCorrecaoGPS qualidade, double precisaoCm, double saudeModulo)
{
double notaFix = NotaQualidadeGnss(qualidade);
double notaPrecisao = NotaPrecisaoGnss(precisaoCm);
/*
* O pior dos três critérios define a cor.
*
* RTK Fixo com saúde ruim não fica verde.
* Saúde boa com modo autônomo também não.
*/
return Math.Min(notaFix, Math.Min(notaPrecisao, Limitar(saudeModulo, 0, 100)));
}
private static string FormatarQualidadeGnss(Enums.TiposCorrecaoGPS qualidade)
{
switch (qualidade)
{
case Enums.TiposCorrecaoGPS.SemCorrecao:
return "Sem correção";
case Enums.TiposCorrecaoGPS.Autonomo:
return "Autônomo";
case Enums.TiposCorrecaoGPS.DGPS:
return "DGPS";
case Enums.TiposCorrecaoGPS.PPS:
return "PPS";
case Enums.TiposCorrecaoGPS.RTKFixo:
return "RTK Fixo";
case Enums.TiposCorrecaoGPS.RTKFlutuante:
return "RTK Flutuante";
case Enums.TiposCorrecaoGPS.DeadReckoing:
return "Dead Reckoning";
case Enums.TiposCorrecaoGPS.BaseFix:
return "Base Fix";
default:
return "Desconhecido";
}
}
private static Color CorDistanciaBase(double distanciaMetros, double distanciaMaximaMetros)
{
if (double.IsNaN(distanciaMetros) || double.IsInfinity(distanciaMetros) || distanciaMetros < 0)
{
return HmiTheme.Danger;
}
double percentualSaudavel = 100 - (distanciaMetros / distanciaMaximaMetros * 100);
return CorPorPercentual(percentualSaudavel);
}
private static string FormatarDistancia(double distanciaMetros)
{
if (double.IsNaN(distanciaMetros) || double.IsInfinity(distanciaMetros) || distanciaMetros < 0)
{
return "Indisponível";
}
if (distanciaMetros >= 1000)
{
return $"{distanciaMetros / 1000.0:0.00} km";
}
return $"{distanciaMetros:0.0} m";
}
private void AtualizarStatusOperacao(Enums.StatusOperacao status, bool pausada, bool emergencia, int? inicio_em = null) private void AtualizarStatusOperacao(Enums.StatusOperacao status, bool pausada, bool emergencia, int? inicio_em = null)
{ {
string titulo; string titulo;
@ -843,39 +645,10 @@ namespace AgroBase.Forms.IHM
if (item == null) if (item == null)
return 0; return 0;
return Limitar(Convert.ToDouble(item.saude), 0, 100); return FuncoesIHM.Limitar(Convert.ToDouble(item.saude), 0, 100);
}
private static Color InterpolarCor(Color inicial, Color final, double fator)
{
fator = Limitar(fator, 0, 1);
int r = (int)Math.Round(inicial.R + (final.R - inicial.R) * fator);
int g = (int)Math.Round(inicial.G + (final.G - inicial.G) * fator);
int b = (int)Math.Round(inicial.B + (final.B - inicial.B) * fator);
return Color.FromArgb(r, g, b);
}
private static double InterpolarValor(double valor, double origemMinima, double origemMaxima, double destinoInicial, double destinoFinal)
{
if (origemMaxima <= origemMinima)
return destinoInicial;
double fator = (valor - origemMinima) / (origemMaxima - origemMinima);
fator = Limitar(fator, 0, 1);
return destinoInicial + (destinoFinal - destinoInicial) * fator;
}
private static double Limitar(double valor, double minimo, double maximo)
{
return Math.Max(minimo, Math.Min(maximo, valor));
} }
} }

View File

@ -56,6 +56,7 @@ namespace AgroBase.Forms.IHM
_ucPulverizador.AtualizarDadosTela(); _ucPulverizador.AtualizarDadosTela();
break; break;
case AbaOperacaoIHM.Navegacao: case AbaOperacaoIHM.Navegacao:
_ucNavegacao.AtualizarDadosTela();
break; break;
case AbaOperacaoIHM.Parametros: case AbaOperacaoIHM.Parametros:
break; break;

View File

@ -258,7 +258,7 @@ namespace AgroBase
GeneralJoystick.AtualizaDispositivo(); GeneralJoystick.AtualizaDispositivo();
cmbJoysticks.Items.Clear(); cmbJoysticks.Items.Clear();
cmbJoysticks.Items.AddRange(GeneralJoystick.JoysticksConectados.ToArray()); cmbJoysticks.Items.AddRange(GeneralJoystick.JoysticksConectados.ToArray());
cmbJoysticks.SelectedIndex = GeneralJoystick.JoysticksConectados.IndexOf(GeneralJoystick.JoystickConectado.Information.InstanceName); cmbJoysticks.SelectedIndex = GeneralJoystick.JoysticksConectados.IndexOf(GeneralJoystick.JoystickConectado?.Information?.InstanceName);
} }
private void btnJoyEdt_Click(object sender, EventArgs e) private void btnJoyEdt_Click(object sender, EventArgs e)

View File

@ -381,6 +381,7 @@
SemAgitacao = 0, SemAgitacao = 0,
Continuo = 1, Continuo = 1,
Intermitente = 2, Intermitente = 2,
Manual = 3,
} }
public enum ModoControleBomba public enum ModoControleBomba

View File

@ -45,7 +45,7 @@ namespace AgroBase.Models
private RenderState _state = RenderState.Empty; private RenderState _state = RenderState.Empty;
private readonly Panel _painel; private readonly Panel _painel;
private readonly Form _parent; private readonly Control _parent;
private double _zoom = ZoomInicial; private double _zoom = ZoomInicial;
@ -137,7 +137,7 @@ namespace AgroBase.Models
#endregion #endregion
public MapaDinamicoModel(Form parent, Panel painel) public MapaDinamicoModel(Control parent, Panel painel)
{ {
if (parent == null) if (parent == null)
throw new ArgumentNullException(nameof(parent)); throw new ArgumentNullException(nameof(parent));

View File

@ -1093,7 +1093,6 @@ namespace AgroBase.Models
if (CarregarModulos) if (CarregarModulos)
{ {
op.DefinirComponentesEmUso(); op.DefinirComponentesEmUso();
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
op.AtualizarSensoriamentoSeguro(); op.AtualizarSensoriamentoSeguro();
} }
@ -4909,7 +4908,7 @@ namespace AgroBase.Models
DistanciaErroMapaCana = _Trajetoria?.DistanciaErroMapaPlantacao ?? 0, DistanciaErroMapaCana = _Trajetoria?.DistanciaErroMapaPlantacao ?? 0,
PrimeiroPontoDentroMapa = _Trajetoria?.PrimeiroPontoDentroMapa?.Clone() ?? new GPSModel(), PrimeiroPontoDentroMapa = _Trajetoria?.PrimeiroPontoDentroMapa?.Clone() ?? new GPSModel(),
PrimeiroPontoDentroCana = _Trajetoria?.PrimeiroPontoDentroCana?.Clone() ?? new GPSModel(), PrimeiroPontoDentroCana = _Trajetoria?.PrimeiroPontoDentroCana?.Clone() ?? new GPSModel(),
AutonomiaCooredor = _Trajetoria?.AutonomiaCorredor?.Clone(), AutonomiaCorredor = _Trajetoria?.AutonomiaCorredor?.Clone(),
}; };
} }
@ -5307,7 +5306,7 @@ namespace AgroBase.Models
public GPSModel PrimeiroPontoDentroCana { get; set; } public GPSModel PrimeiroPontoDentroCana { get; set; }
public double DistanciaErroMapaCana { get; set; } public double DistanciaErroMapaCana { get; set; }
public AutonomiaCorredorModel AutonomiaCooredor { get; set; } public AutonomiaCorredorModel AutonomiaCorredor { get; set; }
public OperacaoSensoriamentoLogTrajetoriaModel Clone() public OperacaoSensoriamentoLogTrajetoriaModel Clone()
{ {
@ -5345,7 +5344,7 @@ namespace AgroBase.Models
PrimeiroPontoDentroCana = PrimeiroPontoDentroCana?.Clone(), PrimeiroPontoDentroCana = PrimeiroPontoDentroCana?.Clone(),
PrimeiroPontoDentroMapa = PrimeiroPontoDentroMapa?.Clone(), PrimeiroPontoDentroMapa = PrimeiroPontoDentroMapa?.Clone(),
DistanciaErroMapaCana = DistanciaErroMapaCana, DistanciaErroMapaCana = DistanciaErroMapaCana,
AutonomiaCooredor = AutonomiaCooredor?.Clone() AutonomiaCorredor = AutonomiaCorredor?.Clone()
}; };
} }
} }

View File

@ -591,6 +591,20 @@ namespace AgroBase.Models.Operacoes
} }
} }
private double _distanciaManobra = 3.0;
public double DistanciaManobra
{
get => _distanciaManobra;
set
{
if (_distanciaManobra != value)
{
_distanciaManobra = value;
OnPropertyChanged(nameof(DistanciaManobra));
}
}
}
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string nome) protected void OnPropertyChanged(string nome)
@ -696,7 +710,7 @@ namespace AgroBase.Models.Operacoes
return; return;
} }
var autonomia = t.AutonomiaCooredor; var autonomia = t.AutonomiaCorredor;
var corredorAtual = t.CorredorAtual; var corredorAtual = t.CorredorAtual;
var pontoAtual = t.PontoAtual; var pontoAtual = t.PontoAtual;
var proximoPonto = t.ProximoPonto; var proximoPonto = t.ProximoPonto;

View File

@ -133,7 +133,7 @@ namespace AgroBase.Models
public List<CorredorTrajetoriaModel> _Corredores { get; set; } public List<CorredorTrajetoriaModel> _Corredores { get; set; }
public List<GPSModel> TrajetoriaFixa => _TrajetoriaFixa?.ConvertAll(x => x.Posicao); public List<GPSModel> TrajetoriaFixa => _TrajetoriaFixa?.ConvertAll(x => x.Posicao);
public List<PontoTrajetoriaModel> _TrajetoriaDinamica { get; private set; } public List<PontoTrajetoriaModel> _TrajetoriaDinamica { get; private set; }
public List<GPSModel> TrajetoriaDinamica => _TrajetoriaDinamica.ConvertAll(x => x.Posicao); public List<GPSModel> TrajetoriaDinamica => _TrajetoriaDinamica?.ConvertAll(x => x.Posicao);
public void AtualizarTrajetoriaDinamica() public void AtualizarTrajetoriaDinamica()
{ {
// Cria a lista com a última leitura do robô // Cria a lista com a última leitura do robô

View File

@ -84,6 +84,8 @@ namespace AgroBase.Models
_op = value; _op = value;
_op?.IniciarTimersSistema(); _op?.IniciarTimersSistema();
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
} }
} }
} }
@ -2355,4 +2357,23 @@ namespace AgroBase.Models
} }
public static class CloneHelper
{
public static T DeepClone<T>(T origem)
{
if (object.ReferenceEquals(origem, null))
return default(T);
JsonSerializerSettings settings =
new JsonSerializerSettings
{
ObjectCreationHandling = ObjectCreationHandling.Replace,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
string json = JsonConvert.SerializeObject(origem, settings);
return JsonConvert.DeserializeObject<T>(json, settings);
}
}
} }

View File

@ -1616,8 +1616,7 @@ namespace AgroBase.Services
private int AtuAgitadorTempoDesligadoMs = 30000; private int AtuAgitadorTempoDesligadoMs = 30000;
private int AtuAgitadorBoostRetomadaMs = 15000; private int AtuAgitadorBoostRetomadaMs = 15000;
private double PotenciaLimitePorNivel( private double PotenciaLimitePorNivel(double nivelPct)
double nivelPct)
{ {
if (nivelPct <= 5) if (nivelPct <= 5)
return 0; return 0;
@ -1634,33 +1633,21 @@ namespace AgroBase.Services
return 100; return 100;
} }
public void AtualizarAgitadorCalda( public void AtualizarAgitadorCalda(ModoAgitadorCalda modo)
ModoAgitadorCalda modo)
{ {
var op = var op = Variaveis.OperacaoEmAndamento;
Variaveis.OperacaoEmAndamento;
if ( if (op?.Sensoriamento?.Operacao?.Calibrando == true)
op?
.Sensoriamento?
.Operacao?
.Calibrando == true
)
{ {
return; return;
} }
var agitador = var agitador = op?.DispAtu?.Dados?.AgitadorDeCalda;
op?
.DispAtu?
.Dados?
.AgitadorDeCalda;
if (!(agitador?.Inicializado ?? false)) if (!(agitador?.Inicializado ?? false))
return; return;
var controle = var controle = op.Parametros?.Controle;
op.Parametros?.Controle;
if (controle == null) if (controle == null)
{ {
@ -1670,12 +1657,10 @@ namespace AgroBase.Services
return; return;
} }
bool operacaoConcluida = if (controle.AtuAgitadorModo == ModoAgitadorCalda.Manual)
op return;
.Sensoriamento?
.Operacao? bool operacaoConcluida = op.Sensoriamento?.Operacao?.StatusOperacaoAtual == StatusOperacao.Concluido;
.StatusOperacaoAtual ==
StatusOperacao.Concluido;
bool operacaoAtiva = bool operacaoAtiva =
op.Sensoriamento.Operacao.OperacaoIniciada && op.Sensoriamento.Operacao.OperacaoIniciada &&
@ -1683,37 +1668,20 @@ namespace AgroBase.Services
!operacaoConcluida && !operacaoConcluida &&
PulverizadorLiberado; PulverizadorLiberado;
bool bicosAtuando = bool bicosAtuando = op.DispAtu?.Dados?.BicosPulverizadores?.Any(x => x.Comandar && x.ComandoAtuar) ?? false;
op
.DispAtu?
.Dados?
.BicosPulverizadores?
.Any(
x =>
x.Comandar &&
x.ComandoAtuar
)
?? false;
double potenciaFinal = 0; double potenciaFinal = 0;
DateTime agora = DateTime.Now; DateTime agora = DateTime.Now;
if ( if (operacaoAtiva && !_agitadorOperacaoAtivaAnterior)
operacaoAtiva &&
!_agitadorOperacaoAtivaAnterior
)
{ {
_agitadorBoostAte = _agitadorBoostAte = agora.AddMilliseconds(AtuAgitadorBoostRetomadaMs);
agora.AddMilliseconds(
AtuAgitadorBoostRetomadaMs
);
_agitadorUltimaTroca = agora; _agitadorUltimaTroca = agora;
_agitadorIntermitenteLigado = true; _agitadorIntermitenteLigado = true;
} }
bool emBoost = bool emBoost = agora < _agitadorBoostAte;
agora < _agitadorBoostAte;
switch (modo) switch (modo)
{ {
@ -1726,18 +1694,15 @@ namespace AgroBase.Services
{ {
if (emBoost) if (emBoost)
{ {
potenciaFinal = potenciaFinal = AtuAgitadorPotenciaBoost;
AtuAgitadorPotenciaBoost;
} }
else if (bicosAtuando) else if (bicosAtuando)
{ {
potenciaFinal = potenciaFinal = AtuAgitadorPotenciaContinua;
AtuAgitadorPotenciaContinua;
} }
else else
{ {
potenciaFinal = potenciaFinal = AtuAgitadorPotenciaManutencao;
AtuAgitadorPotenciaManutencao;
} }
} }
break; break;
@ -1751,65 +1716,35 @@ namespace AgroBase.Services
} }
else if (emBoost) else if (emBoost)
{ {
potenciaFinal = potenciaFinal = AtuAgitadorPotenciaBoost;
AtuAgitadorPotenciaBoost;
} }
else else
{ {
int tempoAtualMs = int tempoAtualMs = _agitadorIntermitenteLigado ? AtuAgitadorTempoLigadoMs : AtuAgitadorTempoDesligadoMs;
_agitadorIntermitenteLigado
? AtuAgitadorTempoLigadoMs
: AtuAgitadorTempoDesligadoMs;
if ( if ((agora - _agitadorUltimaTroca).TotalMilliseconds >= tempoAtualMs)
(
agora -
_agitadorUltimaTroca
).TotalMilliseconds >=
tempoAtualMs
)
{ {
_agitadorIntermitenteLigado = _agitadorIntermitenteLigado = !_agitadorIntermitenteLigado;
!_agitadorIntermitenteLigado;
_agitadorUltimaTroca = _agitadorUltimaTroca = agora;
agora;
} }
potenciaFinal = potenciaFinal = _agitadorIntermitenteLigado ? AtuAgitadorPotenciaIntermitente : 0;
_agitadorIntermitenteLigado
? AtuAgitadorPotenciaIntermitente
: 0;
} }
break; break;
} }
potenciaFinal = potenciaFinal = Math.Min(potenciaFinal, PotenciaLimitePorNivel(PercentualAtual));
Math.Min(
potenciaFinal,
PotenciaLimitePorNivel(
PercentualAtual
)
);
potenciaFinal = potenciaFinal = Clamp(potenciaFinal, 0, 100);
Clamp(
potenciaFinal,
0,
100
);
agitador.PotenciaSP = agitador.PotenciaSP = potenciaFinal;
potenciaFinal;
agitador.PressaoSP = -1; agitador.PressaoSP = -1;
agitador.ComandoAtuar = agitador.ComandoAtuar = agitador.Comandar && potenciaFinal > 0;
agitador.Comandar &&
potenciaFinal > 0;
_agitadorOperacaoAtivaAnterior = _agitadorOperacaoAtivaAnterior = operacaoAtiva;
operacaoAtiva;
} }
} }
} }

View File

@ -181,15 +181,15 @@ namespace AgroBase.Services.Operadores
dist_dir = _t.DistanciaDireita, dist_dir = _t.DistanciaDireita,
angulo = _t.AnguloMedioCorredor, angulo = _t.AnguloMedioCorredor,
pontos_restantes = _t.CorredorAtual.QtdPontos - pontoComparar.idxPontoCorredor, pontos_restantes = _t.CorredorAtual.QtdPontos - pontoComparar.idxPontoCorredor,
liberado = _t.AutonomiaCooredor?.Liberado ?? false, liberado = _t.AutonomiaCorredor?.Liberado ?? false,
motivo_bat = _t.AutonomiaCooredor?.Motivos?.FirstOrDefault(x => x.Contains("Bateria")) ?? "", motivo_bat = _t.AutonomiaCorredor?.Motivos?.FirstOrDefault(x => x.Contains("Bateria")) ?? "",
bateria_ok = _t.AutonomiaCooredor?.BateriaSuficiente ?? false, bateria_ok = _t.AutonomiaCorredor?.BateriaSuficiente ?? false,
motivo_hrb = _t.AutonomiaCooredor?.Motivos?.FirstOrDefault(x => x.Contains("Herbicida")) ?? "", motivo_hrb = _t.AutonomiaCorredor?.Motivos?.FirstOrDefault(x => x.Contains("Herbicida")) ?? "",
herbicida_ok = _t.AutonomiaCooredor?.HerbicidaSuficiente ?? false, herbicida_ok = _t.AutonomiaCorredor?.HerbicidaSuficiente ?? false,
autonomia_liberada = _t.AutonomiaCooredor?.Liberado ?? false, autonomia_liberada = _t.AutonomiaCorredor?.Liberado ?? false,
autonomia_status = (int)(_t.AutonomiaCooredor?.Status ?? AutonomiaCorredorStatus.Desconhecido), autonomia_status = (int)(_t.AutonomiaCorredor?.Status ?? AutonomiaCorredorStatus.Desconhecido),
autonomia_motivo = _t.AutonomiaCooredor?.Motivo ?? "", autonomia_motivo = _t.AutonomiaCorredor?.Motivo ?? "",
autonomia_ok_supervisionado = _t.AutonomiaCooredor?.Status == AutonomiaCorredorStatus.OkSupervisionado, autonomia_ok_supervisionado = _t.AutonomiaCorredor?.Status == AutonomiaCorredorStatus.OkSupervisionado,
}, },
} : null } : null
), ),
@ -1290,11 +1290,11 @@ namespace AgroBase.Services.Operadores
var DadosTrj = _Sensoriamento?.Trajetoria; var DadosTrj = _Sensoriamento?.Trajetoria;
RedisService.AtualizarCampos(RedisService.ModKey(Enums.T_Code.Trj), RedisService.AtualizarCampos(RedisService.ModKey(Enums.T_Code.Trj),
("timestamp", agora), ("timestamp", agora),
("iniciado", DadosTrj?.AutonomiaCooredor?.Iniciado ?? false), ("iniciado", DadosTrj?.AutonomiaCorredor?.Iniciado ?? false),
("liberado", DadosTrj?.AutonomiaCooredor?.Liberado ?? false), ("liberado", DadosTrj?.AutonomiaCorredor?.Liberado ?? false),
("bateria_ok", DadosTrj?.AutonomiaCooredor?.BateriaSuficiente ?? false), ("bateria_ok", DadosTrj?.AutonomiaCorredor?.BateriaSuficiente ?? false),
("herbicida_ok", DadosTrj?.AutonomiaCooredor?.HerbicidaSuficiente ?? false), ("herbicida_ok", DadosTrj?.AutonomiaCorredor?.HerbicidaSuficiente ?? false),
("motivos", DadosTrj?.AutonomiaCooredor?.Motivos ?? new List<string>()) ("motivos", DadosTrj?.AutonomiaCorredor?.Motivos ?? new List<string>())
); );
double distanciaBase = -1; double distanciaBase = -1;