Limpiando el codigo de MainWindow y MainViewModel
This commit is contained in:
parent
77ff643642
commit
664d325de8
|
@ -20,6 +20,9 @@
|
|||
<None Remove="Icons\save.png" />
|
||||
<None Remove="Icons\start.png" />
|
||||
<None Remove="Icons\stop.png" />
|
||||
<None Remove="imagenes\filler.png" />
|
||||
<None Remove="imagenes\motorNegro.png" />
|
||||
<None Remove="imagenes\motorVerde.png" />
|
||||
<None Remove="motor2.png" />
|
||||
<None Remove="tank.png" />
|
||||
</ItemGroup>
|
||||
|
@ -42,7 +45,6 @@
|
|||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.77" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Ookii.Dialogs.Wpf" Version="5.0.1" />
|
||||
<PackageReference Include="OpenCvSharp4.Windows" Version="4.9.0.20240103" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -58,7 +60,9 @@
|
|||
<Resource Include="Icons\save.png" />
|
||||
<Resource Include="Icons\start.png" />
|
||||
<Resource Include="Icons\stop.png" />
|
||||
<Resource Include="imagenes\motor2.png" />
|
||||
<Resource Include="imagenes\filler.png" />
|
||||
<Resource Include="imagenes\motorNegro.png" />
|
||||
<Resource Include="imagenes\motorVerde.png" />
|
||||
<Resource Include="imagenes\tank.png" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
323
MainViewModel.cs
323
MainViewModel.cs
|
@ -37,14 +37,9 @@ namespace CtrEditor
|
|||
public DatosDeTrabajo datosDeTrabajo { get; }
|
||||
public ObservableCollection<string> listaImagenes { get; private set; } // Publicación de las claves del diccionario
|
||||
public ObservableCollection<TipoSimulable> ListaOsBase { get; } = new ObservableCollection<TipoSimulable>();
|
||||
private ObservableCollection<osBase> _objetosSimulables = new ObservableCollection<osBase>();
|
||||
public PLCViewModel plcViewModelData;
|
||||
public Stopwatch stopwatch_PLCRefresh;
|
||||
public Stopwatch stopwatch_SimRefresh;
|
||||
|
||||
private bool isSimulationRunning;
|
||||
private bool isConnected;
|
||||
|
||||
public SimulationManagerFP simulationManager = new SimulationManagerFP();
|
||||
|
||||
private readonly DispatcherTimer _timerSimulacion;
|
||||
|
@ -59,11 +54,153 @@ namespace CtrEditor
|
|||
public ICommand TBConnectPLCCommand { get; }
|
||||
public ICommand TBDisconnectPLCCommand { get; }
|
||||
|
||||
public ICommand OpenWorkDirectoryCommand { get; }
|
||||
|
||||
// Evento que se dispara cuando se selecciona una nueva imagen
|
||||
public event EventHandler<string> ImageSelected;
|
||||
public event EventHandler<TickSimulacionEventArgs> TickSimulacion;
|
||||
public event Action<UserControl> OnUserControlSelected;
|
||||
|
||||
|
||||
private bool isSimulationRunning;
|
||||
private bool isConnected;
|
||||
public PLCViewModel plcViewModelData;
|
||||
private osBase _selectedItemOsList;
|
||||
private string _selectedImage = null;
|
||||
private ObservableCollection<osBase> _objetosSimulables = new ObservableCollection<osBase>();
|
||||
private float _left;
|
||||
private float _top;
|
||||
|
||||
public float CanvasLeft
|
||||
{
|
||||
get => _left;
|
||||
set
|
||||
{
|
||||
_left = value;
|
||||
OnPropertyChanged(nameof(CanvasLeft));
|
||||
}
|
||||
}
|
||||
public float CanvasTop
|
||||
{
|
||||
get => _top;
|
||||
set
|
||||
{
|
||||
_top = value;
|
||||
OnPropertyChanged(nameof(CanvasTop));
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSimulationRunning
|
||||
{
|
||||
get => isSimulationRunning;
|
||||
set
|
||||
{
|
||||
isSimulationRunning = value;
|
||||
OnPropertyChanged(nameof(IsSimulationRunning));
|
||||
CommandManager.InvalidateRequerySuggested(); // Notificar que el estado de los comandos ha cambiado
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsConnected
|
||||
{
|
||||
get => isConnected;
|
||||
set
|
||||
{
|
||||
isConnected = value;
|
||||
OnPropertyChanged(nameof(IsConnected));
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
}
|
||||
}
|
||||
|
||||
public string directorioTrabajo
|
||||
{
|
||||
get => EstadoPersistente.Instance.directorio;
|
||||
set
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
EstadoPersistente.Instance.directorio = value; // Actualizar el estado persistente
|
||||
EstadoPersistente.Instance.GuardarEstado(); // Guardar el estado actualizado
|
||||
datosDeTrabajo.CargarImagenes();
|
||||
listaImagenes = new ObservableCollection<string>(datosDeTrabajo.Imagenes.Keys); // Actualizar claves
|
||||
SelectedImage = null;
|
||||
if (listaImagenes.FirstOrDefault() != null)
|
||||
SelectedImage = listaImagenes.FirstOrDefault();
|
||||
OnPropertyChanged(nameof(directorioTrabajo)); // Notificar el cambio de propiedad
|
||||
OnPropertyChanged(nameof(listaImagenes)); // Notificar que la lista de imágenes ha cambiado
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PLCViewModel PLCViewModel
|
||||
{
|
||||
get { return plcViewModelData; }
|
||||
set
|
||||
{
|
||||
plcViewModelData = value;
|
||||
OnPropertyChanged(nameof(PLCViewModel));
|
||||
}
|
||||
}
|
||||
|
||||
public string SelectedImage
|
||||
{
|
||||
get => _selectedImage;
|
||||
set
|
||||
{
|
||||
if (_selectedImage != value && value != null)
|
||||
{
|
||||
StopSimulation();
|
||||
SaveStateObjetosSimulables(); // Guarda el estado antes de cambiar la imagen
|
||||
_selectedImage = value;
|
||||
ImageSelected?.Invoke(this, datosDeTrabajo.Imagenes[value]); // Dispara el evento con la nueva ruta de imagen
|
||||
LoadStateObjetosSimulables();
|
||||
}
|
||||
_selectedImage = value;
|
||||
OnPropertyChanged(nameof(SelectedImage));
|
||||
}
|
||||
}
|
||||
|
||||
public osBase SelectedItemOsList
|
||||
{
|
||||
get => _selectedItemOsList;
|
||||
set
|
||||
{
|
||||
if (_selectedItemOsList != value)
|
||||
{
|
||||
_selectedItemOsList = value;
|
||||
OnPropertyChanged(nameof(SelectedItemOsList));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private TipoSimulable _selectedItem = null;
|
||||
public TipoSimulable SelectedItem
|
||||
{
|
||||
get => _selectedItem;
|
||||
set
|
||||
{
|
||||
if (_selectedItem != value)
|
||||
{
|
||||
_selectedItem = value;
|
||||
OnPropertyChanged(nameof(SelectedItem)); // Notificar que la propiedad ha cambiado
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<osBase> ObjetosSimulables
|
||||
{
|
||||
get => _objetosSimulables;
|
||||
set
|
||||
{
|
||||
if (_objetosSimulables != value)
|
||||
{
|
||||
_objetosSimulables = value;
|
||||
OnPropertyChanged(nameof(ObjetosSimulables));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public MainViewModel()
|
||||
{
|
||||
OpenWorkDirectoryCommand = new RelayCommand(OpenWorkDirectory);
|
||||
|
@ -101,27 +238,11 @@ namespace CtrEditor
|
|||
}
|
||||
|
||||
|
||||
private TipoSimulable _selectedItem = null;
|
||||
public TipoSimulable SelectedItem
|
||||
{
|
||||
get => _selectedItem;
|
||||
set
|
||||
{
|
||||
if (_selectedItem != value)
|
||||
{
|
||||
_selectedItem = value;
|
||||
OnPropertyChanged(nameof(SelectedItem)); // Notificar que la propiedad ha cambiado
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ExecuteDoubleClick(object parameter)
|
||||
{
|
||||
if (parameter is TipoSimulable tipoSimulable)
|
||||
public void CrearUserControl(Type tipoSimulable)
|
||||
{
|
||||
// Crear una nueva instancia del osBase correspondiente
|
||||
osBase? newosBase = UserControlFactory.GetInstanceForType(tipoSimulable.Tipo);
|
||||
osBase? newosBase = UserControlFactory.GetInstanceForType(tipoSimulable);
|
||||
if (newosBase != null)
|
||||
{
|
||||
if (CrearUsercontrol(newosBase))
|
||||
|
@ -129,6 +250,33 @@ namespace CtrEditor
|
|||
ObjetosSimulables.Add(newosBase);
|
||||
}
|
||||
}
|
||||
|
||||
private bool CrearUsercontrol(osBase osObjeto)
|
||||
{
|
||||
Type tipoObjeto = osObjeto.GetType();
|
||||
|
||||
// Obtén el UserControl correspondiente para el tipo de objeto
|
||||
UserControl? userControl = UserControlFactory.GetControlForType(tipoObjeto);
|
||||
|
||||
if (userControl != null)
|
||||
{
|
||||
// Asignar los datos al UserControl
|
||||
UserControlFactory.AssignDatos(userControl, osObjeto, simulationManager);
|
||||
osObjeto._mainViewModel = this;
|
||||
|
||||
OnUserControlSelected?.Invoke(userControl);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void ExecuteDoubleClick(object parameter)
|
||||
{
|
||||
if (parameter is TipoSimulable tipoSimulable)
|
||||
{
|
||||
CrearUserControl(tipoSimulable.Tipo);
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeTipoSimulableList()
|
||||
|
@ -144,28 +292,6 @@ namespace CtrEditor
|
|||
}
|
||||
}
|
||||
|
||||
public bool IsSimulationRunning
|
||||
{
|
||||
get => isSimulationRunning;
|
||||
set
|
||||
{
|
||||
isSimulationRunning = value;
|
||||
OnPropertyChanged(nameof(IsSimulationRunning));
|
||||
CommandManager.InvalidateRequerySuggested(); // Notificar que el estado de los comandos ha cambiado
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsConnected
|
||||
{
|
||||
get => isConnected;
|
||||
set
|
||||
{
|
||||
isConnected = value;
|
||||
OnPropertyChanged(nameof(IsConnected));
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
}
|
||||
}
|
||||
|
||||
private void StartSimulation()
|
||||
{
|
||||
foreach (var objetoSimulable in ObjetosSimulables)
|
||||
|
@ -238,77 +364,6 @@ namespace CtrEditor
|
|||
|
||||
}
|
||||
|
||||
//protected virtual void OnTickSimulacion(TickSimulacionEventArgs e)
|
||||
//{
|
||||
// TickSimulacion?.Invoke(this, e);
|
||||
//}
|
||||
|
||||
public string directorioTrabajo
|
||||
{
|
||||
get => EstadoPersistente.Instance.directorio;
|
||||
set
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
EstadoPersistente.Instance.directorio = value; // Actualizar el estado persistente
|
||||
EstadoPersistente.Instance.GuardarEstado(); // Guardar el estado actualizado
|
||||
datosDeTrabajo.CargarImagenes();
|
||||
listaImagenes = new ObservableCollection<string>(datosDeTrabajo.Imagenes.Keys); // Actualizar claves
|
||||
SelectedImage = null;
|
||||
if (listaImagenes.FirstOrDefault() != null)
|
||||
SelectedImage = listaImagenes.FirstOrDefault();
|
||||
OnPropertyChanged(nameof(directorioTrabajo)); // Notificar el cambio de propiedad
|
||||
OnPropertyChanged(nameof(listaImagenes)); // Notificar que la lista de imágenes ha cambiado
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public PLCViewModel PLCViewModel
|
||||
{
|
||||
get { return plcViewModelData; }
|
||||
set
|
||||
{
|
||||
plcViewModelData = value;
|
||||
OnPropertyChanged(nameof(PLCViewModel));
|
||||
}
|
||||
}
|
||||
|
||||
private string _selectedImage = null;
|
||||
public string SelectedImage
|
||||
{
|
||||
get => _selectedImage;
|
||||
set
|
||||
{
|
||||
if (_selectedImage != value && value != null)
|
||||
{
|
||||
StopSimulation();
|
||||
SaveStateObjetosSimulables(); // Guarda el estado antes de cambiar la imagen
|
||||
_selectedImage = value;
|
||||
ImageSelected?.Invoke(this, datosDeTrabajo.Imagenes[value]); // Dispara el evento con la nueva ruta de imagen
|
||||
LoadStateObjetosSimulables();
|
||||
}
|
||||
_selectedImage = value;
|
||||
OnPropertyChanged(nameof(SelectedImage));
|
||||
}
|
||||
}
|
||||
|
||||
private osBase _selectedItemOsList;
|
||||
public osBase SelectedItemOsList
|
||||
{
|
||||
get => _selectedItemOsList;
|
||||
set
|
||||
{
|
||||
if (_selectedItemOsList != value)
|
||||
{
|
||||
_selectedItemOsList = value;
|
||||
OnPropertyChanged(nameof(SelectedItemOsList));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand OpenWorkDirectoryCommand { get; }
|
||||
|
||||
private void OpenWorkDirectory()
|
||||
{
|
||||
var dialog = new VistaFolderBrowserDialog();
|
||||
|
@ -322,20 +377,6 @@ namespace CtrEditor
|
|||
// Lista de osBase
|
||||
//
|
||||
|
||||
|
||||
public ObservableCollection<osBase> ObjetosSimulables
|
||||
{
|
||||
get => _objetosSimulables;
|
||||
set
|
||||
{
|
||||
if (_objetosSimulables != value)
|
||||
{
|
||||
_objetosSimulables = value;
|
||||
OnPropertyChanged(nameof(ObjetosSimulables));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
SaveStateObjetosSimulables();
|
||||
|
@ -423,28 +464,6 @@ namespace CtrEditor
|
|||
}
|
||||
|
||||
|
||||
private bool CrearUsercontrol(osBase osObjeto)
|
||||
{
|
||||
Type tipoObjeto = osObjeto.GetType();
|
||||
|
||||
// Obtén el UserControl correspondiente para el tipo de objeto
|
||||
UserControl? userControl = UserControlFactory.GetControlForType(tipoObjeto);
|
||||
|
||||
if (userControl != null)
|
||||
{
|
||||
// Asignar los datos al UserControl
|
||||
UserControlFactory.AssignDatos(userControl, osObjeto, simulationManager);
|
||||
osObjeto._mainViewModel = this;
|
||||
|
||||
OnUserControlSelected?.Invoke(userControl);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Implementación de INotifyPropertyChanged...
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
|
|
@ -22,7 +22,6 @@ using UserControl = System.Windows.Controls.UserControl;
|
|||
using CheckBox = System.Windows.Controls.CheckBox;
|
||||
using Orientation = System.Windows.Controls.Orientation;
|
||||
using ListBox = System.Windows.Controls.ListBox;
|
||||
//using OpenCvSharp;
|
||||
|
||||
|
||||
namespace CtrEditor
|
||||
|
@ -70,6 +69,33 @@ namespace CtrEditor
|
|||
}
|
||||
}
|
||||
|
||||
private (float X, float Y) ObtenerCentroCanvasPixels()
|
||||
{
|
||||
var scaleTransform = ImagenEnTrabajoCanvas.LayoutTransform as ScaleTransform;
|
||||
float scaleX = (float)(scaleTransform?.ScaleX ?? 1.0);
|
||||
float scaleY = (float)(scaleTransform?.ScaleY ?? 1.0);
|
||||
|
||||
// Obtiene el área visible del ScrollViewer
|
||||
float visibleWidth = (float)ImagenEnTrabajoScrollViewer.ViewportWidth;
|
||||
float visibleHeight = (float)ImagenEnTrabajoScrollViewer.ViewportHeight;
|
||||
|
||||
// Obtiene la posición actual del desplazamiento ajustada por el zoom
|
||||
float offsetX = (float)ImagenEnTrabajoScrollViewer.HorizontalOffset / scaleX;
|
||||
float offsetY = (float)ImagenEnTrabajoScrollViewer.VerticalOffset / scaleY;
|
||||
|
||||
// Calcula el centro visible ajustado
|
||||
float centerX = offsetX + (visibleWidth / scaleX) / 2;
|
||||
float centerY = offsetY + (visibleHeight / scaleY) / 2;
|
||||
|
||||
return (centerX, centerY);
|
||||
}
|
||||
|
||||
private (float X, float Y) ObtenerCentroCanvasMeters()
|
||||
{
|
||||
var c = ObtenerCentroCanvasPixels();
|
||||
return (PixelToMeter.Instance.calc.PixelsToMeters(c.X), PixelToMeter.Instance.calc.PixelsToMeters(c.Y));
|
||||
}
|
||||
|
||||
private void AgregarUserControl(UserControl userControl)
|
||||
{
|
||||
if (userControl is IDataContainer dataContainer)
|
||||
|
@ -78,26 +104,12 @@ namespace CtrEditor
|
|||
if (!NuevoOS.Inicializado) // Aun no fue inicializado
|
||||
{
|
||||
Random rnd = new Random();
|
||||
// Obtiene el factor de escala
|
||||
var scaleTransform = ImagenEnTrabajoCanvas.LayoutTransform as ScaleTransform;
|
||||
double scaleX = scaleTransform?.ScaleX ?? 1.0;
|
||||
double scaleY = scaleTransform?.ScaleY ?? 1.0;
|
||||
|
||||
// Obtiene el área visible del ScrollViewer
|
||||
double visibleWidth = ImagenEnTrabajoScrollViewer.ViewportWidth;
|
||||
double visibleHeight = ImagenEnTrabajoScrollViewer.ViewportHeight;
|
||||
|
||||
// Obtiene la posición actual del desplazamiento ajustada por el zoom
|
||||
double offsetX = ImagenEnTrabajoScrollViewer.HorizontalOffset / scaleX;
|
||||
double offsetY = ImagenEnTrabajoScrollViewer.VerticalOffset / scaleY;
|
||||
|
||||
// Calcula el centro visible ajustado
|
||||
double centerX = offsetX + (visibleWidth / scaleX) / 2;
|
||||
double centerY = offsetY + (visibleHeight / scaleY) / 2;
|
||||
var centro = ObtenerCentroCanvasPixels();
|
||||
|
||||
// Ajusta la posición del UserControl para que esté centrado en el área visible
|
||||
double leftPixels = centerX - (userControl.ActualWidth / 2);
|
||||
double topPixels = centerY - (userControl.ActualHeight / 2);
|
||||
double leftPixels = centro.X - (userControl.ActualWidth / 2);
|
||||
double topPixels = centro.Y - (userControl.ActualHeight / 2);
|
||||
|
||||
// Establece la posición del UserControl
|
||||
NuevoOS.Left = PixelToMeter.Instance.calc.PixelsToMeters((float)leftPixels + (float)(rnd.NextDouble() - 0.5) );
|
||||
|
|
|
@ -31,6 +31,8 @@ namespace CtrEditor.ObjetosSim
|
|||
return new ucTanque();
|
||||
if (tipoObjeto == typeof(osSensTemperatura))
|
||||
return new ucSensTemperatura();
|
||||
if (tipoObjeto == typeof(osFiller))
|
||||
return new ucFiller();
|
||||
|
||||
|
||||
// Puedes añadir más condiciones para otros tipos
|
||||
|
@ -58,6 +60,8 @@ namespace CtrEditor.ObjetosSim
|
|||
return new osTanque();
|
||||
if (tipoObjeto == typeof(osSensTemperatura))
|
||||
return new osSensTemperatura();
|
||||
if (tipoObjeto == typeof(osFiller))
|
||||
return new osFiller();
|
||||
|
||||
|
||||
// Puedes añadir más condiciones para otros tipos
|
||||
|
|
|
@ -18,6 +18,7 @@ using System.Windows.Media;
|
|||
using Microsoft.Xna.Framework;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using Siemens.Simatic.Simulation.Runtime;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace CtrEditor.ObjetosSim
|
||||
{
|
||||
|
@ -33,6 +34,7 @@ namespace CtrEditor.ObjetosSim
|
|||
|
||||
public interface IDataContainer
|
||||
{
|
||||
[JsonIgnore]
|
||||
osBase? Datos { get; set; }
|
||||
void Resize(float width, float height);
|
||||
void Move(float Left, float Top);
|
||||
|
@ -48,6 +50,7 @@ namespace CtrEditor.ObjetosSim
|
|||
|
||||
public bool Inicializado = false;
|
||||
|
||||
[JsonIgnore]
|
||||
protected UserControl? _visualRepresentation = null;
|
||||
|
||||
public abstract string Nombre { get; set; }
|
||||
|
@ -241,6 +244,28 @@ namespace CtrEditor.ObjetosSim
|
|||
return simulationManager.AddLine(coords.Start, coords.End);
|
||||
}
|
||||
|
||||
public ImageSource ImageFromPath(string value)
|
||||
{
|
||||
if (value is string stringValue)
|
||||
{
|
||||
return new BitmapImage(new Uri(stringValue, UriKind.RelativeOrAbsolute));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static protected T GetLastElement<T>(List<T> list) where T : class
|
||||
{
|
||||
if (list.Count > 0)
|
||||
{
|
||||
return list[list.Count - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
|
|
|
@ -13,8 +13,12 @@
|
|||
|
||||
<Grid>
|
||||
<Image Source="/motor2.png"
|
||||
Width="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}"
|
||||
Height="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}"
|
||||
Stretch="Uniform"/>
|
||||
Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}"
|
||||
Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}"
|
||||
Stretch="Uniform">
|
||||
<Image.RenderTransform>
|
||||
<RotateTransform Angle="{Binding Angulo}" />
|
||||
</Image.RenderTransform>
|
||||
</Image>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
|
@ -27,9 +27,9 @@ namespace CtrEditor.ObjetosSim
|
|||
private string _nombre = "Ejemplo";
|
||||
private float _ancho;
|
||||
private float _alto;
|
||||
private float _angulo;
|
||||
private float _left;
|
||||
private float _top;
|
||||
private float _angulo;
|
||||
|
||||
public override float Left
|
||||
{
|
||||
|
@ -112,7 +112,7 @@ namespace CtrEditor.ObjetosSim
|
|||
{
|
||||
}
|
||||
|
||||
public override void UpdateControl()
|
||||
public override void UpdateControl(int elapsedMilliseconds)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<UserControl x:Class="CtrEditor.ObjetosSim.ucFiller"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:CtrEditor.ObjetosSim"
|
||||
mc:Ignorable="d"
|
||||
xmlns:convert="clr-namespace:CtrEditor.Convertidores">
|
||||
|
||||
<UserControl.Resources>
|
||||
<convert:MeterToPixelConverter x:Key="MeterToPixelConverter"/>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
<Image Source="/imagenes/filler.png"
|
||||
Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}"
|
||||
Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}"
|
||||
Stretch="Uniform">
|
||||
<Image.RenderTransform>
|
||||
<RotateTransform Angle="{Binding Angulo}" />
|
||||
</Image.RenderTransform>
|
||||
</Image>
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -0,0 +1,242 @@
|
|||
using CtrEditor.Convertidores;
|
||||
using CtrEditor.Siemens;
|
||||
using CtrEditor.Simulacion;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace CtrEditor.ObjetosSim
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ucFiller.xaml
|
||||
/// </summary>
|
||||
public class osFiller : osBase
|
||||
{
|
||||
// Otros datos y métodos relevantes para la simulación
|
||||
|
||||
private string _nombre = "Filler";
|
||||
private float _ancho;
|
||||
private float _alto;
|
||||
private float _left;
|
||||
private float _top;
|
||||
private float _angulo;
|
||||
private float _botellas_hora;
|
||||
private float _velocidad_actual;
|
||||
private float _diametro_botella;
|
||||
private string _tag_consenso;
|
||||
private bool _consenso;
|
||||
private float TiempoRestante;
|
||||
private List<simCircle> Botellas = new List<simCircle>();
|
||||
|
||||
public bool Consenso
|
||||
{
|
||||
get => _consenso;
|
||||
set
|
||||
{
|
||||
_consenso = value;
|
||||
OnPropertyChanged(nameof(Consenso));
|
||||
}
|
||||
}
|
||||
|
||||
public float Botellas_hora
|
||||
{
|
||||
get => _botellas_hora;
|
||||
set
|
||||
{
|
||||
_botellas_hora = value;
|
||||
OnPropertyChanged(nameof(Botellas_hora));
|
||||
}
|
||||
}
|
||||
public float Velocidad_actual_percentual
|
||||
{
|
||||
get => _velocidad_actual;
|
||||
set
|
||||
{
|
||||
_velocidad_actual = value;
|
||||
OnPropertyChanged(nameof(Velocidad_actual_percentual));
|
||||
}
|
||||
}
|
||||
public float Diametro_botella
|
||||
{
|
||||
get => _diametro_botella;
|
||||
set
|
||||
{
|
||||
_diametro_botella = value;
|
||||
OnPropertyChanged(nameof(Diametro_botella));
|
||||
}
|
||||
}
|
||||
public string Tag_consenso
|
||||
{
|
||||
get => _tag_consenso;
|
||||
set
|
||||
{
|
||||
_tag_consenso = value;
|
||||
OnPropertyChanged(nameof(Tag_consenso));
|
||||
}
|
||||
}
|
||||
|
||||
public override float Left
|
||||
{
|
||||
get => _left;
|
||||
set
|
||||
{
|
||||
_left = value;
|
||||
CanvasSetLeftinMeter(value);
|
||||
OnPropertyChanged(nameof(Left));
|
||||
}
|
||||
}
|
||||
public override float Top
|
||||
{
|
||||
get => _top;
|
||||
set
|
||||
{
|
||||
_top = value;
|
||||
CanvasSetTopinMeter(value);
|
||||
OnPropertyChanged(nameof(Top));
|
||||
}
|
||||
}
|
||||
|
||||
public float Ancho
|
||||
{
|
||||
get => _ancho;
|
||||
set
|
||||
{
|
||||
_ancho = value;
|
||||
OnPropertyChanged(nameof(Ancho));
|
||||
}
|
||||
}
|
||||
public float Alto
|
||||
{
|
||||
get => _alto;
|
||||
set
|
||||
{
|
||||
_alto = value;
|
||||
OnPropertyChanged(nameof(Alto));
|
||||
}
|
||||
}
|
||||
|
||||
public float Angulo
|
||||
{
|
||||
get => _angulo;
|
||||
set
|
||||
{
|
||||
_angulo = value;
|
||||
OnPropertyChanged(nameof(Angulo));
|
||||
}
|
||||
}
|
||||
|
||||
public override string Nombre
|
||||
{
|
||||
get => _nombre;
|
||||
set
|
||||
{
|
||||
if (_nombre != value)
|
||||
{
|
||||
_nombre = value;
|
||||
OnPropertyChanged(nameof(Nombre));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public osFiller()
|
||||
{
|
||||
Ancho = 0.30f;
|
||||
Alto = 0.30f;
|
||||
Angulo = 0;
|
||||
Velocidad_actual_percentual = 0;
|
||||
Diametro_botella = 0.1f;
|
||||
Botellas_hora = 10000;
|
||||
}
|
||||
|
||||
public override void UpdateGeometryStart()
|
||||
{
|
||||
// Se llama antes de la simulacion
|
||||
|
||||
}
|
||||
public override void UpdateGeometryStep()
|
||||
{
|
||||
}
|
||||
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds)
|
||||
{
|
||||
Consenso = LeerBitTag(plc, Tag_consenso);
|
||||
}
|
||||
|
||||
public override void UpdateControl(int elapsedMilliseconds)
|
||||
{
|
||||
if (Consenso && Velocidad_actual_percentual>0)
|
||||
{
|
||||
TiempoRestante -= elapsedMilliseconds / 1000.0f;
|
||||
if (TiempoRestante <= 0)
|
||||
{
|
||||
TiempoRestante = Botellas_hora * (Velocidad_actual_percentual / 100.0f) / 3600.0f;
|
||||
var PosSalida = new Vector2(Left, Top);
|
||||
|
||||
var UltimaBotellla = GetLastElement<simCircle>(Botellas);
|
||||
if (UltimaBotellla != null && UltimaBotellla.Center != PosSalida)
|
||||
Botellas.Add(simulationManager.AddCircle(Diametro_botella, PosSalida, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
public override void ucLoaded()
|
||||
{
|
||||
// El UserControl ya se ha cargado y podemos obtener las coordenadas para
|
||||
// crear el objeto de simulacion
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public partial class ucFiller : UserControl, IDataContainer
|
||||
{
|
||||
public osBase? Datos { get; set; }
|
||||
|
||||
public ucFiller()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.Loaded += OnLoaded;
|
||||
}
|
||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Datos?.ucLoaded();
|
||||
}
|
||||
public void Resize(float width, float height)
|
||||
{
|
||||
if (Datos is osFiller datos)
|
||||
{
|
||||
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
|
||||
datos.Alto = PixelToMeter.Instance.calc.PixelsToMeters(width);
|
||||
}
|
||||
}
|
||||
public void Move(float LeftPixels, float TopPixels)
|
||||
{
|
||||
if (Datos != null)
|
||||
{
|
||||
Datos.Left = PixelToMeter.Instance.calc.PixelsToMeters(LeftPixels);
|
||||
Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels);
|
||||
}
|
||||
}
|
||||
public void Rotate(float Angle)
|
||||
{
|
||||
if (Datos != null)
|
||||
if (Datos is osFiller datos)
|
||||
datos.Angulo = Angle;
|
||||
}
|
||||
public void Highlight(bool State) { }
|
||||
public int ZIndex()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
using CtrEditor.Convertidores;
|
||||
using CtrEditor.Siemens;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OpenCvSharp.Flann;
|
||||
using Siemens.Simatic.Simulation.Runtime;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -46,7 +45,6 @@ namespace CtrEditor.ObjetosSim
|
|||
private bool _SalidaAbierta_Bool;
|
||||
private float _capacidadLitros;
|
||||
|
||||
|
||||
public float Capacidad_Litros
|
||||
{
|
||||
get => _capacidadLitros;
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
<Image Source="/imagenes/motor2.png"
|
||||
<Image Source="{Binding ImageSource}"
|
||||
Width="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}"
|
||||
Height="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}"
|
||||
Stretch="Uniform"/>
|
||||
|
|
|
@ -15,6 +15,7 @@ using System.Windows.Media.Imaging;
|
|||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using CtrEditor.Simulacion;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace CtrEditor.ObjetosSim
|
||||
{
|
||||
|
@ -22,25 +23,10 @@ namespace CtrEditor.ObjetosSim
|
|||
/// Interaction logic for ucVMmotorSim.xaml
|
||||
/// </summary>
|
||||
///
|
||||
public class VMSimMotor
|
||||
{
|
||||
public bool _STATUS_VFD_Ready;
|
||||
public float STATUS_VFD_ACT_Speed_Hz;
|
||||
public bool Motor_Running;
|
||||
public bool STATUS_VFD_Trip;
|
||||
public bool STATUS_VFD_Warning;
|
||||
public bool STATUS_VFD_Coasting;
|
||||
public bool OUT_Run;
|
||||
public bool OUT_Stop;
|
||||
public bool OUT_Reversal;
|
||||
public float OUT_OUT_VFD_REQ_Speed_Hz;
|
||||
}
|
||||
|
||||
|
||||
public class osVMmotorSim : osBase
|
||||
{
|
||||
|
||||
|
||||
// Otros datos y métodos relevantes para la simulación
|
||||
|
||||
private string _nombre = "VetroMeccanica Motor";
|
||||
|
@ -53,9 +39,21 @@ namespace CtrEditor.ObjetosSim
|
|||
private bool _encendido;
|
||||
private float _rampaSegundos;
|
||||
private float _maxHz;
|
||||
private ImageSource _imageSource;
|
||||
|
||||
public VMSimMotor motState = new VMSimMotor();
|
||||
private VMSimMotor motState = new VMSimMotor();
|
||||
|
||||
[Hidden]
|
||||
[JsonIgnore]
|
||||
public ImageSource ImageSource
|
||||
{
|
||||
get { return _imageSource; }
|
||||
set
|
||||
{
|
||||
_imageSource = value;
|
||||
OnPropertyChanged(nameof(ImageSource));
|
||||
}
|
||||
}
|
||||
|
||||
public float Tamano
|
||||
{
|
||||
|
@ -89,7 +87,6 @@ namespace CtrEditor.ObjetosSim
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public bool Encendido
|
||||
{
|
||||
get => _encendido;
|
||||
|
@ -157,6 +154,11 @@ namespace CtrEditor.ObjetosSim
|
|||
get => _velocidad;
|
||||
set {
|
||||
_velocidad = value;
|
||||
if (value > 0)
|
||||
ImageSource = ImageFromPath("/imagenes/motorVerde.png");
|
||||
else
|
||||
ImageSource = ImageFromPath("/imagenes/motorNegro.png");
|
||||
|
||||
OnPropertyChanged(nameof(Velocidad));
|
||||
}
|
||||
}
|
||||
|
@ -167,6 +169,7 @@ namespace CtrEditor.ObjetosSim
|
|||
PLC_NumeroMotor = 31;
|
||||
MaxRatedHz = 100;
|
||||
TiempoRampa = 3;
|
||||
ImageSource = ImageFromPath("/imagenes/motor2.png");
|
||||
}
|
||||
|
||||
public override void UpdateGeometryStart()
|
||||
|
@ -178,68 +181,19 @@ namespace CtrEditor.ObjetosSim
|
|||
{
|
||||
}
|
||||
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds) {
|
||||
var index = 0;
|
||||
switch (PLC_NumeroMotor)
|
||||
{
|
||||
case < 100:
|
||||
index = (int)PLC_NumeroMotor-30+300;
|
||||
break;
|
||||
}
|
||||
|
||||
motState.OUT_Run = plc.LeerTagBool($"\"DB MotorSimulate\".Motors[{index}].OUT.Run");
|
||||
motState.OUT_Reversal = plc.LeerTagBool($"\"DB MotorSimulate\".Motors[{index}].OUT.\"Reversal Direction\"");
|
||||
motState.OUT_OUT_VFD_REQ_Speed_Hz = (float)plc.LeerTagInt16($"\"DB MotorSimulate\".Motors[{index}].OUT.OUT_VFD_REQ_Speed_Hz");
|
||||
|
||||
|
||||
|
||||
if (Encendido)
|
||||
{
|
||||
motState._STATUS_VFD_Ready = true;
|
||||
motState.Motor_Running = true;
|
||||
motState.STATUS_VFD_Trip = false;
|
||||
motState.STATUS_VFD_Warning = false;
|
||||
motState.STATUS_VFD_Coasting = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
motState._STATUS_VFD_Ready = false;
|
||||
motState.Motor_Running = false;
|
||||
motState.STATUS_VFD_Trip = true;
|
||||
motState.STATUS_VFD_Warning = false;
|
||||
motState.STATUS_VFD_Coasting = false;
|
||||
}
|
||||
|
||||
// Calculamos la velocidad
|
||||
motState.STATUS_VFD_ACT_Speed_Hz += CalcSpeedRamp(motState.STATUS_VFD_ACT_Speed_Hz, motState.OUT_OUT_VFD_REQ_Speed_Hz, elapsedMilliseconds);
|
||||
|
||||
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_Ready", motState._STATUS_VFD_Ready);
|
||||
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].Motor_Running", motState.Motor_Running);
|
||||
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_Trip", motState.STATUS_VFD_Trip);
|
||||
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_Warning", motState.STATUS_VFD_Warning);
|
||||
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_Coasting", motState.STATUS_VFD_Coasting);
|
||||
|
||||
plc.EscribirTagInt16($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_ACT_Speed_Hz",(int)motState.STATUS_VFD_ACT_Speed_Hz);
|
||||
|
||||
motState.UpdatePLC(plc,PLC_NumeroMotor,Encendido, elapsedMilliseconds);
|
||||
Velocidad = motState.STATUS_VFD_ACT_Speed_Hz / 10;
|
||||
}
|
||||
|
||||
private float CalcSpeedRamp(float actual, float expected, int elapsedMilliseconds)
|
||||
{
|
||||
float hzIncrementsRamp = (MaxRatedHz * 10) / (TiempoRampa * (1000.0f / elapsedMilliseconds));
|
||||
float delta = expected - actual;
|
||||
// Conrtolar si la diferencia no es mayor de lo que falta
|
||||
if (Math.Abs(hzIncrementsRamp)>Math.Abs(delta))
|
||||
hzIncrementsRamp = Math.Abs(delta);
|
||||
if (delta < 0)
|
||||
return -hzIncrementsRamp;
|
||||
else
|
||||
return hzIncrementsRamp;
|
||||
}
|
||||
|
||||
public override void UpdateControl(int elapsedMilliseconds)
|
||||
{
|
||||
// Calculamos la velocidad
|
||||
motState.UpdateSpeed(MaxRatedHz,TiempoRampa, elapsedMilliseconds);
|
||||
|
||||
}
|
||||
|
||||
public override void ucLoaded()
|
||||
{
|
||||
// El UserControl ya se ha cargado y podemos obtener las coordenadas para
|
||||
|
@ -277,4 +231,82 @@ namespace CtrEditor.ObjetosSim
|
|||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
public class VMSimMotor
|
||||
{
|
||||
public bool _STATUS_VFD_Ready;
|
||||
public float STATUS_VFD_ACT_Speed_Hz;
|
||||
public bool Motor_Running;
|
||||
public bool STATUS_VFD_Trip;
|
||||
public bool STATUS_VFD_Warning;
|
||||
public bool STATUS_VFD_Coasting;
|
||||
public bool OUT_Run;
|
||||
public bool OUT_Stop;
|
||||
public bool OUT_Reversal;
|
||||
public float OUT_OUT_VFD_REQ_Speed_Hz;
|
||||
|
||||
public void UpdatePLC(PLCModel plc, int NumeroMotor, bool Encendido, int elapsedMilliseconds)
|
||||
{
|
||||
var index = 0;
|
||||
switch (NumeroMotor)
|
||||
{
|
||||
case < 100:
|
||||
index = (int)NumeroMotor - 30 + 300;
|
||||
break;
|
||||
}
|
||||
|
||||
OUT_Run = plc.LeerTagBool($"\"DB MotorSimulate\".Motors[{index}].OUT.Run");
|
||||
OUT_Reversal = plc.LeerTagBool($"\"DB MotorSimulate\".Motors[{index}].OUT.\"Reversal Direction\"");
|
||||
OUT_OUT_VFD_REQ_Speed_Hz = (float)plc.LeerTagInt16($"\"DB MotorSimulate\".Motors[{index}].OUT.OUT_VFD_REQ_Speed_Hz");
|
||||
|
||||
|
||||
|
||||
if (Encendido)
|
||||
{
|
||||
_STATUS_VFD_Ready = true;
|
||||
Motor_Running = true;
|
||||
STATUS_VFD_Trip = false;
|
||||
STATUS_VFD_Warning = false;
|
||||
STATUS_VFD_Coasting = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_STATUS_VFD_Ready = false;
|
||||
Motor_Running = false;
|
||||
STATUS_VFD_Trip = true;
|
||||
STATUS_VFD_Warning = false;
|
||||
STATUS_VFD_Coasting = false;
|
||||
}
|
||||
|
||||
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_Ready", _STATUS_VFD_Ready);
|
||||
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].Motor_Running", Motor_Running);
|
||||
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_Trip", STATUS_VFD_Trip);
|
||||
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_Warning", STATUS_VFD_Warning);
|
||||
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_Coasting", STATUS_VFD_Coasting);
|
||||
|
||||
plc.EscribirTagInt16($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_ACT_Speed_Hz", (int)STATUS_VFD_ACT_Speed_Hz);
|
||||
|
||||
}
|
||||
|
||||
private float CalcSpeedRamp(float MaxRatedHz, float TiempoRampa, float actual, float expected, int elapsedMilliseconds)
|
||||
{
|
||||
float hzIncrementsRamp = (MaxRatedHz * 10) / (TiempoRampa * (1000.0f / elapsedMilliseconds));
|
||||
float delta = expected - actual;
|
||||
// Conrtolar si la diferencia no es mayor de lo que falta
|
||||
if (Math.Abs(hzIncrementsRamp) > Math.Abs(delta))
|
||||
hzIncrementsRamp = Math.Abs(delta);
|
||||
if (delta < 0)
|
||||
return -hzIncrementsRamp;
|
||||
else
|
||||
return hzIncrementsRamp;
|
||||
}
|
||||
|
||||
public void UpdateSpeed(float MaxRatedHz, float TiempoRampa, int elapsedMilliseconds)
|
||||
{
|
||||
// Calculamos la velocidad
|
||||
STATUS_VFD_ACT_Speed_Hz += CalcSpeedRamp(MaxRatedHz, TiempoRampa, STATUS_VFD_ACT_Speed_Hz, OUT_OUT_VFD_REQ_Speed_Hz, elapsedMilliseconds);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
Loading…
Reference in New Issue