Compare commits

..

No commits in common. "b224070690b08a97c6814b642497bbead449b035" and "56a2e994a2be7348c84a11921e5031923ce0156c" have entirely different histories.

10 changed files with 113 additions and 515 deletions

View File

@ -38,7 +38,6 @@ namespace CtrEditor.Convertidores
if (parameter != null) if (parameter != null)
if (parameter.ToString() == "0.5") factor = 0.5f; if (parameter.ToString() == "0.5") factor = 0.5f;
else if (parameter.ToString() == "-0.5") factor = -0.5f; else if (parameter.ToString() == "-0.5") factor = -0.5f;
else if (parameter.ToString() == "1.5") factor = 1.5f;
return PixelToMeter.Instance.calc.MetersToPixels(meters) * factor; return PixelToMeter.Instance.calc.MetersToPixels(meters) * factor;
} }
@ -50,7 +49,6 @@ namespace CtrEditor.Convertidores
if (parameter != null) if (parameter != null)
if (parameter.ToString() == "0.5") factor = 0.5f; if (parameter.ToString() == "0.5") factor = 0.5f;
else if (parameter.ToString() == "-0.5") factor = -0.5f; else if (parameter.ToString() == "-0.5") factor = -0.5f;
else if (parameter.ToString() == "1.5") factor = 1.5f;
return PixelToMeter.Instance.calc.PixelsToMeters(pixels) * factor; return PixelToMeter.Instance.calc.PixelsToMeters(pixels) * factor;
} }

View File

@ -58,7 +58,6 @@ namespace CtrEditor
// Inicializa el PLCViewModel // Inicializa el PLCViewModel
_plcViewModelData = new PLCViewModel(); _plcViewModelData = new PLCViewModel();
_plcViewModelData.RefreshEvent += OnRefreshEvent;
InitializeTipoSimulableList(); InitializeTipoSimulableList();
@ -131,37 +130,30 @@ namespace CtrEditor
simulationManager.Debug_DrawInitialBodies(); simulationManager.Debug_DrawInitialBodies();
_timerSimulacion.Start(); _timerSimulacion.Start();
simulationManager.stopwatch.Start();
} }
private void StopSimulation() private void StopSimulation()
{ {
_timerSimulacion.Stop(); _timerSimulacion.Stop();
simulationManager.stopwatch.Stop();
} }
private void OnTickSimulacion(object sender, EventArgs e) private void OnTickSimulacion(object sender, EventArgs e)
{ {
foreach (var objetoSimulable in ObjetosSimulables) foreach (var objetoSimulable in ObjetosSimulables)
{
if (_plcViewModelData.IsConnected)
objetoSimulable.UpdatePLC(_plcViewModelData.PLCInterface);
objetoSimulable.UpdateGeometryStep(); objetoSimulable.UpdateGeometryStep();
}
simulationManager.Step(); simulationManager.Step((float)_timerSimulacion.Interval.TotalMilliseconds);
foreach (var objetoSimulable in ObjetosSimulables) foreach (var objetoSimulable in ObjetosSimulables)
objetoSimulable.UpdateControl(); objetoSimulable.UpdateControl();
} }
private void OnRefreshEvent(object sender, EventArgs e)
{
foreach (var objetoSimulable in ObjetosSimulables)
{
if (_plcViewModelData.IsConnected)
objetoSimulable.UpdatePLC(_plcViewModelData.PLCInterface);
}
}
//protected virtual void OnTickSimulacion(TickSimulacionEventArgs e) //protected virtual void OnTickSimulacion(TickSimulacionEventArgs e)
//{ //{
// TickSimulacion?.Invoke(this, e); // TickSimulacion?.Invoke(this, e);
@ -293,7 +285,6 @@ namespace CtrEditor
try try
{ {
ObjetosSimulables.Clear(); ObjetosSimulables.Clear();
simulationManager.Clear();
if (_selectedImage != null) if (_selectedImage != null)
{ {
string jsonPath = datosDeTrabajo.ObtenerPathImagenConExtension(_selectedImage, ".json"); string jsonPath = datosDeTrabajo.ObtenerPathImagenConExtension(_selectedImage, ".json");

View File

@ -3,9 +3,8 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Siemens="clr-namespace:CtrEditor.Siemens" xmlns:Siemens="clr-namespace:CtrEditor.Siemens" x:Class="CtrEditor.MainWindow"
xmlns:convert="clr-namespace:CtrEditor.Convertidores" xmlns:convert="clr-namespace:CtrEditor.Convertidores"
xmlns:ObjetosSim="clr-namespace:CtrEditor.ObjetosSim" x:Class="CtrEditor.MainWindow"
Height="900" Width="1600" Height="900" Width="1600"
ResizeMode="CanResize" Title="{Binding directorioTrabajo}"> ResizeMode="CanResize" Title="{Binding directorioTrabajo}">

View File

@ -19,8 +19,6 @@ using Label = System.Windows.Controls.Label;
using MouseEventArgs = System.Windows.Input.MouseEventArgs; using MouseEventArgs = System.Windows.Input.MouseEventArgs;
using TextBox = System.Windows.Controls.TextBox; 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 Orientation = System.Windows.Controls.Orientation;
//using OpenCvSharp; //using OpenCvSharp;
@ -418,73 +416,41 @@ namespace CtrEditor
foreach (var property in properties) foreach (var property in properties)
{ {
var grid = new Grid(); if (property.PropertyType == typeof(float) || property.PropertyType == typeof(string))
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
var label = new Label
{ {
Content = property.Name + ":", var label = new Label { Content = property.Name };
Margin = new Thickness(0, 0, 5, 0), var textBox = new TextBox { Width = 200, Margin = new Thickness(0) };
VerticalAlignment = VerticalAlignment.Center
};
if (property.PropertyType == typeof(float) || property.PropertyType == typeof(string) || property.PropertyType == typeof(int))
{
var textBox = new TextBox
{
Margin = new Thickness(0),
MinWidth = 200,
VerticalContentAlignment = VerticalAlignment.Center
};
var binding = new Binding(property.Name) var binding = new Binding(property.Name)
{ {
Source = selectedObject, Source = selectedObject,
Mode = BindingMode.TwoWay, Mode = BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.LostFocus UpdateSourceTrigger = UpdateSourceTrigger.LostFocus, // Actualizar solo al perder el foco
//Converter = (FloatToFormattedStringConverter)Resources["floatFormatter"] // Usar el convertidor
}; };
// Aplicar el convertidor solo a propiedades float
if (property.PropertyType == typeof(float)) if (property.PropertyType == typeof(float))
{ {
binding.Converter = (FloatToFormattedStringConverter)Resources["floatFormatter"]; textBox.SetBinding(TextBox.TextProperty, binding);
}
else
{
textBox.SetBinding(TextBox.TextProperty, new Binding(property.Name)
{
Source = selectedObject,
Mode = BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.LostFocus
});
} }
textBox.SetBinding(TextBox.TextProperty, binding); PanelEdicion.Children.Add(label);
PanelEdicion.Children.Add(textBox);
Grid.SetColumn(label, 0);
Grid.SetColumn(textBox, 1);
grid.Children.Add(label);
grid.Children.Add(textBox);
} }
else if (property.PropertyType == typeof(bool))
{
var checkBox = new CheckBox
{
Margin = new Thickness(5, 0, 0, 0),
VerticalAlignment = VerticalAlignment.Center
};
var binding = new Binding(property.Name)
{
Source = selectedObject,
Mode = BindingMode.TwoWay
};
checkBox.SetBinding(CheckBox.IsCheckedProperty, binding);
Grid.SetColumn(label, 0);
Grid.SetColumn(checkBox, 1);
grid.Children.Add(label);
grid.Children.Add(checkBox);
}
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

@ -25,8 +25,6 @@ namespace CtrEditor.ObjetosSim
// return new ucTransporteCurva(); // return new ucTransporteCurva();
if (tipoObjeto == typeof(osVMmotorSim )) if (tipoObjeto == typeof(osVMmotorSim ))
return new ucVMmotorSim(); return new ucVMmotorSim();
if (tipoObjeto == typeof(osBoton))
return new ucBoton();
// Puedes añadir más condiciones para otros tipos // Puedes añadir más condiciones para otros tipos
@ -47,8 +45,6 @@ namespace CtrEditor.ObjetosSim
// return new osTransporteCurva(); // return new osTransporteCurva();
if (tipoObjeto == typeof(osVMmotorSim)) if (tipoObjeto == typeof(osVMmotorSim))
return new osVMmotorSim(); return new osVMmotorSim();
if (tipoObjeto == typeof(osBoton))
return new osBoton();
// Puedes añadir más condiciones para otros tipos // Puedes añadir más condiciones para otros tipos

View File

@ -1,49 +0,0 @@
<UserControl x:Class="CtrEditor.ObjetosSim.ucBoton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:ei="http://schemas.microsoft.com/xaml/behaviors"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:convert="clr-namespace:CtrEditor.Convertidores"
mc:Ignorable="d">
<UserControl.Resources>
<convert:MeterToPixelConverter x:Key="MeterToPixelConverter"/>
</UserControl.Resources>
<Grid>
<Rectangle x:Name="BackgroundRectangle"
Fill="LightGray"
Width="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}"
Height="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=1.5}"
VerticalAlignment="Top"
HorizontalAlignment="Left"
/>
<Button Content="Button"
Width="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}"
Height="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}"
Background="{Binding Color}"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
MouseLeftButtonDown="Button_MouseLeftButtonDown"
MouseLeftButtonUp="Button_MouseLeftButtonUp">
<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>
</UserControl>

View File

@ -1,216 +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 ucBoton.xaml
/// </summary>
public class osBoton : osBase
{
// Otros datos y métodos relevantes para la simulación
private string _nombre = "Boton";
private float _tamano;
private float _left;
private float _top;
private bool _estado;
private string _tag;
private Brush _color;
public Brush Color
{
get => _color;
set
{
_color = value;
OnPropertyChanged(nameof(Color));
}
}
public ICommand ButtonClickCommand { get; }
public ICommand ButtonDownCommand { get; }
public ICommand ButtonUpCommand { get; }
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 Tamano
{
get => _tamano;
set
{
_tamano = value;
OnPropertyChanged(nameof(Tamano));
}
}
public bool Estado
{
get => _estado;
set
{
_estado = value;
OnPropertyChanged(nameof(Estado));
}
}
public override string Nombre
{
get => _nombre;
set
{
if (_nombre != value)
{
_nombre = value;
OnPropertyChanged(nameof(Nombre));
}
}
}
public string Tag
{
get => _tag;
set
{
if (_tag != value)
{
_tag = value;
OnPropertyChanged(nameof(Tag));
}
}
}
private void OnButtonClick()
{
// Handle the click event here
// Example: Change color on click
Color = Brushes.LightGreen;
}
private void OnButtonDown()
{
Estado = true;
}
private void OnButtonUp()
{
Estado = false;
}
public osBoton()
{
Tamano = 0.30f;
Estado = false;
Tag = "M50.0";
// Set initial color
Color = Brushes.LightBlue;
// Initialize the command
ButtonClickCommand = new RelayCommand(OnButtonClick);
ButtonDownCommand = new RelayCommand(OnButtonDown);
ButtonUpCommand = new RelayCommand(OnButtonUp);
}
public override void UpdateGeometryStart()
{
// Se llama antes de la simulacion
}
public override void UpdateGeometryStep()
{
}
public override void UpdatePLC(PLCModel plc)
{
plc.EscribirTagBool(Tag, Estado);
}
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 ucBoton : UserControl, IDataContainer
{
public osBase? Datos { get; set; }
public ucBoton()
{
InitializeComponent();
this.Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
Datos?.ucLoaded();
}
private void Button_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (Datos is osBoton osBotonData)
{
osBotonData.ButtonDownCommand.Execute(null);
Mouse.Capture((UIElement)sender);
}
}
private void Button_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (Datos is osBoton osBotonData)
{
osBotonData.ButtonUpCommand.Execute(null);
Mouse.Capture(null); // Release mouse capture
}
}
public void Resize(float width, float height) { }
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) { }
public void Highlight(bool State) { }
public int ZIndex()
{
return 10;
}
}
}

View File

@ -21,25 +21,9 @@ namespace CtrEditor.ObjetosSim
/// <summary> /// <summary>
/// Interaction logic for ucVMmotorSim.xaml /// Interaction logic for ucVMmotorSim.xaml
/// </summary> /// </summary>
///
public class VMSimMotor
{
public bool _STATUS_VFD_Ready;
public float STATUS_VFD_ACT_Speed_Hz;
public bool Motor_Running;
public bool STATUS_VFD_Trip;
public bool STATUS_VFD_Warning;
public bool STATUS_VFD_Coasting;
public bool OUT_Run;
public bool OUT_Stop;
public bool OUT_Reversal;
public float OUT_OUT_VFD_REQ_Speed_Hz;
}
public class osVMmotorSim : osBase public class osVMmotorSim : osBase
{ {
// Otros datos y métodos relevantes para la simulación // Otros datos y métodos relevantes para la simulación
@ -47,12 +31,7 @@ namespace CtrEditor.ObjetosSim
private float _tamano; private float _tamano;
private float _left; private float _left;
private float _top; private float _top;
private int _numeroMotor; private float _numeroMotor;
private float _ratio;
private float _velocidad;
private bool _encendido;
public VMSimMotor motState = new VMSimMotor();
public float Tamano public float Tamano
{ {
@ -64,17 +43,7 @@ namespace CtrEditor.ObjetosSim
} }
} }
public bool Encendido public float PLC_NumeroMotor
{
get => _encendido;
set
{
_encendido = value;
OnPropertyChanged(nameof(Encendido));
}
}
public int PLC_NumeroMotor
{ {
get => _numeroMotor; get => _numeroMotor;
set set
@ -119,22 +88,6 @@ namespace CtrEditor.ObjetosSim
} }
} }
public float Ratio {
get => _ratio;
set {
_ratio = value;
OnPropertyChanged(nameof(Ratio));
}
}
public float Velocidad {
get => _velocidad;
set {
_velocidad = value;
OnPropertyChanged(nameof(Velocidad));
}
}
public osVMmotorSim() public osVMmotorSim()
{ {
Tamano = 0.30f; Tamano = 0.30f;
@ -149,49 +102,7 @@ namespace CtrEditor.ObjetosSim
public override void UpdateGeometryStep() public override void UpdateGeometryStep()
{ {
} }
public override void UpdatePLC(PLCModel plc) { public override void UpdatePLC(PLCModel plc) { }
var index = 0;
switch (PLC_NumeroMotor)
{
case < 100:
index = (int)PLC_NumeroMotor-30+300;
break;
}
motState.OUT_Run = plc.LeerTagBool($"\"DB MotorSimulate\".Motors[{index}].OUT.Run");
motState.OUT_Reversal = plc.LeerTagBool($"\"DB MotorSimulate\".Motors[{index}].OUT.\"Reversal Direction\"");
motState.OUT_OUT_VFD_REQ_Speed_Hz = (float)plc.LeerTagInt16($"\"DB MotorSimulate\".Motors[{index}].OUT.OUT_VFD_REQ_Speed_Hz");
if (Encendido)
{
motState._STATUS_VFD_Ready = true;
motState.Motor_Running = true;
motState.STATUS_VFD_Trip = false;
motState.STATUS_VFD_Warning = false;
motState.STATUS_VFD_Coasting = false;
if (motState.STATUS_VFD_ACT_Speed_Hz < motState.OUT_OUT_VFD_REQ_Speed_Hz)
motState.STATUS_VFD_ACT_Speed_Hz += motState.OUT_OUT_VFD_REQ_Speed_Hz / 375 ; // Simulate Ramp
} else
{
motState._STATUS_VFD_Ready = false;
motState.Motor_Running = false;
motState.STATUS_VFD_Trip = true;
motState.STATUS_VFD_Warning = false;
motState.STATUS_VFD_Coasting = false;
if (motState.STATUS_VFD_ACT_Speed_Hz > 0)
motState.STATUS_VFD_ACT_Speed_Hz -= 1; // Simulate Ramp
}
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_Ready", motState._STATUS_VFD_Ready);
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].Motor_Running", motState.Motor_Running);
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_Trip", motState.STATUS_VFD_Trip);
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_Warning", motState.STATUS_VFD_Warning);
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_Coasting", motState.STATUS_VFD_Coasting);
plc.EscribirTagInt16($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_ACT_Speed_Hz",(int)motState.STATUS_VFD_ACT_Speed_Hz);
Velocidad = motState.STATUS_VFD_ACT_Speed_Hz/10;
}
public override void UpdateControl() public override void UpdateControl()
{ {
@ -212,11 +123,6 @@ namespace CtrEditor.ObjetosSim
public ucVMmotorSim() public ucVMmotorSim()
{ {
InitializeComponent(); InitializeComponent();
this.Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
Datos?.ucLoaded();
} }
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

@ -36,8 +36,6 @@ namespace CtrEditor.Siemens
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
public event EventHandler RefreshEvent;
public PLCViewModel() public PLCViewModel()
{ {
IsConnected = false; IsConnected = false;
@ -121,6 +119,7 @@ namespace CtrEditor.Siemens
private void Instance_OnSoftwareConfigurationChanged(IInstance instance, SOnSoftwareConfigChangedParameter event_param) private void Instance_OnSoftwareConfigurationChanged(IInstance instance, SOnSoftwareConfigChangedParameter event_param)
{ {
PLCInterface.UpdateTagList(); PLCInterface.UpdateTagList();
} }
private void Disconnect() private void Disconnect()
@ -135,12 +134,10 @@ namespace CtrEditor.Siemens
{ {
if (PLCInterface.Instance != null) if (PLCInterface.Instance != null)
{ {
CpuTime = PLCInterface.LeerTagInt16("\"DB HMI\".CPU_Scan_Time")?.ToString() ?? "N/A";
CpuTime = PLCInterface.LeerInt16("\"DB HMI\".CPU_Scan_Time")?.ToString() ?? "N/A";
LastError = PLCInterface.LastError; LastError = PLCInterface.LastError;
} }
// Disparar el evento RefreshEvent
RefreshEvent?.Invoke(this, EventArgs.Empty);
} }
private void OnPropertyChanged([CallerMemberName] string propertyName = null) private void OnPropertyChanged([CallerMemberName] string propertyName = null)
@ -205,18 +202,6 @@ namespace CtrEditor.Siemens
LastError = pTag + ":" + ex.Message; LastError = pTag + ":" + ex.Message;
} }
} }
public void EscribirTagInt16(string pTag, int pValue)
{
try
{
Instance?.WriteInt16(pTag,(short) pValue);
}
catch (Exception ex)
{
LastError = pTag + ":" + ex.Message;
}
}
public bool LeerTagBool(string pTag) public bool LeerTagBool(string pTag)
{ {
try try
@ -230,7 +215,7 @@ namespace CtrEditor.Siemens
} }
} }
public int? LeerTagInt16(string pTag) public int? LeerInt16(string pTag)
{ {
try try
{ {

View File

@ -1,20 +1,31 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.DirectoryServices;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Shapes; using System.Windows.Shapes;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories;
using FarseerPhysics.Collision.Shapes;
using Microsoft.Xna.Framework;
using CtrEditor.Convertidores; using CtrEditor.Convertidores;
using CtrEditor.ObjetosSim;
using FarseerPhysics.Collision.Shapes;
using FarseerPhysics.Common; using FarseerPhysics.Common;
using System.Windows; using FarseerPhysics.Dynamics;
using System.Diagnostics; using FarseerPhysics.Dynamics.Contacts;
using FarseerPhysics.Factories;
using Microsoft.Xna.Framework;
using OpenCvSharp;
using Siemens.Simatic.Simulation.Runtime;
using static System.Windows.Forms.DataFormats;
using Point = System.Windows.Point;
namespace CtrEditor.Simulacion namespace CtrEditor.Simulacion
{ {
public class simRectangle public class simRectangle
{ {
public Body Body { get; private set; } public Body Body { get; private set; }
@ -45,16 +56,17 @@ namespace CtrEditor.Simulacion
public void SetDimensions(float width, float height) public void SetDimensions(float width, float height)
{ {
// Primero, elimina el fixture antiguo
Body.DestroyFixture(Body.FixtureList[0]); Body.DestroyFixture(Body.FixtureList[0]);
// Crea un nuevo fixture con las nuevas dimensiones
var newShape = new PolygonShape(PolygonTools.CreateRectangle(width / 2, height / 2), 1f); var newShape = new PolygonShape(PolygonTools.CreateRectangle(width / 2, height / 2), 1f);
Body.CreateFixture(newShape); Body.CreateFixture(newShape);
} }
public void Create(float width, float height, Vector2 position, float angle = 0) public void Create(float width, float height, Vector2 position, float angle = 0)
{ {
if (Body != null) if (Body != null) {
{
_world.RemoveBody(Body); _world.RemoveBody(Body);
} }
Body = BodyFactory.CreateRectangle(_world, width, height, 1f, position); Body = BodyFactory.CreateRectangle(_world, width, height, 1f, position);
@ -63,8 +75,12 @@ namespace CtrEditor.Simulacion
Body.Rotation = MathHelper.ToRadians(angle); Body.Rotation = MathHelper.ToRadians(angle);
Body.UserData = this; // Importante para la identificación durante la colisión Body.UserData = this; // Importante para la identificación durante la colisión
} }
// Otros métodos según sea necesario, como mover, rotar, etc.
} }
public class simLine public class simLine
{ {
public Body Body { get; private set; } public Body Body { get; private set; }
@ -93,6 +109,8 @@ namespace CtrEditor.Simulacion
} }
} }
public class simCircle public class simCircle
{ {
public Body Body { get; private set; } public Body Body { get; private set; }
@ -111,7 +129,7 @@ namespace CtrEditor.Simulacion
public float CenterX public float CenterX
{ {
get { return Body.Position.X; } get { return Body.Position.X; }
set { } set { }
} }
public float CenterY public float CenterY
@ -127,8 +145,7 @@ namespace CtrEditor.Simulacion
public float Mass public float Mass
{ {
get get {
{
if (_mass <= 0) if (_mass <= 0)
_mass = 1; _mass = 1;
return _mass; return _mass;
@ -142,12 +159,12 @@ namespace CtrEditor.Simulacion
{ {
_world.RemoveBody(Body); // Remover el cuerpo anterior si existe _world.RemoveBody(Body); // Remover el cuerpo anterior si existe
} }
Body = BodyFactory.CreateCircle(_world, _radius, 1f, position); Body = BodyFactory.CreateCircle(_world, _radius, 10f, position);
Body.BodyType = BodyType.Dynamic; Body.BodyType = BodyType.Dynamic;
// Restablecer manejador de eventos de colisión // Restablecer manejador de eventos de colisión
Body.OnCollision += HandleCollision; Body.OnCollision += HandleCollision;
//Body.OnSeparation += HandleOnSeparation; Body.OnSeparation += HandleOnSeparation;
Body.UserData = this; // Importante para la identificación durante la colisión Body.UserData = this; // Importante para la identificación durante la colisión
@ -155,14 +172,20 @@ namespace CtrEditor.Simulacion
Body.Friction = 0.5f; // 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 = 0f; // Ajustar para controlar la reducción de la velocidad lineal Body.LinearDamping = 0.01f; // Ajustar para controlar la reducción de la velocidad lineal
Body.AngularDamping = 0f; // Ajustar para controlar la reducción de la velocidad angular Body.AngularDamping = 1f; // 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;
}
private void HandleOnSeparation(Fixture fixtureA, Fixture fixtureB)
{
Body.LinearDamping = 5f; // Ajustar para controlar la reducción de la velocidad lineal
} }
public void SetPosition(float x, float y) public void SetPosition(float x, float y)
{ {
// Usar el ángulo actual, ya que no es relevante para un círculo en este contexto
Body.SetTransform(new Vector2(x, y), Body.Rotation); Body.SetTransform(new Vector2(x, y), Body.Rotation);
} }
@ -177,30 +200,38 @@ namespace CtrEditor.Simulacion
Mass = mass; Mass = mass;
} }
private bool HandleCollision(Fixture fixtureA, Fixture fixtureB, FarseerPhysics.Dynamics.Contacts.Contact contact) private bool HandleCollision(Fixture fixtureA, Fixture fixtureB, FarseerPhysics.Dynamics.Contacts.Contact contact)
{ {
if (fixtureB.Body.UserData is simRectangle) if (fixtureB.Body.UserData is simRectangle)
{ {
simRectangle conveyor = fixtureB.Body.UserData as simRectangle; simRectangle conveyor = fixtureB.Body.UserData as simRectangle;
ApplyConveyorEffect(conveyor, fixtureA); ApplyConveyorEffect(conveyor, fixtureA, contact);
return true; // No aplicar respuestas físicas return true; // No aplicar respuestas fisicas
} }
return true; // No aplicar respuestas físicas return true; // No aplicar respuestas fisicas
} }
private void HandleOnSeparation(Fixture fixtureA, Fixture fixtureB) private void ApplyConveyorEffect(simRectangle conveyor, Fixture circleFixture, FarseerPhysics.Dynamics.Contacts.Contact contact)
{
// Aquí puedes restablecer cualquier estado si es necesario al separarse de un simRectangle
}
private void ApplyConveyorEffect(simRectangle conveyor, Fixture circleFixture)
{ {
// Calcular la velocidad deseada en metros por segundo
float speedMetersPerSecond = conveyor.Speed / 60.0f; float speedMetersPerSecond = conveyor.Speed / 60.0f;
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;
// Calcular la fuerza necesaria para alcanzar esa velocidad
Vector2 velocityChange = desiredVelocity - circleFixture.Body.LinearVelocity;
float timeStep = 1.0f / 60.0f; // Asumiendo 60 Hz de tasa de actualización
Vector2 acceleration = velocityChange / timeStep;
Vector2 force = acceleration / Mass;
// Aplicar la fuerza al círculo
circleFixture.Body.ApplyForce(force);
} }
} }
public class SimulationManagerFP public class SimulationManagerFP
{ {
private World world; private World world;
@ -208,40 +239,16 @@ namespace CtrEditor.Simulacion
public List<simCircle> circles; public List<simCircle> circles;
public List<simRectangle> rectangles; public List<simRectangle> rectangles;
public List<simLine> lines; public List<simLine> lines;
public Stopwatch stopwatch;
public Canvas DebugCanvas { get => simulationCanvas; set => simulationCanvas = value; } public Canvas DebugCanvas { get => simulationCanvas; set => simulationCanvas = value; }
public SimulationManagerFP() public SimulationManagerFP()
{ {
world = new World(new Vector2(0, 0)); // Vector2.Zero world = new World(new Vector2(0,0)); // Vector2.Zero
circles = new List<simCircle>(); circles = new List<simCircle>();
rectangles = new List<simRectangle>(); rectangles = new List<simRectangle>();
lines = new List<simLine>(); lines = new List<simLine>();
stopwatch = new Stopwatch();
} }
public void Clear()
{
circles.Clear();
rectangles.Clear();
lines.Clear();
world.Clear();
}
public void Step()
{
// 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();
// Pasar el tiempo transcurrido al método Step
world.Step(elapsedMilliseconds / 1000.0f);
}
public simCircle AddCircle(float diameter, Vector2 position, float mass) public simCircle AddCircle(float diameter, Vector2 position, float mass)
{ {
simCircle circle = new simCircle(world, diameter, position, mass); simCircle circle = new simCircle(world, diameter, position, mass);
@ -249,6 +256,7 @@ namespace CtrEditor.Simulacion
return circle; return circle;
} }
public simRectangle AddRectangle(float width, float height, Vector2 position, float angle) public simRectangle AddRectangle(float width, float height, Vector2 position, float angle)
{ {
simRectangle rectangle = new simRectangle(world, width, height, position, angle); simRectangle rectangle = new simRectangle(world, width, height, position, angle);
@ -263,6 +271,14 @@ namespace CtrEditor.Simulacion
return line; return line;
} }
// Otros métodos para agregar círculos y ejecutar la simulación
public void Step(float timeStep)
{
world.Step(timeStep/1000.0f);
// Actualiza y gestiona otras lógicas si es necesario
}
public void Debug_DrawInitialBodies() public void Debug_DrawInitialBodies()
{ {
ClearSimulationShapes(); ClearSimulationShapes();
@ -318,14 +334,14 @@ namespace CtrEditor.Simulacion
EdgeShape edge = fixture.Shape as EdgeShape; EdgeShape edge = fixture.Shape as EdgeShape;
Line line = new Line Line line = new Line
{ {
X1 = p(edge.Vertex1.X + fixture.Body.Position.X), // Aplicar escala y posición X1 = p(edge.Vertex1.X + fixture.Body.Position.X ), // Aplicar escala y posición
Y1 = p(edge.Vertex1.Y + fixture.Body.Position.Y), Y1 = p(edge.Vertex1.Y + fixture.Body.Position.Y ),
X2 = p(edge.Vertex2.X + fixture.Body.Position.X), X2 = p(edge.Vertex2.X + fixture.Body.Position.X ),
Y2 = p(edge.Vertex2.Y + fixture.Body.Position.Y), Y2 = p(edge.Vertex2.Y + fixture.Body.Position.Y ),
Stroke = Brushes.Black, Stroke = Brushes.Black,
StrokeThickness = 2 StrokeThickness = 2
}; };
return line; return line;
} }
private System.Windows.Shapes.Shape DrawCircle(Fixture fixture) private System.Windows.Shapes.Shape DrawCircle(Fixture fixture)
@ -338,8 +354,8 @@ namespace CtrEditor.Simulacion
Stroke = Brushes.Black, Stroke = Brushes.Black,
StrokeThickness = 2 StrokeThickness = 2
}; };
Canvas.SetLeft(ellipse, p(fixture.Body.Position.X - circle.Radius)); Canvas.SetLeft(ellipse, p(fixture.Body.Position.X - circle.Radius ));
Canvas.SetTop(ellipse, p(fixture.Body.Position.Y - circle.Radius)); Canvas.SetTop(ellipse, p(fixture.Body.Position.Y - circle.Radius ));
return ellipse; return ellipse;
} }
@ -353,6 +369,7 @@ namespace CtrEditor.Simulacion
foreach (Vector2 vertex in polyShape.Vertices) foreach (Vector2 vertex in polyShape.Vertices)
{ {
// Aplicar la rotación alrededor del origen y luego trasladar
float rotatedX = vertex.X * cos - vertex.Y * sin + fixture.Body.Position.X; float rotatedX = vertex.X * cos - vertex.Y * sin + fixture.Body.Position.X;
float rotatedY = vertex.X * sin + vertex.Y * cos + fixture.Body.Position.Y; float rotatedY = vertex.X * sin + vertex.Y * cos + fixture.Body.Position.Y;
@ -361,5 +378,10 @@ namespace CtrEditor.Simulacion
return polygon; return polygon;
} }
} }
} }