Ajustes na barra pulverizadora
This commit is contained in:
parent
59c1326d0a
commit
c4cf9a2742
|
|
@ -51,6 +51,9 @@ namespace OperationControl.Controls
|
||||||
public static readonly DependencyProperty LongitudeProperty = DependencyProperty.Register(nameof(Longitude), typeof(double), typeof(MapViewControl), new PropertyMetadata(0.0, OnViewPropertyChanged));
|
public static readonly DependencyProperty LongitudeProperty = DependencyProperty.Register(nameof(Longitude), typeof(double), typeof(MapViewControl), new PropertyMetadata(0.0, OnViewPropertyChanged));
|
||||||
public static readonly DependencyProperty ScaleProperty = DependencyProperty.Register(nameof(Scale), typeof(double), typeof(MapViewControl), new PropertyMetadata(5000.0, OnViewPropertyChanged));
|
public static readonly DependencyProperty ScaleProperty = DependencyProperty.Register(nameof(Scale), typeof(double), typeof(MapViewControl), new PropertyMetadata(5000.0, OnViewPropertyChanged));
|
||||||
public static readonly DependencyProperty MbTilesPathProperty = DependencyProperty.Register(nameof(MbTilesPath), typeof(string), typeof(MapViewControl), new PropertyMetadata(string.Empty, OnMbTilesPathChanged));
|
public static readonly DependencyProperty MbTilesPathProperty = DependencyProperty.Register(nameof(MbTilesPath), typeof(string), typeof(MapViewControl), new PropertyMetadata(string.Empty, OnMbTilesPathChanged));
|
||||||
|
|
||||||
|
public string PathMapaSelecionado;
|
||||||
|
|
||||||
public double Latitude
|
public double Latitude
|
||||||
{
|
{
|
||||||
get => (double)GetValue(LatitudeProperty);
|
get => (double)GetValue(LatitudeProperty);
|
||||||
|
|
@ -122,7 +125,10 @@ namespace OperationControl.Controls
|
||||||
public List<StreetMapDictionaryModel> RuasMapaCarregado;
|
public List<StreetMapDictionaryModel> RuasMapaCarregado;
|
||||||
|
|
||||||
public event EventHandler<StreetMapClickedEventArgs>? StreetMapClicked;
|
public event EventHandler<StreetMapClickedEventArgs>? StreetMapClicked;
|
||||||
private bool ParametrizandoOperacao => !(VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Iniciada ?? false) && (VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Status ?? StatusOperacao.NaoIniciado) == StatusOperacao.Parametrizando;
|
private bool ParametrizandoOperacao =>
|
||||||
|
!(VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Iniciada ?? false) &&
|
||||||
|
(VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Status ?? StatusOperacao.NaoIniciado) == StatusOperacao.Parametrizando &&
|
||||||
|
((App)System.Windows.Application.Current).Shell.Dock?._vm?._viewOperacaoRight?._vm?.SecaoAtual == ViewModels.Views.Operacao.SecaoRightBar.Parametrizacao;
|
||||||
protected virtual void OnStreetMapClicked(string streetId)
|
protected virtual void OnStreetMapClicked(string streetId)
|
||||||
{
|
{
|
||||||
StreetMapClicked?.Invoke(this, new StreetMapClickedEventArgs(streetId, RuasMapaCarregado.Where(x => x.Selected).Select(x => x.Id).ToList()));
|
StreetMapClicked?.Invoke(this, new StreetMapClickedEventArgs(streetId, RuasMapaCarregado.Where(x => x.Selected).Select(x => x.Id).ToList()));
|
||||||
|
|
@ -653,15 +659,15 @@ namespace OperationControl.Controls
|
||||||
|
|
||||||
if (dlg.ShowDialog() == true)
|
if (dlg.ShowDialog() == true)
|
||||||
{
|
{
|
||||||
var path = dlg.FileName;
|
PathMapaSelecionado = dlg.FileName;
|
||||||
if (path.EndsWith(".shp", StringComparison.OrdinalIgnoreCase))
|
if (PathMapaSelecionado.EndsWith(".shp", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
var geojson = ConvertShpToGeoJson(path);
|
var geojson = ConvertShpToGeoJson(PathMapaSelecionado);
|
||||||
AddGeoJsonLayer(geojson);
|
AddGeoJsonLayer(geojson);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var geojson = File.ReadAllText(path);
|
var geojson = File.ReadAllText(PathMapaSelecionado);
|
||||||
AddGeoJsonLayer(geojson);
|
AddGeoJsonLayer(geojson);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -800,19 +806,21 @@ namespace OperationControl.Controls
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void LoadMapFile(string path)
|
public void LoadMapFile(string? path)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
|
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path) || path == PathMapaSelecionado)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (path.EndsWith(".shp", StringComparison.OrdinalIgnoreCase))
|
PathMapaSelecionado = path;
|
||||||
|
|
||||||
|
if (PathMapaSelecionado.EndsWith(".shp", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
var geojson = ConvertShpToGeoJson(path);
|
var geojson = ConvertShpToGeoJson(PathMapaSelecionado);
|
||||||
AddGeoJsonLayer(geojson);
|
AddGeoJsonLayer(geojson);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var geojson = File.ReadAllText(path);
|
var geojson = File.ReadAllText(PathMapaSelecionado);
|
||||||
AddGeoJsonLayer(geojson);
|
AddGeoJsonLayer(geojson);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,13 @@
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="clr-namespace:OperationControl.Controls.Pulverizador"
|
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="120" d:DesignWidth="120">
|
MinWidth="56"
|
||||||
|
MinHeight="80"
|
||||||
|
d:DesignWidth="80"
|
||||||
|
d:DesignHeight="88">
|
||||||
|
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<!-- pode reaproveitar as mesmas cores do outro control -->
|
|
||||||
<SolidColorBrush x:Key="LineBrush" Color="#FFB0BAC8"/>
|
|
||||||
<SolidColorBrush x:Key="SprayBrush" Color="#FF00A8E8"/>
|
<SolidColorBrush x:Key="SprayBrush" Color="#FF00A8E8"/>
|
||||||
<SolidColorBrush x:Key="CommandOnBrush" Color="#FFE74C3C"/>
|
<SolidColorBrush x:Key="CommandOnBrush" Color="#FFE74C3C"/>
|
||||||
<SolidColorBrush x:Key="CommandOffBrush" Color="#FFB0BAC8"/>
|
<SolidColorBrush x:Key="CommandOffBrush" Color="#FFB0BAC8"/>
|
||||||
|
|
@ -17,33 +17,36 @@
|
||||||
<SolidColorBrush x:Key="TextPrimary" Color="#FFF5F7FA"/>
|
<SolidColorBrush x:Key="TextPrimary" Color="#FFF5F7FA"/>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
|
||||||
<Grid Margin="0">
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="30"/>
|
||||||
<!-- dados -->
|
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
<!-- desenho -->
|
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<!-- Dados do bico (mock, depois a gente binda) -->
|
<!-- infos -->
|
||||||
<UniformGrid Grid.Row="0" Rows="2" Columns="2" Height="30" Width="90" HorizontalAlignment="Center">
|
<!-- infos -->
|
||||||
|
<StackPanel Grid.Row="0"
|
||||||
|
Orientation="Vertical"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
HorizontalAlignment="Center">
|
||||||
|
|
||||||
<TextBlock Text="{Binding Vazao, RelativeSource={RelativeSource AncestorType=UserControl}, StringFormat={}{0:F1} mL/s}" Foreground="{StaticResource TextSecondary}" FontSize="10" HorizontalAlignment="Center"/>
|
<TextBlock Text="{Binding Vazao, RelativeSource={RelativeSource AncestorType=UserControl}, StringFormat={}{0:F1} mL/s}" Foreground="{StaticResource TextSecondary}" FontSize="10" HorizontalAlignment="Center"/>
|
||||||
|
|
||||||
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
||||||
|
<TextBlock Text="{Binding Atuacoes, RelativeSource={RelativeSource AncestorType=UserControl}, StringFormat={}{0}x}" Foreground="{StaticResource TextSecondary}" FontSize="10" Margin="0 0 5 0"/>
|
||||||
<TextBlock Text="{Binding TempoAtuado, RelativeSource={RelativeSource AncestorType=UserControl}, StringFormat={}{0:F1} s}" Foreground="{StaticResource TextSecondary}" FontSize="10" HorizontalAlignment="Center"/>
|
<TextBlock Text="{Binding TempoAtuado, RelativeSource={RelativeSource AncestorType=UserControl}, StringFormat={}{0:F1} s}" Foreground="{StaticResource TextSecondary}" FontSize="10" HorizontalAlignment="Center"/>
|
||||||
<TextBlock Text="{Binding AnguloControle, RelativeSource={RelativeSource AncestorType=UserControl}, StringFormat={}{0:F0}°}" Foreground="{StaticResource TextSecondary}" FontSize="10" HorizontalAlignment="Center"/>
|
</StackPanel>
|
||||||
<TextBlock Text="{Binding Atuacoes, RelativeSource={RelativeSource AncestorType=UserControl}, StringFormat={}{0} x}" Foreground="{StaticResource TextSecondary}" FontSize="10" HorizontalAlignment="Center"/>
|
</StackPanel>
|
||||||
</UniformGrid>
|
|
||||||
|
|
||||||
<!-- Desenho do bico + leque -->
|
<!-- desenho -->
|
||||||
<Canvas x:Name="DrawCanvas" Grid.Row="1" Margin="0,2,0,0" Width="Auto" Height="80">
|
<Grid Grid.Row="1">
|
||||||
|
<Canvas x:Name="DrawCanvas" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||||
|
<Polygon x:Name="SprayPolygon" Stroke="{StaticResource SprayBrush}" StrokeThickness="2" Fill="#2200A8E8" Visibility="Collapsed"/>
|
||||||
|
|
||||||
<!-- Solenoide -->
|
|
||||||
<Rectangle x:Name="SolenoidRect" Width="14" Height="14" Fill="{StaticResource TextPrimary}" Stroke="{StaticResource CommandOffBrush}" StrokeThickness="3" Canvas.Left="53" Canvas.Top="0"/>
|
|
||||||
|
|
||||||
<!-- Linha central do jato -->
|
|
||||||
<Line x:Name="CenterLine" Stroke="{StaticResource SprayBrush}" StrokeThickness="2" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Visibility="Collapsed"/>
|
<Line x:Name="CenterLine" Stroke="{StaticResource SprayBrush}" StrokeThickness="2" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Visibility="Collapsed"/>
|
||||||
|
|
||||||
<!-- Leque (triângulo) -->
|
<Rectangle x:Name="SolenoidRect" Width="14" Height="14" RadiusX="2" RadiusY="2" Fill="{StaticResource TextPrimary}" Stroke="{StaticResource CommandOffBrush}" StrokeThickness="3"/>
|
||||||
<Polygon x:Name="SprayPolygon" Stroke="{StaticResource SprayBrush}" StrokeThickness="2" Fill="#2200A8E8" Visibility="Collapsed"/>
|
|
||||||
</Canvas>
|
</Canvas>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
@ -1,179 +1,166 @@
|
||||||
using System.Windows;
|
using System.ComponentModel;
|
||||||
using System.Windows.Controls;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Windows;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
using UserControl = System.Windows.Controls.UserControl;
|
using UserControl = System.Windows.Controls.UserControl;
|
||||||
using Brush = System.Windows.Media.Brush;
|
using Brush = System.Windows.Media.Brush;
|
||||||
using Point = System.Windows.Point;
|
using Point = System.Windows.Point;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
namespace OperationControl.Controls.Pulverizador
|
namespace OperationControl.Controls.Pulverizador
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Interaction logic for BicoControl.xaml
|
|
||||||
/// </summary>
|
|
||||||
public partial class BicoLequeIndicator : UserControl
|
public partial class BicoLequeIndicator : UserControl
|
||||||
{
|
{
|
||||||
public BicoLequeIndicator()
|
public BicoLequeIndicator()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Loaded += (s, e) => UpdateGeometry();
|
|
||||||
|
Loaded += (_, __) => UpdateGeometry();
|
||||||
|
SizeChanged += (_, __) => UpdateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region DependencyProperties básicas
|
|
||||||
|
|
||||||
// Comando enviado para a solenoide
|
|
||||||
public bool IsCommandOn
|
public bool IsCommandOn
|
||||||
{
|
{
|
||||||
get => (bool)GetValue(IsCommandOnProperty);
|
get => (bool)GetValue(IsCommandOnProperty);
|
||||||
set => SetValue(IsCommandOnProperty, value);
|
set => SetValue(IsCommandOnProperty, value);
|
||||||
}
|
}
|
||||||
public static readonly DependencyProperty IsCommandOnProperty = DependencyProperty.Register(nameof(IsCommandOn), typeof(bool), typeof(BicoLequeIndicator), new PropertyMetadata(false, OnVisualPropertyChanged));
|
public static readonly DependencyProperty IsCommandOnProperty =
|
||||||
|
DependencyProperty.Register(nameof(IsCommandOn), typeof(bool), typeof(BicoLequeIndicator),
|
||||||
|
new PropertyMetadata(false, OnVisualPropertyChanged));
|
||||||
|
|
||||||
// Leitura de ligado (se está realmente pulverizando)
|
|
||||||
public bool IsSpraying
|
public bool IsSpraying
|
||||||
{
|
{
|
||||||
get => (bool)GetValue(IsSprayingProperty);
|
get => (bool)GetValue(IsSprayingProperty);
|
||||||
set => SetValue(IsSprayingProperty, value);
|
set => SetValue(IsSprayingProperty, value);
|
||||||
}
|
}
|
||||||
public static readonly DependencyProperty IsSprayingProperty = DependencyProperty.Register(nameof(IsSpraying), typeof(bool), typeof(BicoLequeIndicator), new PropertyMetadata(false, OnVisualPropertyChanged));
|
public static readonly DependencyProperty IsSprayingProperty =
|
||||||
|
DependencyProperty.Register(nameof(IsSpraying), typeof(bool), typeof(BicoLequeIndicator),
|
||||||
|
new PropertyMetadata(false, OnVisualPropertyChanged));
|
||||||
|
|
||||||
// Ângulo central do jato (0 = vertical; positivo gira p/ esquerda, negativo p/ direita)
|
|
||||||
public double AnguloControle
|
public double AnguloControle
|
||||||
{
|
{
|
||||||
get => (double)GetValue(AnguloControleProperty);
|
get => (double)GetValue(AnguloControleProperty);
|
||||||
set => SetValue(AnguloControleProperty, value);
|
set => SetValue(AnguloControleProperty, value);
|
||||||
}
|
}
|
||||||
public static readonly DependencyProperty AnguloControleProperty = DependencyProperty.Register(nameof(AnguloControle), typeof(double), typeof(BicoLequeIndicator), new PropertyMetadata(0.0, OnGeometryPropertyChanged));
|
public static readonly DependencyProperty AnguloControleProperty =
|
||||||
|
DependencyProperty.Register(nameof(AnguloControle), typeof(double), typeof(BicoLequeIndicator),
|
||||||
|
new PropertyMetadata(0.0, OnGeometryPropertyChanged));
|
||||||
|
|
||||||
// Abertura total do leque (em graus) – ex: 110°
|
|
||||||
public double OpeningAngle
|
public double OpeningAngle
|
||||||
{
|
{
|
||||||
get => (double)GetValue(OpeningAngleProperty);
|
get => (double)GetValue(OpeningAngleProperty);
|
||||||
set => SetValue(OpeningAngleProperty, value);
|
set => SetValue(OpeningAngleProperty, value);
|
||||||
}
|
}
|
||||||
public static readonly DependencyProperty OpeningAngleProperty = DependencyProperty.Register(nameof(OpeningAngle), typeof(double), typeof(BicoLequeIndicator), new PropertyMetadata(110.0, OnGeometryPropertyChanged));
|
public static readonly DependencyProperty OpeningAngleProperty =
|
||||||
|
DependencyProperty.Register(nameof(OpeningAngle), typeof(double), typeof(BicoLequeIndicator),
|
||||||
|
new PropertyMetadata(110.0, OnGeometryPropertyChanged));
|
||||||
|
|
||||||
// Vazao instantanea (mL/s)
|
|
||||||
public double Vazao
|
public double Vazao
|
||||||
{
|
{
|
||||||
get => (double)GetValue(VazaoProperty);
|
get => (double)GetValue(VazaoProperty);
|
||||||
set => SetValue(VazaoProperty, value);
|
set => SetValue(VazaoProperty, value);
|
||||||
}
|
}
|
||||||
public static readonly DependencyProperty VazaoProperty = DependencyProperty.Register(nameof(Vazao), typeof(double), typeof(BicoLequeIndicator), new PropertyMetadata(0.0, OnGeometryPropertyChanged));
|
public static readonly DependencyProperty VazaoProperty =
|
||||||
|
DependencyProperty.Register(nameof(Vazao), typeof(double), typeof(BicoLequeIndicator),
|
||||||
|
new PropertyMetadata(0.0));
|
||||||
|
|
||||||
// Tempo atuado (s)
|
|
||||||
public double TempoAtuado
|
public double TempoAtuado
|
||||||
{
|
{
|
||||||
get => (double)GetValue(TempoAtuadoProperty);
|
get => (double)GetValue(TempoAtuadoProperty);
|
||||||
set => SetValue(TempoAtuadoProperty, value);
|
set => SetValue(TempoAtuadoProperty, value);
|
||||||
}
|
}
|
||||||
public static readonly DependencyProperty TempoAtuadoProperty = DependencyProperty.Register(nameof(TempoAtuado), typeof(double), typeof(BicoLequeIndicator), new PropertyMetadata(0.0, OnGeometryPropertyChanged));
|
public static readonly DependencyProperty TempoAtuadoProperty =
|
||||||
|
DependencyProperty.Register(nameof(TempoAtuado), typeof(double), typeof(BicoLequeIndicator),
|
||||||
|
new PropertyMetadata(0.0));
|
||||||
|
|
||||||
// Atuacoes
|
|
||||||
public int Atuacoes
|
public int Atuacoes
|
||||||
{
|
{
|
||||||
get => (int)GetValue(AtuacoesProperty);
|
get => (int)GetValue(AtuacoesProperty);
|
||||||
set => SetValue(AtuacoesProperty, value);
|
set => SetValue(AtuacoesProperty, value);
|
||||||
}
|
}
|
||||||
public static readonly DependencyProperty AtuacoesProperty = DependencyProperty.Register(nameof(Atuacoes), typeof(int), typeof(BicoLequeIndicator), new PropertyMetadata(0, OnGeometryPropertyChanged));
|
public static readonly DependencyProperty AtuacoesProperty =
|
||||||
|
DependencyProperty.Register(nameof(Atuacoes), typeof(int), typeof(BicoLequeIndicator),
|
||||||
#endregion
|
new PropertyMetadata(0));
|
||||||
|
|
||||||
private static void OnGeometryPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
private static void OnGeometryPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
var ctrl = (BicoLequeIndicator)d;
|
if (d is BicoLequeIndicator ctrl)
|
||||||
ctrl.UpdateGeometry();
|
ctrl.UpdateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OnVisualPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
private static void OnVisualPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
var ctrl = (BicoLequeIndicator)d;
|
if (d is BicoLequeIndicator ctrl)
|
||||||
ctrl.UpdateVisualState();
|
ctrl.UpdateVisualState();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Atualiza cor da solenoide e visibilidade do leque.
|
|
||||||
/// </summary>
|
|
||||||
private void UpdateVisualState()
|
private void UpdateVisualState()
|
||||||
{
|
{
|
||||||
if (SolenoidRect == null || SprayPolygon == null)
|
if (SolenoidRect == null || SprayPolygon == null || CenterLine == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var onBrush = (Brush)FindResource("CommandOnBrush");
|
var onBrush = (Brush)FindResource("CommandOnBrush");
|
||||||
var offBrush = (Brush)FindResource("CommandOffBrush");
|
var offBrush = (Brush)FindResource("CommandOffBrush");
|
||||||
|
|
||||||
SolenoidRect.Stroke = IsCommandOn ? onBrush : offBrush;
|
SolenoidRect.Stroke = IsCommandOn ? onBrush : offBrush;
|
||||||
|
|
||||||
SprayPolygon.Visibility = IsSpraying && OpeningAngle > 0 ? Visibility.Visible : Visibility.Collapsed;
|
SprayPolygon.Visibility = IsSpraying && OpeningAngle > 0 ? Visibility.Visible : Visibility.Collapsed;
|
||||||
CenterLine.Visibility = IsSpraying ? Visibility.Visible : Visibility.Collapsed;
|
CenterLine.Visibility = IsSpraying ? Visibility.Visible : Visibility.Collapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Recalcula geometria do leque e da linha central a partir do ângulo central e abertura.
|
|
||||||
/// </summary>
|
|
||||||
private void UpdateGeometry()
|
private void UpdateGeometry()
|
||||||
{
|
{
|
||||||
if (DrawCanvas == null || SprayPolygon == null || CenterLine == null)
|
if (DrawCanvas == null || SprayPolygon == null || CenterLine == null || SolenoidRect == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
double width = DrawCanvas.ActualWidth;
|
double width = DrawCanvas.ActualWidth;
|
||||||
double height = DrawCanvas.ActualHeight;
|
double height = DrawCanvas.ActualHeight;
|
||||||
if (width <= 0) width = 120;
|
|
||||||
if (height <= 0) height = 80;
|
|
||||||
|
|
||||||
// Origem do bico (ponto da solenoide)
|
if (width <= 0) width = 60;
|
||||||
|
if (height <= 0) height = 40;
|
||||||
|
|
||||||
double originX = width / 2.0;
|
double originX = width / 2.0;
|
||||||
double originY = 10.0; // um pouco abaixo do topo
|
double originY = 8.0;
|
||||||
|
|
||||||
double length = height - 10.0; // comprimento do jato até próximo do solo
|
double length = Math.Max(16.0, height - 10.0);
|
||||||
|
|
||||||
// Metade da abertura em radianos
|
|
||||||
double halfAngleRad = OpeningAngle * 0.5 * Math.PI / 180.0;
|
double halfAngleRad = OpeningAngle * 0.5 * Math.PI / 180.0;
|
||||||
|
|
||||||
// Deslocamento horizontal na base do leque
|
|
||||||
double dx = Math.Tan(halfAngleRad) * length;
|
double dx = Math.Tan(halfAngleRad) * length;
|
||||||
|
|
||||||
// Pontos em sistema local (0,0 = bico; y para baixo)
|
|
||||||
Point apex = new Point(0, 0);
|
Point apex = new Point(0, 0);
|
||||||
Point leftLocal = new Point(-dx, length);
|
Point leftLocal = new Point(-dx, length);
|
||||||
Point rightLocal = new Point(dx, length);
|
Point rightLocal = new Point(dx, length);
|
||||||
Point centerLocal = new Point(0, length);
|
Point centerLocal = new Point(0, length);
|
||||||
|
|
||||||
// Rotação pelo ângulo central (em radianos).
|
|
||||||
double theta = AnguloControle * Math.PI / 180.0;
|
double theta = AnguloControle * Math.PI / 180.0;
|
||||||
double cos = Math.Cos(theta);
|
double cos = Math.Cos(theta);
|
||||||
double sin = Math.Sin(theta);
|
double sin = Math.Sin(theta);
|
||||||
|
|
||||||
Point Rot(Point p) => new Point(
|
Point Rotate(Point p) => new Point(
|
||||||
p.X * cos - p.Y * sin,
|
p.X * cos - p.Y * sin,
|
||||||
p.X * sin + p.Y * cos);
|
p.X * sin + p.Y * cos);
|
||||||
|
|
||||||
Point apexR = Rot(apex);
|
Point apexR = Rotate(apex);
|
||||||
Point leftR = Rot(leftLocal);
|
Point leftR = Rotate(leftLocal);
|
||||||
Point rightR = Rot(rightLocal);
|
Point rightR = Rotate(rightLocal);
|
||||||
Point centerR = Rot(centerLocal);
|
Point centerR = Rotate(centerLocal);
|
||||||
|
|
||||||
// Translada para as coordenadas do Canvas
|
|
||||||
apexR.Offset(originX, originY);
|
apexR.Offset(originX, originY);
|
||||||
leftR.Offset(originX, originY);
|
leftR.Offset(originX, originY);
|
||||||
rightR.Offset(originX, originY);
|
rightR.Offset(originX, originY);
|
||||||
centerR.Offset(originX, originY);
|
centerR.Offset(originX, originY);
|
||||||
|
|
||||||
// Atualiza Polygon do leque
|
SprayPolygon.Points = new PointCollection { leftR, apexR, rightR };
|
||||||
var pts = new PointCollection { leftR, apexR, rightR };
|
|
||||||
SprayPolygon.Points = pts;
|
|
||||||
|
|
||||||
// Atualiza linha central do jato
|
|
||||||
CenterLine.X1 = apexR.X;
|
CenterLine.X1 = apexR.X;
|
||||||
CenterLine.Y1 = apexR.Y;
|
CenterLine.Y1 = apexR.Y;
|
||||||
CenterLine.X2 = centerR.X;
|
CenterLine.X2 = centerR.X;
|
||||||
CenterLine.Y2 = centerR.Y;
|
CenterLine.Y2 = centerR.Y;
|
||||||
|
|
||||||
// Reposiciona a solenoide exatamente na origem
|
|
||||||
Canvas.SetLeft(SolenoidRect, originX - SolenoidRect.Width / 2.0);
|
Canvas.SetLeft(SolenoidRect, originX - SolenoidRect.Width / 2.0);
|
||||||
Canvas.SetTop(SolenoidRect, originY - SolenoidRect.Height / 2.0);
|
Canvas.SetTop(SolenoidRect, originY - SolenoidRect.Height / 2.0);
|
||||||
|
|
||||||
|
UpdateVisualState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -239,5 +226,4 @@ namespace OperationControl.Controls.Pulverizador
|
||||||
protected void OnPropertyChanged([CallerMemberName] string propName = null)
|
protected void OnPropertyChanged([CallerMemberName] string propName = null)
|
||||||
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
|
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,101 +1,39 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
|
|
||||||
namespace OperationControl.Controls.Pulverizador
|
namespace OperationControl.Controls.Pulverizador
|
||||||
{
|
{
|
||||||
class Converters
|
public class BarraTopConverter : IMultiValueConverter
|
||||||
{
|
{
|
||||||
}
|
public double MinAlturaCm { get; set; } = 50.0;
|
||||||
|
public double MaxAlturaCm { get; set; } = 80.0;
|
||||||
|
public double TopMinPx { get; set; } = 18.0;
|
||||||
|
public double TopMaxPx { get; set; } = 62.0;
|
||||||
|
|
||||||
public class AlturaBarraToMarginFisicaConverter : IValueConverter
|
|
||||||
{
|
|
||||||
public double GroundTop { get; set; } = 80.0; // Y do solo
|
|
||||||
public double Top80Px { get; set; } = 20.0; // Y da barra quando está a 80 cm
|
|
||||||
public double AlturaMaxCm { get; set; } = 80.0;
|
|
||||||
public double BarraOffset { get; set; } = 13.0;
|
|
||||||
|
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
|
||||||
{
|
|
||||||
if (value is double alturaCm)
|
|
||||||
{
|
|
||||||
alturaCm = Math.Clamp(alturaCm, 0, AlturaMaxCm);
|
|
||||||
|
|
||||||
double distanciaPx = GroundTop - Top80Px; // px que representam 80 cm
|
|
||||||
double pxPorCm = distanciaPx / AlturaMaxCm; // regra de 3
|
|
||||||
double alturaPx = alturaCm * pxPorCm;
|
|
||||||
|
|
||||||
double yBarra = GroundTop - alturaPx; // Y da barra na GRID
|
|
||||||
|
|
||||||
double marginTop = yBarra - BarraOffset; // compensa o offset interno
|
|
||||||
|
|
||||||
return new Thickness(33, marginTop, 33, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Thickness(33, 0, 33, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
|
||||||
=> System.Windows.Data.Binding.DoNothing;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class BicoPositionFisicaConverter : IMultiValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (values.Length < 5)
|
if (values.Length < 2)
|
||||||
return 0.0;
|
return new Thickness(0);
|
||||||
|
|
||||||
if (values[0] is not double barraWidth ||
|
if (values[0] is not double alturaCm || values[1] is not double areaHeight)
|
||||||
values[1] is not int index ||
|
return new Thickness(0);
|
||||||
values[2] is not int qtd ||
|
|
||||||
values[3] is not double distEntreBicosCm ||
|
|
||||||
values[4] is not double comprimentoBarraCm)
|
|
||||||
{
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qtd <= 0 || barraWidth <= 0 || comprimentoBarraCm <= 0)
|
if (MaxAlturaCm <= MinAlturaCm)
|
||||||
return 0.0;
|
return new Thickness(0);
|
||||||
|
|
||||||
// garante valores válidos
|
double extraOffset = 0.0;
|
||||||
distEntreBicosCm = Math.Max(0.0, distEntreBicosCm);
|
if (parameter != null)
|
||||||
|
double.TryParse(parameter.ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out extraOffset);
|
||||||
|
|
||||||
if (qtd == 1)
|
double h = Math.Max(MinAlturaCm, Math.Min(MaxAlturaCm, alturaCm));
|
||||||
{
|
double t = (h - MinAlturaCm) / (MaxAlturaCm - MinAlturaCm);
|
||||||
// 1 bico: centro da barra
|
|
||||||
return barraWidth / 2.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// span "ideal" em cm (do primeiro ao último bico)
|
double maxTop = Math.Min(TopMaxPx, Math.Max(TopMinPx, areaHeight - 20));
|
||||||
double spanIdealCm = (qtd - 1) * distEntreBicosCm;
|
double top = maxTop - (t * (maxTop - TopMinPx));
|
||||||
|
|
||||||
// Se o span ideal for maior que a barra física, comprimimos
|
return new Thickness(0, top + extraOffset, 0, 0);
|
||||||
double escala = 1.0;
|
|
||||||
if (spanIdealCm > comprimentoBarraCm && qtd > 1)
|
|
||||||
{
|
|
||||||
escala = comprimentoBarraCm / spanIdealCm;
|
|
||||||
}
|
|
||||||
|
|
||||||
double distEfetivaCm = distEntreBicosCm * escala;
|
|
||||||
double spanEfetivoCm = (qtd - 1) * distEfetivaCm;
|
|
||||||
|
|
||||||
// centraliza o conjunto de bicos na barra
|
|
||||||
double offsetCm = (comprimentoBarraCm - spanEfetivoCm) / 2.0;
|
|
||||||
|
|
||||||
// posição em cm do bico atual
|
|
||||||
double xCm = offsetCm + index * distEfetivaCm;
|
|
||||||
|
|
||||||
// regra de 3: cm → px
|
|
||||||
double pxPorCm = barraWidth / comprimentoBarraCm;
|
|
||||||
double xPx = xCm * pxPorCm;
|
|
||||||
|
|
||||||
return xPx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
||||||
|
|
@ -116,12 +54,11 @@ namespace OperationControl.Controls.Pulverizador
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// px por cm na faixa do solo (usando comprimento da barra como referência física)
|
|
||||||
double pxPorCm = totalWidth / comprimentoBarraCm;
|
double pxPorCm = totalWidth / comprimentoBarraCm;
|
||||||
double widthPx = larguraRuaCm * pxPorCm;
|
double widthPx = larguraRuaCm * pxPorCm;
|
||||||
|
|
||||||
// não deixa a rua ficar maior que a área disponível
|
if (widthPx > totalWidth)
|
||||||
if (widthPx > totalWidth) widthPx = totalWidth;
|
widthPx = totalWidth;
|
||||||
|
|
||||||
return widthPx;
|
return widthPx;
|
||||||
}
|
}
|
||||||
|
|
@ -134,7 +71,8 @@ namespace OperationControl.Controls.Pulverizador
|
||||||
{
|
{
|
||||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (values.Length < 4) return new Thickness(0);
|
if (values.Length < 4)
|
||||||
|
return new Thickness(0);
|
||||||
|
|
||||||
if (values[0] is not double totalWidth ||
|
if (values[0] is not double totalWidth ||
|
||||||
values[1] is not double erroLateralCm ||
|
values[1] is not double erroLateralCm ||
|
||||||
|
|
@ -150,19 +88,14 @@ namespace OperationControl.Controls.Pulverizador
|
||||||
|
|
||||||
double center = totalWidth / 2.0;
|
double center = totalWidth / 2.0;
|
||||||
|
|
||||||
// erro > 0 = robô desviado pra direita → rua aparece indo pra esquerda
|
// erro > 0 = robô está para a direita, então a rua aparece deslocando para a esquerda
|
||||||
double roadCenter = center - erroLateralCm * pxPorCm;
|
double roadCenter = center - erroLateralCm * pxPorCm;
|
||||||
|
|
||||||
double left = roadCenter - widthPx / 2.0;
|
double left = roadCenter - widthPx / 2.0;
|
||||||
|
|
||||||
// SEM travas aqui: pode ser negativo ou maior que totalWidth
|
|
||||||
// o Grid com ClipToBounds cuida de cortar o desenho
|
|
||||||
|
|
||||||
return new Thickness(left, 0, 0, 0);
|
return new Thickness(left, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
||||||
=> throw new NotImplementedException();
|
=> throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -4,189 +4,250 @@
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="clr-namespace:OperationControl.Controls.Pulverizador"
|
xmlns:local="clr-namespace:OperationControl.Controls.Pulverizador"
|
||||||
mc:Ignorable="d" Width="458" Height="123">
|
xmlns:ctrl="clr-namespace:OperationControl.Controls"
|
||||||
<!-- ========= RECURSOS ========= -->
|
mc:Ignorable="d"
|
||||||
<UserControl.Resources>
|
MinWidth="420"
|
||||||
<local:BicoPositionFisicaConverter x:Key="BicoPositionFisicaConverter" />
|
MinHeight="150"
|
||||||
<local:AlturaBarraToMarginFisicaConverter x:Key="AlturaBarraToMarginFisicaConverter" GroundTop="80" Top80Px="7" AlturaMaxCm="80" />
|
d:DesignWidth="900"
|
||||||
<local:RuaWidthFisicaConverter x:Key="RuaWidthFisicaConverter" />
|
d:DesignHeight="180">
|
||||||
<local:RuaOffsetFisicaConverter x:Key="RuaOffsetFisicaConverter" />
|
|
||||||
|
|
||||||
<SolidColorBrush x:Key="BgBrush" Color="#FF101820"/>
|
<UserControl.Resources>
|
||||||
<SolidColorBrush x:Key="CardBrush" Color="#FF1C2530"/>
|
<local:BarraTopConverter x:Key="BarraTopConverter" MinAlturaCm="50" MaxAlturaCm="80" TopMinPx="18" TopMaxPx="62"/>
|
||||||
<SolidColorBrush x:Key="LineBrush" Color="#FFB0BAC8"/>
|
|
||||||
<SolidColorBrush x:Key="AccentBrush" Color="#FF00A8E8"/>
|
<local:RuaWidthFisicaConverter x:Key="RuaWidthFisicaConverter"/>
|
||||||
<SolidColorBrush x:Key="CommandBrush" Color="#FFE74C3C"/>
|
<local:RuaOffsetFisicaConverter x:Key="RuaOffsetFisicaConverter"/>
|
||||||
<SolidColorBrush x:Key="SprayBrush" Color="#FF00A8E8"/>
|
|
||||||
|
<SolidColorBrush x:Key="CardBrush" Color="#FF162437"/>
|
||||||
|
<SolidColorBrush x:Key="LineBrush" Color="#FFD4DBE5"/>
|
||||||
<SolidColorBrush x:Key="TextPrimary" Color="#FFF5F7FA"/>
|
<SolidColorBrush x:Key="TextPrimary" Color="#FFF5F7FA"/>
|
||||||
<SolidColorBrush x:Key="TextSecondary" Color="#FFB0BAC8"/>
|
<SolidColorBrush x:Key="TextSecondary" Color="#FFB0BAC8"/>
|
||||||
|
<SolidColorBrush x:Key="GroundBrush" Color="#AA8B0000"/>
|
||||||
<Style x:Key="Card" TargetType="Border">
|
<SolidColorBrush x:Key="CropBrush" Color="#5F6A36"/>
|
||||||
<Setter Property="CornerRadius" Value="8"/>
|
|
||||||
<Setter Property="Background" Value="{StaticResource CardBrush}"/>
|
|
||||||
<Setter Property="Padding" Value="8"/>
|
|
||||||
<Setter Property="Margin" Value="0"/>
|
|
||||||
</Style>
|
|
||||||
|
|
||||||
<Style x:Key="SectionTitle" TargetType="TextBlock">
|
<Style x:Key="SectionTitle" TargetType="TextBlock">
|
||||||
<Setter Property="Foreground" Value="{StaticResource TextSecondary}"/>
|
<Setter Property="Foreground" Value="{StaticResource TextSecondary}"/>
|
||||||
<Setter Property="FontSize" Value="12"/>
|
<Setter Property="FontSize" Value="13"/>
|
||||||
|
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="InfoLabelStyle" TargetType="TextBlock">
|
||||||
|
<Setter Property="Foreground" Value="{StaticResource TextSecondary}"/>
|
||||||
|
<Setter Property="FontSize" Value="11"/>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="InfoValueStyle" TargetType="TextBlock">
|
||||||
|
<Setter Property="Foreground" Value="{StaticResource TextPrimary}"/>
|
||||||
|
<Setter Property="FontSize" Value="15"/>
|
||||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||||
<Setter Property="Margin" Value="0,0,0,6"/>
|
|
||||||
</Style>
|
</Style>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
|
||||||
<!-- ========= LAYOUT ========= -->
|
<Border Background="{StaticResource CardBrush}" CornerRadius="12" Padding="12">
|
||||||
<Grid Background="Transparent" Margin="0" ClipToBounds="True">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="*"/>
|
|
||||||
<!-- Vista de trás -->
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
|
|
||||||
<!-- ===================== VISTA TRASEIRA / LEQUES ===================== -->
|
|
||||||
<Border Grid.Row="1" Style="{StaticResource Card}">
|
|
||||||
<Grid>
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="72"/>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="100"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<!-- ===================== ESQUERDA ===================== -->
|
||||||
|
<Grid Grid.Column="0" Margin="0,0,10,0">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="24"/>
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
|
<RowDefinition Height="18"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<TextBlock Grid.Row="0" Text="" Style="{StaticResource SectionTitle}"/>
|
<TextBlock Grid.Row="0" Text="{Binding AlturaBarra, RelativeSource={RelativeSource AncestorType={x:Type ctrl:PulverizadorIndicator}}, StringFormat={}{0:F0} cm}" Foreground="{StaticResource TextPrimary}" FontSize="16" FontWeight="SemiBold" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||||
|
|
||||||
<Grid Grid.Row="1" Margin="10,0,10,-8">
|
<Grid Grid.Row="1" x:Name="AreaRegua" Margin="0,8,0,30">
|
||||||
<!-- Cota de altura à esquerda -->
|
<!-- Slider -->
|
||||||
<Canvas Width="50" HorizontalAlignment="Left">
|
<Slider Minimum="50"
|
||||||
<TextBlock Foreground="{StaticResource TextSecondary}" FontSize="10" Canvas.Top="-15" Canvas.Left="1" HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding AlturaBarra, RelativeSource={RelativeSource AncestorType=UserControl}, StringFormat={}{0:F0} cm}" />
|
Maximum="80"
|
||||||
<Slider Minimum="50" Maximum="80" Value="{Binding AlturaBarra, RelativeSource={RelativeSource AncestorType=UserControl}, Mode=TwoWay}" Orientation="Vertical" Height="58" VerticalAlignment="Top" IsDirectionReversed="False" HorizontalAlignment="Center" Canvas.Left="5" />
|
Value="{Binding AlturaBarra, RelativeSource={RelativeSource AncestorType={x:Type ctrl:PulverizadorIndicator}}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||||
</Canvas>
|
Orientation="Vertical"
|
||||||
|
Width="30"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
IsDirectionReversed="False"
|
||||||
|
Margin="0,0,0,0"/>
|
||||||
|
|
||||||
<!-- Bicos e leques (traseira) -->
|
|
||||||
<Canvas x:Name="canvasPai">
|
|
||||||
<Canvas.Margin>
|
|
||||||
<Binding Path="AlturaBarra" RelativeSource="{RelativeSource AncestorType=UserControl}" Converter="{StaticResource AlturaBarraToMarginFisicaConverter}" />
|
|
||||||
</Canvas.Margin>
|
|
||||||
|
|
||||||
<!-- Barra -->
|
</Grid>
|
||||||
<Line x:Name="linhaBarra" X1="4" Y1="10" X2="250" Y2="10" Stroke="{StaticResource LineBrush}" StrokeThickness="4" StrokeStartLineCap="Round" StrokeEndLineCap="Round" HorizontalAlignment="Left" VerticalAlignment="Center" Height="20" Canvas.Left="50" Canvas.Top="5" Width="256" />
|
|
||||||
|
|
||||||
<!-- Bicos dinâmicos -->
|
<Rectangle Grid.Row="2" Fill="Transparent"/>
|
||||||
<ItemsControl ItemsSource="{Binding Bicos, RelativeSource={RelativeSource AncestorType=UserControl}}" AlternationCount="1000">
|
</Grid>
|
||||||
|
|
||||||
|
<!-- ===================== CENTRO ===================== -->
|
||||||
|
<Grid Grid.Column="1" Margin="0,0,10,0">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="85"/>
|
||||||
|
<RowDefinition Height="33"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<!-- área dos bicos -->
|
||||||
|
<Grid Grid.Row="0" x:Name="AreaTecnica">
|
||||||
|
|
||||||
|
<Grid VerticalAlignment="Top">
|
||||||
|
<Grid.Margin>
|
||||||
|
<MultiBinding Converter="{StaticResource BarraTopConverter}" ConverterParameter="5">
|
||||||
|
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ctrl:PulverizadorIndicator}}" Path="AlturaBarra"/>
|
||||||
|
<Binding ElementName="AreaTecnica" Path="ActualHeight"/>
|
||||||
|
</MultiBinding>
|
||||||
|
</Grid.Margin>
|
||||||
|
|
||||||
|
<!-- barra -->
|
||||||
|
<Border Height="5" Background="{StaticResource LineBrush}" CornerRadius="3" VerticalAlignment="Top"/>
|
||||||
|
|
||||||
|
<!-- bicos -->
|
||||||
|
<ItemsControl ItemsSource="{Binding Bicos, RelativeSource={RelativeSource AncestorType={x:Type ctrl:PulverizadorIndicator}}}" Margin="0,-35,0,0">
|
||||||
<ItemsControl.ItemsPanel>
|
<ItemsControl.ItemsPanel>
|
||||||
<ItemsPanelTemplate>
|
<ItemsPanelTemplate>
|
||||||
<Canvas />
|
<UniformGrid Rows="1" Columns="{Binding QtdBicos, RelativeSource={RelativeSource AncestorType={x:Type ctrl:PulverizadorIndicator}}}" />
|
||||||
</ItemsPanelTemplate>
|
</ItemsPanelTemplate>
|
||||||
</ItemsControl.ItemsPanel>
|
</ItemsControl.ItemsPanel>
|
||||||
|
|
||||||
<!-- Define onde cada item fica no Canvas -->
|
|
||||||
<ItemsControl.ItemContainerStyle>
|
<ItemsControl.ItemContainerStyle>
|
||||||
<Style TargetType="ContentPresenter">
|
<Style TargetType="ContentPresenter">
|
||||||
<Setter Property="Canvas.Top" Value="-27" />
|
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||||
<Setter Property="Canvas.Left">
|
<Setter Property="VerticalAlignment" Value="Top"/>
|
||||||
<Setter.Value>
|
|
||||||
<MultiBinding Converter="{StaticResource BicoPositionFisicaConverter}">
|
|
||||||
<!-- largura visível da barra em px -->
|
|
||||||
<Binding ElementName="linhaBarra" Path="ActualWidth" />
|
|
||||||
<!-- índice do bico (do modelo) -->
|
|
||||||
<Binding Path="Index" />
|
|
||||||
<!-- quantidade total de bicos -->
|
|
||||||
<Binding Path="QtdBicos" RelativeSource="{RelativeSource AncestorType=UserControl}" />
|
|
||||||
<!-- distância entre bicos em cm -->
|
|
||||||
<Binding Path="DistanciaEntreBicosCm" RelativeSource="{RelativeSource AncestorType=UserControl}" />
|
|
||||||
<!-- comprimento da barra em cm -->
|
|
||||||
<Binding Path="ComprimentoBarraCm" RelativeSource="{RelativeSource AncestorType=UserControl}" />
|
|
||||||
</MultiBinding>
|
|
||||||
</Setter.Value>
|
|
||||||
</Setter>
|
|
||||||
</Style>
|
</Style>
|
||||||
</ItemsControl.ItemContainerStyle>
|
</ItemsControl.ItemContainerStyle>
|
||||||
|
|
||||||
<!-- Como desenhar cada bico -->
|
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
<DataTemplate DataType="{x:Type local:BicoModel}">
|
<DataTemplate DataType="{x:Type local:BicoModel}">
|
||||||
<local:BicoLequeIndicator AnguloControle="{Binding AnguloControle}" OpeningAngle="{Binding OpeningAngle}" IsCommandOn="{Binding IsCommandOn}" IsSpraying="{Binding IsSpraying}" Vazao="{Binding Vazao}" TempoAtuado="{Binding TempoAtuado}" Atuacoes="{Binding Atuacoes}" />
|
<local:BicoLequeIndicator HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="2,0,2,0"
|
||||||
|
AnguloControle="{Binding AnguloControle}"
|
||||||
|
OpeningAngle="{Binding OpeningAngle}"
|
||||||
|
IsCommandOn="{Binding IsCommandOn}"
|
||||||
|
IsSpraying="{Binding IsSpraying}"
|
||||||
|
Vazao="{Binding Vazao}"
|
||||||
|
TempoAtuado="{Binding TempoAtuado}"
|
||||||
|
Atuacoes="{Binding Atuacoes}" />
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ItemsControl.ItemTemplate>
|
</ItemsControl.ItemTemplate>
|
||||||
</ItemsControl>
|
</ItemsControl>
|
||||||
</Canvas>
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<!-- Bomba Pressurizadora -->
|
<!-- solo -->
|
||||||
<Canvas Width="50" HorizontalAlignment="Right" Margin="0,0,0,0">
|
<Grid Grid.Row="1" ClipToBounds="True" Margin="8,0,8,0">
|
||||||
<!-- Título -->
|
<Border Background="{StaticResource CropBrush}" CornerRadius="0,0,8,8"/>
|
||||||
<TextBlock Text="Bomba" FontSize="10" Canvas.Top="-30" Canvas.Left="10" TextAlignment="Right" Width="50">
|
|
||||||
|
<Border HorizontalAlignment="Left" Background="{StaticResource GroundBrush}" CornerRadius="0,0,8,8">
|
||||||
|
<Border.Width>
|
||||||
|
<MultiBinding Converter="{StaticResource RuaWidthFisicaConverter}">
|
||||||
|
<Binding RelativeSource="{RelativeSource AncestorType=Grid}" Path="ActualWidth"/>
|
||||||
|
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ctrl:PulverizadorIndicator}}" Path="LarguraRuaCm"/>
|
||||||
|
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ctrl:PulverizadorIndicator}}" Path="ComprimentoBarraCm"/>
|
||||||
|
</MultiBinding>
|
||||||
|
</Border.Width>
|
||||||
|
|
||||||
|
<Border.Margin>
|
||||||
|
<MultiBinding Converter="{StaticResource RuaOffsetFisicaConverter}">
|
||||||
|
<Binding RelativeSource="{RelativeSource AncestorType=Grid}" Path="ActualWidth"/>
|
||||||
|
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ctrl:PulverizadorIndicator}}" Path="ErroLateralCm"/>
|
||||||
|
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ctrl:PulverizadorIndicator}}" Path="LarguraRuaCm"/>
|
||||||
|
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ctrl:PulverizadorIndicator}}" Path="ComprimentoBarraCm"/>
|
||||||
|
</MultiBinding>
|
||||||
|
</Border.Margin>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!-- ===================== DIREITA ===================== -->
|
||||||
|
<Grid Grid.Column="2">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="10"/>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
<RowDefinition Height="28"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="0"
|
||||||
|
Text="Bomba"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center">
|
||||||
<TextBlock.Style>
|
<TextBlock.Style>
|
||||||
<Style TargetType="TextBlock" BasedOn="{StaticResource SectionTitle}">
|
<Style TargetType="TextBlock" BasedOn="{StaticResource SectionTitle}">
|
||||||
<Setter Property="Foreground" Value="LightGray"/>
|
<Setter Property="Foreground" Value="{StaticResource TextSecondary}"/>
|
||||||
|
|
||||||
<Style.Triggers>
|
<Style.Triggers>
|
||||||
<!-- Quando a bomba estiver ligada -->
|
<DataTrigger Binding="{Binding IsBombaOn, RelativeSource={RelativeSource AncestorType={x:Type ctrl:PulverizadorIndicator}}}" Value="True">
|
||||||
<DataTrigger Binding="{Binding IsBombaOn, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="True">
|
|
||||||
<Setter Property="Foreground" Value="#4CD964"/>
|
<Setter Property="Foreground" Value="#4CD964"/>
|
||||||
</DataTrigger>
|
</DataTrigger>
|
||||||
|
|
||||||
<!-- Quando desligada -->
|
|
||||||
<DataTrigger Binding="{Binding IsBombaOn, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="False">
|
|
||||||
<Setter Property="Foreground" Value="#FFB0BAC8"/>
|
|
||||||
</DataTrigger>
|
|
||||||
</Style.Triggers>
|
</Style.Triggers>
|
||||||
</Style>
|
</Style>
|
||||||
</TextBlock.Style>
|
</TextBlock.Style>
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
|
|
||||||
<!-- Dados da bomba (pressão e tempo) -->
|
<Grid Grid.Row="1"
|
||||||
<StackPanel Orientation="Vertical" Canvas.Left="10" Canvas.Top="-18" TextBlock.TextAlignment="Right">
|
VerticalAlignment="Center"
|
||||||
<!-- Linha 1: pressão -->
|
Margin="0,2,0,2">
|
||||||
<TextBlock Text="Pressão" Foreground="{StaticResource TextSecondary}" FontSize="10"/>
|
<Grid.RowDefinitions>
|
||||||
<TextBlock Text="{Binding PressaoLinha, RelativeSource={RelativeSource AncestorType=UserControl}, StringFormat={}{0:F2} psi}" Foreground="{StaticResource TextPrimary}" FontSize="12" FontWeight="SemiBold" Margin="0,0,0,4"/>
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<!-- Linha 2: tempo ligado -->
|
<!-- Pressão -->
|
||||||
<TextBlock Text="Tempo" Foreground="{StaticResource TextSecondary}" FontSize="10"/>
|
<Grid Grid.Row="0" Margin="0,0,0,6">
|
||||||
<TextBlock Text="{Binding TempoAtuado, RelativeSource={RelativeSource AncestorType=UserControl}, StringFormat={}{0:F2} s}" Foreground="{StaticResource TextPrimary}" FontSize="12" FontWeight="SemiBold" Margin="0,0,0,4"/>
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<!-- Linha 3: vazao -->
|
<TextBlock Text="Pressão"
|
||||||
<TextBlock Text="Vazão" Foreground="{StaticResource TextSecondary}" FontSize="10"/>
|
Style="{StaticResource InfoLabelStyle}"
|
||||||
<TextBlock Text="{Binding VazaoInstantanea, RelativeSource={RelativeSource AncestorType=UserControl}, StringFormat={}{0:F2} mL/s}" Foreground="{StaticResource TextPrimary}" FontSize="12" FontWeight="SemiBold"/>
|
VerticalAlignment="Center"/>
|
||||||
</StackPanel>
|
|
||||||
</Canvas>
|
|
||||||
|
|
||||||
<!-- Solo + Rua -->
|
<TextBlock Grid.Column="1"
|
||||||
<Grid Height="13" VerticalAlignment="Top" Margin="-18,80,-18,0" ClipToBounds="True">
|
Text="{Binding PressaoLinha, RelativeSource={RelativeSource AncestorType={x:Type ctrl:PulverizadorIndicator}}, StringFormat={}{0:F1} psi}"
|
||||||
|
Foreground="{StaticResource TextPrimary}"
|
||||||
<!-- Cana (fundo) -->
|
FontSize="13"
|
||||||
<Border Background="#5F6A36" CornerRadius="0,0,8,8"/>
|
FontWeight="SemiBold"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
<!-- Rua (faixa vermelha que desliza) -->
|
|
||||||
<Border Height="13" HorizontalAlignment="Left" Background="#AA8B0000" CornerRadius="0,0,8,8">
|
|
||||||
|
|
||||||
<!-- Largura da rua em px -->
|
|
||||||
<Border.Width>
|
|
||||||
<MultiBinding Converter="{StaticResource RuaWidthFisicaConverter}">
|
|
||||||
<!-- largura em px da faixa do solo -->
|
|
||||||
<Binding RelativeSource="{RelativeSource AncestorType=Grid}" Path="ActualWidth"/>
|
|
||||||
<!-- largura da rua em cm -->
|
|
||||||
<Binding Path="LarguraRuaCm"/>
|
|
||||||
<!-- comprimento físico representado (cm) -->
|
|
||||||
<Binding Path="ComprimentoBarraCm"/>
|
|
||||||
</MultiBinding>
|
|
||||||
</Border.Width>
|
|
||||||
|
|
||||||
<!-- Deslocamento lateral da rua -->
|
|
||||||
<Border.Margin>
|
|
||||||
<MultiBinding Converter="{StaticResource RuaOffsetFisicaConverter}">
|
|
||||||
<!-- largura em px -->
|
|
||||||
<Binding RelativeSource="{RelativeSource AncestorType=Grid}" Path="ActualWidth"/>
|
|
||||||
<!-- erro lateral em cm (0 centro, - esquerda, + direita) -->
|
|
||||||
<Binding Path="ErroLateralCm"/>
|
|
||||||
<!-- largura rua cm -->
|
|
||||||
<Binding Path="LarguraRuaCm"/>
|
|
||||||
<!-- comprimento barra cm (escala px/cm) -->
|
|
||||||
<Binding Path="ComprimentoBarraCm"/>
|
|
||||||
</MultiBinding>
|
|
||||||
</Border.Margin>
|
|
||||||
</Border>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Tempo -->
|
||||||
|
<Grid Grid.Row="1" Margin="0,0,0,6">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<TextBlock Text="Tempo"
|
||||||
|
Style="{StaticResource InfoLabelStyle}"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
|
||||||
|
<TextBlock Grid.Column="1"
|
||||||
|
Text="{Binding TempoAtuado, RelativeSource={RelativeSource AncestorType={x:Type ctrl:PulverizadorIndicator}}, StringFormat={}{0:F1} s}"
|
||||||
|
Foreground="{StaticResource TextPrimary}"
|
||||||
|
FontSize="13"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Vazão -->
|
||||||
|
<Grid Grid.Row="2">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<TextBlock Text="Vazão"
|
||||||
|
Style="{StaticResource InfoLabelStyle}"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
|
||||||
|
<TextBlock Grid.Column="1"
|
||||||
|
Text="{Binding VazaoInstantanea, RelativeSource={RelativeSource AncestorType={x:Type ctrl:PulverizadorIndicator}}, StringFormat={}{0:F1} mL/s}"
|
||||||
|
Foreground="{StaticResource TextPrimary}"
|
||||||
|
FontSize="13"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
</Grid>
|
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
@ -7,28 +7,22 @@ using UserControl = System.Windows.Controls.UserControl;
|
||||||
|
|
||||||
namespace OperationControl.Controls
|
namespace OperationControl.Controls
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Interaction logic for PulverizadorIndicator.xaml
|
|
||||||
/// </summary>
|
|
||||||
public partial class PulverizadorIndicator : UserControl
|
public partial class PulverizadorIndicator : UserControl
|
||||||
{
|
{
|
||||||
public PulverizadorIndicator()
|
public PulverizadorIndicator()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
RebuildBicos();
|
RebuildBicos();
|
||||||
DataContext = this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public double DistanciaEntreBicosCm
|
public double DistanciaEntreBicosCm
|
||||||
{
|
{
|
||||||
get => (double)GetValue(DistanciaEntreBicosCmProperty);
|
get => (double)GetValue(DistanciaEntreBicosCmProperty);
|
||||||
set => SetValue(DistanciaEntreBicosCmProperty, value);
|
set => SetValue(DistanciaEntreBicosCmProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly DependencyProperty DistanciaEntreBicosCmProperty = DependencyProperty.Register(nameof(DistanciaEntreBicosCm), typeof(double), typeof(PulverizadorIndicator), new PropertyMetadata(50.0));
|
public static readonly DependencyProperty DistanciaEntreBicosCmProperty =
|
||||||
|
DependencyProperty.Register(nameof(DistanciaEntreBicosCm), typeof(double), typeof(PulverizadorIndicator), new PropertyMetadata(50.0));
|
||||||
|
|
||||||
public double ComprimentoBarraCm
|
public double ComprimentoBarraCm
|
||||||
{
|
{
|
||||||
|
|
@ -36,7 +30,8 @@ namespace OperationControl.Controls
|
||||||
set => SetValue(ComprimentoBarraCmProperty, value);
|
set => SetValue(ComprimentoBarraCmProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly DependencyProperty ComprimentoBarraCmProperty = DependencyProperty.Register(nameof(ComprimentoBarraCm), typeof(double), typeof(PulverizadorIndicator), new PropertyMetadata(103.7));
|
public static readonly DependencyProperty ComprimentoBarraCmProperty =
|
||||||
|
DependencyProperty.Register(nameof(ComprimentoBarraCm), typeof(double), typeof(PulverizadorIndicator), new PropertyMetadata(103.7));
|
||||||
|
|
||||||
public double AlturaBarra
|
public double AlturaBarra
|
||||||
{
|
{
|
||||||
|
|
@ -44,7 +39,8 @@ namespace OperationControl.Controls
|
||||||
set => SetValue(AlturaBarraProperty, value);
|
set => SetValue(AlturaBarraProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly DependencyProperty AlturaBarraProperty = DependencyProperty.Register(nameof(AlturaBarra), typeof(double), typeof(PulverizadorIndicator), new PropertyMetadata(50.0));
|
public static readonly DependencyProperty AlturaBarraProperty =
|
||||||
|
DependencyProperty.Register(nameof(AlturaBarra), typeof(double), typeof(PulverizadorIndicator), new PropertyMetadata(50.0));
|
||||||
|
|
||||||
public bool IsBombaOn
|
public bool IsBombaOn
|
||||||
{
|
{
|
||||||
|
|
@ -52,7 +48,8 @@ namespace OperationControl.Controls
|
||||||
set => SetValue(IsBombaOnProperty, value);
|
set => SetValue(IsBombaOnProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly DependencyProperty IsBombaOnProperty = DependencyProperty.Register(nameof(IsBombaOn), typeof(bool), typeof(PulverizadorIndicator), new PropertyMetadata(false));
|
public static readonly DependencyProperty IsBombaOnProperty =
|
||||||
|
DependencyProperty.Register(nameof(IsBombaOn), typeof(bool), typeof(PulverizadorIndicator), new PropertyMetadata(false));
|
||||||
|
|
||||||
public double PressaoLinha
|
public double PressaoLinha
|
||||||
{
|
{
|
||||||
|
|
@ -60,8 +57,8 @@ namespace OperationControl.Controls
|
||||||
set => SetValue(PressaoLinhaProperty, value);
|
set => SetValue(PressaoLinhaProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly DependencyProperty PressaoLinhaProperty = DependencyProperty.Register(nameof(PressaoLinha), typeof(double), typeof(PulverizadorIndicator), new PropertyMetadata(0.0));
|
public static readonly DependencyProperty PressaoLinhaProperty =
|
||||||
|
DependencyProperty.Register(nameof(PressaoLinha), typeof(double), typeof(PulverizadorIndicator), new PropertyMetadata(0.0));
|
||||||
|
|
||||||
public double TempoAtuado
|
public double TempoAtuado
|
||||||
{
|
{
|
||||||
|
|
@ -69,7 +66,8 @@ namespace OperationControl.Controls
|
||||||
set => SetValue(TempoAtuadoProperty, value);
|
set => SetValue(TempoAtuadoProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly DependencyProperty TempoAtuadoProperty = DependencyProperty.Register(nameof(TempoAtuado), typeof(double), typeof(PulverizadorIndicator), new PropertyMetadata(0.0));
|
public static readonly DependencyProperty TempoAtuadoProperty =
|
||||||
|
DependencyProperty.Register(nameof(TempoAtuado), typeof(double), typeof(PulverizadorIndicator), new PropertyMetadata(0.0));
|
||||||
|
|
||||||
public double VazaoInstantanea
|
public double VazaoInstantanea
|
||||||
{
|
{
|
||||||
|
|
@ -77,7 +75,8 @@ namespace OperationControl.Controls
|
||||||
set => SetValue(VazaoInstantaneaProperty, value);
|
set => SetValue(VazaoInstantaneaProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly DependencyProperty VazaoInstantaneaProperty = DependencyProperty.Register(nameof(VazaoInstantanea), typeof(double), typeof(PulverizadorIndicator), new PropertyMetadata(0.0));
|
public static readonly DependencyProperty VazaoInstantaneaProperty =
|
||||||
|
DependencyProperty.Register(nameof(VazaoInstantanea), typeof(double), typeof(PulverizadorIndicator), new PropertyMetadata(0.0));
|
||||||
|
|
||||||
public int QtdBicos
|
public int QtdBicos
|
||||||
{
|
{
|
||||||
|
|
@ -85,7 +84,9 @@ namespace OperationControl.Controls
|
||||||
set => SetValue(QtdBicosProperty, value);
|
set => SetValue(QtdBicosProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly DependencyProperty QtdBicosProperty = DependencyProperty.Register(nameof(QtdBicos), typeof(int), typeof(PulverizadorIndicator), new PropertyMetadata(VariaveisEquipamento.QuantidadeBicosPulverizadores, OnQtdBicosChanged));
|
public static readonly DependencyProperty QtdBicosProperty =
|
||||||
|
DependencyProperty.Register(nameof(QtdBicos), typeof(int), typeof(PulverizadorIndicator),
|
||||||
|
new PropertyMetadata(VariaveisEquipamento.QuantidadeBicosPulverizadores, OnQtdBicosChanged));
|
||||||
|
|
||||||
public double LarguraRuaCm
|
public double LarguraRuaCm
|
||||||
{
|
{
|
||||||
|
|
@ -93,8 +94,8 @@ namespace OperationControl.Controls
|
||||||
set => SetValue(LarguraRuaCmProperty, value);
|
set => SetValue(LarguraRuaCmProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly DependencyProperty LarguraRuaCmProperty = DependencyProperty.Register(nameof(LarguraRuaCm), typeof(double), typeof(PulverizadorIndicator), new PropertyMetadata(150.0));
|
public static readonly DependencyProperty LarguraRuaCmProperty =
|
||||||
|
DependencyProperty.Register(nameof(LarguraRuaCm), typeof(double), typeof(PulverizadorIndicator), new PropertyMetadata(150.0));
|
||||||
|
|
||||||
public double ErroLateralCm
|
public double ErroLateralCm
|
||||||
{
|
{
|
||||||
|
|
@ -102,14 +103,14 @@ namespace OperationControl.Controls
|
||||||
set => SetValue(ErroLateralCmProperty, value);
|
set => SetValue(ErroLateralCmProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly DependencyProperty ErroLateralCmProperty = DependencyProperty.Register(nameof(ErroLateralCm), typeof(double), typeof(PulverizadorIndicator), new PropertyMetadata(0.0));
|
public static readonly DependencyProperty ErroLateralCmProperty =
|
||||||
|
DependencyProperty.Register(nameof(ErroLateralCm), typeof(double), typeof(PulverizadorIndicator), new PropertyMetadata(0.0));
|
||||||
|
|
||||||
public ObservableCollection<BicoModel> Bicos { get; } = new();
|
public ObservableCollection<BicoModel> Bicos { get; } = new();
|
||||||
|
|
||||||
private static void OnQtdBicosChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
private static void OnQtdBicosChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
var ctl = (PulverizadorIndicator)d;
|
if (d is PulverizadorIndicator ctl)
|
||||||
ctl.RebuildBicos();
|
ctl.RebuildBicos();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,7 +118,9 @@ namespace OperationControl.Controls
|
||||||
{
|
{
|
||||||
Bicos.Clear();
|
Bicos.Clear();
|
||||||
|
|
||||||
for (int i = 0; i < QtdBicos; i++)
|
int quantidade = QtdBicos < 0 ? 0 : QtdBicos;
|
||||||
|
|
||||||
|
for (int i = 0; i < quantidade; i++)
|
||||||
{
|
{
|
||||||
Bicos.Add(new BicoModel
|
Bicos.Add(new BicoModel
|
||||||
{
|
{
|
||||||
|
|
@ -132,10 +135,5 @@ namespace OperationControl.Controls
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -8,6 +8,8 @@ namespace OperationControl.Models
|
||||||
{
|
{
|
||||||
public class AppShell
|
public class AppShell
|
||||||
{
|
{
|
||||||
|
public static readonly bool Mock = true;
|
||||||
|
|
||||||
private readonly System.Timers.Timer tmrComunicacao = new(1000) { AutoReset = true };
|
private readonly System.Timers.Timer tmrComunicacao = new(1000) { AutoReset = true };
|
||||||
private int tmrComunicacaoTicks = 0;
|
private int tmrComunicacaoTicks = 0;
|
||||||
private bool tmrComunicacaoTicking = false;
|
private bool tmrComunicacaoTicking = false;
|
||||||
|
|
@ -33,6 +35,93 @@ namespace OperationControl.Models
|
||||||
Main = new MainWindow();
|
Main = new MainWindow();
|
||||||
Dock = new DockWindow();
|
Dock = new DockWindow();
|
||||||
Dock.Show();
|
Dock.Show();
|
||||||
|
|
||||||
|
if (Mock)
|
||||||
|
{
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await Task.Delay(1000);
|
||||||
|
VariaveisControleOperacao.AdicionarNovoRoverNaRede("01", "192.168.1.100");
|
||||||
|
VariaveisControleOperacao.RoversNaRede.FirstOrDefault().DadosLeitura = new AgroBase.Models.Operacoes.OperacaoParametrosDadosModel()
|
||||||
|
{
|
||||||
|
StatusRover = StatusModulo.Operante,
|
||||||
|
Operacao = new AgroBase.Models.Operacoes.OperacaoParametrosDadosOperacaoModel()
|
||||||
|
{
|
||||||
|
Status = StatusOperacao.Parametrizando
|
||||||
|
},
|
||||||
|
Atuador = new AgroBase.Models.Operacoes.OperacaoParametrosDadosAtuadorModel()
|
||||||
|
{
|
||||||
|
Bombas = new List<AgroBase.Models.Operacoes.OperacaoParametrosDadosBombaModel>()
|
||||||
|
{
|
||||||
|
new AgroBase.Models.Operacoes.OperacaoParametrosDadosBombaModel()
|
||||||
|
{
|
||||||
|
ComandoEstado = true,
|
||||||
|
LeituraEstado = true,
|
||||||
|
ID = "BOMBA",
|
||||||
|
ID_Num = 10,
|
||||||
|
Inicializado = true,
|
||||||
|
Potencia = 50,
|
||||||
|
TempoAtuado = 3000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Bicos = new List<AgroBase.Models.Operacoes.OperacaoParametrosDadosBicoModel>()
|
||||||
|
{
|
||||||
|
new AgroBase.Models.Operacoes.OperacaoParametrosDadosBicoModel()
|
||||||
|
{
|
||||||
|
AnguloAbertura = 30,
|
||||||
|
ComandoAngulo = 0,
|
||||||
|
ComandoEstado = true,
|
||||||
|
ID = "B01",
|
||||||
|
ID_Num = 1,
|
||||||
|
Inicializado = true,
|
||||||
|
LeituraAngulo = 0,
|
||||||
|
LeituraEstado = true,
|
||||||
|
Posicao = 1,
|
||||||
|
QtdAtuacoes = 5,
|
||||||
|
TempoAtuado = 300,
|
||||||
|
VazaoInstantaneaMLs = 15,
|
||||||
|
VazaoMediaMLs = 30,
|
||||||
|
VolumeVazadoML = 325
|
||||||
|
},
|
||||||
|
new AgroBase.Models.Operacoes.OperacaoParametrosDadosBicoModel()
|
||||||
|
{
|
||||||
|
AnguloAbertura = 30,
|
||||||
|
ComandoAngulo = 0,
|
||||||
|
ComandoEstado = true,
|
||||||
|
ID = "B02",
|
||||||
|
ID_Num = 2,
|
||||||
|
Inicializado = true,
|
||||||
|
LeituraAngulo = 0,
|
||||||
|
LeituraEstado = false,
|
||||||
|
Posicao = 1,
|
||||||
|
QtdAtuacoes = 5,
|
||||||
|
TempoAtuado = 300,
|
||||||
|
VazaoInstantaneaMLs = 15,
|
||||||
|
VazaoMediaMLs = 30,
|
||||||
|
VolumeVazadoML = 325
|
||||||
|
},
|
||||||
|
new AgroBase.Models.Operacoes.OperacaoParametrosDadosBicoModel()
|
||||||
|
{
|
||||||
|
AnguloAbertura = 30,
|
||||||
|
ComandoAngulo = 0,
|
||||||
|
ComandoEstado = false,
|
||||||
|
ID = "B03",
|
||||||
|
ID_Num = 3,
|
||||||
|
Inicializado = true,
|
||||||
|
LeituraAngulo = 0,
|
||||||
|
LeituraEstado = true,
|
||||||
|
Posicao = 2,
|
||||||
|
QtdAtuacoes = 5,
|
||||||
|
TempoAtuado = 300,
|
||||||
|
VazaoInstantaneaMLs = 15,
|
||||||
|
VazaoMediaMLs = 30,
|
||||||
|
VolumeVazadoML = 325
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tmrComunicacao_Elapsed()
|
private void tmrComunicacao_Elapsed()
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,7 @@ namespace OperationControl.Models
|
||||||
|
|
||||||
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
{
|
{
|
||||||
(((App)Application.Current).Shell.Dock?.DataContext as DockWindowViewModel)?.AtualizarDadosTela(rover);
|
((App)Application.Current).Shell.Dock?._vm?.AtualizarDadosTela(rover);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
@ -237,7 +237,7 @@ namespace OperationControl.Models
|
||||||
}
|
}
|
||||||
foreach (var rover in rovers_atual)
|
foreach (var rover in rovers_atual)
|
||||||
{
|
{
|
||||||
rover.Alive = (DateTime.Now - rover.UltimoContato).TotalSeconds < TempoRoverVivo;
|
rover.Alive = AppShell.Mock || (DateTime.Now - rover.UltimoContato).TotalSeconds < TempoRoverVivo;
|
||||||
if (!rover.Alive)
|
if (!rover.Alive)
|
||||||
{
|
{
|
||||||
//((App)Application.Current).Shell.Main?.MAP?.markers?.UpdateMarkerInfo(rover.RoverId, status: AgroBase.Models.Enums.StatusOperacao.Erro);
|
//((App)Application.Current).Shell.Main?.MAP?.markers?.UpdateMarkerInfo(rover.RoverId, status: AgroBase.Models.Enums.StatusOperacao.Erro);
|
||||||
|
|
|
||||||
|
|
@ -221,8 +221,7 @@ namespace OperationControl.ViewModels
|
||||||
// string fix = GnssService.FixMode(); // "No Fix", "3D", "RTK Float", "RTK Fixed"
|
// string fix = GnssService.FixMode(); // "No Fix", "3D", "RTK Float", "RTK Fixed"
|
||||||
// double? hdop = GnssService.Hdop();
|
// double? hdop = GnssService.Hdop();
|
||||||
|
|
||||||
bool conectado = Variaveis.GpsService?.IsConnected ?? false; // <-- seu método real aqui
|
bool conectado = AppShell.Mock || (Variaveis.GpsService?.IsConnected ?? false);
|
||||||
conectado = true;
|
|
||||||
|
|
||||||
if (!conectado)
|
if (!conectado)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -126,12 +126,6 @@ namespace OperationControl.ViewModels.Views.Operacao
|
||||||
SelecionarAlerta(alerta);
|
SelecionarAlerta(alerta);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AtualizarListaAlertasRoverSelecionado(string rover_id)
|
|
||||||
{
|
|
||||||
var rover = VariaveisControleOperacao.RoversNaRede.FirstOrDefault(x => x.RoverId == rover_id);
|
|
||||||
if (rover == null) return;
|
|
||||||
var dados_leitura = rover?.DadosLeitura;
|
|
||||||
if (dados_leitura?.ModulosSaude == null) return;
|
|
||||||
|
|
||||||
SeveridadeAlerta DeParaStatus(StatusModulo status, bool mandatorio)
|
SeveridadeAlerta DeParaStatus(StatusModulo status, bool mandatorio)
|
||||||
{
|
{
|
||||||
|
|
@ -152,6 +146,13 @@ namespace OperationControl.ViewModels.Views.Operacao
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AtualizarListaAlertasRoverSelecionado(string rover_id)
|
||||||
|
{
|
||||||
|
var rover = VariaveisControleOperacao.RoversNaRede.FirstOrDefault(x => x.RoverId == rover_id);
|
||||||
|
if (rover == null) return;
|
||||||
|
var dados_leitura = rover?.DadosLeitura;
|
||||||
|
if (dados_leitura?.ModulosSaude == null) return;
|
||||||
|
|
||||||
foreach (var mod in dados_leitura.ModulosSaude)
|
foreach (var mod in dados_leitura.ModulosSaude)
|
||||||
{
|
{
|
||||||
if (mod.saude_individual.Any())
|
if (mod.saude_individual.Any())
|
||||||
|
|
@ -182,5 +183,112 @@ namespace OperationControl.ViewModels.Views.Operacao
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AtualizarListaAlertasTodosRovers()
|
||||||
|
{
|
||||||
|
App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
|
{
|
||||||
|
var alertasEsperados = new List<AlertaModel>();
|
||||||
|
|
||||||
|
foreach (var rover in VariaveisControleOperacao.RoversNaRede)
|
||||||
|
{
|
||||||
|
var dadosLeitura = rover?.DadosLeitura;
|
||||||
|
if (dadosLeitura?.ModulosSaude == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach (var mod in dadosLeitura.ModulosSaude)
|
||||||
|
{
|
||||||
|
if (mod.saude_individual != null && mod.saude_individual.Any())
|
||||||
|
{
|
||||||
|
foreach (var ind in mod.saude_individual)
|
||||||
|
{
|
||||||
|
if (ind.status == StatusModulo.Operante)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
alertasEsperados.Add(new AlertaModel
|
||||||
|
{
|
||||||
|
Rover_ID = rover.RoverId,
|
||||||
|
Modulo = mod.modulo,
|
||||||
|
Mod_ID = ind.label,
|
||||||
|
Severidade = DeParaStatus(ind.status, ind.em_uso),
|
||||||
|
Mensagem = string.Join(", ", ind.motivos ?? new List<string>()),
|
||||||
|
Timestamp = DateTime.Now
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mod.status == StatusModulo.Operante)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool mandatorio = rover.ModulosMandatorios?.Any(x =>
|
||||||
|
x.Dispositivo == mod.modulo && x.Mandatorio) ?? false;
|
||||||
|
|
||||||
|
alertasEsperados.Add(new AlertaModel
|
||||||
|
{
|
||||||
|
Rover_ID = rover.RoverId,
|
||||||
|
Modulo = mod.modulo,
|
||||||
|
Mod_ID = null,
|
||||||
|
Severidade = DeParaStatus(mod.status, mandatorio),
|
||||||
|
Mensagem = string.Join(", ", mod.motivos ?? new List<string>()),
|
||||||
|
Timestamp = DateTime.Now
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string GerarChave(string roverId, T_Code modulo, string? modId)
|
||||||
|
=> $"{roverId}|{modulo}|{modId ?? ""}";
|
||||||
|
|
||||||
|
var mapaEsperado = alertasEsperados.ToDictionary(
|
||||||
|
x => GerarChave(x.Rover_ID, x.Modulo, x.Mod_ID),
|
||||||
|
x => x);
|
||||||
|
|
||||||
|
var alertasAtuais = AlertasAtivos.ToList();
|
||||||
|
|
||||||
|
// Remove os alertas que não deveriam mais existir
|
||||||
|
foreach (var atual in alertasAtuais)
|
||||||
|
{
|
||||||
|
var chave = GerarChave(atual.Rover_ID, atual.Modulo, atual.Mod_ID);
|
||||||
|
if (!mapaEsperado.ContainsKey(chave))
|
||||||
|
{
|
||||||
|
AlertasAtivos.Remove(atual);
|
||||||
|
|
||||||
|
if (ToastAlerta == atual)
|
||||||
|
LimparToast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adiciona ou atualiza os alertas esperados
|
||||||
|
foreach (var esperado in alertasEsperados)
|
||||||
|
{
|
||||||
|
var existente = AlertasAtivos.FirstOrDefault(x =>
|
||||||
|
x.Rover_ID == esperado.Rover_ID &&
|
||||||
|
x.Modulo == esperado.Modulo &&
|
||||||
|
x.Mod_ID == esperado.Mod_ID);
|
||||||
|
|
||||||
|
if (existente == null)
|
||||||
|
{
|
||||||
|
AlertasAtivos.Add(esperado);
|
||||||
|
MostrarToast(esperado);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool mudou =
|
||||||
|
existente.Mensagem != esperado.Mensagem ||
|
||||||
|
existente.Severidade != esperado.Severidade;
|
||||||
|
|
||||||
|
existente.Mensagem = esperado.Mensagem;
|
||||||
|
existente.Severidade = esperado.Severidade;
|
||||||
|
|
||||||
|
if (mudou)
|
||||||
|
{
|
||||||
|
existente.Timestamp = DateTime.Now;
|
||||||
|
MostrarToast(existente);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -93,6 +93,8 @@ namespace OperationControl.ViewModels
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AtualizarDados(GPSModel dados)
|
public void AtualizarDados(GPSModel dados)
|
||||||
|
{
|
||||||
|
System.Windows.Application.Current.Dispatcher.Invoke(() =>
|
||||||
{
|
{
|
||||||
LatitudeTexto = dados.Latitude.ToString("F6");
|
LatitudeTexto = dados.Latitude.ToString("F6");
|
||||||
LongitudeTexto = dados.Longitude.ToString("F6");
|
LongitudeTexto = dados.Longitude.ToString("F6");
|
||||||
|
|
@ -104,6 +106,7 @@ namespace OperationControl.ViewModels
|
||||||
IdadeCorrecaoTexto = $"{dados.IdadeCorrecao:F1} s";
|
IdadeCorrecaoTexto = $"{dados.IdadeCorrecao:F1} s";
|
||||||
|
|
||||||
AtualizarCorFix(dados.QualidadeFix);
|
AtualizarCorFix(dados.QualidadeFix);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AtualizarCorFix(TiposCorrecaoGPS fix)
|
private void AtualizarCorFix(TiposCorrecaoGPS fix)
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ using AgroBase.Models.Operacoes;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using OperationControl.ViewModels.Views.Operacao;
|
using OperationControl.ViewModels.Views.Operacao;
|
||||||
using OperationControl.Controls;
|
using OperationControl.Controls;
|
||||||
|
using static OpenTK.Graphics.OpenGL.GL;
|
||||||
|
|
||||||
namespace OperationControl.ViewModels
|
namespace OperationControl.ViewModels
|
||||||
{
|
{
|
||||||
|
|
@ -136,7 +137,7 @@ namespace OperationControl.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _baseFixada;
|
private bool _baseFixada = AppShell.Mock;
|
||||||
public bool BaseFixada
|
public bool BaseFixada
|
||||||
{
|
{
|
||||||
get => _baseFixada;
|
get => _baseFixada;
|
||||||
|
|
@ -343,10 +344,8 @@ namespace OperationControl.ViewModels
|
||||||
CenterContent = _viewOperacaoCenter;
|
CenterContent = _viewOperacaoCenter;
|
||||||
RightContent = _viewOperacaoRight;
|
RightContent = _viewOperacaoRight;
|
||||||
BottomContent = _viewOperacaoBottom;
|
BottomContent = _viewOperacaoBottom;
|
||||||
CriarMarcadorBase(_viewOperacaoCenter?.MapaOperacao);
|
CriarMarcadorBase(_viewOperacaoCenter?.Mapa);
|
||||||
|
AtualizarDadosMapa(null);
|
||||||
if (!string.IsNullOrWhiteSpace(_ultimoMapaCarregado))
|
|
||||||
_viewOperacaoCenter?.MapaOperacao?.LoadMapFile(_ultimoMapaCarregado);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -371,25 +370,18 @@ namespace OperationControl.ViewModels
|
||||||
AtualizarProgressoFixacaoBase(bf.Progresso, bf.ProgressoStr);
|
AtualizarProgressoFixacaoBase(bf.Progresso, bf.ProgressoStr);
|
||||||
if (bf.Progresso >= 100) FinalizarFixacaoBase(true, bf.ProgressoStr);
|
if (bf.Progresso >= 100) FinalizarFixacaoBase(true, bf.ProgressoStr);
|
||||||
}
|
}
|
||||||
switch (CurrentStep)
|
MapViewControl? Mapa = CurrentStep == DockStep.PreparacaoMapa ? _viewPreparacaoMapa?.MapaPreparacao : CurrentStep == DockStep.ParametrizacaoRover ? _viewOperacaoCenter?.Mapa : null;
|
||||||
{
|
if (CurrentStep == DockStep.PreparacaoMapa)
|
||||||
case DockStep.PreparacaoMapa:
|
|
||||||
System.Windows.Application.Current.Dispatcher.Invoke(() =>
|
|
||||||
{
|
{
|
||||||
_viewPreparacaoMapaTop?._vm?.AtualizarDados(dados);
|
_viewPreparacaoMapaTop?._vm?.AtualizarDados(dados);
|
||||||
_viewPreparacaoMapa?.MapaPreparacao?.markers?.UpdateMarkerPosition(VariaveisControleOperacao.BaseMarkerID, lat: dados?.Latitude, lon: dados?.Longitude, heading: dados?.OrientacaoReal);
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DockStep.ParametrizacaoRover:
|
|
||||||
_viewOperacaoCenter?.MapaOperacao?.markers?.UpdateMarkerPosition(VariaveisControleOperacao.BaseMarkerID, lat: dados?.Latitude, lon: dados?.Longitude, heading: dados?.OrientacaoReal);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
Mapa?.markers?.UpdateMarkerPosition(VariaveisControleOperacao.BaseMarkerID, lat: dados?.Latitude, lon: dados?.Longitude, heading: dados?.OrientacaoReal);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AtualizarDadosMapa(OperacaoParametrosModel dados)
|
public void AtualizarDadosMapa(OperacaoParametrosModel? dados)
|
||||||
{
|
{
|
||||||
_viewOperacaoCenter?.MapaOperacao?.CarregarDadosMapa(dados?.Mapa, dados?.RuasPercorrer);
|
_viewOperacaoCenter?.Mapa?.LoadMapFile(_ultimoMapaCarregado);
|
||||||
|
_viewOperacaoCenter?.Mapa?.CarregarDadosMapa(dados?.Mapa, dados?.RuasPercorrer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region TELA 2
|
#region TELA 2
|
||||||
|
|
@ -500,6 +492,131 @@ namespace OperationControl.ViewModels
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region TELA 3
|
#region TELA 3
|
||||||
|
public void AtualizarListaRovers(List<OperacaoParametrosModel> rovers_atual)
|
||||||
|
{
|
||||||
|
var cards = rovers_atual.Select(x => new RoverCardModel()
|
||||||
|
{
|
||||||
|
EquipamentoId = x.IP,
|
||||||
|
NumeroSerie = x.RoverId,
|
||||||
|
Status = x.DadosLeitura?.StatusRover ?? AgroBase.Models.Enums.StatusModulo.Desconectado
|
||||||
|
}).ToArray();
|
||||||
|
|
||||||
|
_viewOperacaoRight?._vm?.AtualizarListaRovers(cards);
|
||||||
|
|
||||||
|
foreach (var rover in cards)
|
||||||
|
{
|
||||||
|
if (!_viewOperacaoCenter?.Mapa?.markers?.Added(rover.NumeroSerie) ?? false)
|
||||||
|
{
|
||||||
|
var roverDados = VariaveisControleOperacao.RoversNaRede.FirstOrDefault(x => x.RoverId == rover.NumeroSerie);
|
||||||
|
if (roverDados != null)
|
||||||
|
{
|
||||||
|
_viewOperacaoCenter?.Mapa?.markers?.AddMarker(
|
||||||
|
rover.NumeroSerie,
|
||||||
|
false,
|
||||||
|
lat: roverDados.DadosLeitura?.Gnss?.Latitude ?? 0,
|
||||||
|
lon: roverDados.DadosLeitura?.Gnss?.Longitude ?? 0,
|
||||||
|
heading: roverDados.DadosLeitura?.Gnss?.OrientacaoReal ?? 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AtualizarDadosTela(OperacaoParametrosModel rover)
|
||||||
|
{
|
||||||
|
if (rover == null) return;
|
||||||
|
var obj = rover.DadosLeitura;
|
||||||
|
if (obj == null) return;
|
||||||
|
|
||||||
|
var simulacao = obj.Controle?.SimulacaoMPC?.Select(x => new double[] { x.longitude, x.latitude })?.ToList();
|
||||||
|
_viewOperacaoCenter?.Mapa?.markers.UpdateMarkerPosition(rover.RoverId, lat: obj.Gnss?.Latitude, lon: obj.Gnss?.Longitude, heading: obj.Gnss?.OrientacaoReal, predict: simulacao);
|
||||||
|
_viewOperacaoCenter?.Mapa?.markers.UpdateMarkerInfo(rover.RoverId, status: obj.Operacao?.Status ?? AgroBase.Models.Enums.StatusOperacao.NaoIniciado);
|
||||||
|
|
||||||
|
//_viewOperacaoBottom?._vm?.AtualizarListaAlertasRoverSelecionado(rover.RoverId);
|
||||||
|
_viewOperacaoBottom?._vm?.AtualizarListaAlertasTodosRovers();
|
||||||
|
|
||||||
|
if (rover.RoverId != VariaveisControleOperacao.SelectedRoverId) return;
|
||||||
|
|
||||||
|
var conexao = obj.ModulosSaude?.FirstOrDefault(x => x.modulo == AgroBase.Models.Enums.T_Code.Ipb);
|
||||||
|
double c = conexao?.saude ?? 0;
|
||||||
|
double conexao_latencia = conexao?.detalhes?["avg_rtt"]?.Value<double>() ?? 0.0;
|
||||||
|
double conexao_perda = conexao?.detalhes?["loss_pct"]?.Value<double>() ?? 0.0;
|
||||||
|
double bwTot = conexao?.detalhes?["bw_total_mbps"]?.Value<double>() ?? 0;
|
||||||
|
string comunicacao = $"{conexao_latencia:0.00} ms {bwTot:0.00} Mbps";
|
||||||
|
string comunicacao_extended = $"{conexao_latencia:0.00} ms {conexao_perda:F2}% {bwTot:0.00} Mbps";
|
||||||
|
|
||||||
|
_viewOperacaoLeft?._vm?.AtualizarRover(
|
||||||
|
rover?.Descricao ?? "",
|
||||||
|
obj.Controle?.PercentualVelocidadeSPKmh ?? 0,
|
||||||
|
obj.Controle?.Angulo ?? 0,
|
||||||
|
obj.Controle?.TipoMovimento ?? AgroBase.Models.Enums.TipoMovimentoDirecional.Diagnostico,
|
||||||
|
obj.Refrigeracao?.Temperatura ?? 0,
|
||||||
|
obj.Bateria?.PercentualBateria ?? 0,
|
||||||
|
obj.Atuador?.PercentualReservatorio ?? 0,
|
||||||
|
$"{c}%",
|
||||||
|
$"{obj.Gnss?.QualidadeFix ?? AgroBase.Models.Enums.TiposCorrecaoGPS.SemCorrecao} {obj.Gnss?.PrecisaoCm:F2} cm"
|
||||||
|
);
|
||||||
|
|
||||||
|
_viewOperacaoRight?._vm?.AtualizarResumo(r =>
|
||||||
|
{
|
||||||
|
r.Operacao = (obj.Operacao?.Liberada ?? false) ? "🔓 Liberada" : "🔒 Bloqueada";
|
||||||
|
r.Modo = obj.Operacao == null ? "-" : obj.Operacao.Modo.ToString();
|
||||||
|
r.Status = obj.Operacao == null ? "-" : $"{obj.Operacao.Status}" + (obj.Operacao.Status == AgroBase.Models.Enums.StatusOperacao.Aguardando ? $" ({obj.Operacao.TempoAguardandoSegs:0}s)" : "");
|
||||||
|
r.Carro = obj.Trajetoria == null ? "-" : obj.Trajetoria.StatusCarro.ToString();
|
||||||
|
r.Temperatura = $"{(obj.PerformanceNcp?.CPU_temp ?? 0):0.00} °C";
|
||||||
|
r.RuaAtual = obj.Trajetoria == null ? "-" : $"{obj.Trajetoria.CorredorAtualDistanciaPercorrida:0.00} m / " + $"{obj.Trajetoria.CorredorAtualDistanciaTotal:0.00} m " + $"({obj.Trajetoria.CorredorAtualIdx + 1})";
|
||||||
|
r.AreaTotal = obj.Trajetoria == null ? "-" : $"{obj.Trajetoria.DistanciaPercorrida:0.00} m / " + $"{obj.Trajetoria.DistanciaTotal:0.00} m";
|
||||||
|
r.Bateria = obj.Bateria == null ? "-" : $"{obj.Bateria.TensaoInstantanea:0.00} V " + $"({TimeSpan.FromMinutes(obj.Bateria.TempoEstimadoRestanteMinutos):dd\\.hh\\:mm\\:ss} " + $"{obj.Bateria.DistanciaEstimadaRestanteMetros:0.00} m)";
|
||||||
|
r.Herbicida = obj.Atuador == null ? "-" : $"{obj.Atuador.VolumeReservatorioL:0.00} L " + $"({TimeSpan.FromMinutes(obj.Atuador.TempoEstimadoRestanteMinutos):hh\\:mm\\:ss} " + $"{obj.Atuador.DistanciaEstimadaRestanteMetros:0.00} m)";
|
||||||
|
r.Infestacao = obj.Atuador == null ? "-" : $"{obj.Atuador.HerbicidaPorAtuacaoMl:0.00} mL/atuação";
|
||||||
|
r.Conexao = comunicacao == null ? "-" : $"{comunicacao}";
|
||||||
|
r.Duracao = obj.Operacao == null ? "00:00:00 / 00:00:00" : $"{TimeSpan.FromSeconds(obj.Operacao.TempoDecorridoSegs):hh\\:mm\\:ss} / " + $"{(string.IsNullOrWhiteSpace(obj.Trajetoria?.TempoEstimadoOperacao) ? "00:00:00" : obj.Trajetoria.TempoEstimadoOperacao)}";
|
||||||
|
|
||||||
|
// Opcionais para progress bars, caso queira evoluir o resumo
|
||||||
|
r.RuaAtualPercentual = obj.Trajetoria?.PercentualRuaAtual ?? 0;
|
||||||
|
r.AreaTotalPercentual = obj.Trajetoria?.PercentualOperacao ?? 0;
|
||||||
|
r.BateriaPercentual = obj.Bateria?.PercentualBateria ?? 0;
|
||||||
|
r.HerbicidaPercentual = obj.Atuador?.PercentualReservatorio ?? 0;
|
||||||
|
r.InfestacaoPercentual = obj.Atuador?.PercentualErvasTerreno ?? 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
_viewOperacaoCenter?.Diagnostico?._vm?.AtualizarDados(rover);
|
||||||
|
_viewOperacaoCenter?.Diagnostico?.AtualizarGraficos();
|
||||||
|
|
||||||
|
var bomba = obj.Atuador?.Bombas?.FirstOrDefault();
|
||||||
|
var ATU = _viewOperacaoCenter.Monitoramento.Pulverizador;
|
||||||
|
ATU.ComprimentoBarraCm = AgroBase.Models.VariaveisEquipamento.ComprimentoBarraPulverizadoraCm;
|
||||||
|
ATU.DistanciaEntreBicosCm = AgroBase.Models.VariaveisEquipamento.DistanciaEntreBicosCm;
|
||||||
|
ATU.AlturaBarra = obj?.Controle?.AlturaBarra ?? AgroBase.Models.VariaveisEquipamento.AlturaBarraPulverizadoraCm;
|
||||||
|
ATU.IsBombaOn = bomba?.LeituraEstado ?? false;
|
||||||
|
ATU.PressaoLinha = obj?.Atuador?.PressaoLinhaPsi ?? 0;
|
||||||
|
ATU.VazaoInstantanea = obj?.Atuador?.VazaoInstantaneaMLs ?? 0;
|
||||||
|
ATU.TempoAtuado = (bomba?.TempoAtuado ?? 0) / 1000.0;
|
||||||
|
|
||||||
|
double erroLateral = ((obj?.Trajetoria?.DistanciaEsquerda ?? 0) - (obj?.Trajetoria?.DistanciaDireita ?? 0)) / 2.0 * 100.0;
|
||||||
|
ATU.LarguraRuaCm = 100.0;
|
||||||
|
ATU.ErroLateralCm = erroLateral;
|
||||||
|
|
||||||
|
if (ATU.QtdBicos != obj?.Atuador?.Bicos?.Count)
|
||||||
|
{
|
||||||
|
ATU.QtdBicos = obj?.Atuador?.Bicos?.Count ?? AgroBase.Models.VariaveisEquipamento.QuantidadeBicosPulverizadores;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var bico in ATU.Bicos)
|
||||||
|
{
|
||||||
|
var _bc = obj?.Atuador?.Bicos?.FirstOrDefault(x => (x.Posicao - 1) == bico.Index);
|
||||||
|
if (_bc == null) continue;
|
||||||
|
|
||||||
|
bico.OpeningAngle = _bc.AnguloAbertura;
|
||||||
|
bico.AnguloControle = _bc.ComandoAngulo;
|
||||||
|
bico.IsCommandOn = _bc.ComandoEstado;
|
||||||
|
bico.IsSpraying = _bc.LeituraEstado;
|
||||||
|
bico.Vazao = _bc.VazaoInstantaneaMLs;
|
||||||
|
bico.Atuacoes = _bc.QtdAtuacoes;
|
||||||
|
bico.TempoAtuado = _bc.TempoAtuado / 1000.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void AtualizarTopOperacaoBase()
|
public void AtualizarTopOperacaoBase()
|
||||||
{
|
{
|
||||||
|
|
@ -558,117 +675,12 @@ namespace OperationControl.ViewModels
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void AtualizarListaRovers(List<OperacaoParametrosModel> rovers_atual)
|
|
||||||
{
|
|
||||||
var cards = rovers_atual.Select(x => new RoverCardModel()
|
|
||||||
{
|
|
||||||
EquipamentoId = x.IP,
|
|
||||||
NumeroSerie = x.RoverId,
|
|
||||||
Status = x.DadosLeitura?.StatusRover ?? AgroBase.Models.Enums.StatusModulo.Desconectado
|
|
||||||
}).ToArray();
|
|
||||||
|
|
||||||
_viewOperacaoRight?._vm?.AtualizarListaRovers(cards);
|
|
||||||
|
|
||||||
foreach (var rover in cards)
|
|
||||||
{
|
|
||||||
if (!_viewOperacaoCenter?.MapaOperacao?.markers?.Added(rover.NumeroSerie) ?? false)
|
|
||||||
{
|
|
||||||
if (rover.NumeroSerie == VariaveisControleOperacao.BaseMarkerID)
|
|
||||||
{
|
|
||||||
_viewOperacaoCenter?.MapaOperacao?.markers?.AddMarker(
|
|
||||||
rover.NumeroSerie,
|
|
||||||
true,
|
|
||||||
lat: Variaveis.GpsService?.UltimaLeitura?.Latitude ?? 0,
|
|
||||||
lon: Variaveis.GpsService?.UltimaLeitura?.Longitude ?? 0,
|
|
||||||
heading: Variaveis.GpsService?.UltimaLeitura?.OrientacaoReal ?? 0,
|
|
||||||
label: "Base"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var roverDados = VariaveisControleOperacao.RoversNaRede.FirstOrDefault(x => x.RoverId == rover.NumeroSerie);
|
|
||||||
if (roverDados != null)
|
|
||||||
{
|
|
||||||
_viewOperacaoCenter?.MapaOperacao?.markers?.AddMarker(
|
|
||||||
rover.NumeroSerie,
|
|
||||||
false,
|
|
||||||
lat: roverDados.DadosLeitura?.Gnss?.Latitude ?? 0,
|
|
||||||
lon: roverDados.DadosLeitura?.Gnss?.Longitude ?? 0,
|
|
||||||
heading: roverDados.DadosLeitura?.Gnss?.OrientacaoReal ?? 0
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AtualizarDadosTela(OperacaoParametrosModel rover)
|
|
||||||
{
|
|
||||||
if (rover == null) return;
|
|
||||||
var obj = rover.DadosLeitura;
|
|
||||||
if (obj == null) return;
|
|
||||||
|
|
||||||
var simulacao = obj.Controle?.SimulacaoMPC?.Select(x => new double[] { x.longitude, x.latitude })?.ToList();
|
|
||||||
_viewOperacaoCenter?.MapaOperacao?.markers.UpdateMarkerPosition(rover.RoverId, lat: obj.Gnss?.Latitude, lon: obj.Gnss?.Longitude, heading: obj.Gnss?.OrientacaoReal, predict: simulacao);
|
|
||||||
_viewOperacaoCenter?.MapaOperacao?.markers.UpdateMarkerInfo(rover.RoverId, status: obj.Operacao?.Status ?? AgroBase.Models.Enums.StatusOperacao.NaoIniciado);
|
|
||||||
|
|
||||||
_viewOperacaoBottom?._vm?.AtualizarListaAlertasRoverSelecionado(rover.RoverId);
|
|
||||||
|
|
||||||
if (rover.RoverId == VariaveisControleOperacao.SelectedRoverId)
|
|
||||||
{
|
|
||||||
var conexao = obj.ModulosSaude?.FirstOrDefault(x => x.modulo == AgroBase.Models.Enums.T_Code.Ipb);
|
|
||||||
double c = conexao?.saude ?? 0;
|
|
||||||
double conexao_latencia = conexao?.detalhes?["avg_rtt"]?.Value<double>() ?? 0.0;
|
|
||||||
double conexao_perda = conexao?.detalhes?["loss_pct"]?.Value<double>() ?? 0.0;
|
|
||||||
double bwTot = conexao?.detalhes?["bw_total_mbps"]?.Value<double>() ?? 0;
|
|
||||||
string comunicacao = $"{conexao_latencia:0.00} ms {bwTot:0.00} Mbps";
|
|
||||||
string comunicacao_extended = $"{conexao_latencia:0.00} ms {conexao_perda:F2}% {bwTot:0.00} Mbps";
|
|
||||||
|
|
||||||
_viewOperacaoLeft?._vm?.AtualizarRover(
|
|
||||||
rover?.Descricao ?? "",
|
|
||||||
obj.Controle?.PercentualVelocidadeSPKmh ?? 0,
|
|
||||||
obj.Controle?.Angulo ?? 0,
|
|
||||||
obj.Controle?.TipoMovimento ?? AgroBase.Models.Enums.TipoMovimentoDirecional.Diagnostico,
|
|
||||||
obj.Refrigeracao?.Temperatura ?? 0,
|
|
||||||
obj.Bateria?.PercentualBateria ?? 0,
|
|
||||||
obj.Atuador?.PercentualReservatorio ?? 0,
|
|
||||||
$"{c}%",
|
|
||||||
$"{obj.Gnss?.QualidadeFix ?? AgroBase.Models.Enums.TiposCorrecaoGPS.SemCorrecao} {obj.Gnss?.PrecisaoCm:F2} cm"
|
|
||||||
);
|
|
||||||
|
|
||||||
_viewOperacaoRight?._vm?.AtualizarResumo(r =>
|
|
||||||
{
|
|
||||||
r.Operacao = (obj.Operacao?.Liberada ?? false) ? "🔓 Liberada" : "🔒 Bloqueada";
|
|
||||||
r.Modo = obj.Operacao == null ? "-" : obj.Operacao.Modo.ToString();
|
|
||||||
r.Status = obj.Operacao == null ? "-" : $"{obj.Operacao.Status}" + (obj.Operacao.Status == AgroBase.Models.Enums.StatusOperacao.Aguardando ? $" ({obj.Operacao.TempoAguardandoSegs:0}s)" : "");
|
|
||||||
r.Carro = obj.Trajetoria == null ? "-" : obj.Trajetoria.StatusCarro.ToString();
|
|
||||||
r.Temperatura = $"{(obj.PerformanceNcp?.CPU_temp ?? 0):0.00} °C";
|
|
||||||
r.RuaAtual = obj.Trajetoria == null ? "-" : $"{obj.Trajetoria.CorredorAtualDistanciaPercorrida:0.00} m / " + $"{obj.Trajetoria.CorredorAtualDistanciaTotal:0.00} m " + $"({obj.Trajetoria.CorredorAtualIdx + 1})";
|
|
||||||
r.AreaTotal = obj.Trajetoria == null ? "-" : $"{obj.Trajetoria.DistanciaPercorrida:0.00} m / " + $"{obj.Trajetoria.DistanciaTotal:0.00} m";
|
|
||||||
r.Bateria = obj.Bateria == null ? "-" : $"{obj.Bateria.TensaoInstantanea:0.00} V " + $"({TimeSpan.FromMinutes(obj.Bateria.TempoEstimadoRestanteMinutos):dd\\.hh\\:mm\\:ss} " + $"{obj.Bateria.DistanciaEstimadaRestanteMetros:0.00} m)";
|
|
||||||
r.Herbicida = obj.Atuador == null ? "-" : $"{obj.Atuador.VolumeReservatorioL:0.00} L " + $"({TimeSpan.FromMinutes(obj.Atuador.TempoEstimadoRestanteMinutos):hh\\:mm\\:ss} " + $"{obj.Atuador.DistanciaEstimadaRestanteMetros:0.00} m)";
|
|
||||||
r.Infestacao = obj.Atuador == null ? "-" : $"{obj.Atuador.HerbicidaPorAtuacaoMl:0.00} mL/atuação";
|
|
||||||
r.Conexao = comunicacao == null ? "-" : $"{comunicacao}";
|
|
||||||
r.Duracao = obj.Operacao == null ? "00:00:00 / 00:00:00" : $"{TimeSpan.FromSeconds(obj.Operacao.TempoDecorridoSegs):hh\\:mm\\:ss} / " + $"{(string.IsNullOrWhiteSpace(obj.Trajetoria?.TempoEstimadoOperacao) ? "00:00:00" : obj.Trajetoria.TempoEstimadoOperacao)}";
|
|
||||||
|
|
||||||
// Opcionais para progress bars, caso queira evoluir o resumo
|
|
||||||
r.RuaAtualPercentual = obj.Trajetoria?.PercentualRuaAtual ?? 0;
|
|
||||||
r.AreaTotalPercentual = obj.Trajetoria?.PercentualOperacao ?? 0;
|
|
||||||
r.BateriaPercentual = obj.Bateria?.PercentualBateria ?? 0;
|
|
||||||
r.HerbicidaPercentual = obj.Atuador?.PercentualReservatorio ?? 0;
|
|
||||||
r.InfestacaoPercentual = obj.Atuador?.PercentualErvasTerreno ?? 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
_viewOperacaoCenter?.Diagnostico?._vm?.AtualizarDados(rover);
|
|
||||||
_viewOperacaoCenter?.Diagnostico?.AtualizarGraficos();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnRoverSelecionadoChanged(string roverId)
|
private void OnRoverSelecionadoChanged(string roverId)
|
||||||
{
|
{
|
||||||
_viewOperacaoRight?._vm?.DestacarRoverNoMapa(roverId);
|
_viewOperacaoRight?._vm?.DestacarRoverNoMapa(roverId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnRoverSelecionadoChanged(RoverCardModel rover)
|
private void OnRoverSelecionadoChanged(RoverCardModel rover)
|
||||||
{
|
{
|
||||||
bool dados_base = rover == null;
|
bool dados_base = rover == null;
|
||||||
|
|
@ -683,7 +695,7 @@ namespace OperationControl.ViewModels
|
||||||
VariaveisControleOperacao.RoverEmFoco?.RuasPercorrer?.Clear();
|
VariaveisControleOperacao.RoverEmFoco?.RuasPercorrer?.Clear();
|
||||||
AtualizarDadosMapa(VariaveisControleOperacao.RoverEmFoco);
|
AtualizarDadosMapa(VariaveisControleOperacao.RoverEmFoco);
|
||||||
VariaveisControleOperacao.SelectedRoverId = VariaveisControleOperacao.BaseMarkerID;
|
VariaveisControleOperacao.SelectedRoverId = VariaveisControleOperacao.BaseMarkerID;
|
||||||
_viewOperacaoCenter?.MapaOperacao?.markers?.SetMarkerFocused(VariaveisControleOperacao.SelectedRoverId, true);
|
_viewOperacaoCenter?.Mapa?.markers?.SetMarkerFocused(VariaveisControleOperacao.SelectedRoverId, true);
|
||||||
|
|
||||||
_viewOperacaoCenter?._vm?.SelecionarRoverLista(rover);
|
_viewOperacaoCenter?._vm?.SelecionarRoverLista(rover);
|
||||||
|
|
||||||
|
|
@ -693,7 +705,7 @@ namespace OperationControl.ViewModels
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VariaveisControleOperacao.SelectedRoverId = rover.NumeroSerie.ToString();
|
VariaveisControleOperacao.SelectedRoverId = rover.NumeroSerie.ToString();
|
||||||
_viewOperacaoCenter?.MapaOperacao?.markers?.SetMarkerFocused(VariaveisControleOperacao.SelectedRoverId, true);
|
_viewOperacaoCenter?.Mapa?.markers?.SetMarkerFocused(VariaveisControleOperacao.SelectedRoverId, true);
|
||||||
AtualizarDadosTela(VariaveisControleOperacao.RoverEmFoco);
|
AtualizarDadosTela(VariaveisControleOperacao.RoverEmFoco);
|
||||||
|
|
||||||
VariaveisControleOperacao.RequisitarParametrosOperacao();
|
VariaveisControleOperacao.RequisitarParametrosOperacao();
|
||||||
|
|
@ -703,12 +715,15 @@ namespace OperationControl.ViewModels
|
||||||
|
|
||||||
_viewOperacaoCenter?._vm?.SelecionarRoverLista(rover);
|
_viewOperacaoCenter?._vm?.SelecionarRoverLista(rover);
|
||||||
|
|
||||||
|
AtualizarDadosMapa(VariaveisControleOperacao.RoverEmFoco);
|
||||||
|
|
||||||
AtualizarTopOperacaoRover(VariaveisControleOperacao.SelectedRoverId, ModoOperacaoAtual == ModoOperacao.Manual);
|
AtualizarTopOperacaoRover(VariaveisControleOperacao.SelectedRoverId, ModoOperacaoAtual == ModoOperacao.Manual);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void OnSecaoSelecionadaChanged(SecaoRightBar secao)
|
private void OnSecaoSelecionadaChanged(SecaoRightBar secao)
|
||||||
{
|
{
|
||||||
_viewOperacaoCenter?._vm?.DefinirSecao(secao);
|
_viewOperacaoCenter?._vm?.DefinirSecao(secao);
|
||||||
|
AtualizarDadosMapa(VariaveisControleOperacao.RoverEmFoco);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnLerParametrosSolicitado()
|
private void OnLerParametrosSolicitado()
|
||||||
|
|
@ -727,7 +742,7 @@ namespace OperationControl.ViewModels
|
||||||
|
|
||||||
var rover = VariaveisControleOperacao.RoverEmFoco;
|
var rover = VariaveisControleOperacao.RoverEmFoco;
|
||||||
|
|
||||||
VariaveisControleOperacao.EnviarParametrosOperacao(new OperacaoParametrosModel()
|
var novosParametros = new OperacaoParametrosModel()
|
||||||
{
|
{
|
||||||
Modo = parametros.Modo ?? AgroBase.Models.Enums.ModoOperacao.NaoDefinido,
|
Modo = parametros.Modo ?? AgroBase.Models.Enums.ModoOperacao.NaoDefinido,
|
||||||
Descricao = parametros.Descricao,
|
Descricao = parametros.Descricao,
|
||||||
|
|
@ -740,9 +755,20 @@ namespace OperationControl.ViewModels
|
||||||
ModulosMandatorios = rover?.ModulosMandatorios,
|
ModulosMandatorios = rover?.ModulosMandatorios,
|
||||||
ParametrosMandatorios = rover?.ParametrosMandatorios,
|
ParametrosMandatorios = rover?.ParametrosMandatorios,
|
||||||
|
|
||||||
RuasPercorrer = _viewOperacaoCenter?.MapaOperacao?.RuasMapaCarregado?.Where(x => x.Selected)?.Select(x => x.Id)?.ToList(),
|
RuasPercorrer = _viewOperacaoCenter?.Mapa?.RuasMapaCarregado?.Where(x => x.Selected)?.Select(x => x.Id)?.ToList(),
|
||||||
Mapa = _viewOperacaoCenter?.MapaOperacao?.CriarDadosMapa()
|
Mapa = _viewOperacaoCenter?.Mapa?.CriarDadosMapa()
|
||||||
});
|
};
|
||||||
|
|
||||||
|
VariaveisControleOperacao.EnviarParametrosOperacao(novosParametros);
|
||||||
|
|
||||||
|
VariaveisControleOperacao.RoverEmFoco.Modo = novosParametros.Modo;
|
||||||
|
VariaveisControleOperacao.RoverEmFoco.Descricao = novosParametros.Descricao;
|
||||||
|
VariaveisControleOperacao.RoverEmFoco.QtdCamerasSolo = novosParametros.QtdCamerasSolo;
|
||||||
|
VariaveisControleOperacao.RoverEmFoco.QtdBicos = novosParametros.QtdBicos;
|
||||||
|
VariaveisControleOperacao.RoverEmFoco.CapacidadeReservatorio = novosParametros.CapacidadeReservatorio;
|
||||||
|
VariaveisControleOperacao.RoverEmFoco.Controle = novosParametros.Controle;
|
||||||
|
VariaveisControleOperacao.RoverEmFoco.RuasPercorrer = novosParametros.RuasPercorrer;
|
||||||
|
VariaveisControleOperacao.RoverEmFoco.Mapa = novosParametros.Mapa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,49 +87,23 @@
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<DockPanel Grid.Row="0" Margin="0,0,0,8">
|
<DockPanel Grid.Row="0" Margin="0,0,0,8">
|
||||||
<TextBlock Text="Câmera de ervas"
|
<TextBlock Text="Câmera de ervas" DockPanel.Dock="Left" FontSize="12" FontWeight="SemiBold" Foreground="#E6E6E6" VerticalAlignment="Center"/>
|
||||||
DockPanel.Dock="Left"
|
|
||||||
FontSize="12"
|
|
||||||
FontWeight="SemiBold"
|
|
||||||
Foreground="#E6E6E6"
|
|
||||||
VerticalAlignment="Center"/>
|
|
||||||
|
|
||||||
<ComboBox x:Name="cmbCameraTraseiraFrameTipo"
|
<ComboBox x:Name="cmbCameraTraseiraFrameTipo" Width="130" Height="26" HorizontalAlignment="Right" SelectionChanged="cmbCameraTraseiraFrameTipo_SelectionChanged"/>
|
||||||
Width="130"
|
|
||||||
Height="26"
|
|
||||||
HorizontalAlignment="Right"
|
|
||||||
SelectionChanged="cmbCameraTraseiraFrameTipo_SelectionChanged"/>
|
|
||||||
|
|
||||||
<TextBlock Text="10 fps • 193 kbps • 5,41% erva • 0,00% cana"
|
<TextBlock Text="10 fps • 193 kbps • 5,41% erva • 0,00% cana" Margin="12,0,8,0" Foreground="#AFAFAF" FontSize="11" VerticalAlignment="Center" HorizontalAlignment="Right"/>
|
||||||
Margin="12,0,8,0"
|
|
||||||
Foreground="#AFAFAF"
|
|
||||||
FontSize="11"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
HorizontalAlignment="Right"/>
|
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
|
|
||||||
<Grid Grid.Row="1" Background="Black">
|
<Grid Grid.Row="1" Background="Black">
|
||||||
<TextBlock Text="SEM SINAL"
|
<TextBlock Text="SEM SINAL" Foreground="Gray" FontSize="18" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||||
Foreground="Gray"
|
|
||||||
FontSize="18"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"/>
|
|
||||||
|
|
||||||
<Image x:Name="imgVideoWeed"
|
<Image x:Name="imgVideoWeed" Stretch="Uniform" RenderOptions.BitmapScalingMode="LowQuality"/>
|
||||||
Stretch="Uniform"
|
|
||||||
RenderOptions.BitmapScalingMode="LowQuality"/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<!-- MAPA -->
|
<!-- MAPA -->
|
||||||
<Border Grid.Row="1" Grid.Column="0"
|
<Border Grid.Row="1" Grid.Column="0" Margin="0,6,6,0" Padding="10" CornerRadius="10" Background="#202020" BorderBrush="#353535" BorderThickness="1">
|
||||||
Margin="0,6,6,0"
|
|
||||||
Padding="10"
|
|
||||||
CornerRadius="10"
|
|
||||||
Background="#202020"
|
|
||||||
BorderBrush="#353535"
|
|
||||||
BorderThickness="1">
|
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
|
|
@ -137,12 +111,7 @@
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<TextBlock Grid.Row="0"
|
<TextBlock Grid.Row="0" Text="Mapa e posição do rover" Margin="0,0,0,8" FontSize="12" FontWeight="SemiBold" Foreground="#E6E6E6"/>
|
||||||
Text="Mapa e posição do rover"
|
|
||||||
Margin="0,0,0,8"
|
|
||||||
FontSize="12"
|
|
||||||
FontWeight="SemiBold"
|
|
||||||
Foreground="#E6E6E6"/>
|
|
||||||
|
|
||||||
<controls:MapViewControl x:Name="MapaMonitoramento" MarkerClicked="MAP_MarkerClicked" StreetMapClicked="MAP_StreetMapClicked" Grid.Row="1" Latitude="-22.1726572492617" Longitude="-47.3952163870556" Scale="5000" />
|
<controls:MapViewControl x:Name="MapaMonitoramento" MarkerClicked="MAP_MarkerClicked" StreetMapClicked="MAP_StreetMapClicked" Grid.Row="1" Latitude="-22.1726572492617" Longitude="-47.3952163870556" Scale="5000" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
@ -177,21 +146,15 @@
|
||||||
FontWeight="SemiBold"
|
FontWeight="SemiBold"
|
||||||
Foreground="#E6E6E6"/>
|
Foreground="#E6E6E6"/>
|
||||||
|
|
||||||
<Grid Grid.Row="1">
|
<controls:PulverizadorIndicator Grid.Row="1"
|
||||||
<controls:PulverizadorIndicator x:Name="ATU"
|
x:Name="areaPulverizador"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Center"/>
|
VerticalAlignment="Stretch"/>
|
||||||
</Grid>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<!-- AÇÕES RÁPIDAS -->
|
<!-- AÇÕES RÁPIDAS -->
|
||||||
<Border Grid.Row="1"
|
<Border Grid.Row="1" Padding="10" CornerRadius="10" Background="#202020" BorderBrush="#353535" BorderThickness="1">
|
||||||
Padding="10"
|
|
||||||
CornerRadius="10"
|
|
||||||
Background="#202020"
|
|
||||||
BorderBrush="#353535"
|
|
||||||
BorderThickness="1">
|
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
|
|
@ -199,12 +162,7 @@
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<TextBlock Grid.Row="0"
|
<TextBlock Grid.Row="0" Text="Ações rápidas" Margin="0,0,0,8" FontSize="12" FontWeight="SemiBold" Foreground="#E6E6E6"/>
|
||||||
Text="Ações rápidas"
|
|
||||||
Margin="0,0,0,8"
|
|
||||||
FontSize="12"
|
|
||||||
FontWeight="SemiBold"
|
|
||||||
Foreground="#E6E6E6"/>
|
|
||||||
|
|
||||||
<UniformGrid Grid.Row="1" Rows="2" Columns="2" Margin="0,4,0,0">
|
<UniformGrid Grid.Row="1" Rows="2" Columns="2" Margin="0,4,0,0">
|
||||||
<Button Content="Retorno à base" Margin="4"/>
|
<Button Content="Retorno à base" Margin="4"/>
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ namespace OperationControl.Views.Operacao
|
||||||
|
|
||||||
private TcpVideoReceiver videoFront;
|
private TcpVideoReceiver videoFront;
|
||||||
private TcpVideoReceiver videoWeed;
|
private TcpVideoReceiver videoWeed;
|
||||||
|
public PulverizadorIndicator Pulverizador => areaPulverizador;
|
||||||
|
|
||||||
public MonitoramentoView()
|
public MonitoramentoView()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
<!-- MAPA -->
|
<!-- MAPA -->
|
||||||
<Grid Visibility="{Binding ExibirMapa, Converter={StaticResource BoolToVisibilityConverter}}">
|
<Grid Visibility="{Binding ExibirMapa, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
<Border Margin="12" Padding="0" CornerRadius="10" Background="#202020" BorderBrush="#353535" BorderThickness="1" ClipToBounds="True">
|
<Border Margin="12" Padding="0" CornerRadius="10" Background="#202020" BorderBrush="#353535" BorderThickness="1" ClipToBounds="True">
|
||||||
<controls:MapViewControl x:Name="MapaOperacao" MarkerClicked="MAP_MarkerClicked" StreetMapClicked="MAP_StreetMapClicked" Latitude="-22.1726572492617" Longitude="-47.3952163870556" Scale="5000" />
|
<controls:MapViewControl x:Name="areaMapa" MarkerClicked="MAP_MarkerClicked" StreetMapClicked="MAP_StreetMapClicked" Latitude="-22.1726572492617" Longitude="-47.3952163870556" Scale="5000" />
|
||||||
</Border>
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,5 @@
|
||||||
using OperationControl.Controls;
|
using OperationControl.Controls;
|
||||||
using OperationControl.Models;
|
|
||||||
using OperationControl.ViewModels.Views.Operacao;
|
using OperationControl.ViewModels.Views.Operacao;
|
||||||
using OperationControl.ViewModels.Views.Operacao.Diagnostico;
|
|
||||||
using OperationControl.ViewModels.Views.Operacao.Monitoramento;
|
|
||||||
using System.Windows.Controls;
|
|
||||||
|
|
||||||
namespace OperationControl.Views.Operacao
|
namespace OperationControl.Views.Operacao
|
||||||
{
|
{
|
||||||
|
|
@ -13,6 +9,7 @@ namespace OperationControl.Views.Operacao
|
||||||
public partial class OperacaoCenterView : System.Windows.Controls.UserControl
|
public partial class OperacaoCenterView : System.Windows.Controls.UserControl
|
||||||
{
|
{
|
||||||
public OperacaoCenterViewModel _vm;
|
public OperacaoCenterViewModel _vm;
|
||||||
|
public MapViewControl Mapa => _vm?.ConteudoAtual == OperacaoCenterConteudo.Mapa ? areaMapa : _vm?.ConteudoAtual == OperacaoCenterConteudo.Monitoramento ? Monitoramento?.MapaMonitoramento : null;
|
||||||
public MonitoramentoView Monitoramento => areaMonitor;
|
public MonitoramentoView Monitoramento => areaMonitor;
|
||||||
public DiagnosticoView Diagnostico => areaDiagnostico;
|
public DiagnosticoView Diagnostico => areaDiagnostico;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue