Compare commits

..

No commits in common. "e54dba175ac68e84edc26edaa3b0ab6cf06eda14" and "ecf433ceccbc8afc18bbb243d518d3d16fa9e83f" have entirely different histories.

44 changed files with 310 additions and 412 deletions

View File

@ -216,28 +216,6 @@ namespace CtrEditor.Convertidores
} }
} }
public class DoubleToFormattedStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is double floatValue)
{
return floatValue.ToString("0.00", culture); // Formatear a dos decimales
}
return value; // Devolver el valor original si no es un float
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is string stringValue && double.TryParse(stringValue, NumberStyles.Float, culture, out double result))
{
return result;
}
return value; // Devolver el valor original si no se puede convertir
}
}
public class UnitConverter public class UnitConverter
{ {
// La escala representa cuántos metros hay en un píxel // La escala representa cuántos metros hay en un píxel

View File

@ -9,6 +9,7 @@
</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>
@ -40,6 +41,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Page Remove="ObjetosSim\ucBasicExample.xaml" />
<Page Remove="ObjetosSim\ucTransporteCurva.xaml" /> <Page Remove="ObjetosSim\ucTransporteCurva.xaml" />
</ItemGroup> </ItemGroup>

View File

@ -4,29 +4,30 @@ using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using Ookii.Dialogs.Wpf; using Ookii.Dialogs.Wpf;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Windows.Media;
using System.Windows.Threading; using System.Windows.Threading;
using CtrEditor.ObjetosSim; using CtrEditor.ObjetosSim;
using CtrEditor.Siemens; using CtrEditor.Siemens;
using System.IO; using System.IO;
// using System.Windows.Forms;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Windows.Data;
using System.Windows; using System.Windows;
using CtrEditor.Convertidores; using CtrEditor.Convertidores;
using CtrEditor.Simulacion; using CtrEditor.Simulacion;
using System.Diagnostics; using System.Diagnostics;
using System.Reflection; using System.Reflection;
using CommunityToolkit.Mvvm.ComponentModel;
namespace CtrEditor namespace CtrEditor
{ {
public partial class MainViewModel : ObservableObject public class MainViewModel : INotifyPropertyChanged
{ {
public Stopwatch stopwatch_Sim; public DatosDeTrabajo datosDeTrabajo { get; }
public ObservableCollection<string> listaImagenes { get; private set; } // Publicación de las claves del diccionario
private double stopwatch_SimPLC_last; public ObservableCollection<TipoSimulable> ListaOsBase { get; } = new ObservableCollection<TipoSimulable>();
private double stopwatch_SimModel_last; public Stopwatch stopwatch_PLCRefresh;
public Stopwatch stopwatch_SimRefresh;
private float TiempoDesdeStartSimulacion; private float TiempoDesdeStartSimulacion;
private bool Debug_SimulacionCreado = false; private bool Debug_SimulacionCreado = false;
@ -34,15 +35,6 @@ namespace CtrEditor
private readonly DispatcherTimer _timerSimulacion; private readonly DispatcherTimer _timerSimulacion;
[ObservableProperty]
private DatosDeTrabajo datosDeTrabajo;
[ObservableProperty]
private ObservableCollection<string> listaImagenes; // Publicación de las claves del diccionario
[ObservableProperty]
public ObservableCollection<TipoSimulable> listaOsBase;
public ICommand StartSimulationCommand { get; } public ICommand StartSimulationCommand { get; }
public ICommand StopSimulationCommand { get; } public ICommand StopSimulationCommand { get; }
public ICommand ItemDoubleClickCommand { get; private set; } public ICommand ItemDoubleClickCommand { get; private set; }
@ -55,6 +47,7 @@ namespace CtrEditor
public ICommand TBEliminarUserControlCommand { get; } public ICommand TBEliminarUserControlCommand { get; }
public ICommand TBDuplicarUserControlCommand { get; } public ICommand TBDuplicarUserControlCommand { get; }
public ICommand OpenWorkDirectoryCommand { get; } public ICommand OpenWorkDirectoryCommand { get; }
@ -64,33 +57,59 @@ namespace CtrEditor
// Propiedades // Propiedades
private bool isSimulationRunning;
private bool isConnected;
private bool habilitarEliminarUserControl; private bool habilitarEliminarUserControl;
public PLCViewModel plcViewModelData;
private osBase _selectedItemOsList;
private string _selectedImage = null;
private ObservableCollection<osBase> _objetosSimulables = new ObservableCollection<osBase>();
private float _left;
private float _top;
private MainWindow mainWindow; private MainWindow mainWindow;
public MainWindow MainWindow { get => mainWindow; set => mainWindow = value; } public MainWindow MainWindow { get => mainWindow; set => mainWindow = value; }
public float CanvasLeft
[ObservableProperty]
private float canvasLeft;
[ObservableProperty]
private float canvasTop;
[ObservableProperty]
private bool isSimulationRunning;
partial void OnIsSimulationRunningChanged(bool value)
{ {
CommandManager.InvalidateRequerySuggested(); // Notificar que el estado de los comandos ha cambiado get => _left;
set
{
_left = value;
OnPropertyChanged(nameof(CanvasLeft));
}
}
public float CanvasTop
{
get => _top;
set
{
_top = value;
OnPropertyChanged(nameof(CanvasTop));
}
} }
[ObservableProperty] public bool IsSimulationRunning
private bool isConnected;
partial void OnIsConnectedChanged(bool value)
{ {
CommandManager.InvalidateRequerySuggested(); 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 public string directorioTrabajo
@ -102,51 +121,90 @@ namespace CtrEditor
{ {
EstadoPersistente.Instance.directorio = value; // Actualizar el estado persistente EstadoPersistente.Instance.directorio = value; // Actualizar el estado persistente
EstadoPersistente.Instance.GuardarEstado(); // Guardar el estado actualizado EstadoPersistente.Instance.GuardarEstado(); // Guardar el estado actualizado
DatosDeTrabajo.CargarImagenes(); datosDeTrabajo.CargarImagenes();
ListaImagenes = new ObservableCollection<string>(DatosDeTrabajo.Imagenes.Keys); // Actualizar claves listaImagenes = new ObservableCollection<string>(datosDeTrabajo.Imagenes.Keys); // Actualizar claves
SelectedImage = null; SelectedImage = null;
if (ListaImagenes.FirstOrDefault() != null) if (listaImagenes.FirstOrDefault() != null)
SelectedImage = ListaImagenes.FirstOrDefault(); SelectedImage = listaImagenes.FirstOrDefault();
OnPropertyChanged(nameof(directorioTrabajo)); // Notificar el cambio de propiedad OnPropertyChanged(nameof(directorioTrabajo)); // Notificar el cambio de propiedad
OnPropertyChanged(nameof(ListaImagenes)); // Notificar que la lista de imágenes ha cambiado OnPropertyChanged(nameof(listaImagenes)); // Notificar que la lista de imágenes ha cambiado
} }
} }
} }
[ObservableProperty] public PLCViewModel PLCViewModel
private PLCViewModel pLCViewModel;
[ObservableProperty]
private string selectedImage;
partial void OnSelectedImageChanged(string value)
{ {
if (value != null) get { return plcViewModelData; }
set
{ {
StopSimulation(); plcViewModelData = value;
// SaveStateObjetosSimulables(); // Guarda el estado antes de cambiar la imagen OnPropertyChanged(nameof(PLCViewModel));
ImageSelected?.Invoke(this, datosDeTrabajo.Imagenes[value]); // Dispara el evento con la nueva ruta de imagen
LoadStateObjetosSimulables();
} }
} }
[ObservableProperty] public string SelectedImage
private osBase selectedItemOsList;
partial void OnSelectedItemOsListChanged(osBase value)
{ {
if (value != null) get => _selectedImage;
habilitarEliminarUserControl = true; set
else {
habilitarEliminarUserControl = false; 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));
}
} }
[ObservableProperty] public osBase SelectedItemOsList
private TipoSimulable selectedItem; {
get => _selectedItemOsList;
set
{
if (_selectedItemOsList != value)
{
if (value != null)
habilitarEliminarUserControl = true;
else
habilitarEliminarUserControl = false;
_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));
}
}
}
[ObservableProperty]
public ObservableCollection<osBase> objetosSimulables;
// //
// Constructor // Constructor
// //
@ -156,12 +214,9 @@ namespace CtrEditor
OpenWorkDirectoryCommand = new RelayCommand(OpenWorkDirectory); OpenWorkDirectoryCommand = new RelayCommand(OpenWorkDirectory);
datosDeTrabajo = new DatosDeTrabajo(); datosDeTrabajo = new DatosDeTrabajo();
ObjetosSimulables = new ObservableCollection<osBase>();
ListaOsBase = new ObservableCollection<TipoSimulable>();
// Inicializa el PLCViewModel // Inicializa el PLCViewModel
PLCViewModel = new PLCViewModel(); plcViewModelData = new PLCViewModel();
PLCViewModel.RefreshEvent += OnRefreshEvent; plcViewModelData.RefreshEvent += OnRefreshEvent;
InitializeTipoSimulableList(); InitializeTipoSimulableList();
@ -183,8 +238,8 @@ namespace CtrEditor
TBEliminarUserControlCommand = new RelayCommand(EliminarUserControl, () => habilitarEliminarUserControl); TBEliminarUserControlCommand = new RelayCommand(EliminarUserControl, () => habilitarEliminarUserControl);
TBDuplicarUserControlCommand = new RelayCommand(DuplicarUserControl, () => habilitarEliminarUserControl); TBDuplicarUserControlCommand = new RelayCommand(DuplicarUserControl, () => habilitarEliminarUserControl);
stopwatch_Sim = new Stopwatch(); stopwatch_PLCRefresh = new Stopwatch();
stopwatch_Sim.Start(); stopwatch_SimRefresh = new Stopwatch();
} }
public void LoadInitialData() public void LoadInitialData()
@ -332,6 +387,8 @@ namespace CtrEditor
Debug_SimulacionCreado = true; Debug_SimulacionCreado = true;
_timerSimulacion.Start(); _timerSimulacion.Start();
simulationManager.stopwatch.Start();
stopwatch_SimRefresh.Start();
} }
private void StopSimulation() private void StopSimulation()
@ -347,19 +404,24 @@ namespace CtrEditor
Debug_SimulacionCreado = false; Debug_SimulacionCreado = false;
} }
_timerSimulacion.Stop(); _timerSimulacion.Stop();
simulationManager.stopwatch.Stop();
stopwatch_SimRefresh.Stop();
} }
private void OnTickSimulacion(object sender, EventArgs e) private void OnTickSimulacion(object sender, EventArgs e)
{ {
// Detener el cronómetro y obtener el tiempo transcurrido en milisegundos // Detener el cronómetro y obtener el tiempo transcurrido en milisegundos
var elapsedMilliseconds = stopwatch_Sim.Elapsed.TotalMilliseconds - stopwatch_SimModel_last; stopwatch_SimRefresh.Stop();
stopwatch_SimModel_last = stopwatch_Sim.Elapsed.TotalMilliseconds; float elapsedMilliseconds = (float)stopwatch_SimRefresh.Elapsed.TotalMilliseconds;
// Eliminar el diseño de Debug luego de 2 segundos // Eliminar el diseño de Debug luego de 2 segundos
if (TiempoDesdeStartSimulacion > 2000) if (TiempoDesdeStartSimulacion > 2000)
simulationManager.Debug_ClearSimulationShapes(); simulationManager.Debug_ClearSimulationShapes();
else else
TiempoDesdeStartSimulacion += (float)elapsedMilliseconds; TiempoDesdeStartSimulacion += elapsedMilliseconds;
// Reiniciar el cronómetro para la próxima medición
stopwatch_SimRefresh.Restart();
foreach (var objetoSimulable in ObjetosSimulables) foreach (var objetoSimulable in ObjetosSimulables)
objetoSimulable.UpdateGeometryStep(); objetoSimulable.UpdateGeometryStep();
@ -380,12 +442,13 @@ namespace CtrEditor
private void ConnectPLC() private void ConnectPLC()
{ {
PLCViewModel.Connect(); plcViewModelData.Connect();
} }
private void DisconnectPLC() private void DisconnectPLC()
{ {
PLCViewModel.Disconnect(); plcViewModelData.Disconnect();
IsConnected = false; IsConnected = false;
foreach (var objetoSimulable in ObjetosSimulables) foreach (var objetoSimulable in ObjetosSimulables)
objetoSimulable.SetPLC(null); objetoSimulable.SetPLC(null);
@ -394,23 +457,28 @@ namespace CtrEditor
private void OnRefreshEvent(object sender, EventArgs e) private void OnRefreshEvent(object sender, EventArgs e)
{ {
if (PLCViewModel.IsConnected) if (plcViewModelData.IsConnected)
{ {
if (!isConnected) if (!isConnected)
{ {
IsConnected = true; IsConnected = true;
foreach (var objetoSimulable in ObjetosSimulables) foreach (var objetoSimulable in ObjetosSimulables)
objetoSimulable.SetPLC(PLCViewModel.PLCInterface); objetoSimulable.SetPLC(plcViewModelData.PLCInterface);
} }
// Detener el cronómetro y obtener el tiempo transcurrido en milisegundos // Detener el cronómetro y obtener el tiempo transcurrido en milisegundos
var elapsedMilliseconds = stopwatch_Sim.Elapsed.TotalMilliseconds - stopwatch_SimPLC_last; stopwatch_PLCRefresh.Stop();
stopwatch_SimPLC_last = stopwatch_Sim.Elapsed.TotalMilliseconds; float elapsedMilliseconds = (float)stopwatch_PLCRefresh.Elapsed.TotalMilliseconds;
// Reiniciar el cronómetro para la próxima medición // Reiniciar el cronómetro para la próxima medición
stopwatch_PLCRefresh.Restart();
foreach (var objetoSimulable in ObjetosSimulables) foreach (var objetoSimulable in ObjetosSimulables)
objetoSimulable.UpdatePLC(PLCViewModel.PLCInterface, (int) elapsedMilliseconds); objetoSimulable.UpdatePLC(plcViewModelData.PLCInterface, (int) elapsedMilliseconds);
} } else
stopwatch_PLCRefresh.Stop();
} }
private void OpenWorkDirectory() private void OpenWorkDirectory()
@ -433,13 +501,13 @@ namespace CtrEditor
public void SaveStateObjetosSimulables() public void SaveStateObjetosSimulables()
{ {
if (SelectedImage != null) if (_selectedImage != null)
{ {
StopSimulation(); StopSimulation();
DisconnectPLC(); DisconnectPLC();
// Ruta del archivo a ser guardado // Ruta del archivo a ser guardado
var path = DatosDeTrabajo.ObtenerPathImagenConExtension(SelectedImage, ".json"); var path = datosDeTrabajo.ObtenerPathImagenConExtension(_selectedImage, ".json");
// Verificar si el archivo ya existe y crear un respaldo // Verificar si el archivo ya existe y crear un respaldo
if (File.Exists(path)) if (File.Exists(path))
@ -485,9 +553,9 @@ namespace CtrEditor
DisconnectPLC(); DisconnectPLC();
ObjetosSimulables.Clear(); ObjetosSimulables.Clear();
simulationManager.Clear(); simulationManager.Clear();
if (SelectedImage != null) if (_selectedImage != null)
{ {
string jsonPath = datosDeTrabajo.ObtenerPathImagenConExtension(SelectedImage, ".json"); string jsonPath = datosDeTrabajo.ObtenerPathImagenConExtension(_selectedImage, ".json");
if (File.Exists(jsonPath)) if (File.Exists(jsonPath))
{ {
string jsonString = File.ReadAllText(jsonPath); string jsonString = File.ReadAllText(jsonPath);
@ -513,7 +581,7 @@ namespace CtrEditor
PixelToMeter.Instance.calc = simulationData.UnitConverter; PixelToMeter.Instance.calc = simulationData.UnitConverter;
// Re-register to the events // Re-register to the events
PLCViewModel.RefreshEvent += OnRefreshEvent; 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)
@ -531,6 +599,14 @@ namespace CtrEditor
UserControlFactory.CargarPropiedadesosDatos(selectedObject,PanelEdicion, Resources); UserControlFactory.CargarPropiedadesosDatos(selectedObject,PanelEdicion, Resources);
} }
// Implementación de INotifyPropertyChanged...
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private RelayCommand saveCommand; private RelayCommand saveCommand;
public ICommand SaveCommand => saveCommand ??= new RelayCommand(Save); public ICommand SaveCommand => saveCommand ??= new RelayCommand(Save);
@ -549,15 +625,15 @@ namespace CtrEditor
} }
public class SimulationData public class SimulationData
{ {
public ObservableCollection<osBase>? ObjetosSimulables { get; set; } public ObservableCollection<osBase> ObjetosSimulables { get; set; }
public UnitConverter? UnitConverter { get; set; } public UnitConverter UnitConverter { get; set; }
public PLCViewModel? PLC_ConnectionData { get; set; } public PLCViewModel PLC_ConnectionData { get; set; }
} }
public class TipoSimulable public class TipoSimulable
{ {
public string? Nombre { get; set; } public string Nombre { get; set; }
public Type? Tipo { get; set; } public Type Tipo { get; set; }
} }
public class TickSimulacionEventArgs : EventArgs public class TickSimulacionEventArgs : EventArgs

View File

@ -15,7 +15,6 @@
<Window.Resources> <Window.Resources>
<convert:FloatToFormattedStringConverter x:Key="floatFormatter"/> <convert:FloatToFormattedStringConverter x:Key="floatFormatter"/>
<convert:DoubleToFormattedStringConverter x:Key="doubleFormatter"/>
<convert:BrushToColorNameConverter x:Key="BrushToColorNameConverter"/> <convert:BrushToColorNameConverter x:Key="BrushToColorNameConverter"/>
<!-- Style for Start/Stop Button --> <!-- Style for Start/Stop Button -->
@ -66,7 +65,7 @@
<RowDefinition Height="2*"/> <RowDefinition Height="2*"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<ListBox x:Name="ListaImagenes" Grid.Row="0" Margin="5" ItemsSource="{Binding ListaImagenes}" SelectedItem="{Binding SelectedImage}" /> <ListBox x:Name="ListaImagenes" Grid.Row="0" Margin="5" ItemsSource="{Binding listaImagenes}" SelectedItem="{Binding SelectedImage}" />
<ListBox x:Name="ListaFunciones" Grid.Row="1" Margin="5" ItemsSource="{Binding ListaOsBase}" DisplayMemberPath="Nombre" SelectedItem="{Binding SelectedItem}"> <ListBox x:Name="ListaFunciones" Grid.Row="1" Margin="5" ItemsSource="{Binding ListaOsBase}" DisplayMemberPath="Nombre" SelectedItem="{Binding SelectedItem}">
<i:Interaction.Triggers> <i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick"> <i:EventTrigger EventName="MouseDoubleClick">

View File

@ -1,46 +0,0 @@
<UserControl x:Class="CtrEditor.ObjetosSim.ucGearEncoder"
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.UserControls"
mc:Ignorable="d"
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim"
xmlns:convert="clr-namespace:CtrEditor.Convertidores">
<UserControl.Resources>
<convert:MeterToPixelConverter x:Key="MeterToPixelConverter"/>
</UserControl.Resources>
<UserControl.DataContext>
<vm:osGearEncoder Dientes="9"/>
</UserControl.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Radio_Externo, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=1}"/>
<ColumnDefinition Width="{Binding Radio_Externo, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=0.02}"/>
<!-- Espacio entre el Rectangle y el Canvas -->
<ColumnDefinition Width="{Binding Radio_Externo, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=1}"/>
</Grid.ColumnDefinitions>
<!-- StackPanel to contain the Rectangle -->
<Canvas Grid.Column="0" HorizontalAlignment="Right">
<Rectangle Canvas.Top="{Binding Radio_Externo, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=-0.12}"
Grid.Column="0" Width="{Binding Radio_Externo, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=1}"
Height="{Binding Radio_Externo, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=0.25}"
Fill="{Binding Color_oculto}"
HorizontalAlignment="Left" VerticalAlignment="Center"/>
</Canvas>
<Canvas Grid.Column="0" HorizontalAlignment="Left">
<Canvas.RenderTransform>
<RotateTransform Angle="{Binding Angulo}" CenterX="0" CenterY="0"/>
</Canvas.RenderTransform>
<local:GearControl ToothWidthRatio="{Binding Ancho_Dientes}" TeethCount="{Binding Dientes}"
InnerRadius="{Binding Radio_Interno, Converter={StaticResource MeterToPixelConverter}}"
OuterRadius="{Binding Radio_Externo, Converter={StaticResource MeterToPixelConverter}}"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</Canvas>
</Grid>
</UserControl>

View File

@ -102,7 +102,7 @@ namespace CtrEditor.ObjetosSim
Grid.SetColumn(label, 0); Grid.SetColumn(label, 0);
grid.Children.Add(label); grid.Children.Add(label);
if (property.PropertyType == typeof(double) || property.PropertyType == typeof(float) || property.PropertyType == typeof(string) || property.PropertyType == typeof(int)) if (property.PropertyType == typeof(float) || property.PropertyType == typeof(string) || property.PropertyType == typeof(int))
{ {
var textBox = new TextBox var textBox = new TextBox
{ {
@ -123,11 +123,6 @@ namespace CtrEditor.ObjetosSim
if (Resources != null) if (Resources != null)
binding.Converter = (FloatToFormattedStringConverter)Resources["floatFormatter"]; binding.Converter = (FloatToFormattedStringConverter)Resources["floatFormatter"];
} }
if (property.PropertyType == typeof(double))
{
if (Resources != null)
binding.Converter = (DoubleToFormattedStringConverter)Resources["doubleFormatter"];
}
textBox.SetBinding(TextBox.TextProperty, binding); textBox.SetBinding(TextBox.TextProperty, binding);
@ -231,7 +226,7 @@ namespace CtrEditor.ObjetosSim
Grid.SetColumn(label, 0); Grid.SetColumn(label, 0);
grid.Children.Add(label); grid.Children.Add(label);
if (property.PropertyType == typeof(double) || property.PropertyType == typeof(float) || property.PropertyType == typeof(string) || property.PropertyType == typeof(int)) if (property.PropertyType == typeof(float) || property.PropertyType == typeof(string) || property.PropertyType == typeof(int))
{ {
var textBox = new TextBox var textBox = new TextBox
{ {
@ -252,11 +247,6 @@ namespace CtrEditor.ObjetosSim
if (Resources != null) if (Resources != null)
binding.Converter = (FloatToFormattedStringConverter)Resources["floatFormatter"]; binding.Converter = (FloatToFormattedStringConverter)Resources["floatFormatter"];
} }
if (property.PropertyType == typeof(double))
{
if (Resources != null)
binding.Converter = (DoubleToFormattedStringConverter)Resources["doubleFormatter"];
}
textBox.SetBinding(TextBox.TextProperty, binding); textBox.SetBinding(TextBox.TextProperty, binding);

View File

@ -1,6 +1,16 @@
using System.Windows; 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.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes; using System.Windows.Shapes;
namespace CtrEditor.ObjetosSim.UserControls namespace CtrEditor.ObjetosSim.UserControls
@ -84,25 +94,8 @@ namespace CtrEditor.ObjetosSim.UserControls
Canvas.SetTop(innerCircle, centerY - InnerRadius); Canvas.SetTop(innerCircle, centerY - InnerRadius);
GearCanvas.Children.Add(innerCircle); GearCanvas.Children.Add(innerCircle);
// Draw the zero angle marker
double zeroAngle = 0;
double radianZero = zeroAngle * Math.PI / 180;
double markerLength = InnerRadius * 1.2; // Length of the marker line extending outside the inner circle
Line zeroAngleMarker = new Line
{
X1 = centerX,
Y1 = centerY,
X2 = centerX + markerLength * Math.Cos(radianZero),
Y2 = centerY - markerLength * Math.Sin(radianZero),
Stroke = Brushes.Red,
StrokeThickness = 2
};
GearCanvas.Children.Add(zeroAngleMarker);
for (int i = 0; i < TeethCount; i++) for (int i = 0; i < TeethCount; i++)
{ {
// Offset the angle to center the first tooth on the 0 angle
double angle = i * angleStep; double angle = i * angleStep;
double radianStart = (angle - toothWidthAngle / 2) * Math.PI / 180; double radianStart = (angle - toothWidthAngle / 2) * Math.PI / 180;
double radianEnd = (angle + toothWidthAngle / 2) * Math.PI / 180; double radianEnd = (angle + toothWidthAngle / 2) * Math.PI / 180;
@ -114,16 +107,14 @@ namespace CtrEditor.ObjetosSim.UserControls
Polygon tooth = new Polygon Polygon tooth = new Polygon
{ {
Fill = Brushes.Black, Stroke = Brushes.Black,
StrokeThickness = 2,
Fill = Brushes.LightGray,
Points = new PointCollection { p1, p2, p3, p4 } Points = new PointCollection { p1, p2, p3, p4 }
}; };
GearCanvas.Children.Add(tooth); GearCanvas.Children.Add(tooth);
} }
} }
} }
} }

View File

@ -1,4 +1,4 @@
<UserControl x:Class="CtrEditor.ObjetosSim.ucAnalogTag" <UserControl x:Class="CtrEditor.ObjetosSim.UserControls.ucAnalogTag"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
@ -6,7 +6,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:convert="clr-namespace:CtrEditor.Convertidores" xmlns:convert="clr-namespace:CtrEditor.Convertidores"
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim" xmlns:vm="clr-namespace:CtrEditor.ObjetosSim.UserControls"
mc:Ignorable="d"> mc:Ignorable="d">
<UserControl.Resources> <UserControl.Resources>

View File

@ -6,7 +6,7 @@ using System.Windows.Media;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
namespace CtrEditor.ObjetosSim namespace CtrEditor.ObjetosSim.UserControls
{ {
/// <summary> /// <summary>
/// Interaction logic for ucAnalogTag.xaml /// Interaction logic for ucAnalogTag.xaml
@ -32,23 +32,17 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty] [ObservableProperty]
public float tamano; public float tamano;
[ObservableProperty] [ObservableProperty]
[NotifyPropertyChangedFor(nameof(Value))]
public string tag; public string tag;
[ObservableProperty] [ObservableProperty]
public string descripcion; public string descripcion;
[ObservableProperty] [ObservableProperty]
[NotifyPropertyChangedFor(nameof(Value))]
public float min_IN_Scaled; public float min_IN_Scaled;
[ObservableProperty] [ObservableProperty]
[NotifyPropertyChangedFor(nameof(Value))]
public float max_IN_Scaled; public float max_IN_Scaled;
[ObservableProperty] [ObservableProperty]
[NotifyPropertyChangedFor(nameof(Value))]
public float min_OUT_Scaled; public float min_OUT_Scaled;
[ObservableProperty] [ObservableProperty]
[NotifyPropertyChangedFor(nameof(Value))]
public float max_OUT_Scaled; public float max_OUT_Scaled;
[ObservableProperty] [ObservableProperty]
public float value; public float value;

View File

@ -1,4 +1,4 @@
<UserControl x:Class="CtrEditor.ObjetosSim.ucBoolTag" <UserControl x:Class="CtrEditor.ObjetosSim.UserControls.ucBoolTag"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
@ -6,7 +6,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:convert="clr-namespace:CtrEditor.Convertidores" xmlns:convert="clr-namespace:CtrEditor.Convertidores"
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim" xmlns:vm="clr-namespace:CtrEditor.ObjetosSim.UserControls"
mc:Ignorable="d"> mc:Ignorable="d">
<UserControl.Resources> <UserControl.Resources>

View File

@ -4,9 +4,8 @@ using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Media; using System.Windows.Media;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using Newtonsoft.Json.Linq;
namespace CtrEditor.ObjetosSim namespace CtrEditor.ObjetosSim.UserControls
{ {
/// <summary> /// <summary>
/// Interaction logic for ucBoolTag.xaml /// Interaction logic for ucBoolTag.xaml
@ -32,12 +31,8 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty] [ObservableProperty]
private Brush color_oculto; private Brush color_oculto;
[ObservableProperty]
public bool estado;
partial void OnEstadoChanged(bool value) partial void OnEstadoChanged(bool value)
{ {
EscribirBitTag(Tag, value);
if (value) if (value)
Color_oculto = Brushes.LightGreen; Color_oculto = Brushes.LightGreen;
else else
@ -47,11 +42,12 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty] [ObservableProperty]
public float tamano; public float tamano;
[ObservableProperty] [ObservableProperty]
[NotifyPropertyChangedFor(nameof(Estado))]
public string tag; public string tag;
[ObservableProperty] [ObservableProperty]
public string descripcion; public string descripcion;
[ObservableProperty]
public bool estado;
public osBoolTag() public osBoolTag()
{ {
@ -60,6 +56,22 @@ namespace CtrEditor.ObjetosSim
Descripcion = "Nombre del Tag"; Descripcion = "Nombre del Tag";
} }
public override void UpdateGeometryStart()
{
// Se llama antes de la simulacion
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds)
{
plc.EscribirTagBool(Tag, Estado);
}
public override void UpdateControl(int elapsedMilliseconds)
{
// Calculamos la velocidad
}
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,10 +1,10 @@
<UserControl x:Class="CtrEditor.ObjetosSim.ucConsensGeneric" <UserControl x:Class="CtrEditor.ObjetosSim.UserControls.ucConsensGeneric"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" mc:Ignorable="d"
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim" xmlns:vm="clr-namespace:CtrEditor.ObjetosSim.UserControls"
xmlns:convert="clr-namespace:CtrEditor.Convertidores" xmlns:convert="clr-namespace:CtrEditor.Convertidores"
Background="LightGray"> Background="LightGray">

View File

@ -5,7 +5,7 @@ using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
namespace CtrEditor.ObjetosSim namespace CtrEditor.ObjetosSim.UserControls
{ {
/// <summary> /// <summary>
/// Interaction logic for ucConsensGeneric.xaml /// Interaction logic for ucConsensGeneric.xaml

View File

@ -28,39 +28,25 @@ namespace CtrEditor.ObjetosSim
} }
[ObservableProperty] [ObservableProperty]
private float offsetLeftSalida; public float offsetLeftSalida;
[ObservableProperty] [ObservableProperty]
private float offsetTopSalida; public float offsetTopSalida;
[ObservableProperty] [ObservableProperty]
private bool consenso; public bool consenso;
[ObservableProperty] [ObservableProperty]
private float botellas_hora; public float botellas_hora;
partial void OnBotellas_horaChanged(float value)
{
Botellas_segundo = value / 3600;
}
[ObservableProperty] [ObservableProperty]
private float botellas_segundo; public float velocidad_actual_percentual;
partial void OnBotellas_segundoChanged(float value)
{
Botellas_hora = value * 3600;
}
[ObservableProperty] [ObservableProperty]
private float velocidad_actual_percentual; public float diametro_botella;
[ObservableProperty] [ObservableProperty]
private float diametro_botella; public string tag_consenso;
[ObservableProperty] [ObservableProperty]
private string tag_consenso; public float ancho;
[ObservableProperty] [ObservableProperty]
private float ancho; public float alto;
[ObservableProperty] [ObservableProperty]
private float alto; public float angulo;
[ObservableProperty]
private float angulo;
public osFiller() public osFiller()
{ {
@ -84,7 +70,7 @@ namespace CtrEditor.ObjetosSim
TiempoRestante -= elapsedMilliseconds / 1000.0f; TiempoRestante -= elapsedMilliseconds / 1000.0f;
if (TiempoRestante <= 0) if (TiempoRestante <= 0)
{ {
TiempoRestante += 3600 / (Botellas_hora * (Velocidad_actual_percentual / 100.0f)); TiempoRestante = 3600 / (Botellas_hora * (Velocidad_actual_percentual / 100.0f));
var X = Left + OffsetLeftSalida; var X = Left + OffsetLeftSalida;
var Y = Top + OffsetTopSalida; var Y = Top + OffsetTopSalida;

View File

@ -0,0 +1,29 @@
<UserControl x:Class="CtrEditor.ObjetosSim.UserControls.ucGearEncoder"
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.UserControls"
mc:Ignorable="d"
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim.UserControls"
xmlns:convert="clr-namespace:CtrEditor.Convertidores">
<UserControl.Resources>
<convert:MeterToPixelConverter x:Key="MeterToPixelConverter"/>
</UserControl.Resources>
<UserControl.DataContext>
<vm:osGearEncoder/>
</UserControl.DataContext>
<Canvas>
<Canvas.RenderTransform>
<RotateTransform Angle="{Binding Angulo}" CenterX="0" CenterY="0"/>
</Canvas.RenderTransform>
<local:GearControl ToothWidthRatio="{Binding Ancho_Dientes}" TeethCount="{Binding Dientes}"
InnerRadius="{Binding Radio_Interno, Converter={StaticResource MeterToPixelConverter}}"
OuterRadius="{Binding Radio_Externo, Converter={StaticResource MeterToPixelConverter}}"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</Canvas>
</UserControl>

View File

@ -5,9 +5,8 @@ using System.Windows.Controls;
using System.Windows.Media; using System.Windows.Media;
using Newtonsoft.Json; using Newtonsoft.Json;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using System.Diagnostics;
namespace CtrEditor.ObjetosSim namespace CtrEditor.ObjetosSim.UserControls
{ {
/// <summary> /// <summary>
/// Interaction logic for ucGearEncoder.xaml /// Interaction logic for ucGearEncoder.xaml
@ -15,8 +14,6 @@ namespace CtrEditor.ObjetosSim
public partial class osGearEncoder : osBase, IosBase public partial class osGearEncoder : osBase, IosBase
{ {
private osBase _osMotor = null; private osBase _osMotor = null;
private Stopwatch Stopwatch = new Stopwatch();
private double stopwatch_last = 0;
// Otros datos y métodos relevantes para la simulación // Otros datos y métodos relevantes para la simulación
@ -24,7 +21,6 @@ namespace CtrEditor.ObjetosSim
{ {
return "Ruota Fonica"; return "Ruota Fonica";
} }
private string nombre = NombreClase(); private string nombre = NombreClase();
public override string Nombre public override string Nombre
{ {
@ -36,56 +32,10 @@ namespace CtrEditor.ObjetosSim
public string tag; public string tag;
[ObservableProperty] [ObservableProperty]
public bool pulso; public bool pulso;
partial void OnPulsoChanged(bool value)
{
if (value)
{
var dTime = Stopwatch.ElapsedMilliseconds - stopwatch_last;
stopwatch_last = Stopwatch.ElapsedMilliseconds;
Tiempo_Pulso = (float)dTime;
}
EscribirBitTag(Tag, Pulso);
if (value)
Color_oculto = Brushes.LightGreen;
else
Color_oculto = Brushes.Gray;
}
[ObservableProperty]
private Brush color_oculto;
[ObservableProperty] [ObservableProperty]
public float velocidadActual; public float velocidadActual;
[ObservableProperty] [ObservableProperty]
public double angulo; public float angulo;
partial void OnAnguloChanged(double value)
{
// Generar pulsos cuadrados en función del ángulo
Pulso = DetectarDiente();
}
[ObservableProperty]
public float tiempo_Pulso;
[ObservableProperty]
public float pulsos_Por_Segundo;
partial void OnPulsos_Por_SegundoChanged(float value)
{
if (VelocidadActual > 0)
Giros_segundo_a_100 = (float)((pulsos_Por_Segundo / Dientes) * 100 / VelocidadActual);
}
[ObservableProperty]
private bool homing;
partial void OnHomingChanged(bool value)
{
homing = false;
Angulo = 0;
}
[ObservableProperty] [ObservableProperty]
public float dientes; public float dientes;
[ObservableProperty] [ObservableProperty]
@ -95,7 +45,7 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty] [ObservableProperty]
public float ancho_Dientes; public float ancho_Dientes;
[ObservableProperty] [ObservableProperty]
public float giros_segundo_a_100; public float giros_segundo_a_50hz;
[ObservableProperty] [ObservableProperty]
public string motor; public string motor;
@ -104,14 +54,13 @@ namespace CtrEditor.ObjetosSim
_osMotor = ObtenerLink(Motor, typeof(osVMmotorSim)); _osMotor = ObtenerLink(Motor, typeof(osVMmotorSim));
} }
public osGearEncoder() public osGearEncoder()
{ {
Ancho_Dientes = 0.5f; Ancho_Dientes = 0.5f;
Dientes = 10; Dientes = 10;
Radio_Interno = 0.5f; Radio_Interno = 0.5f;
Radio_Externo = 0.6f; Radio_Externo = 0.6f;
Color_oculto = Brushes.Gray;
Stopwatch.Start();
} }
public override void UpdateGeometryStart() public override void UpdateGeometryStart()
@ -128,7 +77,7 @@ namespace CtrEditor.ObjetosSim
VelocidadActual = motor.Velocidad; VelocidadActual = motor.Velocidad;
// Calcular la cantidad de giros por segundo // Calcular la cantidad de giros por segundo
double girosPorSegundo = (VelocidadActual / 100.0) * Giros_segundo_a_100; double girosPorSegundo = (VelocidadActual / 50.0) * Giros_segundo_a_50hz;
// Calcular la fracción del segundo que ha pasado // Calcular la fracción del segundo que ha pasado
double segundosTranscurridos = elapsedMilliseconds / 1000.0; double segundosTranscurridos = elapsedMilliseconds / 1000.0;
@ -137,48 +86,20 @@ namespace CtrEditor.ObjetosSim
double incrementoAngulo = (girosPorSegundo * 360.0) * segundosTranscurridos; double incrementoAngulo = (girosPorSegundo * 360.0) * segundosTranscurridos;
// Actualizar el ángulo // Actualizar el ángulo
Angulo = (Angulo + incrementoAngulo) % 360; Angulo = (float)(Angulo + incrementoAngulo) % 360;
// Calcular la duración de un pulso
double duracionPulso = (360.0 / Dientes) / 2;
// Generar pulsos cuadrados en función del ángulo
Pulso = ((Angulo % (360.0 / Dientes)) < duracionPulso) ? true : false;
EscribirBitTag(Tag,Pulso);
} }
} else if (Motor.Length>0) } else if (Motor.Length>0)
_osMotor = ObtenerLink(Motor, typeof(osVMmotorSim)); _osMotor = ObtenerLink(Motor, typeof(osVMmotorSim));
} }
public bool DetectarDiente()
{
double angleStep = 360.0 / Dientes;
double halfToothWidthAngle = (angleStep * Ancho_Dientes) / 2;
// Normalize the Angulo to be within 0-360 degrees
double normalizedAngle = Angulo % 360;
if (normalizedAngle < 0) normalizedAngle += 360;
// Calculate the position of the first tooth's center at angle 0
double firstToothCenterAngle = 0;
// Calculate the angular distance from the current angle to the first tooth's center
double angularDistance = Math.Abs(firstToothCenterAngle - normalizedAngle);
if (angularDistance > 180) angularDistance = 360 - angularDistance;
// Check if the normalized angle falls within the segment of the first tooth
if (angularDistance <= halfToothWidthAngle)
{
return true;
}
// Calculate the number of steps to reach the nearest tooth's center
int steps = (int)Math.Round(normalizedAngle / angleStep);
// Calculate the angular position of the nearest tooth's center
double nearestToothCenterAngle = steps * angleStep;
// Calculate the angular distance from the current angle to the nearest tooth's center
angularDistance = Math.Abs(nearestToothCenterAngle - normalizedAngle);
if (angularDistance > 180) angularDistance = 360 - angularDistance;
// Check if the normalized angle falls within the segment of the nearest tooth
return angularDistance <= halfToothWidthAngle;
}
public override void UpdateControl(int elapsedMilliseconds) public override void UpdateControl(int elapsedMilliseconds)
{ {

View File

@ -1,11 +1,11 @@
<UserControl x:Class="CtrEditor.ObjetosSim.ucPhotocell" <UserControl x:Class="CtrEditor.ObjetosSim.UserControls.ucPhotocell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:CtrEditor.ObjetosSim.UserControls" xmlns:local="clr-namespace:CtrEditor.ObjetosSim.UserControls"
mc:Ignorable="d" mc:Ignorable="d"
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim" xmlns:vm="clr-namespace:CtrEditor.ObjetosSim.UserControls"
xmlns:convert="clr-namespace:CtrEditor.Convertidores"> xmlns:convert="clr-namespace:CtrEditor.Convertidores">
<UserControl.Resources> <UserControl.Resources>

View File

@ -7,7 +7,7 @@ using System.Windows.Media;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
namespace CtrEditor.ObjetosSim namespace CtrEditor.ObjetosSim.UserControls
{ {
/// <summary> /// <summary>
/// Interaction logic for ucPhotocell.xaml /// Interaction logic for ucPhotocell.xaml

View File

@ -20,6 +20,7 @@ namespace CtrEditor.ObjetosSim
private float _velocidadActual; private float _velocidadActual;
private osBase _osMotor = null; private osBase _osMotor = null;
private string _motor;
private simCurve Simulation_TransporteCurva; private simCurve Simulation_TransporteCurva;
@ -100,7 +101,7 @@ namespace CtrEditor.ObjetosSim
VelocidadActual = motor.Velocidad; VelocidadActual = motor.Velocidad;
} }
else else
_osMotor = ObtenerLink(Motor, typeof(osVMmotorSim)); _osMotor = ObtenerLink(_motor, typeof(osVMmotorSim));
} }
public override void ucLoaded() public override void ucLoaded()

View File

@ -30,13 +30,20 @@ namespace CtrEditor.ObjetosSim
set => SetProperty(ref nombre, value); set => SetProperty(ref nombre, value);
} }
[ObservableProperty]
private float velocidadActual; private float velocidadActual;
public float VelocidadActual
partial void OnVelocidadActualChanged(float value)
{ {
SimGeometria?.SetSpeed(value); get => velocidadActual;
ActualizarAnimacionStoryBoardTransporte(VelocidadActual); set
{
if (value != velocidadActual)
{
velocidadActual = value;
SimGeometria?.SetSpeed(value);
SetProperty(ref velocidadActual, value);
ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
}
}
} }
[ObservableProperty] [ObservableProperty]
@ -51,12 +58,6 @@ namespace CtrEditor.ObjetosSim
public float ancho; public float ancho;
[ObservableProperty] [ObservableProperty]
public float alto; public float alto;
partial void OnAltoChanged(float value)
{
ActualizarGeometrias();
}
[ObservableProperty] [ObservableProperty]
public float angulo; public float angulo;
[ObservableProperty] [ObservableProperty]
@ -80,7 +81,6 @@ namespace CtrEditor.ObjetosSim
UpdateOrCreateLine(Guia_Superior, uc.GuiaSuperior); UpdateOrCreateLine(Guia_Superior, uc.GuiaSuperior);
UpdateOrCreateLine(Guia_Inferior, uc.GuiaInferior) ; UpdateOrCreateLine(Guia_Inferior, uc.GuiaInferior) ;
SimGeometria.DistanceGuide2Guide = Alto;
SimGeometria.Speed = VelocidadActual; SimGeometria.Speed = VelocidadActual;
ActualizarAnimacionStoryBoardTransporte(VelocidadActual); ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
} }
@ -126,8 +126,6 @@ namespace CtrEditor.ObjetosSim
if (_visualRepresentation is ucTransporteGuias uc) if (_visualRepresentation is ucTransporteGuias uc)
{ {
SimGeometria = AddRectangle(simulationManager, uc.Transporte, Alto, Ancho, Angulo); SimGeometria = AddRectangle(simulationManager, uc.Transporte, Alto, Ancho, Angulo);
SimGeometria.TransportWithGuides = true;
SimGeometria.DistanceGuide2Guide = Alto;
Guia_Superior = AddLine(simulationManager, uc.GuiaSuperior); Guia_Superior = AddLine(simulationManager, uc.GuiaSuperior);
Guia_Inferior = AddLine(simulationManager, uc.GuiaInferior); Guia_Inferior = AddLine(simulationManager, uc.GuiaInferior);

View File

@ -423,6 +423,14 @@ namespace CtrEditor.ObjetosSim
} }
} }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
} }
[AttributeUsage(AttributeTargets.Property)] [AttributeUsage(AttributeTargets.Property)]

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(30) }; _timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(1) };
_timer.Tick += (s, e) => Refresh(); _timer.Tick += (s, e) => Refresh();
ConnectCommand = new RelayCommand(Connect, () => true); ConnectCommand = new RelayCommand(Connect, () => true);

View File

@ -15,7 +15,6 @@ using System.Diagnostics;
using FarseerPhysics.Dynamics.Joints; using FarseerPhysics.Dynamics.Joints;
using CtrEditor.ObjetosSim; using CtrEditor.ObjetosSim;
using System.Windows.Documents;
namespace CtrEditor.Simulacion namespace CtrEditor.Simulacion
{ {
@ -170,8 +169,6 @@ namespace CtrEditor.Simulacion
public class simTransporte : simBase public class simTransporte : simBase
{ {
public float Speed { get; set; } // Velocidad para efectos de cinta transportadora public float Speed { get; set; } // Velocidad para efectos de cinta transportadora
public float DistanceGuide2Guide { get; set; }
public bool TransportWithGuides = false;
public simTransporte(World world, float width, float height, Vector2 position, float angle = 0) public simTransporte(World world, float width, float height, Vector2 position, float angle = 0)
{ {
@ -321,7 +318,7 @@ namespace CtrEditor.Simulacion
private void Create(Vector2 position) private void Create(Vector2 position)
{ {
RemoverBody(); RemoverBody();
Body = BodyFactory.CreateCircle(_world, _radius, 0.2f, position); Body = BodyFactory.CreateCircle(_world, _radius, 1f, position);
Body.BodyType = BodyType.Dynamic; Body.BodyType = BodyType.Dynamic;
// Restablecer manejador de eventos de colisión // Restablecer manejador de eventos de colisión
@ -331,13 +328,13 @@ namespace CtrEditor.Simulacion
Body.UserData = this; // Importante para la identificación durante la colisión Body.UserData = this; // Importante para la identificación durante la colisión
// Configurar la fricción // Configurar la fricción
Body.Friction = 0.3f; // Ajustar según sea necesario para tu simulación Body.Friction = 0.5f; // Ajustar según sea necesario para tu simulación
// Configurar amortiguamiento // Configurar amortiguamiento
Body.LinearDamping = 0.4f; // Ajustar para controlar la reducción de la velocidad lineal Body.LinearDamping = 0f; // Ajustar para controlar la reducción de la velocidad lineal
Body.AngularDamping = 0.4f; // Ajustar para controlar la reducción de la velocidad angular Body.AngularDamping = 0f; // Ajustar para controlar la reducción de la velocidad angular
Body.Restitution = 0.2f; // Baja restitución para menos rebote Body.Restitution = 0.2f; // Baja restitución para menos rebote
// Body.IsBullet = true; Body.IsBullet = true;
} }
public void SetDiameter(float diameter) public void SetDiameter(float diameter)
@ -397,11 +394,7 @@ namespace CtrEditor.Simulacion
float porcentajeCompartido = InterseccionCirculoRectangulo.CalcularSuperficieCompartida(vertices, centroCirculo, radio); float porcentajeCompartido = InterseccionCirculoRectangulo.CalcularSuperficieCompartida(vertices, centroCirculo, radio);
// Aplicar el efecto del transportador usando el porcentaje calculado // Aplicar el efecto del transportador usando el porcentaje calculado
if (conveyor.TransportWithGuides)
if (conveyor.DistanceGuide2Guide <= radio * 2)
CenterFixtureOnConveyor(fixtureA, conveyor);
ApplyConveyorEffect(conveyor, fixtureA, porcentajeCompartido); ApplyConveyorEffect(conveyor, fixtureA, porcentajeCompartido);
} }
return true; // No aplicar respuestas físicas return true; // No aplicar respuestas físicas
} }
@ -414,41 +407,6 @@ namespace CtrEditor.Simulacion
Vector2 desiredVelocity = new Vector2((float)Math.Cos(conveyor.Body.Rotation), (float)Math.Sin(conveyor.Body.Rotation)) * speedMetersPerSecond; Vector2 desiredVelocity = new Vector2((float)Math.Cos(conveyor.Body.Rotation), (float)Math.Sin(conveyor.Body.Rotation)) * speedMetersPerSecond;
circleFixture.Body.LinearVelocity += desiredVelocity * porcentajeCompartido; circleFixture.Body.LinearVelocity += desiredVelocity * porcentajeCompartido;
} }
private void CenterFixtureOnConveyor(Fixture fixtureA, simTransporte conveyor)
{
// Obtener el centro del conveyor
Vector2 conveyorCenter = conveyor.Body.Position;
// Calcular el vector de la línea horizontal centrada de conveyor
float halfDistance = conveyor.DistanceGuide2Guide / 2;
float cos = (float)Math.Cos(conveyor.Body.Rotation);
float sin = (float)Math.Sin(conveyor.Body.Rotation);
Vector2 offset = new Vector2(halfDistance * cos, halfDistance * sin);
// Línea horizontal centrada de conveyor en el espacio del mundo
Vector2 lineStart = conveyorCenter - offset;
Vector2 lineEnd = conveyorCenter + offset;
// Proyectar el centro de fixtureA sobre la línea horizontal
Vector2 fixtureCenter = fixtureA.Body.Position;
Vector2 closestPoint = ProjectPointOntoLine(fixtureCenter, lineStart, lineEnd);
// Mover fixtureA al punto más cercano en la línea horizontal
fixtureA.Body.Position = closestPoint;
}
private Vector2 ProjectPointOntoLine(Vector2 point, Vector2 lineStart, Vector2 lineEnd)
{
Vector2 lineDirection = lineEnd - lineStart;
lineDirection.Normalize();
Vector2 pointToLineStart = point - lineStart;
float projectionLength = Vector2.Dot(pointToLineStart, lineDirection);
return lineStart + projectionLength * lineDirection;
}
} }
public class SimulationManagerFP public class SimulationManagerFP
@ -457,8 +415,7 @@ namespace CtrEditor.Simulacion
private Canvas simulationCanvas; private Canvas simulationCanvas;
public List<simBase> Cuerpos; public List<simBase> Cuerpos;
private Stopwatch stopwatch; public Stopwatch stopwatch;
private double stopwatch_last;
public Canvas DebugCanvas { get => simulationCanvas; set => simulationCanvas = value; } public Canvas DebugCanvas { get => simulationCanvas; set => simulationCanvas = value; }
@ -467,7 +424,6 @@ namespace CtrEditor.Simulacion
world = new World(new Vector2(0, 0)); // Vector2.Zero world = new World(new Vector2(0, 0)); // Vector2.Zero
Cuerpos = new List<simBase>(); Cuerpos = new List<simBase>();
stopwatch = new Stopwatch(); stopwatch = new Stopwatch();
stopwatch.Start();
} }
public void Clear() public void Clear()
@ -481,8 +437,11 @@ namespace CtrEditor.Simulacion
public void Step() public void Step()
{ {
// Detener el cronómetro y obtener el tiempo transcurrido en milisegundos // Detener el cronómetro y obtener el tiempo transcurrido en milisegundos
float elapsedMilliseconds = (float) (stopwatch.Elapsed.TotalMilliseconds - stopwatch_last); stopwatch.Stop();
stopwatch_last = stopwatch.Elapsed.TotalMilliseconds; float elapsedMilliseconds = (float)stopwatch.Elapsed.TotalMilliseconds;
// Reiniciar el cronómetro para la próxima medición
stopwatch.Restart();
// Pasar el tiempo transcurrido al método Step // Pasar el tiempo transcurrido al método Step
world.Step(elapsedMilliseconds / 1000.0f); world.Step(elapsedMilliseconds / 1000.0f);