From 494f960628396ddbec9a47de4e226ac502174b1a Mon Sep 17 00:00:00 2001 From: Miguel Date: Tue, 14 May 2024 18:17:46 +0200 Subject: [PATCH] Tanque funcionando --- Convertidores/Converters.cs | 36 +++++ CtrEditor.csproj | 6 + ObjetosSim/UserControlFactory.cs | 4 + ObjetosSim/ucBasicExample.xaml | 20 +++ ObjetosSim/ucBasicExample.xaml.cs | 167 +++++++++++++++++++++++ ObjetosSim/ucTanque.xaml | 39 ++++++ ObjetosSim/ucTanque.xaml.cs | 201 ++++++++++++++++++++++++++++ ObjetosSim/ucTransporteTTop.xaml.cs | 36 ++++- Siemens/PLCControl.xaml.cs | 24 +++- tank.png | Bin 0 -> 2592 bytes 10 files changed, 529 insertions(+), 4 deletions(-) create mode 100644 ObjetosSim/ucBasicExample.xaml create mode 100644 ObjetosSim/ucBasicExample.xaml.cs create mode 100644 ObjetosSim/ucTanque.xaml create mode 100644 ObjetosSim/ucTanque.xaml.cs create mode 100644 tank.png diff --git a/Convertidores/Converters.cs b/Convertidores/Converters.cs index b72972d..e711305 100644 --- a/Convertidores/Converters.cs +++ b/Convertidores/Converters.cs @@ -10,6 +10,42 @@ using System.Windows.Media; namespace CtrEditor.Convertidores { + + public class WidthPercentageConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is double width) + { + return width * 0.25; + } + return 0; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } + + public class LevelToHeightMultiConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + if (values[0] is float level && values[1] is double containerHeight) + { + return containerHeight * (level / 100); + } + return 0; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } + + public class BrushToColorNameConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) diff --git a/CtrEditor.csproj b/CtrEditor.csproj index 121c8c3..36e5d46 100644 --- a/CtrEditor.csproj +++ b/CtrEditor.csproj @@ -9,19 +9,24 @@ + + + + + @@ -44,6 +49,7 @@ + diff --git a/ObjetosSim/UserControlFactory.cs b/ObjetosSim/UserControlFactory.cs index ab8d84e..4c0fe9b 100644 --- a/ObjetosSim/UserControlFactory.cs +++ b/ObjetosSim/UserControlFactory.cs @@ -27,6 +27,8 @@ namespace CtrEditor.ObjetosSim return new ucVMmotorSim(); if (tipoObjeto == typeof(osBoton)) return new ucBoton(); + if (tipoObjeto == typeof(osTanque)) + return new ucTanque(); // Puedes añadir más condiciones para otros tipos @@ -49,6 +51,8 @@ namespace CtrEditor.ObjetosSim return new osVMmotorSim(); if (tipoObjeto == typeof(osBoton)) return new osBoton(); + if (tipoObjeto == typeof(osTanque)) + return new osTanque(); // Puedes añadir más condiciones para otros tipos diff --git a/ObjetosSim/ucBasicExample.xaml b/ObjetosSim/ucBasicExample.xaml new file mode 100644 index 0000000..4da1c1f --- /dev/null +++ b/ObjetosSim/ucBasicExample.xaml @@ -0,0 +1,20 @@ + + + + + + + + + + diff --git a/ObjetosSim/ucBasicExample.xaml.cs b/ObjetosSim/ucBasicExample.xaml.cs new file mode 100644 index 0000000..ff5445e --- /dev/null +++ b/ObjetosSim/ucBasicExample.xaml.cs @@ -0,0 +1,167 @@ +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 +{ + /// + /// Interaction logic for ucBasicExample.xaml + /// + public class osBasicExample : osBase + { + // Otros datos y métodos relevantes para la simulación + + private string _nombre = "Ejemplo"; + private float _ancho; + private float _alto; + private float _left; + private float _top; + private float _angulo; + + public override float Left + { + get => _left; + set + { + _left = value; + CanvasSetLeftinMeter(value); + OnPropertyChanged(nameof(Left)); + } + } + public override float Top + { + get => _top; + set + { + _top = value; + CanvasSetTopinMeter(value); + OnPropertyChanged(nameof(Top)); + } + } + + public float Ancho + { + get => _ancho; + set + { + _ancho = value; + OnPropertyChanged(nameof(Ancho)); + } + } + public float Alto + { + get => _alto; + set + { + _alto = value; + OnPropertyChanged(nameof(Alto)); + } + } + + public float Angulo + { + get => _angulo; + set + { + _angulo = value; + OnPropertyChanged(nameof(Angulo)); + } + } + + public override string Nombre + { + get => _nombre; + set + { + if (_nombre != value) + { + _nombre = value; + OnPropertyChanged(nameof(Nombre)); + } + } + } + + public osBasicExample() + { + Ancho = 0.30f; + Alto = 0.30f; + } + + public override void UpdateGeometryStart() + { + // Se llama antes de la simulacion + + } + public override void UpdateGeometryStep() + { + } + public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds) + { + } + + public override void UpdateControl() + { + + } + public override void ucLoaded() + { + // El UserControl ya se ha cargado y podemos obtener las coordenadas para + // crear el objeto de simulacion + } + + } + + public partial class ucBasicExample : UserControl, IDataContainer + { + public osBase? Datos { get; set; } + + public ucBasicExample() + { + InitializeComponent(); + this.Loaded += OnLoaded; + } + private void OnLoaded(object sender, RoutedEventArgs e) + { + Datos?.ucLoaded(); + } + public void Resize(float width, float height) { + if (Datos is osBasicExample datos) + { + datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width); + datos.Alto = PixelToMeter.Instance.calc.PixelsToMeters(width); + } + } + public void Move(float LeftPixels, float TopPixels) + { + if (Datos != null) + { + Datos.Left = PixelToMeter.Instance.calc.PixelsToMeters(LeftPixels); + Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels); + } + } + public void Rotate(float Angle) + { + if (Datos != null) + if (Datos is osBasicExample datos) + datos.Angulo = Angle; + } + public void Highlight(bool State) { } + public int ZIndex() + { + return 10; + } + } +} diff --git a/ObjetosSim/ucTanque.xaml b/ObjetosSim/ucTanque.xaml new file mode 100644 index 0000000..c91e3f1 --- /dev/null +++ b/ObjetosSim/ucTanque.xaml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ObjetosSim/ucTanque.xaml.cs b/ObjetosSim/ucTanque.xaml.cs new file mode 100644 index 0000000..baf37a2 --- /dev/null +++ b/ObjetosSim/ucTanque.xaml.cs @@ -0,0 +1,201 @@ +using CtrEditor.Convertidores; +using CtrEditor.Siemens; +using OpenCvSharp.Flann; +using Siemens.Simatic.Simulation.Runtime; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace CtrEditor.ObjetosSim +{ + /// + /// Interaction logic for ucTanque.xaml + /// + public class osTanque : osBase + { + // Otros datos y métodos relevantes para la simulación + + private string _nombre = "Tanque"; + private float _ancho; + private float _alto; + private float _left; + private float _top; + private float _angulo; + private float _level; + private string _tag; + + + public string Tag + { + get => _tag; + set + { + if (_tag != value) + { + _tag = value; + OnPropertyChanged(nameof(Tag)); + } + } + } + public float Level + { + get => _level; + set + { + _level = value; + OnPropertyChanged(nameof(Level)); + } + } + + public override float Left + { + get => _left; + set + { + _left = value; + CanvasSetLeftinMeter(value); + OnPropertyChanged(nameof(Left)); + } + } + public override float Top + { + get => _top; + set + { + _top = value; + CanvasSetTopinMeter(value); + OnPropertyChanged(nameof(Top)); + } + } + + public float Ancho + { + get => _ancho; + set + { + _ancho = value; + OnPropertyChanged(nameof(Ancho)); + } + } + public float Alto + { + get => _alto; + set + { + _alto = value; + OnPropertyChanged(nameof(Alto)); + } + } + + public float Angulo + { + get => _angulo; + set + { + _angulo = value; + OnPropertyChanged(nameof(Angulo)); + } + } + + public override string Nombre + { + get => _nombre; + set + { + if (_nombre != value) + { + _nombre = value; + OnPropertyChanged(nameof(Nombre)); + } + } + } + + public osTanque() + { + Ancho = 0.30f; + Alto = 0.30f; + } + + public override void UpdateGeometryStart() + { + // Se llama antes de la simulacion + + } + public override void UpdateGeometryStep() + { + } + public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds) + { + if (Tag.Length > 0) + { + SDataValue s = new SDataValue(); + s.UInt16 = (ushort)(Level / 100.0 * 26600); + plc.EscribirTag(Tag, s); + } + } + + public override void UpdateControl() + { + + } + public override void ucLoaded() + { + // El UserControl ya se ha cargado y podemos obtener las coordenadas para + // crear el objeto de simulacion + } + + } + + public partial class ucTanque : UserControl, IDataContainer + { + public osBase? Datos { get; set; } + + public ucTanque() + { + InitializeComponent(); + this.Loaded += OnLoaded; + } + private void OnLoaded(object sender, RoutedEventArgs e) + { + Datos?.ucLoaded(); + } + public void Resize(float width, float height) + { + if (Datos is osTanque datos) + { + datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width); + datos.Alto = PixelToMeter.Instance.calc.PixelsToMeters(width); + } + } + public void Move(float LeftPixels, float TopPixels) + { + if (Datos != null) + { + Datos.Left = PixelToMeter.Instance.calc.PixelsToMeters(LeftPixels); + Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels); + } + } + public void Rotate(float Angle) + { + if (Datos != null) + if (Datos is osTanque datos) + datos.Angulo = Angle; + } + public void Highlight(bool State) { } + public int ZIndex() + { + return 10; + } + } +} diff --git a/ObjetosSim/ucTransporteTTop.xaml.cs b/ObjetosSim/ucTransporteTTop.xaml.cs index 0db5381..c5c4fb6 100644 --- a/ObjetosSim/ucTransporteTTop.xaml.cs +++ b/ObjetosSim/ucTransporteTTop.xaml.cs @@ -27,10 +27,23 @@ namespace CtrEditor.ObjetosSim private float _top; private float _angulo; private float _velocidadActual; + private osBase _osMotor = null; + private string _motor; private simRectangle Simulation_Transporte; - + public string Motor + { + get => _motor; + set + { + if (_motor != value) + { + _motor = value; + OnPropertyChanged(nameof(Motor)); + } + } + } public override float Left { get => _left; @@ -132,8 +145,25 @@ namespace CtrEditor.ObjetosSim public override void UpdateGeometryStep() { } - public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds) { } - + public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds) + { + if (_osMotor != null) + { + if (_osMotor is osVMmotorSim motor) + VelocidadActual = motor.Velocidad; + } + else + { + if (Motor.Length > 0) + if (_mainViewModel != null) + foreach (var objetoSimulable in _mainViewModel.ObjetosSimulables) + if (objetoSimulable.Nombre == _motor) + { + _osMotor = objetoSimulable; + break; + } + } + } public override void UpdateControl() { diff --git a/Siemens/PLCControl.xaml.cs b/Siemens/PLCControl.xaml.cs index 6634f0b..19e338f 100644 --- a/Siemens/PLCControl.xaml.cs +++ b/Siemens/PLCControl.xaml.cs @@ -193,7 +193,29 @@ namespace CtrEditor.Siemens LastError = ex.Message; } } - + public void EscribirTag(string pTag, SDataValue Value) + { + try + { + Instance?.Write(pTag, Value); + } + catch (Exception ex) + { + LastError = pTag + ":" + ex.Message; + } + } + public SDataValue LeerTag(string pTag) + { + try + { + return Instance.Read(pTag); + } + catch (Exception ex) + { + LastError = pTag + ":" + ex.Message; + return new SDataValue(); + } + } public void EscribirTagBool(string pTag, bool pValue) { try diff --git a/tank.png b/tank.png new file mode 100644 index 0000000000000000000000000000000000000000..68a319e4450fc7af13ab19c9ff6047c198329e26 GIT binary patch literal 2592 zcmd^BeNYtV89%iNi7`UN5?dA5)3!QwZ};|&`&c;0jNM-F^4n-}8HZ&&NKqudT^>?&;}2o-UKgp3crP=E1v5I-htPUjOpto#)~0Nmo`O zFOxl$D4kPeZ#B%3$sRk+nhS&i(+eccITRGbS%AXpkW6K=)HJV)qDz5*Sb&Xn8swq& zlX8S*4Dxj;Cfwx81SM=%g&X8oGfIuN$huz7OUW0s`mxOC+ z8J>_j8dqtSAq1|}W4I1es!&`>;uCV?i?!=VmG49yFx zwm>gYz28a9o6B7Q%L6=D=BB}_Ex;)(nsmm{Ftr|&zf@8bH2_9R00udM6KWJ! zqlC(=BuJ%_B#58m1c~DlP!sF}h7zbp19J>(Eq@fK$wX#5d4Y1$Alqn=Ls1HrWk`x3 z7`2|JP@M*-QGJS9jZ&041;rV43ZYZ0tr{gYt_#{5Il4?rpJYGLwhTu@j#!3Bg0kQM z=yWL1;a1e5Q8OsTSaqnL(!g!V2?+fpTdtdhUk+veHmjtHfs8<_A{d}0P#jlkP=ZkF zpgt{*YV{Vqg;rbjxKb-e7@D+lZU+VXgmq9hfVrGDIr48cnVg+-n>YsMTqSigWQS2? zu{}#@h4zBXB9k@ z8>HJ{rvGbmVc#d7r?xy?`lA*8e<(egR=R|8+5jA!m|O}5lSa%$QLz84*Z8|{jiX68 zoN>}JHeBIDY&-)eq;|vMyDQ;ZrA#(0l5I>kdmC<^?|pueZC=+udc!@)_JsHs_wPt% z>XR>jv>-0tH!D?$HypjU;KqTQZT?%$Yp#LOle_kA-&%F6*}M%oo$*Oc^8NI-jcdO! zTAR3d)tfI^<~mqY+U;_x=Sq1~xpj|rR^yxd4}MmXdcyBF%v^|=@=xFH+`M!5?%lOX zNlAkvy(e-y{C@vu;c&Qj{d?#0WgF7&nm+LtSA>RYYimyy78eiRnvpa`tI-771A)k< zl4C!MZ!0=r9_;Dq`S9SmO(9zLr@rC$gTY|&jIrRA^roVsB17r1zvh;1{>cP_vwRBdtGK_<>8t5oIF**rYbP@qt#<`zVege zAMUnRCCtd4wQ(=*+uJ@b7-+T>N+SJMI2iLF5Blo%ds_!u-&nCY z^V&{v!RjTioW3}6QT*E%LGR{bPjFkA7=EyPteLG*n|3e$xa0ET?1avxpQ~>*=KkK- zJ6ap=QvCCWk1hUV)s@-18m8{aU+JEnl{4kzrHKCjWb@dG6YSRu8@ijq`<8bN+^?d= zPYptK-=J^sf$#Occltl77<{`hR5ud&=Gm?f;;xqM9WwS7^!~E)&a=FyYqeOoGLg(%2&!ChV&2Nt99eCO0c7OHT(Z~*JXxDvoC?_W;@HT5@VLy@j0GzE5sSw& z`o`b8Z*P5f{d<)sj~=}X#J1tuw$|40rAQ=_-8x`=_guxDxv#hP%s6}YY+Zf5FVND` eQrI*$?dtm3%}d{2@GI#bE_+pu@leLbZT|x8ao%wN literal 0 HcmV?d00001