diff --git a/CtrEditor.csproj b/CtrEditor.csproj
index 9a88f2c..9b3f0af 100644
--- a/CtrEditor.csproj
+++ b/CtrEditor.csproj
@@ -20,6 +20,9 @@
+
+
+
@@ -42,7 +45,6 @@
-
@@ -58,7 +60,9 @@
-
+
+
+
diff --git a/MainViewModel.cs b/MainViewModel.cs
index 61d074b..7ad26c2 100644
--- a/MainViewModel.cs
+++ b/MainViewModel.cs
@@ -37,14 +37,9 @@ namespace CtrEditor
public DatosDeTrabajo datosDeTrabajo { get; }
public ObservableCollection listaImagenes { get; private set; } // Publicación de las claves del diccionario
public ObservableCollection ListaOsBase { get; } = new ObservableCollection();
- private ObservableCollection _objetosSimulables = new ObservableCollection();
- 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 ImageSelected;
public event EventHandler TickSimulacion;
public event Action OnUserControlSelected;
+
+ private bool isSimulationRunning;
+ private bool isConnected;
+ public PLCViewModel plcViewModelData;
+ private osBase _selectedItemOsList;
+ private string _selectedImage = null;
+ private ObservableCollection _objetosSimulables = new ObservableCollection();
+ 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(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 ObjetosSimulables
+ {
+ get => _objetosSimulables;
+ set
+ {
+ if (_objetosSimulables != value)
+ {
+ _objetosSimulables = value;
+ OnPropertyChanged(nameof(ObjetosSimulables));
+ }
+ }
+ }
+
+
public MainViewModel()
{
OpenWorkDirectoryCommand = new RelayCommand(OpenWorkDirectory);
@@ -101,33 +238,44 @@ namespace CtrEditor
}
- private TipoSimulable _selectedItem = null;
- public TipoSimulable SelectedItem
+
+ public void CrearUserControl(Type tipoSimulable)
{
- get => _selectedItem;
- set
+ // Crear una nueva instancia del osBase correspondiente
+ osBase? newosBase = UserControlFactory.GetInstanceForType(tipoSimulable);
+ if (newosBase != null)
{
- if (_selectedItem != value)
- {
- _selectedItem = value;
- OnPropertyChanged(nameof(SelectedItem)); // Notificar que la propiedad ha cambiado
- }
+ if (CrearUsercontrol(newosBase))
+ // Añadir el nuevo osBase a la colección de objetos simulables
+ 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)
{
- // Crear una nueva instancia del osBase correspondiente
- osBase? newosBase = UserControlFactory.GetInstanceForType(tipoSimulable.Tipo);
- if (newosBase != null)
- {
- if (CrearUsercontrol(newosBase))
- // Añadir el nuevo osBase a la colección de objetos simulables
- ObjetosSimulables.Add(newosBase);
- }
+ CrearUserControl(tipoSimulable.Tipo);
}
}
@@ -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(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 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;
diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs
index bcd5029..2709948 100644
--- a/MainWindow.xaml.cs
+++ b/MainWindow.xaml.cs
@@ -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) );
diff --git a/ObjetosSim/UserControlFactory.cs b/ObjetosSim/UserControlFactory.cs
index e281b25..f792f63 100644
--- a/ObjetosSim/UserControlFactory.cs
+++ b/ObjetosSim/UserControlFactory.cs
@@ -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
diff --git a/ObjetosSim/osBase.cs b/ObjetosSim/osBase.cs
index 624d1da..607e349 100644
--- a/ObjetosSim/osBase.cs
+++ b/ObjetosSim/osBase.cs
@@ -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);
@@ -47,7 +49,8 @@ namespace CtrEditor.ObjetosSim
public abstract float Top { get; set; }
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(List list) where T : class
+ {
+ if (list.Count > 0)
+ {
+ return list[list.Count - 1];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+
public event PropertyChangedEventHandler PropertyChanged;
diff --git a/ObjetosSim/ucBasicExample.xaml b/ObjetosSim/ucBasicExample.xaml
index 4da1c1f..4da0235 100644
--- a/ObjetosSim/ucBasicExample.xaml
+++ b/ObjetosSim/ucBasicExample.xaml
@@ -13,8 +13,12 @@
+ Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}"
+ Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}"
+ Stretch="Uniform">
+
+
+
+
diff --git a/ObjetosSim/ucBasicExample.xaml.cs b/ObjetosSim/ucBasicExample.xaml.cs
index ff5445e..7448c26 100644
--- a/ObjetosSim/ucBasicExample.xaml.cs
+++ b/ObjetosSim/ucBasicExample.xaml.cs
@@ -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)
{
}
diff --git a/ObjetosSim/ucFiller.xaml b/ObjetosSim/ucFiller.xaml
new file mode 100644
index 0000000..f39e039
--- /dev/null
+++ b/ObjetosSim/ucFiller.xaml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ObjetosSim/ucFiller.xaml.cs b/ObjetosSim/ucFiller.xaml.cs
new file mode 100644
index 0000000..8c0ceb9
--- /dev/null
+++ b/ObjetosSim/ucFiller.xaml.cs
@@ -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
+{
+ ///
+ /// Interaction logic for ucFiller.xaml
+ ///
+ 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 Botellas = new List();
+
+ 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(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;
+ }
+ }
+
+}
diff --git a/ObjetosSim/ucTanque.xaml.cs b/ObjetosSim/ucTanque.xaml.cs
index 0bb4d24..1b431fc 100644
--- a/ObjetosSim/ucTanque.xaml.cs
+++ b/ObjetosSim/ucTanque.xaml.cs
@@ -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;
diff --git a/ObjetosSim/ucVMmotorSim.xaml b/ObjetosSim/ucVMmotorSim.xaml
index 0379f7e..6297680 100644
--- a/ObjetosSim/ucVMmotorSim.xaml
+++ b/ObjetosSim/ucVMmotorSim.xaml
@@ -12,7 +12,7 @@
-
diff --git a/ObjetosSim/ucVMmotorSim.xaml.cs b/ObjetosSim/ucVMmotorSim.xaml.cs
index edad0f9..438a43d 100644
--- a/ObjetosSim/ucVMmotorSim.xaml.cs
+++ b/ObjetosSim/ucVMmotorSim.xaml.cs
@@ -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
///
///
- 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;
+
+ private VMSimMotor motState = new VMSimMotor();
- public VMSimMotor motState = new VMSimMotor();
-
+ [Hidden]
+ [JsonIgnore]
+ public ImageSource ImageSource
+ {
+ get { return _imageSource; }
+ set
+ {
+ _imageSource = value;
+ OnPropertyChanged(nameof(ImageSource));
+ }
+ }
public float Tamano
{
@@ -89,13 +87,12 @@ namespace CtrEditor.ObjetosSim
}
}
-
public bool Encendido
{
get => _encendido;
set
{
- _encendido = value;
+ _encendido = value;
OnPropertyChanged(nameof(Encendido));
}
}
@@ -156,7 +153,12 @@ namespace CtrEditor.ObjetosSim
public float Velocidad {
get => _velocidad;
set {
- _velocidad = value;
+ _velocidad = value;
+ if (value > 0)
+ ImageSource = ImageFromPath("/imagenes/motorVerde.png");
+ else
+ ImageSource = ImageFromPath("/imagenes/motorNegro.png");
+
OnPropertyChanged(nameof(Velocidad));
}
}
@@ -167,7 +169,8 @@ 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");
+ motState.UpdatePLC(plc,PLC_NumeroMotor,Encendido, elapsedMilliseconds);
+ Velocidad = motState.STATUS_VFD_ACT_Speed_Hz / 10;
-
-
- 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);
-
- 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);
+
+ }
+ }
+
}
diff --git a/imagenes/filler.png b/imagenes/filler.png
new file mode 100644
index 0000000..53f6d7f
Binary files /dev/null and b/imagenes/filler.png differ
diff --git a/imagenes/motor2.png b/imagenes/motorNegro.png
similarity index 100%
rename from imagenes/motor2.png
rename to imagenes/motorNegro.png
diff --git a/imagenes/motorVerde.png b/imagenes/motorVerde.png
new file mode 100644
index 0000000..9703d8f
Binary files /dev/null and b/imagenes/motorVerde.png differ