Compare commits

..

No commits in common. "494f960628396ddbec9a47de4e226ac502174b1a" and "b224070690b08a97c6814b642497bbead449b035" have entirely different histories.

20 changed files with 85 additions and 830 deletions

View File

@ -6,83 +6,9 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Data; using System.Windows.Data;
using System.Windows; using System.Windows;
using System.Windows.Media;
namespace CtrEditor.Convertidores namespace CtrEditor.Convertidores
{ {
public class WidthPercentageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is double width)
{
return width * 0.25;
}
return 0;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class LevelToHeightMultiConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values[0] is float level && values[1] is double containerHeight)
{
return containerHeight * (level / 100);
}
return 0;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class BrushToColorNameConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is SolidColorBrush brush)
{
if (brush == Brushes.Red) return "Rojo";
if (brush == Brushes.Blue) return "Azul";
if (brush == Brushes.Black) return "Negro";
if (brush == Brushes.Green) return "Verde";
if (brush == Brushes.Gray) return "Gris";
}
return "Unknown";
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is string colorName)
{
switch (colorName)
{
case "Rojo":
return Brushes.Red;
case "Azul":
return Brushes.Blue;
case "Negro":
return Brushes.Black;
case "Verde":
return Brushes.Green;
case "Gris":
return Brushes.Gray;
}
}
return Brushes.Transparent;
}
}
public class PixelToMeter public class PixelToMeter
{ {
// Instancia privada estática, parte del patrón Singleton // Instancia privada estática, parte del patrón Singleton

View File

@ -9,24 +9,19 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Remove="ObjetosSim\ucBasicExample.xaml.cs" />
<Compile Remove="ObjetosSim\ucTransporteCurva.xaml.cs" /> <Compile Remove="ObjetosSim\ucTransporteCurva.xaml.cs" />
<Compile Remove="Simulacion\GeometrySimulator.cs" /> <Compile Remove="Simulacion\GeometrySimulator.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Remove="motor2.png" /> <None Remove="motor2.png" />
<None Remove="tank.png" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Page Remove="ObjetosSim\ucBasicExample.xaml" />
<Page Remove="ObjetosSim\ucTransporteCurva.xaml" /> <Page Remove="ObjetosSim\ucTransporteCurva.xaml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="ObjetosSim\ucBasicExample.xaml" />
<None Include="ObjetosSim\ucBasicExample.xaml.cs" />
<None Include="ObjetosSim\ucTransporteCurva.xaml" /> <None Include="ObjetosSim\ucTransporteCurva.xaml" />
<None Include="ObjetosSim\ucTransporteCurva.xaml.cs" /> <None Include="ObjetosSim\ucTransporteCurva.xaml.cs" />
<None Include="Simulacion\GeometrySimulator.cs" /> <None Include="Simulacion\GeometrySimulator.cs" />
@ -49,7 +44,6 @@
<ItemGroup> <ItemGroup>
<Resource Include="motor2.png" /> <Resource Include="motor2.png" />
<Resource Include="tank.png" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,5 +1,4 @@
using CtrEditor; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
@ -26,8 +25,6 @@ using System.Windows;
using static System.Resources.ResXFileRef; using static System.Resources.ResXFileRef;
using CtrEditor.Convertidores; using CtrEditor.Convertidores;
using CtrEditor.Simulacion; using CtrEditor.Simulacion;
using System.Diagnostics;
using Newtonsoft.Json.Linq;
namespace CtrEditor namespace CtrEditor
{ {
@ -39,7 +36,6 @@ namespace CtrEditor
public ObservableCollection<TipoSimulable> ListaOsBase { get; } = new ObservableCollection<TipoSimulable>(); public ObservableCollection<TipoSimulable> ListaOsBase { get; } = new ObservableCollection<TipoSimulable>();
private ObservableCollection<osBase> _objetosSimulables = new ObservableCollection<osBase>(); private ObservableCollection<osBase> _objetosSimulables = new ObservableCollection<osBase>();
public PLCViewModel _plcViewModelData; public PLCViewModel _plcViewModelData;
public Stopwatch stopwatch;
public SimulationManagerFP simulationManager = new SimulationManagerFP(); public SimulationManagerFP simulationManager = new SimulationManagerFP();
@ -74,8 +70,6 @@ namespace CtrEditor
StartSimulationCommand = new RelayCommand(StartSimulation); StartSimulationCommand = new RelayCommand(StartSimulation);
StopSimulationCommand = new RelayCommand(StopSimulation); StopSimulationCommand = new RelayCommand(StopSimulation);
stopwatch = new Stopwatch();
} }
public void LoadInitialData() public void LoadInitialData()
@ -161,21 +155,11 @@ namespace CtrEditor
private void OnRefreshEvent(object sender, EventArgs e) private void OnRefreshEvent(object sender, EventArgs e)
{ {
if (_plcViewModelData.IsConnected)
{
// Detener el cronómetro y obtener el tiempo transcurrido en milisegundos
stopwatch.Stop();
float elapsedMilliseconds = (float)stopwatch.Elapsed.TotalMilliseconds;
// Reiniciar el cronómetro para la próxima medición
stopwatch.Restart();
foreach (var objetoSimulable in ObjetosSimulables) foreach (var objetoSimulable in ObjetosSimulables)
objetoSimulable.UpdatePLC(_plcViewModelData.PLCInterface, (int) elapsedMilliseconds); {
} else if (_plcViewModelData.IsConnected)
stopwatch.Stop(); objetoSimulable.UpdatePLC(_plcViewModelData.PLCInterface);
}
} }
//protected virtual void OnTickSimulacion(TickSimulacionEventArgs e) //protected virtual void OnTickSimulacion(TickSimulacionEventArgs e)
@ -276,19 +260,10 @@ namespace CtrEditor
} }
} }
public void Save()
{
SaveStateObjetosSimulables();
ImageSelected?.Invoke(this, datosDeTrabajo.Imagenes[_selectedImage]); // Dispara el evento con la nueva ruta de imagen
LoadStateObjetosSimulables();
}
public void SaveStateObjetosSimulables() public void SaveStateObjetosSimulables()
{ {
if (_selectedImage != null) if (_selectedImage != null)
{ {
StopSimulation();
PLCViewModel.Disconnect();
var settings = new JsonSerializerSettings var settings = new JsonSerializerSettings
{ {
Formatting = Formatting.Indented, Formatting = Formatting.Indented,
@ -299,7 +274,6 @@ namespace CtrEditor
{ {
obj.VisualRepresentation = null; obj.VisualRepresentation = null;
obj.simulationManager = null; obj.simulationManager = null;
obj._mainViewModel = null;
} }
// Crear un objeto que incluya tanto los ObjetosSimulables como el UnitConverter // Crear un objeto que incluya tanto los ObjetosSimulables como el UnitConverter
var dataToSerialize = new SimulationData var dataToSerialize = new SimulationData
@ -318,8 +292,6 @@ namespace CtrEditor
{ {
try try
{ {
StopSimulation();
PLCViewModel.Disconnect();
ObjetosSimulables.Clear(); ObjetosSimulables.Clear();
simulationManager.Clear(); simulationManager.Clear();
if (_selectedImage != null) if (_selectedImage != null)
@ -349,9 +321,6 @@ namespace CtrEditor
PixelToMeter.Instance.calc = simulationData.UnitConverter; PixelToMeter.Instance.calc = simulationData.UnitConverter;
// Re-register to the events
_plcViewModelData.RefreshEvent += OnRefreshEvent;
// Recorrer la colección de objetos simulables // Recorrer la colección de objetos simulables
foreach (var objetoSimulable in ObjetosSimulables) foreach (var objetoSimulable in ObjetosSimulables)
CrearUsercontrol(objetoSimulable); CrearUsercontrol(objetoSimulable);
@ -374,7 +343,6 @@ namespace CtrEditor
{ {
// Asignar los datos al UserControl // Asignar los datos al UserControl
UserControlFactory.AssignDatos(userControl, osObjeto, simulationManager); UserControlFactory.AssignDatos(userControl, osObjeto, simulationManager);
osObjeto._mainViewModel = this;
OnUserControlSelected?.Invoke(userControl); OnUserControlSelected?.Invoke(userControl);
@ -385,6 +353,7 @@ namespace CtrEditor
// Implementación de INotifyPropertyChanged... // Implementación de INotifyPropertyChanged...
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
@ -393,21 +362,7 @@ namespace CtrEditor
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
} }
private RelayCommand saveCommand;
public ICommand SaveCommand => saveCommand ??= new RelayCommand(Save);
private void Save(object commandParameter)
{
}
private RelayCommand exitCommand;
public ICommand ExitCommand => exitCommand ??= new RelayCommand(Exit);
private void Exit()
{
Save();
Application.Current.Shutdown();
}
} }
public class SimulationData public class SimulationData
{ {

View File

@ -11,7 +11,6 @@
<Window.Resources> <Window.Resources>
<convert:FloatToFormattedStringConverter x:Key="floatFormatter"/> <convert:FloatToFormattedStringConverter x:Key="floatFormatter"/>
<convert:BrushToColorNameConverter x:Key="BrushToColorNameConverter"/>
</Window.Resources> </Window.Resources>
<Window.DataContext> <Window.DataContext>

View File

@ -21,7 +21,6 @@ using TextBox = System.Windows.Controls.TextBox;
using UserControl = System.Windows.Controls.UserControl; using UserControl = System.Windows.Controls.UserControl;
using CheckBox = System.Windows.Controls.CheckBox; using CheckBox = System.Windows.Controls.CheckBox;
using Orientation = System.Windows.Controls.Orientation; using Orientation = System.Windows.Controls.Orientation;
using ListBox = System.Windows.Controls.ListBox;
//using OpenCvSharp; //using OpenCvSharp;
@ -419,11 +418,6 @@ namespace CtrEditor
foreach (var property in properties) foreach (var property in properties)
{ {
if (Attribute.IsDefined(property, typeof(HiddenAttribute)))
{
continue;
}
var grid = new Grid(); var grid = new Grid();
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
@ -486,61 +480,11 @@ namespace CtrEditor
grid.Children.Add(label); grid.Children.Add(label);
grid.Children.Add(checkBox); grid.Children.Add(checkBox);
} }
else if (property.PropertyType == typeof(Brush))
{
var listBox = new ListBox
{
ItemsSource = new List<string> { "Rojo", "Azul", "Negro", "Verde", "Gris" },
Margin = new Thickness(0),
MinWidth = 200
};
listBox.SelectionChanged += (sender, e) =>
{
if (listBox.SelectedItem != null)
{
switch (listBox.SelectedItem.ToString())
{
case "Rojo":
property.SetValue(selectedObject, Brushes.Red);
break;
case "Azul":
property.SetValue(selectedObject, Brushes.Blue);
break;
case "Negro":
property.SetValue(selectedObject, Brushes.Black);
break;
case "Verde":
property.SetValue(selectedObject, Brushes.Green);
break;
case "Gris":
property.SetValue(selectedObject, Brushes.Gray);
break;
}
}
};
var binding = new Binding(property.Name)
{
Source = selectedObject,
Mode = BindingMode.TwoWay,
Converter = new BrushToColorNameConverter()
};
listBox.SetBinding(ListBox.SelectedItemProperty, binding);
Grid.SetColumn(label, 0);
Grid.SetColumn(listBox, 1);
grid.Children.Add(label);
grid.Children.Add(listBox);
}
PanelEdicion.Children.Add(grid); PanelEdicion.Children.Add(grid);
} }
} }
private void MainWindow_Closed(object sender, EventArgs e) private void MainWindow_Closed(object sender, EventArgs e)
{ {
if (DataContext is MainViewModel viewModel) if (DataContext is MainViewModel viewModel)

View File

@ -27,8 +27,6 @@ namespace CtrEditor.ObjetosSim
return new ucVMmotorSim(); return new ucVMmotorSim();
if (tipoObjeto == typeof(osBoton)) if (tipoObjeto == typeof(osBoton))
return new ucBoton(); return new ucBoton();
if (tipoObjeto == typeof(osTanque))
return new ucTanque();
// Puedes añadir más condiciones para otros tipos // Puedes añadir más condiciones para otros tipos
@ -51,8 +49,6 @@ namespace CtrEditor.ObjetosSim
return new osVMmotorSim(); return new osVMmotorSim();
if (tipoObjeto == typeof(osBoton)) if (tipoObjeto == typeof(osBoton))
return new osBoton(); return new osBoton();
if (tipoObjeto == typeof(osTanque))
return new osTanque();
// Puedes añadir más condiciones para otros tipos // Puedes añadir más condiciones para otros tipos

View File

@ -54,12 +54,9 @@ namespace CtrEditor.ObjetosSim
public abstract void UpdateControl(); public abstract void UpdateControl();
public abstract void UpdateGeometryStart(); public abstract void UpdateGeometryStart();
public abstract void UpdateGeometryStep(); public abstract void UpdateGeometryStep();
public abstract void UpdatePLC(PLCModel plc, int elapsedMilliseconds); public abstract void UpdatePLC(PLCModel plc);
public abstract void ucLoaded(); public abstract void ucLoaded();
[JsonIgnore]
public MainViewModel _mainViewModel;
[JsonIgnore] [JsonIgnore]
public UserControl? VisualRepresentation public UserControl? VisualRepresentation
{ {
@ -188,8 +185,4 @@ namespace CtrEditor.ObjetosSim
} }
} }
[AttributeUsage(AttributeTargets.Property)]
public class HiddenAttribute : Attribute
{
}
} }

View File

@ -1,20 +0,0 @@
<UserControl x:Class="CtrEditor.ObjetosSim.ucBasicExample"
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="/motor2.png"
Width="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}"
Height="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}"
Stretch="Uniform"/>
</Grid>
</UserControl>

View File

@ -1,167 +0,0 @@
using CtrEditor.Convertidores;
using CtrEditor.Siemens;
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;
namespace CtrEditor.ObjetosSim
{
/// <summary>
/// Interaction logic for ucBasicExample.xaml
/// </summary>
public class osBasicExample : osBase
{
// Otros datos y métodos relevantes para la simulación
private string _nombre = "Ejemplo";
private float _ancho;
private float _alto;
private float _left;
private float _top;
private float _angulo;
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 osBasicExample()
{
Ancho = 0.30f;
Alto = 0.30f;
}
public override void UpdateGeometryStart()
{
// Se llama antes de la simulacion
}
public override void UpdateGeometryStep()
{
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds)
{
}
public override void UpdateControl()
{
}
public override void ucLoaded()
{
// El UserControl ya se ha cargado y podemos obtener las coordenadas para
// crear el objeto de simulacion
}
}
public partial class ucBasicExample : UserControl, IDataContainer
{
public osBase? Datos { get; set; }
public ucBasicExample()
{
InitializeComponent();
this.Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
Datos?.ucLoaded();
}
public void Resize(float width, float height) {
if (Datos is osBasicExample 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 osBasicExample datos)
datos.Angulo = Angle;
}
public void Highlight(bool State) { }
public int ZIndex()
{
return 10;
}
}
}

View File

@ -139,7 +139,7 @@ namespace CtrEditor.ObjetosSim
ActualizarGeometrias(); ActualizarGeometrias();
} }
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds) { } public override void UpdatePLC(PLCModel plc) { }
public override void UpdateControl() public override void UpdateControl()
{ {

View File

@ -13,24 +13,37 @@
</UserControl.Resources> </UserControl.Resources>
<Grid> <Grid>
<Border x:Name="BackgroundRectangle" <Rectangle x:Name="BackgroundRectangle"
BorderBrush="Black" Fill="LightGray"
BorderThickness="2"
CornerRadius="0,0,10,10"
Width="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}" Width="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}"
Height="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=1.5}" Height="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=1.5}"
VerticalAlignment="Top" VerticalAlignment="Top"
HorizontalAlignment="Left" HorizontalAlignment="Left"
Background="Gray"/> />
<Ellipse Fill="{Binding ColorButton}" <Button Content="Button"
Stroke="Black"
StrokeThickness="2"
Width="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}" Width="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}"
Height="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}" Height="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}"
Background="{Binding Color}"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
MouseLeftButtonDown="Ellipse_MouseLeftButtonDown" MouseLeftButtonDown="Button_MouseLeftButtonDown"
MouseLeftButtonUp="Ellipse_MouseLeftButtonUp"> MouseLeftButtonUp="Button_MouseLeftButtonUp">
</Ellipse> <i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<ei:InvokeCommandAction Command="{Binding ButtonDownCommand}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeftButtonUp">
<ei:InvokeCommandAction Command="{Binding ButtonUpCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="2"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@ -32,8 +32,6 @@ namespace CtrEditor.ObjetosSim
private string _tag; private string _tag;
private Brush _color; private Brush _color;
private Brush _colorButton;
public Brush Color public Brush Color
{ {
get => _color; get => _color;
@ -44,16 +42,9 @@ namespace CtrEditor.ObjetosSim
} }
} }
[Hidden] public ICommand ButtonClickCommand { get; }
public Brush ColorButton public ICommand ButtonDownCommand { get; }
{ public ICommand ButtonUpCommand { get; }
get => _colorButton;
set
{
_colorButton = value;
OnPropertyChanged(nameof(ColorButton));
}
}
public override float Left public override float Left
{ {
@ -90,10 +81,6 @@ namespace CtrEditor.ObjetosSim
set set
{ {
_estado = value; _estado = value;
if (value)
ColorButton = Brushes.LightGreen;
else
ColorButton = Color;
OnPropertyChanged(nameof(Estado)); OnPropertyChanged(nameof(Estado));
} }
} }
@ -123,11 +110,20 @@ namespace CtrEditor.ObjetosSim
} }
} }
public void ButtonDownCommand() private void OnButtonClick()
{
// Handle the click event here
// Example: Change color on click
Color = Brushes.LightGreen;
}
private void OnButtonDown()
{ {
Estado = true; Estado = true;
} }
public void ButtonUpCommand()
private void OnButtonUp()
{ {
Estado = false; Estado = false;
} }
@ -139,6 +135,11 @@ namespace CtrEditor.ObjetosSim
Tag = "M50.0"; Tag = "M50.0";
// Set initial color // Set initial color
Color = Brushes.LightBlue; Color = Brushes.LightBlue;
// Initialize the command
ButtonClickCommand = new RelayCommand(OnButtonClick);
ButtonDownCommand = new RelayCommand(OnButtonDown);
ButtonUpCommand = new RelayCommand(OnButtonUp);
} }
public override void UpdateGeometryStart() public override void UpdateGeometryStart()
@ -149,9 +150,9 @@ namespace CtrEditor.ObjetosSim
public override void UpdateGeometryStep() public override void UpdateGeometryStep()
{ {
} }
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds) public override void UpdatePLC(PLCModel plc)
{ {
plc.EscribirTagBool(_tag, Estado); plc.EscribirTagBool(Tag, Estado);
} }
public override void UpdateControl() public override void UpdateControl()
@ -174,37 +175,28 @@ namespace CtrEditor.ObjetosSim
{ {
InitializeComponent(); InitializeComponent();
this.Loaded += OnLoaded; this.Loaded += OnLoaded;
this.DataContextChanged += OnDataContextChanged;
} }
private void OnLoaded(object sender, RoutedEventArgs e) private void OnLoaded(object sender, RoutedEventArgs e)
{ {
Datos?.ucLoaded(); Datos?.ucLoaded();
} }
private void Button_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
Datos = e.NewValue as osBase;
}
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{ {
if (Datos is osBoton osBotonData) if (Datos is osBoton osBotonData)
{ {
osBotonData.ButtonDownCommand(); osBotonData.ButtonDownCommand.Execute(null);
e.Handled = true; // Evita que el evento se propague Mouse.Capture((UIElement)sender);
} }
} }
private void Ellipse_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) private void Button_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{ {
if (Datos is osBoton osBotonData) if (Datos is osBoton osBotonData)
{ {
osBotonData.ButtonUpCommand(); osBotonData.ButtonUpCommand.Execute(null);
e.Handled = true; // Evita que el evento se propague Mouse.Capture(null); // Release mouse capture
} }
} }
public void Resize(float width, float height) { } public void Resize(float width, float height) { }
public void Move(float LeftPixels, float TopPixels) public void Move(float LeftPixels, float TopPixels)
{ {

View File

@ -121,7 +121,7 @@ namespace CtrEditor.ObjetosSim
public override void UpdateGeometryStep() public override void UpdateGeometryStep()
{ {
} }
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds) { } public override void UpdatePLC(PLCModel plc) { }
public override void ucLoaded() public override void ucLoaded()
{ {
// El UserControl ya se ha cargado y podemos obtener las coordenadas para // El UserControl ya se ha cargado y podemos obtener las coordenadas para

View File

@ -1,39 +0,0 @@
<UserControl x:Class="CtrEditor.ObjetosSim.ucTanque"
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"/>
<convert:LevelToHeightMultiConverter x:Key="LevelToHeightMultiConverter"/>
<convert:WidthPercentageConverter x:Key="WidthPercentageConverter"/>
</UserControl.Resources>
<Grid>
<Image x:Name="TankImage"
Source="/tank.png"
Width="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}"
Height="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}"
Stretch="Uniform"/>
<Rectangle x:Name="WaterLevel"
Fill="Blue"
VerticalAlignment="Bottom"
HorizontalAlignment="Center">
<Rectangle.Width>
<Binding ElementName="TankImage" Path="ActualWidth" Converter="{StaticResource WidthPercentageConverter}" />
</Rectangle.Width>
<Rectangle.Height>
<MultiBinding Converter="{StaticResource LevelToHeightMultiConverter}">
<Binding Path="Level" />
<Binding ElementName="TankImage" Path="ActualHeight" />
</MultiBinding>
</Rectangle.Height>
</Rectangle>
<Label Content="{Binding Level}" HorizontalAlignment="Center" Margin="10,10,0,0" VerticalAlignment="Top"/>
</Grid>
</UserControl>

View File

@ -1,201 +0,0 @@
using CtrEditor.Convertidores;
using CtrEditor.Siemens;
using OpenCvSharp.Flann;
using Siemens.Simatic.Simulation.Runtime;
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;
namespace CtrEditor.ObjetosSim
{
/// <summary>
/// Interaction logic for ucTanque.xaml
/// </summary>
public class osTanque : osBase
{
// Otros datos y métodos relevantes para la simulación
private string _nombre = "Tanque";
private float _ancho;
private float _alto;
private float _left;
private float _top;
private float _angulo;
private float _level;
private string _tag;
public string Tag
{
get => _tag;
set
{
if (_tag != value)
{
_tag = value;
OnPropertyChanged(nameof(Tag));
}
}
}
public float Level
{
get => _level;
set
{
_level = value;
OnPropertyChanged(nameof(Level));
}
}
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 osTanque()
{
Ancho = 0.30f;
Alto = 0.30f;
}
public override void UpdateGeometryStart()
{
// Se llama antes de la simulacion
}
public override void UpdateGeometryStep()
{
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds)
{
if (Tag.Length > 0)
{
SDataValue s = new SDataValue();
s.UInt16 = (ushort)(Level / 100.0 * 26600);
plc.EscribirTag(Tag, s);
}
}
public override void UpdateControl()
{
}
public override void ucLoaded()
{
// El UserControl ya se ha cargado y podemos obtener las coordenadas para
// crear el objeto de simulacion
}
}
public partial class ucTanque : UserControl, IDataContainer
{
public osBase? Datos { get; set; }
public ucTanque()
{
InitializeComponent();
this.Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
Datos?.ucLoaded();
}
public void Resize(float width, float height)
{
if (Datos is osTanque 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 osTanque datos)
datos.Angulo = Angle;
}
public void Highlight(bool State) { }
public int ZIndex()
{
return 10;
}
}
}

View File

@ -15,7 +15,6 @@ using System.Windows.Shapes;
using CtrEditor.Convertidores; using CtrEditor.Convertidores;
using CtrEditor.Siemens; using CtrEditor.Siemens;
using CtrEditor.Simulacion; using CtrEditor.Simulacion;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace CtrEditor.ObjetosSim namespace CtrEditor.ObjetosSim
{ {
@ -40,28 +39,12 @@ namespace CtrEditor.ObjetosSim
private float _top; private float _top;
private float _angulo; private float _angulo;
private float _velocidadActual; private float _velocidadActual;
private osBase _osMotor = null;
private string _motor;
private simRectangle? TransporteCentral; private simRectangle? TransporteCentral;
private simLine? Guia_Superior; private simLine? Guia_Superior;
private simLine? Guia_Inferior; private simLine? Guia_Inferior;
public string Motor
{
get => _motor;
set
{
if (_motor != value)
{
_motor = value;
OnPropertyChanged(nameof(Motor));
}
}
}
public override float Left public override float Left
{ {
get => _left; get => _left;
@ -196,24 +179,7 @@ namespace CtrEditor.ObjetosSim
public override void UpdateControl() public override void UpdateControl()
{ {
} }
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds) public override void UpdatePLC(PLCModel plc) { }
{
if (_osMotor != null)
{
if (_osMotor is osVMmotorSim motor)
VelocidadActual = motor.Velocidad;
} else
{
if (Motor.Length > 0)
if (_mainViewModel != null)
foreach (var objetoSimulable in _mainViewModel.ObjetosSimulables)
if (objetoSimulable.Nombre == _motor)
{
_osMotor = objetoSimulable;
break;
}
}
}
public override void ucLoaded() public override void ucLoaded()
{ {
// El UserControl ya se ha cargado y podemos obtener las coordenadas para // El UserControl ya se ha cargado y podemos obtener las coordenadas para
@ -230,7 +196,6 @@ namespace CtrEditor.ObjetosSim
Guia_Superior = AddLine(simulationManager, uc.GuiaSuperior); Guia_Superior = AddLine(simulationManager, uc.GuiaSuperior);
Guia_Inferior = AddLine(simulationManager, uc.GuiaInferior); Guia_Inferior = AddLine(simulationManager, uc.GuiaInferior);
} }
Motor = Motor; // Forzar la busqueda
} }

View File

@ -27,23 +27,10 @@ namespace CtrEditor.ObjetosSim
private float _top; private float _top;
private float _angulo; private float _angulo;
private float _velocidadActual; private float _velocidadActual;
private osBase _osMotor = null;
private string _motor;
private simRectangle Simulation_Transporte; private simRectangle Simulation_Transporte;
public string Motor
{
get => _motor;
set
{
if (_motor != value)
{
_motor = value;
OnPropertyChanged(nameof(Motor));
}
}
}
public override float Left public override float Left
{ {
get => _left; get => _left;
@ -145,25 +132,8 @@ namespace CtrEditor.ObjetosSim
public override void UpdateGeometryStep() public override void UpdateGeometryStep()
{ {
} }
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds) public override void UpdatePLC(PLCModel plc) { }
{
if (_osMotor != null)
{
if (_osMotor is osVMmotorSim motor)
VelocidadActual = motor.Velocidad;
}
else
{
if (Motor.Length > 0)
if (_mainViewModel != null)
foreach (var objetoSimulable in _mainViewModel.ObjetosSimulables)
if (objetoSimulable.Nombre == _motor)
{
_osMotor = objetoSimulable;
break;
}
}
}
public override void UpdateControl() public override void UpdateControl()
{ {

View File

@ -51,9 +51,6 @@ namespace CtrEditor.ObjetosSim
private float _ratio; private float _ratio;
private float _velocidad; private float _velocidad;
private bool _encendido; private bool _encendido;
private float _rampaSegundos;
private float _maxHz;
public VMSimMotor motState = new VMSimMotor(); public VMSimMotor motState = new VMSimMotor();
@ -67,29 +64,6 @@ namespace CtrEditor.ObjetosSim
} }
} }
public float MaxRatedHz
{
get => _maxHz;
set
{
_maxHz = value;
OnPropertyChanged(nameof(Tamano));
}
}
public float TiempoRampa
{
get => _rampaSegundos;
set
{
if (value < 0.1f)
value = 0.1f;
_rampaSegundos = value;
OnPropertyChanged(nameof(Tamano));
}
}
public bool Encendido public bool Encendido
{ {
get => _encendido; get => _encendido;
@ -165,8 +139,6 @@ namespace CtrEditor.ObjetosSim
{ {
Tamano = 0.30f; Tamano = 0.30f;
PLC_NumeroMotor = 31; PLC_NumeroMotor = 31;
MaxRatedHz = 100;
TiempoRampa = 3;
} }
public override void UpdateGeometryStart() public override void UpdateGeometryStart()
@ -177,7 +149,7 @@ namespace CtrEditor.ObjetosSim
public override void UpdateGeometryStep() public override void UpdateGeometryStep()
{ {
} }
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds) { public override void UpdatePLC(PLCModel plc) {
var index = 0; var index = 0;
switch (PLC_NumeroMotor) switch (PLC_NumeroMotor)
{ {
@ -190,8 +162,6 @@ namespace CtrEditor.ObjetosSim
motState.OUT_Reversal = plc.LeerTagBool($"\"DB MotorSimulate\".Motors[{index}].OUT.\"Reversal Direction\""); 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.OUT_OUT_VFD_REQ_Speed_Hz = (float)plc.LeerTagInt16($"\"DB MotorSimulate\".Motors[{index}].OUT.OUT_VFD_REQ_Speed_Hz");
if (Encendido) if (Encendido)
{ {
motState._STATUS_VFD_Ready = true; motState._STATUS_VFD_Ready = true;
@ -199,19 +169,19 @@ namespace CtrEditor.ObjetosSim
motState.STATUS_VFD_Trip = false; motState.STATUS_VFD_Trip = false;
motState.STATUS_VFD_Warning = false; motState.STATUS_VFD_Warning = false;
motState.STATUS_VFD_Coasting = false; motState.STATUS_VFD_Coasting = false;
} if (motState.STATUS_VFD_ACT_Speed_Hz < motState.OUT_OUT_VFD_REQ_Speed_Hz)
else motState.STATUS_VFD_ACT_Speed_Hz += motState.OUT_OUT_VFD_REQ_Speed_Hz / 375 ; // Simulate Ramp
} else
{ {
motState._STATUS_VFD_Ready = false; motState._STATUS_VFD_Ready = false;
motState.Motor_Running = false; motState.Motor_Running = false;
motState.STATUS_VFD_Trip = true; motState.STATUS_VFD_Trip = true;
motState.STATUS_VFD_Warning = false; motState.STATUS_VFD_Warning = false;
motState.STATUS_VFD_Coasting = false; motState.STATUS_VFD_Coasting = false;
if (motState.STATUS_VFD_ACT_Speed_Hz > 0)
motState.STATUS_VFD_ACT_Speed_Hz -= 1; // Simulate Ramp
} }
// 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}].STATUS_VFD_Ready", motState._STATUS_VFD_Ready);
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].Motor_Running", motState.Motor_Running); 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_Trip", motState.STATUS_VFD_Trip);
@ -223,19 +193,6 @@ namespace CtrEditor.ObjetosSim
Velocidad = motState.STATUS_VFD_ACT_Speed_Hz/10; 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() public override void UpdateControl()
{ {

View File

@ -42,7 +42,7 @@ namespace CtrEditor.Siemens
{ {
IsConnected = false; IsConnected = false;
PLCInterface = new PLCModel(); PLCInterface = new PLCModel();
_timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(10) }; _timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(1000) };
_timer.Tick += (s, e) => Refresh(); _timer.Tick += (s, e) => Refresh();
ConnectCommand = new RelayCommand(Connect, () => true); ConnectCommand = new RelayCommand(Connect, () => true);
@ -102,7 +102,7 @@ namespace CtrEditor.Siemens
} }
} }
public void Connect() private void Connect()
{ {
// Implementa la conexión utilizando PLCModel // Implementa la conexión utilizando PLCModel
PLCInterface.Instance = SimulationRuntimeManager.CreateInterface(Name); PLCInterface.Instance = SimulationRuntimeManager.CreateInterface(Name);
@ -123,7 +123,7 @@ namespace CtrEditor.Siemens
PLCInterface.UpdateTagList(); PLCInterface.UpdateTagList();
} }
public void Disconnect() private void Disconnect()
{ {
IsConnected = false; IsConnected = false;
_timer.Stop(); _timer.Stop();
@ -137,11 +137,11 @@ namespace CtrEditor.Siemens
{ {
CpuTime = PLCInterface.LeerTagInt16("\"DB HMI\".CPU_Scan_Time")?.ToString() ?? "N/A"; CpuTime = PLCInterface.LeerTagInt16("\"DB HMI\".CPU_Scan_Time")?.ToString() ?? "N/A";
LastError = PLCInterface.LastError; LastError = PLCInterface.LastError;
}
// Disparar el evento RefreshEvent // Disparar el evento RefreshEvent
RefreshEvent?.Invoke(this, EventArgs.Empty); RefreshEvent?.Invoke(this, EventArgs.Empty);
} }
}
private void OnPropertyChanged([CallerMemberName] string propertyName = null) private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{ {
@ -193,29 +193,7 @@ namespace CtrEditor.Siemens
LastError = ex.Message; LastError = ex.Message;
} }
} }
public void EscribirTag(string pTag, SDataValue Value)
{
try
{
Instance?.Write(pTag, Value);
}
catch (Exception ex)
{
LastError = pTag + ":" + ex.Message;
}
}
public SDataValue LeerTag(string pTag)
{
try
{
return Instance.Read(pTag);
}
catch (Exception ex)
{
LastError = pTag + ":" + ex.Message;
return new SDataValue();
}
}
public void EscribirTagBool(string pTag, bool pValue) public void EscribirTagBool(string pTag, bool pValue)
{ {
try try

BIN
tank.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB