diff --git a/MainViewModel.cs b/MainViewModel.cs index f74c6c3..0c70a4f 100644 --- a/MainViewModel.cs +++ b/MainViewModel.cs @@ -133,6 +133,9 @@ namespace CtrEditor private void OnTickSimulacion(object sender, EventArgs e) { + foreach (var objetoSimulable in ObjetosSimulables) + objetoSimulable.UpdateGeometry(); + simulationManager.Step((float)_timerSimulacion.Interval.TotalMilliseconds); foreach (var objetoSimulable in ObjetosSimulables) diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index db1e473..fe2acc2 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -170,6 +170,7 @@ namespace CtrEditor PositionAngleDisplay(userControl); _angleDisplayTextBlock.Visibility = Visibility.Visible; + Canvas.SetZIndex(_angleDisplayTextBlock, 15); } // TAMANO else if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) diff --git a/ObjetosSim/osBase.cs b/ObjetosSim/osBase.cs index 61921d5..f3bc049 100644 --- a/ObjetosSim/osBase.cs +++ b/ObjetosSim/osBase.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Text; using System.Text.Json.Serialization; using System.Threading.Tasks; +using System.Windows; using System.Windows.Controls; using System.Windows.Data; using static System.Runtime.InteropServices.JavaScript.JSType; @@ -46,7 +47,8 @@ namespace CtrEditor.ObjetosSim public abstract string Nombre { get; set; } public abstract void ConnectSimManager(SimulationManager simulationManager); - public abstract void UpdateControl(); + public abstract void UpdateControl(); + public abstract void UpdateGeometry(); [JsonIgnore] public UserControl? VisualRepresentation @@ -58,13 +60,26 @@ namespace CtrEditor.ObjetosSim public void CanvasSetLeftinMeter(float left) { if (_visualRepresentation != null) - Canvas.SetLeft(_visualRepresentation, PixelToMeter.Instance.calc.MetersToPixels(left)); + Canvas.SetLeft(_visualRepresentation, PixelToMeter.Instance.calc.MetersToPixels(left)); } + public float CanvasGetLeftinMeter() + { + if (_visualRepresentation != null) + return PixelToMeter.Instance.calc.PixelsToMeters((float)Canvas.GetLeft(_visualRepresentation)); + else return 0f; + } + public void CanvasSetTopinMeter(float top) { if (_visualRepresentation != null) Canvas.SetTop(_visualRepresentation, PixelToMeter.Instance.calc.MetersToPixels(top)); } + public float CanvasGetTopinMeter() + { + if (_visualRepresentation != null) + return PixelToMeter.Instance.calc.PixelsToMeters((float)Canvas.GetTop(_visualRepresentation)); + else return 0f; + } public event PropertyChangedEventHandler PropertyChanged; @@ -100,32 +115,43 @@ namespace CtrEditor.ObjetosSim public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { float meters = (float)value; - return PixelToMeter.Instance.calc.MetersToPixels(meters); + float factor = 1; + if (parameter != null) + if (parameter.ToString() == "0.5") factor = 0.5f; + else if (parameter.ToString() == "-0.5") factor = -0.5f; + + return PixelToMeter.Instance.calc.MetersToPixels(meters) * factor; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { float pixels = (float)value; - return PixelToMeter.Instance.calc.PixelsToMeters(pixels); + float factor = 1; + if (parameter != null) + if (parameter.ToString() == "0.5") factor = 0.5f; + else if (parameter.ToString() == "-0.5") factor = -0.5f; + + return PixelToMeter.Instance.calc.PixelsToMeters(pixels) * factor; } } - public class MeterToPixelConverterDbl : IValueConverter + public class DistanceToMarginConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { - double meters = (double)value; - return (double)PixelToMeter.Instance.calc.MetersToPixels((float)meters); + if (value is double distance) + { + return new Thickness(0, 0, 0, PixelToMeter.Instance.calc.MetersToPixels((float)distance)); // Ajustar Bottom a 'distance' + } + return new Thickness(); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { - double pixels = (double)value; - return PixelToMeter.Instance.calc.PixelsToMeters((float)pixels); + throw new NotSupportedException("ConvertBack is not supported."); } } - public class UnitConverter { // La escala representa cuántos metros hay en un píxel diff --git a/ObjetosSim/ucBotella.xaml.cs b/ObjetosSim/ucBotella.xaml.cs index f44d859..9e85c9f 100644 --- a/ObjetosSim/ucBotella.xaml.cs +++ b/ObjetosSim/ucBotella.xaml.cs @@ -100,6 +100,11 @@ namespace CtrEditor.ObjetosSim { simulationManager.circles.Add(Geometria); } + public override void UpdateGeometry() + { + // Se llama antes de la simulacion + + } public override void UpdateControl() { diff --git a/ObjetosSim/ucGuia.xaml.cs b/ObjetosSim/ucGuia.xaml.cs index 9ffe27f..144892c 100644 --- a/ObjetosSim/ucGuia.xaml.cs +++ b/ObjetosSim/ucGuia.xaml.cs @@ -97,6 +97,10 @@ namespace CtrEditor.ObjetosSim { simulationManager.lines.Add(Geometria); } + public override void UpdateGeometry() + { + // Se llama antes de la simulacion + } public override void UpdateControl() { } diff --git a/ObjetosSim/ucTransporteGuias.xaml b/ObjetosSim/ucTransporteGuias.xaml index 63e8b2b..02a5d3e 100644 --- a/ObjetosSim/ucTransporteGuias.xaml +++ b/ObjetosSim/ucTransporteGuias.xaml @@ -4,28 +4,25 @@ 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" - d:DesignHeight="300" d:DesignWidth="300"> + mc:Ignorable="d"> + - + - - - - - - - - - - - - - - - + + + + + + + + + + diff --git a/ObjetosSim/ucTransporteGuias.xaml.cs b/ObjetosSim/ucTransporteGuias.xaml.cs index 380a594..a5640d3 100644 --- a/ObjetosSim/ucTransporteGuias.xaml.cs +++ b/ObjetosSim/ucTransporteGuias.xaml.cs @@ -26,25 +26,32 @@ namespace CtrEditor.ObjetosSim private float velMax50hz; // en metros por minuto private float tiempoRampa; private bool esMarcha; + private double _distance; + private float altoGuia; - private Rectangle Geometria = new Rectangle(); + private float left; + private float top; + + private Rectangle TransporteCentral = new Rectangle(); + private Line Guia_Superior = new Line(); + private Line Guia_Inferior = new Line(); public override float Left { - get => Geometria.Left; + get => left; set { - Geometria.Left = value; + left = value; CanvasSetLeftinMeter(value); OnPropertyChanged(nameof(Left)); } } public override float Top { - get => Geometria.Top; + get => top; set { - Geometria.Top = value; + top = value; CanvasSetTopinMeter(value); OnPropertyChanged(nameof(Top)); } @@ -52,42 +59,65 @@ namespace CtrEditor.ObjetosSim public float Ancho { - get => Geometria.Length; + get => TransporteCentral.Length; set { - Geometria.Length = value; + TransporteCentral.Length = value; OnPropertyChanged(nameof(Ancho)); } } - public float Alto + public float AltoGuia { - get => Geometria.Width; + get => altoGuia; set { - Geometria.Width = value; + altoGuia = value; + OnPropertyChanged(nameof(AltoGuia)); + } + } + + public float Alto + { + get => TransporteCentral.Width; + set + { + TransporteCentral.Width = value; OnPropertyChanged(nameof(Alto)); } } public float Angulo { - get => Geometria.Angle; + get => TransporteCentral.Angle; set { - Geometria.Angle = value; + TransporteCentral.Angle = value; OnPropertyChanged(nameof(Angulo)); } } public float VelocidadActual { - get => Geometria.Speed; + get => TransporteCentral.Speed; set { - Geometria.Speed = value; + TransporteCentral.Speed = value; OnPropertyChanged(nameof(VelocidadActual)); } } + public double Distance + { + get { return _distance; } + set + { + if (_distance != value) + { + _distance = value; + OnPropertyChanged("Distance"); + } + } + } + public override string Nombre { get => _nombre; @@ -101,6 +131,48 @@ namespace CtrEditor.ObjetosSim } } + private void ActualizarGeometrias() + { + ucTransporteGuias ucTG = (ucTransporteGuias)_visualRepresentation; + if (ucTG != null) + { + var _canvasLeft = CanvasGetLeftinMeter(); + var _canvasTop = CanvasGetTopinMeter(); + + var coordenadas = GetRectangleCoordinatesInMeter(ucTG.Transporte, ucTG); + TransporteCentral.Left = coordenadas.Left + _canvasLeft; + TransporteCentral.Top = coordenadas.Top + _canvasTop; + + coordenadas = GetRectangleCoordinatesInMeter(ucTG.GuiaSuperior, ucTG); + Guia_Superior.Left = coordenadas.Left + _canvasLeft; + Guia_Superior.Top = coordenadas.Top + _canvasTop; ; + + coordenadas = GetRectangleCoordinatesInMeter(ucTG.GuiaInferior, ucTG); + Guia_Inferior.Left = coordenadas.Left + _canvasLeft; + Guia_Inferior.Top = coordenadas.Top + _canvasTop; ; + + TransporteCentral.Angle = Guia_Superior.Angle = Guia_Inferior.Angle = Angulo; + Guia_Superior.Length = Guia_Inferior.Length = Ancho; + } + } + + private (float Left, float Top) GetRectangleCoordinatesInMeter(System.Windows.Shapes.Rectangle rect, ucTransporteGuias ucTG) + { + if (rect != null) + { + // Obtiene la transformada del objeto visual + GeneralTransform transform = rect.TransformToAncestor(ucTG); + + // Obtiene la posición absoluta + Point topLeft = transform.Transform(new Point(0, 0)); + //Point bottomRight = transform.Transform(new Point(rect.ActualWidth, rect.ActualHeight)); + return (PixelToMeter.Instance.calc.PixelsToMeters((float)topLeft.X), PixelToMeter.Instance.calc.PixelsToMeters((float)topLeft.Y)); + } + else return (0,0); + } + + + public float FrictionCoefficient { get => frictionCoefficient; set => frictionCoefficient = value; } public float VelMax50hz { get => velMax50hz; set => velMax50hz = value; } public float TiempoRampa { get => tiempoRampa; set => tiempoRampa = value; } @@ -110,16 +182,27 @@ namespace CtrEditor.ObjetosSim { Ancho = 1; Alto = 0.10f; + AltoGuia = 0.03f; + Distance = 0.01f; } public override void ConnectSimManager(SimulationManager simulationManager) { - simulationManager.rectangles.Add(Geometria); + simulationManager.rectangles.Add(TransporteCentral); + simulationManager.lines.Add(Guia_Superior); + simulationManager.lines.Add(Guia_Inferior); } + public override void UpdateGeometry() + { + // Se llama antes de la simulacion + ActualizarGeometrias(); + } + public override void UpdateControl() { } + } public partial class ucTransporteGuias : UserControl, IDataContainer diff --git a/ObjetosSim/ucTransporteTTop.xaml b/ObjetosSim/ucTransporteTTop.xaml index 94af971..bc0b4d2 100644 --- a/ObjetosSim/ucTransporteTTop.xaml +++ b/ObjetosSim/ucTransporteTTop.xaml @@ -9,13 +9,13 @@ - - + + - - - - + + + + diff --git a/ObjetosSim/ucTransporteTTop.xaml.cs b/ObjetosSim/ucTransporteTTop.xaml.cs index 4946856..0c5647b 100644 --- a/ObjetosSim/ucTransporteTTop.xaml.cs +++ b/ObjetosSim/ucTransporteTTop.xaml.cs @@ -118,6 +118,12 @@ namespace CtrEditor.ObjetosSim { simulationManager.rectangles.Add(Geometria); } + public override void UpdateGeometry() + { + // Se llama antes de la simulacion + + } + public override void UpdateControl() { } diff --git a/Siemens/PLCControl.xaml.cs b/Siemens/PLCControl.xaml.cs index d5e035d..d20f2f4 100644 --- a/Siemens/PLCControl.xaml.cs +++ b/Siemens/PLCControl.xaml.cs @@ -5,6 +5,7 @@ using System.ComponentModel; using System.Linq; using System.Runtime.CompilerServices; using System.Text; +using System.Text.Json.Serialization; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; @@ -84,6 +85,7 @@ namespace CtrEditor.Siemens } } + [JsonIgnore] public ICommand ConnectCommand { get; } public ICommand DisconnectCommand { get; } public string LastError diff --git a/Simulacion/GeometrySimulator.cs b/Simulacion/GeometrySimulator.cs index 58a79a1..6a32261 100644 --- a/Simulacion/GeometrySimulator.cs +++ b/Simulacion/GeometrySimulator.cs @@ -102,6 +102,16 @@ public class Circle Speed = movementVector.Length(); AngleofMovement = PolarAngleFromVector(movementVector); } + + // Ajustar por superposición con otros círculos + foreach (var other in circles) + { + if (this != other && IsColliding(this, other)) + { + AdjustForOverlap(other); + } + } + } Vector2 GetCircleCenter(Circle circle)