niuyx пре 1 месец
родитељ
комит
dc515f568e

+ 2 - 2
CyberX8_MainPages/ViewModels/OperationOverViewModel.cs

@@ -902,12 +902,12 @@ namespace CyberX8_MainPages.ViewModels
                 //Loader1TiltAAxis = CommonFunction.GetValue<BeckhoffStationAxis>(RtDataValues, $"Station.Loader1.TiltA.{_waferSize}");
                 //Loader1TiltBAxis = CommonFunction.GetValue<BeckhoffStationAxis>(RtDataValues, $"Station.Loader1.TiltB.{_waferSize}");
                 //Puf1Rotation比例尺计算
-                var resultRotation = CalculateMaxMin(Puf1RotationAxis);
+                var resultRotation = Puf1RotationAxis != null ? CalculateMaxMin(Puf1RotationAxis) : (0, 0);
                 double distance = resultRotation.max - resultRotation.min;
                 _puf1RotationRatio = distance / _pufLayoutRotationDistance;
                 _puf1RotationMotorPositionMax = resultRotation.max;
                 //Puf2Rotation比例尺计算
-                resultRotation = CalculateMaxMin(Puf2RotationAxis);
+                resultRotation = Puf2RotationAxis != null ? CalculateMaxMin(Puf2RotationAxis) : (0, 0);
                 distance = resultRotation.max - resultRotation.min;
                 _puf2RotationRatio = distance / _pufLayoutRotationDistance;
                 _puf2RotationMotorPositionMin = resultRotation.min;

+ 2 - 2
CyberX8_RT/Config/Devices/FestoControllerCfg-Simulator.xml

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <FestoControllerConfig>
-  <FestoDeviceConfig Name="Festo0" IpAddress="192.168.1.1" Port="502" SendTimeout="2000" RecvTimeout="2000" DIStartAddress="45395" Channel="1"> 
+  <FestoDeviceConfig Name="Festo0" IpAddress="127.0.0.1" Port="502" SendTimeout="2000" RecvTimeout="2000" DIStartAddress="45395" Channel="1"> 
     <DO Name="c_LOADERB_TRANS_BLADDER"  Address="40003" Invert="false" Bit="0"/>
 	<DO Name="Festo0.DO1"  Address="40003" Invert="false" Bit="1"/>
 	<DO Name="c_LOADERB_TRANS_HIGH"  Address="40003" Invert="false" Bit="2"/>
@@ -36,6 +36,6 @@
 	<DO Name="Festo0.DO32" Address="40008" Invert="false" Bit="0"/>
 	<DO Name="Festo0.DO33" Address="40008" Invert="false" Bit="2"/>
 	<DO Name="Festo0.DO34" Address="40008" Invert="false" Bit="4"/>
-	<DO Name="Festo0.DO35" Address="40008" Invert="false" Bit="6"/>
+	<DO Name="Festo0.DO35" Address="40009" Invert="false" Bit="6"/>
   </FestoDeviceConfig>
 </FestoControllerConfig>

+ 1 - 0
CyberX8_RT/Config/Station/StationPositionsCfg_Simulator.xml

@@ -494,4 +494,5 @@
         <Station Name="SRD2.Rotation.Home" Position="0" />
       </Stations>
     </Axis>
+  </Module>
 </StationPositionCfg>

+ 4 - 0
CyberX8_Simulator/Config/UILayout.xml

@@ -41,4 +41,8 @@
 	<Navigation Id="BarcodeReader" Name="BarcodeReader" >
 		<SubView Id="BarcodeReader" Name="BarcodeReader View" ViewClass="CyberX8_Simulator.Views.BarcodeReaderView" Assembly="CyberX8_Simulator"/>
 	</Navigation>
+
+	<Navigation Id="Festo" Name="Festo">
+		<SubView Id="Festo0" Name="Festo0" ViewClass="CyberX8_Simulator.Views.FestoView" Assembly="CyberX8_Simulator" Port="502"/>
+	</Navigation>
 </MECFUI>

+ 8 - 0
CyberX8_Simulator/CyberX8_Simulator.csproj

@@ -79,6 +79,7 @@
       <DependentUpon>App.xaml</DependentUpon>
       <SubType>Code</SubType>
     </Compile>
+    <Compile Include="Devices\FestoSocketSimulator.cs" />
     <Compile Include="Devices\SunWayEfemSimulator.cs" />
     <Compile Include="Devices\AIRSYSChillerMock.cs" />
     <Compile Include="Devices\EdwardsPumpMockLL.cs" />
@@ -98,6 +99,9 @@
     </Compile>
     <Compile Include="Views\Converters\CassetteConverter.cs" />
     <Compile Include="Views\Converters\IoConvert.cs" />
+    <Compile Include="Views\FestoView.xaml.cs">
+      <DependentUpon>FestoView.xaml</DependentUpon>
+    </Compile>
     <Compile Include="Views\IoViewModelBase.cs" />
     <Compile Include="Views\SimulatorIo1View.xaml.cs">
       <DependentUpon>SimulatorIo1View.xaml</DependentUpon>
@@ -215,6 +219,10 @@
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
+    <Page Include="Views\FestoView.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
     <Page Include="Views\SimulatorIo1View.xaml">
       <Generator>MSBuild:Compile</Generator>
       <SubType>Designer</SubType>

+ 192 - 0
CyberX8_Simulator/Devices/FestoSocketSimulator.cs

@@ -0,0 +1,192 @@
+using MECF.Framework.Common.Net;
+using MECF.Framework.Simulator.Core.Driver;
+using System;
+using System.Collections.Generic;
+
+namespace CyberX8_Simulator.Devices
+{
+    public class FestoSocketSimulator : SocketDeviceSimulator
+    {
+        //Write Address
+        private const ushort MODULE_0_OUTPUT_DATA_ADDRESS = 0x9C42;//FB36(16bit)        
+        private const ushort MODULE_1_OUTPUT_DATA_ADDRESS = 0x9C43;//MPA1气动模块(8bit,x 6 x 4 x 2 x 0)
+        private const ushort MODULE_2_OUTPUT_DATA_ADDRESS = 0x9C44;//MPA1气动模块(8bit,7 ... 0)
+        private const ushort MODULE_3_OUTPUT_DATA_ADDRESS = 0x9C45;//MPA1气动模块(8bit,3 ... 0)
+
+        //Read Address
+        private const ushort MODULE_0_ECHO_OUTPUT_DATA_ADDRESS = 0xB151;//FB36(16bit)
+        private const ushort MODULE_1_ECHO_OUTPUT_DATA_ADDRESS = 0xB153;//MPA1气动模块(8bit)
+        private const ushort MODULE_2_ECHO_OUTPUT_DATA_ADDRESS = 0xB155;//MPA1气动模块(8bit)
+        private const ushort MODULE_3_ECHO_OUTPUT_DATA_ADDRESS = 0xB157;//MPA1气动模块(8bit)
+
+        private IByteTransform byteTransform = new BigEndianByteTransformBase();
+        /// <summary>
+        /// 数据字典
+        /// </summary>
+        Dictionary<int, short> _festoOutputDataDic = new Dictionary<int, short>();
+
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="port"></param>
+        public FestoSocketSimulator(int port) : base(port)
+        {
+            _festoOutputDataDic[0] = 0x00;//Module0
+            _festoOutputDataDic[1] = 0x00;//Module1 (6 x 4 x 2 x 0)
+            _festoOutputDataDic[2] = 0x00;//Mdoule2 (7 ... 0)
+            _festoOutputDataDic[3] = 0x00;//Module3 (3 ... 0)
+        }
+        /// <summary>
+        /// 解析信息
+        /// </summary>
+        /// <param name="data"></param>
+        protected override void ProcessUnsplitMessage(byte[] data)
+        {
+            short flag = byteTransform.TransInt16(data, 0);//事务标识符
+            byte channel = data[6];//单元标识符
+            byte command = data[7];//功能码
+            if (command == 0x03)//读取
+            {
+                ushort startAddress = byteTransform.TransUInt16(data, 8);//起始寄存器地址
+                short registerCount = byteTransform.TransInt16(data, 10);//寄存器数量
+
+                byte[] bytes = new byte[2 * registerCount];//读取2 Byte数据
+                switch (startAddress)
+                {
+                    case MODULE_0_OUTPUT_DATA_ADDRESS:
+                        for(int i = 0; i < registerCount; i++)
+                        {
+                            Array.Copy(byteTransform.GetBytes(_festoOutputDataDic[0]), 0, bytes, i*2, 2);
+                        }                        
+                        break;
+                    case MODULE_1_OUTPUT_DATA_ADDRESS:
+                        for (int i = 0; i < registerCount; i++)
+                        {
+                            Array.Copy(byteTransform.GetBytes(_festoOutputDataDic[1]), 0, bytes, i*2, 2);
+                        }
+                        break;
+                    case MODULE_2_OUTPUT_DATA_ADDRESS:
+                        Array.Copy(byteTransform.GetBytes(_festoOutputDataDic[2]), 0, bytes, 0, 2);
+                        break;
+                    case MODULE_3_OUTPUT_DATA_ADDRESS:
+                        Array.Copy(byteTransform.GetBytes(_festoOutputDataDic[3]), 0, bytes, 0, 2);
+                        break;
+                    default:    
+                        break;
+                }
+                OnWriteMessage(CreateReadResponse(flag, channel, command, registerCount, bytes));
+            }
+            else if(command == 0x06)//写入
+            {
+                ushort startAddress = byteTransform.TransUInt16(data, 8);//起始寄存器地址
+                short value = byteTransform.TransInt16(data, 10);//写入的值(2 Byte)
+                switch (startAddress)
+                {
+                    case MODULE_0_ECHO_OUTPUT_DATA_ADDRESS:
+                        _festoOutputDataDic[0] = value;
+                        break;
+                    case MODULE_1_ECHO_OUTPUT_DATA_ADDRESS:
+                        _festoOutputDataDic[1] = value;
+                        break;
+                    case MODULE_2_ECHO_OUTPUT_DATA_ADDRESS:
+                        _festoOutputDataDic[2] = value;
+                        break;
+                    case MODULE_3_ECHO_OUTPUT_DATA_ADDRESS:
+                        _festoOutputDataDic[3] = value;
+                        break;
+                    default: 
+                        break;
+                }
+                OnWriteMessage(CreateWriteResponse(flag, channel, command, startAddress, value));
+            }
+            else
+            {
+                OnWriteMessage(CreateError(flag, channel, command, 0x84));
+            }
+        }
+        /// <summary>
+        /// 读回复
+        /// </summary>
+        /// <param name="flag"></param>
+        /// <param name="channel"></param>
+        /// <param name="command"></param>
+        /// <param name="registerCount"></param>
+        /// <param name="values"></param>
+        /// <returns></returns>
+        private byte[] CreateReadResponse(short flag, byte channel, byte command, short registerCount, byte[] values)
+        {
+            byte[] bytes = new byte[6 + 3 + values.Length];
+            Array.Copy(byteTransform.GetBytes(flag), 0, bytes, 0, 2);
+            bytes[2] = 0x00;
+            bytes[3] = 0x00;
+            short dataLength = (short)(3 + values.Length);
+            Array.Copy(byteTransform.GetBytes(dataLength), 0, bytes, 4, 2);
+            bytes[6] = channel;
+            bytes[7] = command;
+            bytes[8] = (byte)(2 * registerCount);
+            Array.Copy(values, 0, bytes, 9, values.Length);
+            return bytes;
+        }
+        /// <summary>
+        /// 写回复
+        /// </summary>
+        /// <param name="flag"></param>
+        /// <param name="channel"></param>
+        /// <param name="command"></param>
+        /// <param name="startAddress"></param>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        private byte[] CreateWriteResponse(short flag, byte channel, byte command, ushort startAddress, short value)
+        {
+            byte[] bytes = new byte[12];
+            Array.Copy(byteTransform.GetBytes(flag), 0, bytes, 0, 2);
+            bytes[2] = 0x00;
+            bytes[3] = 0x00;
+            bytes[4] = 0x00;
+            bytes[5] = 0x06;
+            bytes[6] = channel;
+            bytes[7] = command;
+            byte[] addressByt = byteTransform.GetBytes(startAddress);
+            Array.Copy(addressByt, 0, bytes, 8, 2);
+            byte[] valueByt = byteTransform.GetBytes(value);
+            Array.Copy(valueByt, 0, bytes, 10, 2);
+            return bytes;
+        }
+        /// <summary>
+        /// 多重写回复
+        /// </summary>
+        /// <param name="flag"></param>
+        /// <param name="channel"></param>
+        /// <param name="command"></param>
+        /// <param name="startAddress"></param>
+        /// <param name="count"></param>
+        /// <returns></returns>
+        private byte[] CreateMultiWriteResponse(short flag, byte channel, byte command, short startAddress, short count)
+        {
+            byte[] byt = new byte[1];            
+            return byt;
+        }
+        /// <summary>
+        /// 错误回复
+        /// </summary>
+        /// <param name="flag"></param>
+        /// <param name="channel"></param>
+        /// <param name="command"></param>
+        /// <param name="error"></param>
+        /// <returns></returns>
+        private byte[] CreateError(short flag, byte channel, byte command, byte error)
+        {
+            byte[] bytes = new byte[9];
+            Array.Copy(byteTransform.GetBytes(flag), 0, bytes, 0, 2);
+            bytes[2] = 0x00;
+            bytes[3] = 0x00;
+            bytes[4] = 0x00;
+            bytes[5] = 0x03;
+            bytes[6] = channel;
+            bytes[7] = (byte)(command | 0x80);
+            bytes[8] = error;
+            return bytes;
+        }
+
+    }
+}

+ 50 - 0
CyberX8_Simulator/Views/FestoView.xaml

@@ -0,0 +1,50 @@
+<UserControl x:Class="CyberX8_Simulator.Views.FestoView"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:CyberX8_Simulator.Views"
+        xmlns:commons="clr-namespace:MECF.Framework.Simulator.Core.Commons;assembly=MECF.Framework.Simulator.Core"
+        mc:Ignorable="d"
+        d:Height="900" d:Width="1200">
+    <Grid>
+        <Grid.RowDefinitions>
+            <RowDefinition Height="100"></RowDefinition>
+            <RowDefinition Height="50"></RowDefinition>
+            <RowDefinition />
+            <RowDefinition Height="10"></RowDefinition>
+        </Grid.RowDefinitions>
+
+        <commons:SocketTitleView Grid.Row="0"></commons:SocketTitleView>
+
+        <Grid  Grid.Row="1">
+            <StackPanel Orientation="Horizontal" Width="1200">
+                <Button Content="Clear Log" Width="100" Height="35"   Command="{Binding ClearLogCommand}"></Button>
+            </StackPanel>
+        </Grid>
+
+        <DataGrid Grid.Row="2" FontSize="16" AutoGenerateColumns="False" CanUserAddRows="False" CanUserResizeRows="False" CanUserSortColumns="False"
+              ItemsSource="{Binding TransactionLogItems}"
+                  Width="1200" VerticalAlignment="Top" MaxHeight="780">
+            <DataGrid.Columns>
+                <DataGridTextColumn Header="Time" Width="200" IsReadOnly="True" Binding="{Binding OccurTime, UpdateSourceTrigger=PropertyChanged}" />
+                <DataGridTextColumn Header="Incoming" Width="500" IsReadOnly="True"  Binding="{Binding Incoming, UpdateSourceTrigger=PropertyChanged}">
+                    <DataGridTextColumn.ElementStyle>
+                        <Style TargetType="TextBlock">
+                            <Setter Property="TextWrapping" Value="Wrap" />
+                            <Setter Property="Height" Value="auto" />
+                        </Style>
+                    </DataGridTextColumn.ElementStyle>
+                </DataGridTextColumn>
+                <DataGridTextColumn Header="Outgoing" Width="500" IsReadOnly="True"  Binding="{Binding Outgoing, UpdateSourceTrigger=PropertyChanged}">
+                    <DataGridTextColumn.ElementStyle>
+                        <Style TargetType="TextBlock">
+                            <Setter Property="TextWrapping" Value="Wrap" />
+                            <Setter Property="Height" Value="auto" />
+                        </Style>
+                    </DataGridTextColumn.ElementStyle>
+                </DataGridTextColumn>
+            </DataGrid.Columns>
+        </DataGrid>
+    </Grid>
+</UserControl>

+ 40 - 0
CyberX8_Simulator/Views/FestoView.xaml.cs

@@ -0,0 +1,40 @@
+using Aitex.Core.UI.MVVM;
+using CyberX8_Simulator.Devices;
+using MECF.Framework.Simulator.Core.Commons;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace CyberX8_Simulator.Views
+{
+    /// <summary>
+    /// FestoView.xaml 的交互逻辑
+    /// </summary>
+    public partial class FestoView : UserControl
+    {
+        public FestoView()
+        {
+            InitializeComponent();
+            this.Loaded += OnViewLoaded;
+        }
+        private void OnViewLoaded(object sender, RoutedEventArgs e)
+        {
+            (DataContext as TimerViewModelBase)?.Start();
+        }        
+    }
+    class FestoViewModel : SocketDeviceViewModel
+    {
+        public string Title
+        {
+            get { return "Festo Simulator"; }
+        }
+
+
+        private FestoSocketSimulator _sim;
+        public FestoViewModel(string str) : base("FestoViewModel")
+        {
+            int.TryParse(str, out int port);
+            _sim = new FestoSocketSimulator(port);
+            Init(_sim);
+        }
+    }
+}