Browse Source

Modify GalilSimualtor and Loader InstallCRS;

niuyx 1 month ago
parent
commit
003e0db28b

+ 61 - 61
CyberX8_RT/Config/Devices/GalilControllerCfg-Simulator.xml

@@ -1,37 +1,37 @@
 <?xml version="1.0" encoding="utf-8"?>
 <GalilControllerConfig>
-	<GalilDeviceConfig Module="PUF1" IpAddress="127.0.0.1" Port="58678" SendTimeout="2000" RecvTimeout="2000">
+	<GalilDeviceConfig Module="PUF1" IpAddress="127.0.0.1" Port="58678" SendTimeout="2000" RecvTimeout="2000" GalilType="Galil40">
 		<GalilAxisConfig Name="Flip" Index="0" Type="Galil">
-			<Speed>100</Speed>
-			<Acceleration>100</Acceleration>
-			<Deceleration>100</Deceleration>
-			<HomingSpeed>100</HomingSpeed>
-			<HomingOffset>0</HomingOffset>
+			<Speed>1000000</Speed>
+			<Acceleration>2000000</Acceleration>
+			<Deceleration>2000000</Deceleration>
+			<HomingSpeed>16000</HomingSpeed>
+			<HomingOffset>495</HomingOffset>
 			<HomingTimeOut>20000</HomingTimeOut>
-			<HomingAcceleration>100</HomingAcceleration>
-			<HomingDeceleration>100</HomingDeceleration>
-			<ReverseSoftwareLimit>-1190000</ReverseSoftwareLimit>
-			<ForwardSoftwareLimit>28000000</ForwardSoftwareLimit>
+			<HomingAcceleration>2000000</HomingAcceleration>
+			<HomingDeceleration>2000000</HomingDeceleration>
+			<ReverseSoftwareLimit>0</ReverseSoftwareLimit>
+			<ForwardSoftwareLimit>0</ForwardSoftwareLimit>
 			<NegativeTorqueLimit>130</NegativeTorqueLimit>
 			<PositiveTorqueLimit>20</PositiveTorqueLimit>
 		</GalilAxisConfig>
 		<GalilAxisConfig Name="Rotation" Index="1" Type="Galil">
-			<Speed>100</Speed>
-			<Acceleration>100</Acceleration>
-			<Deceleration>100</Deceleration>
-			<HomingSpeed>100</HomingSpeed>
+			<Speed>500000</Speed>
+			<Acceleration>500000</Acceleration>
+			<Deceleration>250000</Deceleration>
+			<HomingSpeed>8000</HomingSpeed>
 			<HomingOffset>0</HomingOffset>
 			<HomingTimeOut>20000</HomingTimeOut>
-			<HomingAcceleration>100</HomingAcceleration>
-			<HomingDeceleration>100</HomingDeceleration>
-			<ReverseSoftwareLimit>-1190000</ReverseSoftwareLimit>
-			<ForwardSoftwareLimit>28000000</ForwardSoftwareLimit>
+			<HomingAcceleration>500000</HomingAcceleration>
+			<HomingDeceleration>250000</HomingDeceleration>
+			<ReverseSoftwareLimit>0</ReverseSoftwareLimit>
+			<ForwardSoftwareLimit>0</ForwardSoftwareLimit>
 			<NegativeTorqueLimit>130</NegativeTorqueLimit>
 			<PositiveTorqueLimit>20</PositiveTorqueLimit>
-		</GalilAxisConfig>		
+		</GalilAxisConfig>
 	</GalilDeviceConfig>
-	<GalilDeviceConfig Module="Loader1" IpAddress="127.0.0.1" Port="58679" SendTimeout="2000" RecvTimeout="2000">
-		<GalilAxisConfig Name="LSA" Index="0" Type="GalilLipsel">
+	<GalilDeviceConfig Module="Loader1" IpAddress="127.0.0.2" Port="58679" SendTimeout="2000" RecvTimeout="2000"  GalilType="Galil21">
+		<GalilAxisConfig Name="LSA" Index="4" Type="GalilLipsel">
 			<Speed>150000</Speed>
 			<Acceleration>200000</Acceleration>
 			<Deceleration>200000</Deceleration>
@@ -40,12 +40,12 @@
 			<HomingTimeOut>60000</HomingTimeOut>
 			<HomingAcceleration>200000</HomingAcceleration>
 			<HomingDeceleration>60000000</HomingDeceleration>
-			<ReverseSoftwareLimit>-100</ReverseSoftwareLimit>
-			<ForwardSoftwareLimit>100</ForwardSoftwareLimit>
+			<ReverseSoftwareLimit>-48400</ReverseSoftwareLimit>
+			<ForwardSoftwareLimit>352000</ForwardSoftwareLimit>
 			<NegativeTorqueLimit>130</NegativeTorqueLimit>
 			<PositiveTorqueLimit>20</PositiveTorqueLimit>
 		</GalilAxisConfig>
-		<GalilAxisConfig Name="TiltA" Index="1" Type="Galil">
+		<GalilAxisConfig Name="TiltA" Index="5" Type="Galil">
 			<Speed>150000</Speed>
 			<Acceleration>200000</Acceleration>
 			<Deceleration>200000</Deceleration>
@@ -54,40 +54,40 @@
 			<HomingTimeOut>60000</HomingTimeOut>
 			<HomingAcceleration>200000</HomingAcceleration>
 			<HomingDeceleration>10000000</HomingDeceleration>
-			<ReverseSoftwareLimit>-100</ReverseSoftwareLimit>
-			<ForwardSoftwareLimit>100</ForwardSoftwareLimit>
+			<ReverseSoftwareLimit>-20000</ReverseSoftwareLimit>
+			<ForwardSoftwareLimit>236130</ForwardSoftwareLimit>
 			<NegativeTorqueLimit>130</NegativeTorqueLimit>
 			<PositiveTorqueLimit>20</PositiveTorqueLimit>
 		</GalilAxisConfig>
-		<GalilAxisConfig Name="ShuttleA" Index="2" Type="Galil">
-			<Speed>100</Speed>
-			<Acceleration>100</Acceleration>
-			<Deceleration>100</Deceleration>
-			<HomingSpeed>100</HomingSpeed>
+		<GalilAxisConfig Name="ShuttleA" Index="6" Type="Galil">
+			<Speed>200000</Speed>
+			<Acceleration>200000</Acceleration>
+			<Deceleration>200000</Deceleration>
+			<HomingSpeed>100000</HomingSpeed>
 			<HomingOffset>0</HomingOffset>
-			<HomingTimeOut>20000</HomingTimeOut>
-			<HomingAcceleration>100</HomingAcceleration>
-			<HomingDeceleration>100</HomingDeceleration>
-			<ReverseSoftwareLimit>-100</ReverseSoftwareLimit>
-			<ForwardSoftwareLimit>100</ForwardSoftwareLimit>
+			<HomingTimeOut>60000</HomingTimeOut>
+			<HomingAcceleration>200000</HomingAcceleration>
+			<HomingDeceleration>10000000</HomingDeceleration>
+			<ReverseSoftwareLimit>-25000</ReverseSoftwareLimit>
+			<ForwardSoftwareLimit>270000</ForwardSoftwareLimit>
 			<NegativeTorqueLimit>130</NegativeTorqueLimit>
 			<PositiveTorqueLimit>20</PositiveTorqueLimit>
 		</GalilAxisConfig>
 		<GalilAxisConfig Name="Rotation" Index="3" Type="Galil">
-			<Speed>100</Speed>
-			<Acceleration>100</Acceleration>
-			<Deceleration>100</Deceleration>
-			<HomingSpeed>100</HomingSpeed>
+			<Speed>100000</Speed>
+			<Acceleration>50000</Acceleration>
+			<Deceleration>50000</Deceleration>
+			<HomingSpeed>20000</HomingSpeed>
 			<HomingOffset>0</HomingOffset>
-			<HomingTimeOut>20000</HomingTimeOut>
-			<HomingAcceleration>100</HomingAcceleration>
-			<HomingDeceleration>100</HomingDeceleration>
-			<ReverseSoftwareLimit>-100</ReverseSoftwareLimit>
-			<ForwardSoftwareLimit>100</ForwardSoftwareLimit>
+			<HomingTimeOut>60000</HomingTimeOut>
+			<HomingAcceleration>10000</HomingAcceleration>
+			<HomingDeceleration>1000000</HomingDeceleration>
+			<ReverseSoftwareLimit>-1600</ReverseSoftwareLimit>
+			<ForwardSoftwareLimit>162000</ForwardSoftwareLimit>
 			<NegativeTorqueLimit>130</NegativeTorqueLimit>
 			<PositiveTorqueLimit>20</PositiveTorqueLimit>
 		</GalilAxisConfig>
-		<GalilAxisConfig Name="LSB" Index="4" Type="GalilLipsel">
+		<GalilAxisConfig Name="LSB" Index="0" Type="GalilLipsel">
 			<Speed>150000</Speed>
 			<Acceleration>200000</Acceleration>
 			<Deceleration>200000</Deceleration>
@@ -96,12 +96,12 @@
 			<HomingTimeOut>60000</HomingTimeOut>
 			<HomingAcceleration>200000</HomingAcceleration>
 			<HomingDeceleration>60000000</HomingDeceleration>
-			<ReverseSoftwareLimit>-100</ReverseSoftwareLimit>
-			<ForwardSoftwareLimit>100</ForwardSoftwareLimit>
+			<ReverseSoftwareLimit>-48400</ReverseSoftwareLimit>
+			<ForwardSoftwareLimit>352000</ForwardSoftwareLimit>
 			<NegativeTorqueLimit>130</NegativeTorqueLimit>
 			<PositiveTorqueLimit>20</PositiveTorqueLimit>
 		</GalilAxisConfig>
-		<GalilAxisConfig Name="TiltB" Index="5" Type="Galil">
+		<GalilAxisConfig Name="TiltB" Index="1" Type="Galil">
 			<Speed>150000</Speed>
 			<Acceleration>200000</Acceleration>
 			<Deceleration>200000</Deceleration>
@@ -110,22 +110,22 @@
 			<HomingTimeOut>60000</HomingTimeOut>
 			<HomingAcceleration>200000</HomingAcceleration>
 			<HomingDeceleration>10000000</HomingDeceleration>
-			<ReverseSoftwareLimit>-100</ReverseSoftwareLimit>
-			<ForwardSoftwareLimit>100</ForwardSoftwareLimit>
+			<ReverseSoftwareLimit>-20000</ReverseSoftwareLimit>
+			<ForwardSoftwareLimit>236130</ForwardSoftwareLimit>
 			<NegativeTorqueLimit>130</NegativeTorqueLimit>
 			<PositiveTorqueLimit>20</PositiveTorqueLimit>
 		</GalilAxisConfig>
-		<GalilAxisConfig Name="ShuttleB" Index="6" Type="Galil">
-			<Speed>100</Speed>
-			<Acceleration>100</Acceleration>
-			<Deceleration>100</Deceleration>
-			<HomingSpeed>100</HomingSpeed>
+		<GalilAxisConfig Name="ShuttleB" Index="2" Type="Galil">
+			<Speed>200000</Speed>
+			<Acceleration>200000</Acceleration>
+			<Deceleration>200000</Deceleration>
+			<HomingSpeed>100000</HomingSpeed>
 			<HomingOffset>0</HomingOffset>
-			<HomingTimeOut>20000</HomingTimeOut>
-			<HomingAcceleration>100</HomingAcceleration>
-			<HomingDeceleration>100</HomingDeceleration>
-			<ReverseSoftwareLimit>-100</ReverseSoftwareLimit>
-			<ForwardSoftwareLimit>100</ForwardSoftwareLimit>
+			<HomingTimeOut>60000</HomingTimeOut>
+			<HomingAcceleration>200000</HomingAcceleration>
+			<HomingDeceleration>10000000</HomingDeceleration>
+			<ReverseSoftwareLimit>-25000</ReverseSoftwareLimit>
+			<ForwardSoftwareLimit>270000</ForwardSoftwareLimit>
 			<NegativeTorqueLimit>130</NegativeTorqueLimit>
 			<PositiveTorqueLimit>20</PositiveTorqueLimit>
 		</GalilAxisConfig>

+ 33 - 25
CyberX8_RT/Config/Devices/WagoControllerCfg-Simulator.xml

@@ -76,20 +76,20 @@
 				<AI Name="AI1"  Address="0" Scaling="0=3276.7,-757=16383.5" DataType="short"/>
 				<AI Name="AI2"  Address="1" DataType="short"/>
 				<AI Name="AI3"  Address="2" DataType="short"/>
-				<AI Name="r_LoaderA_LS_Vacuum_anlg"  Address="4" Scaling="1=0,5=-757.5" DataType="short"/>
-				<AI Name="r_LoaderB_LS_Vacuum_anlg"  Address="5" Scaling="1=0,5=-757.5" DataType="short"/>
+				<AI Name="r_LoaderA_LS_Vacuum_anlg"  Address="4" Scaling="0=3276.7,-757=16383.5" DataType="short"/>
+				<AI Name="r_LoaderB_LS_Vacuum_anlg"  Address="5" Scaling="0=3276.7,-757=16383.5" DataType="short"/>
 				<AI Name="AI6"  Address="5" DataType="short"/>
 				<AI Name="r_LOADER_GasFlowSensor_FLOW"  Address="7" Scaling="1=0,5=500" DataType="short"/>
 			</AIGroup>
 			<AIGroup Name="N2">
-				<AI Name="r_LOADERA_BERNOULLI_PRESSURE"  Address="8" Scaling="1=0,5=145.0" DataType="short"/>
-				<AI Name="r_LOADERB_BERNOULLI_PRESSURE"  Address="9" Scaling="1=0,5=145.0" DataType="short"/>
-				<AI Name="r_LOADERA_CHUCK_BLADDER"  Address="10" Scaling="1=0,5=145.0" DataType="short"/>
-				<AI Name="r_LOADERB_CHUCK_BLADDER"  Address="11" Scaling="1=0,5=145.0" DataType="short"/>
-				<AI Name="r_LOADERA_WS_BLADDER_PRESSURE"  Address="12" Scaling="1=0,5=145.0" DataType="short"/>
-				<AI Name="r_LOADERB_WS_BLADDER_PRESSURE"  Address="13" Scaling="1=0,5=145.0" DataType="short"/>
+				<AI Name="r_LOADERA_BERNOULLI_PRESSURE"  Address="8" Scaling="0=3276.7, 145=16383.5" DataType="short"/>
+				<AI Name="r_LOADERB_BERNOULLI_PRESSURE"  Address="9" Scaling="0=3276.7, 145=16383.5" DataType="short"/>
+				<AI Name="r_LOADERA_CHUCK_BLADDER"  Address="10" Scaling="0=3276.7, 145=16383.5" DataType="short"/>
+				<AI Name="r_LOADERB_CHUCK_BLADDER"  Address="11" Scaling="0=3276.7, 145=16383.5" DataType="short"/>
+				<AI Name="r_LOADERA_WS_BLADDER_PRESSURE"  Address="12" Scaling="0=3276.7, 145=16383.5" DataType="short"/>
+				<AI Name="r_LOADERB_WS_BLADDER_PRESSURE"  Address="13" Scaling="0=3276.7, 145=16383.5" DataType="short"/>
 				<AI Name="r_SPUF_VAC"  Address="14" Scaling="1=0,5=-757.5" DataType="short"/>
-				<AI Name="r_LOADER_GasFlowSensor_VACUUM"  Address="15" Scaling="1=0,5=-101" DataType="short"/>
+				<AI Name="r_LOADER_GasFlowSensor_VACUUM"  Address="15" Scaling="0=3276.7,-757=16383.5" DataType="short"/>
 			</AIGroup>
 		</Ano_In>
 		<Ano_Out>
@@ -115,32 +115,40 @@
 			</AOGroup>
 		</Ano_Out>
 	</WagoDeviceConfig>
-	<WagoDeviceConfig Module="Wago1" IpAddress="127.0.0.1" Port="550" SendTimeout="2000" RecvTimeout="2000" Channel="1">
+	<WagoDeviceConfig Module="PUF" IpAddress="127.0.0.1" Port="550" SendTimeout="2000" RecvTimeout="2000" Channel="1">
 		<Dig_In>
-			<DIGroup Name="N5">
-				<DI Name="DI1" Address="0" Invert="false"/>
-				<DI Name="DI2" Address="0" Invert="false"/>
+			<DIGroup Name="N61">
+				<DI Name="r_PUF_A_CHUCK_OUT"  Address="0" Invert="false"/>
+				<DI Name="r_PUF_A_CHUCK_IN"  Address="1" Invert="false"/>
+				<DI Name="r_PUF_B_CHUCK_OUT"  Address="2" Invert="false"/>
+				<DI Name="r_PUF_B_CHUCK_IN"  Address="3" Invert="false"/>
+				<DI Name="DI4"  Address="4" Invert="false"/>
+				<DI Name="DI5"  Address="5" Invert="false"/>
+				<DI Name="DI6"  Address="6" Invert="false"/>
+				<DI Name="DI7"  Address="7" Invert="false"/>
 			</DIGroup>
-	
 		</Dig_In>
 		<Dig_Out>
-			<DOGroup Name="N7">
-				<DO Name="DO1"  Address="512" Invert="false"/>
-				<DO Name="DO2"  Address="513" Invert="false"/>
+			<DOGroup Name="N62">
+				<DO Name="c_PUF_CHUCK"  Address="512" Invert="false"/>
+				<DO Name="D01"  Address="513" Invert="false"/>
+				<DO Name="D02"  Address="514" Invert="false"/>
+				<DO Name="D03"  Address="515" Invert="false"/>
+				<DO Name="D04"  Address="516" Invert="false"/>
+				<DO Name="D05"  Address="517" Invert="false"/>
+				<DO Name="D06"  Address="518" Invert="false"/>
+				<DO Name="D07"  Address="519" Invert="false"/>
 			</DOGroup>
 		</Dig_Out>
 		<Ano_In>
-			<AIGroup Name="N1">
-				<AI Name="AI1"  Address="0" Scaling="0=3276.7,-757=16383.5" DataType="short"/>
-				<AI Name="AI2"  Address="1" DataType="short"/>
+			<AIGroup Name="N60">
+				<AI Name="r_DPUF_A_CHUCK_A_VAC"  Address="0" Scaling="0=3276.7,-757.5=16383.5" DataType="short"/>
+				<AI Name="r_DPUF_A_CHUCK_B_VAC"  Address="1" Scaling="0=3276.7,-757.5=16383.5" DataType="short"/>
+				<AI Name="r_DIST_FRONT"  Address="2" Scaling="13=0,150=32767" DataType="short"/>
+				<AI Name="r_DIST_REAR"  Address="3" Scaling="13=0,150=32767" DataType="short"/>
 			</AIGroup>
-
 		</Ano_In>
 		<Ano_Out>
-			<AOGroup Name="N3">
-				<AO Name="AO1"  Address="512" Scaling="0=3276.7,-757=16383.5" DataType="short"/>
-				<AO Name="AO2"  Address="513" DataType="short"/>
-			</AOGroup>
 		</Ano_Out>
 	</WagoDeviceConfig>
 </WagoControllerConfig>

+ 60 - 101
CyberX8_RT/Config/Station/StationPositionsCfg_Simulator.xml

@@ -4,82 +4,82 @@
 		<Axis Name="Loader1.TiltA">
 			<ToleranceDefault>0.1</ToleranceDefault>
 			<Stations>
-				<Station Name="Loader1.TiltA.HORI" Position="230500" ModifiedDate="2024-08-13 14:39:48.548" />
-				<Station Name="Loader1.TiltA.VERT" Position="-17500" ModifiedDate="2024-06-21 10:37:50.049" />
-				<Station Name="Loader1.TiltA.FLOAT" Position="220000" ModifiedDate="5/12/2015 12:51:37 AM" />
-				<Station Name="Loader1.TiltA.HOME" Position="220000" ModifiedDate="12/10/2020 3:40:44 PM" />
+				<Station Name="Loader1.TiltA.HORI" Position="82.97" ModifiedDate="2025-02-20 16:51:27.564" />
+				<Station Name="Loader1.TiltA.VERT" Position="-7.03" ModifiedDate="2025-02-21 10:57:45.769" />
+				<Station Name="Loader1.TiltA.FLOAT" Position="79.194" ModifiedDate="5/12/2015 12:51:37 AM" />
+				<Station Name="Loader1.TiltA.HOME" Position="79.19" ModifiedDate="2025-02-20 16:52:03.136" />
 			</Stations>
 		</Axis>
 		<Axis Name="Loader1.TiltB">
 			<ToleranceDefault>0.1</ToleranceDefault>
 			<Stations>
-				<Station Name="Loader1.TiltB.HORI" Position="230500" ModifiedDate="2024-08-13 14:39:48.548" />
-				<Station Name="Loader1.TiltB.VERT" Position="-17500" ModifiedDate="2024-06-21 10:37:50.049" />
-				<Station Name="Loader1.TiltB.FLOAT" Position="220000" ModifiedDate="5/12/2015 12:51:37 AM" />
-				<Station Name="Loader1.TiltB.HOME" Position="220000" ModifiedDate="12/10/2020 3:40:44 PM" />
+				<Station Name="Loader1.TiltB.HORI" Position="82.97" ModifiedDate="2025-02-20 16:51:53.944" />
+				<Station Name="Loader1.TiltB.VERT" Position="-6" ModifiedDate="2025-02-25 14:21:15.513" />
+				<Station Name="Loader1.TiltB.FLOAT" Position="79.194" ModifiedDate="5/12/2015 12:51:37 AM" />
+				<Station Name="Loader1.TiltB.HOME" Position="79.194" ModifiedDate="12/10/2020 3:40:44 PM" />
 			</Stations>
 		</Axis>
 		<Axis Name="Loader1.ShuttleA">
 			<ToleranceDefault>0.1</ToleranceDefault>
 			<Stations>
-				<Station Name="Loader1.ShuttleA.IN" Position="25200" ModifiedDate="2024-06-21 10:37:30.041" />
-				<Station Name="Loader1.ShuttleA.LS" Position="247500" ModifiedDate="2024-09-24 17:58:50.950" />
-				<Station Name="Loader1.ShuttleA.MID" Position="200000" ModifiedDate="7/11/2016 6:41:59 PM" />
-				<Station Name="Loader1.ShuttleA.OUT200" Position="-23062" ModifiedDate="12/10/2020 3:32:26 PM" />
-				<Station Name="Loader1.ShuttleA.OUT150" Position="-23062" ModifiedDate="12/10/2020 3:32:26 PM" />
-				<Station Name="Loader1.ShuttleA.OUT100" Position="-23062" ModifiedDate="12/10/2020 3:32:26 PM" />
+				<Station Name="Loader1.ShuttleA.IN" Position="66.88" ModifiedDate="2025-02-19 14:48:19.009" />
+				<Station Name="Loader1.ShuttleA.LS" Position="64.94" ModifiedDate="2025-02-21 16:40:15.442" />
+				<Station Name="Loader1.ShuttleA.MID" Position="51.29" ModifiedDate="2025-02-25 10:41:11.970" />
+				<Station Name="Loader1.ShuttleA.OUT200" Position="-5.91" ModifiedDate="2025-02-25 10:37:40.511" />
+				<Station Name="Loader1.ShuttleA.OUT150" Position="-5.913" ModifiedDate="12/10/2020 3:32:26 PM" />
+				<Station Name="Loader1.ShuttleA.OUT100" Position="-5.913" ModifiedDate="12/10/2020 3:32:26 PM" />
 			</Stations>
 		</Axis>
 		<Axis Name="Loader1.ShuttleB">
 			<ToleranceDefault>0.1</ToleranceDefault>
 			<Stations>
-				<Station Name="Loader1.ShuttleB.IN" Position="25200" ModifiedDate="2024-06-21 10:37:30.041" />
-				<Station Name="Loader1.ShuttleB.LS" Position="247500" ModifiedDate="2024-09-24 17:58:50.950" />
-				<Station Name="Loader1.ShuttleB.MID" Position="200000" ModifiedDate="7/11/2016 6:41:59 PM" />
-				<Station Name="Loader1.ShuttleB.OUT200" Position="-23062" ModifiedDate="12/10/2020 3:32:26 PM" />
-				<Station Name="Loader1.ShuttleB.OUT150" Position="-23062" ModifiedDate="12/10/2020 3:32:26 PM" />
-				<Station Name="Loader1.ShuttleB.OUT100" Position="-23062" ModifiedDate="12/10/2020 3:32:26 PM" />
+				<Station Name="Loader1.ShuttleB.IN" Position="66.97" ModifiedDate="2025-02-20 17:44:32.827" />
+				<Station Name="Loader1.ShuttleB.LS" Position="65.25" ModifiedDate="2025-02-25 14:36:13.613" />
+				<Station Name="Loader1.ShuttleB.MID" Position="51.28" ModifiedDate="7/11/2016 6:41:59 PM" />
+				<Station Name="Loader1.ShuttleB.OUT200" Position="-5.913" ModifiedDate="12/10/2020 3:32:26 PM" />
+				<Station Name="Loader1.ShuttleB.OUT150" Position="-5.913" ModifiedDate="12/10/2020 3:32:26 PM" />
+				<Station Name="Loader1.ShuttleB.OUT100" Position="-5.913" ModifiedDate="12/10/2020 3:32:26 PM" />
 			</Stations>
 		</Axis>
 		<Axis Name="Loader1.LSA">
-			<ToleranceDefault>0.01</ToleranceDefault>
+			<ToleranceDefault>0.04</ToleranceDefault>
 			<Stations>
-				<Station Name="Loader1.LSA.Setup200" Position="100000" />
-				<Station Name="Loader1.LSA.Lock200" Position="75000" ModifiedDate="3/2/2020 6:21:09 PM" />
-				<Station Name="Loader1.LSA.Unlock200" Position="201500" ModifiedDate="2/25/2020 2:54:29 PM" />
-				<Station Name="Loader1.LSA.Setup150" Position="100000" />
-				<Station Name="Loader1.LSA.Lock150" Position="70000" ModifiedDate="3/2/2020 6:21:09 PM" />
-				<Station Name="Loader1.LSA.Unlock150" Position="230000" ModifiedDate="2/25/2020 2:54:29 PM" />
-				<Station Name="Loader1.LSA.Setup100" Position="100000" />
-				<Station Name="Loader1.LSA.Lock100" Position="65000" ModifiedDate="3/2/2020 6:21:09 PM" />
-				<Station Name="Loader1.LSA.Unlock100" Position="280000" ModifiedDate="2/25/2020 2:54:29 PM" />
+				<Station Name="Loader1.LSA.Setup200" Position="2.57" ModifiedDate="2025-02-21 16:44:31.056" />
+				<Station Name="Loader1.LSA.Lock200" Position="1.82" ModifiedDate="2025-02-25 10:06:03.656" />
+				<Station Name="Loader1.LSA.Unlock200" Position="3.84" ModifiedDate="2025-02-25 11:00:32.208" />
+				<Station Name="Loader1.LSA.Setup150" Position="2.273" />
+				<Station Name="Loader1.LSA.Lock150" Position="1.591" ModifiedDate="3/2/2020 6:21:09 PM" />
+				<Station Name="Loader1.LSA.Unlock150" Position="5.227" ModifiedDate="2/25/2020 2:54:29 PM" />
+				<Station Name="Loader1.LSA.Setup100" Position="2.273" />
+				<Station Name="Loader1.LSA.Lock100" Position="1.477" ModifiedDate="3/2/2020 6:21:09 PM" />
+				<Station Name="Loader1.LSA.Unlock100" Position="4.364" ModifiedDate="2/25/2020 2:54:29 PM" />
 			</Stations>
 		</Axis>
 		<Axis Name="Loader1.LSB">
-			<ToleranceDefault>100</ToleranceDefault>
+			<ToleranceDefault>0.04</ToleranceDefault>
 			<Stations>
-				<Station Name="Loader1.LSB.Setup200" Position="100000" />
-				<Station Name="Loader1.LSB.Lock200" Position="75000" ModifiedDate="3/2/2020 6:21:09 PM" />
-				<Station Name="Loader1.LSB.Unlock200" Position="201500" ModifiedDate="2/25/2020 2:54:29 PM" />
-				<Station Name="Loader1.LSB.Setup150" Position="100000" />
-				<Station Name="Loader1.LSB.Lock150" Position="70000" ModifiedDate="3/2/2020 6:21:09 PM" />
-				<Station Name="Loader1.LSB.Unlock150" Position="230000" ModifiedDate="2/25/2020 2:54:29 PM" />
-				<Station Name="Loader1.LSB.Setup100" Position="100000" />
-				<Station Name="Loader1.LSB.Lock100" Position="65000" ModifiedDate="3/2/2020 6:21:09 PM" />
-				<Station Name="Loader1.LSB.Unlock100" Position="280000" ModifiedDate="2/25/2020 2:54:29 PM" />
+				<Station Name="Loader1.LSB.Setup200" Position="2" ModifiedDate="2025-02-25 14:51:06.154" />
+				<Station Name="Loader1.LSB.Lock200" Position="1" ModifiedDate="2025-02-25 14:51:30.953" />
+				<Station Name="Loader1.LSB.Unlock200" Position="3.5" ModifiedDate="2025-02-25 14:44:33.789" />
+				<Station Name="Loader1.LSB.Setup150" Position="2.273" />
+				<Station Name="Loader1.LSB.Lock150" Position="1.591" ModifiedDate="3/2/2020 6:21:09 PM" />
+				<Station Name="Loader1.LSB.Unlock150" Position="5.227" ModifiedDate="2/25/2020 2:54:29 PM" />
+				<Station Name="Loader1.LSB.Setup100" Position="2.273" />
+				<Station Name="Loader1.LSB.Lock100" Position="1.477" ModifiedDate="3/2/2020 6:21:09 PM" />
+				<Station Name="Loader1.LSB.Unlock100" Position="6.364" ModifiedDate="2/25/2020 2:54:29 PM" />
 			</Stations>
 		</Axis>
 		<Axis Name="Loader1.Rotation">
-			<ToleranceDefault>0.1</ToleranceDefault>
+			<ToleranceDefault>0.2</ToleranceDefault>
 			<Stations>
-				<Station Name="Loader1.Rotation.TRNPA" Position="-1093" ModifiedDate="2024-08-27 09:45:08.838" />
-				<Station Name="Loader1.Rotation.TRNPB" Position="144312" ModifiedDate="2/26/2020 12:19:29 PM" />
-				<Station Name="Loader1.Rotation.LOADA200" Position="6656" ModifiedDate="2024-08-13 14:00:52.955" />
-				<Station Name="Loader1.Rotation.LOADB200" Position="151875" ModifiedDate="2024-08-13 14:22:11.332" />
-				<Station Name="Loader1.Rotation.LOADA150" Position="6656" ModifiedDate="2024-08-13 14:00:52.955" />
-				<Station Name="Loader1.Rotation.LOADB150" Position="151875" ModifiedDate="2024-08-13 14:22:11.332" />
-				<Station Name="Loader1.Rotation.LOADA100" Position="6656" ModifiedDate="2024-08-13 14:00:52.955" />
-				<Station Name="Loader1.Rotation.LOADB100" Position="151875" ModifiedDate="2024-08-13 14:22:11.332" />
+				<Station Name="Loader1.Rotation.TRNPA" Position="-1.04" ModifiedDate="2025-02-19 17:13:36.065" />
+				<Station Name="Loader1.Rotation.TRNPB" Position="178.16" ModifiedDate="2/26/2020 12:19:29 PM" />
+				<Station Name="Loader1.Rotation.LOADA200" Position="8.3" ModifiedDate="2025-02-19 17:13:56.677" />
+				<Station Name="Loader1.Rotation.LOADB200" Position="187.5" ModifiedDate="2024-08-13 14:22:11.332" />
+				<Station Name="Loader1.Rotation.LOADA150" Position="8.217" ModifiedDate="2024-08-13 14:00:52.955" />
+				<Station Name="Loader1.Rotation.LOADB150" Position="187.5" ModifiedDate="2024-08-13 14:22:11.332" />
+				<Station Name="Loader1.Rotation.LOADA100" Position="8.217" ModifiedDate="2024-08-13 14:00:52.955" />
+				<Station Name="Loader1.Rotation.LOADB100" Position="187.5" ModifiedDate="2024-08-13 14:22:11.332" />
 			</Stations>
 		</Axis>
 	</Module>
@@ -231,63 +231,22 @@
 	</Module>
 	<Module Name="DualPuf">
 		<Axis Name="PUF1.Flip">
-			<ToleranceDefault>0.5</ToleranceDefault>
+			<ToleranceDefault>0.1</ToleranceDefault>
 			<Stations>
-				<Station Name="PUF1.Flip.SideA" Position="174.95" ModifiedDate="2024-08-09 13:35:19.613" />
-				<Station Name="PUF1.Flip.SideB" Position="-5" ModifiedDate="2024-08-09 13:36:34.531" />
+				<Station Name="PUF1.Flip.Home" Position="0.435" ModifiedDate="2024-08-09 13:35:19.613" />
+				<Station Name="PUF1.Flip.SideA" Position="0.435" ModifiedDate="2024-08-09 13:35:19.613" />
+				<Station Name="PUF1.Flip.SideB" Position="179.13" ModifiedDate="2024-08-09 13:36:34.531" />
 			</Stations>
 		</Axis>
 		<Axis Name="PUF1.Rotation">
-			<ToleranceDefault>0.5</ToleranceDefault>
-			<Stations>
-				<Station Name="PUF1.Rotation.Home" Position="72.9999" ModifiedDate="8/27/2018 2:53:59 PM" />
-				<Station Name="PUF1.Rotation.Park" Position="72.9999" ModifiedDate="8/27/2018 2:54:03 PM" />
-				<Station Name="PUF1.Rotation.Flip" Position="-7" ModifiedDate="4/6/2015 8:34:18 PM" />
-				<Station Name="PUF1.Rotation.Robot" Position="72.9999" ModifiedDate="7/31/2018 4:34:50 PM" />
-				<Station Name="PUF1.Rotation.LoaderPickup" Position="-6.10065" ModifiedDate="9/14/2018 2:13:39 PM" />
-				<Station Name="PUF1.Rotation.LoaderPutDown" Position="-6.30045" ModifiedDate="9/19/2018 4:32:00 PM" />
-			</Stations>
-		</Axis>
-		<Axis Name="PUF1.Vertical">
-			<ToleranceDefault>0.5</ToleranceDefault>
-			<Stations>
-				<Station Name="PUF1.Vertical.Home" Position="2.999983" ModifiedDate="9/14/2018 2:07:45 PM" />
-				<Station Name="PUF1.Vertical.Flip" Position="-148" />
-				<Station Name="PUF1.Vertical.Robot" Position="-145" ModifiedDate="2024-08-09 13:46:54.195" />
-				<Station Name="PUF1.Vertical.Park" Position="2.999992" ModifiedDate="9/14/2018 2:07:39 PM" />
-				<Station Name="PUF1.Vertical.Loader" Position="-27.19027" />
-				<Station Name="PUF1.Vertical.LoaderPickup" Position="-279" ModifiedDate="9/17/2018 2:09:42 PM" />
-				<Station Name="PUF1.Vertical.LoaderPutDown" Position="-277" ModifiedDate="9/19/2018 4:31:55 PM" />
-			</Stations>
-		</Axis>
-		<Axis Name="PUF2.Flip">
-			<ToleranceDefault>0.5</ToleranceDefault>
-			<Stations>
-				<Station Name="PUF2.Flip.SideA" Position="178" ModifiedDate="2024-08-09 13:38:11.955" />
-				<Station Name="PUF2.Flip.SideB" Position="-2.04615" ModifiedDate="9/6/2018 10:24:30 AM" />
-			</Stations>
-		</Axis>
-		<Axis Name="PUF2.Rotation">
-			<ToleranceDefault>0.5</ToleranceDefault>
-			<Stations>
-				<Station Name="PUF2.Rotation.Home" Position="-23.2889" />
-				<Station Name="PUF2.Rotation.Flip" Position="8" ModifiedDate="4/6/2015 8:52:34 PM" />
-				<Station Name="PUF2.Rotation.Robot" Position="-23.2889" />
-				<Station Name="PUF2.Rotation.Park" Position="-23.2889" />
-				<Station Name="PUF2.Rotation.LoaderPickup" Position="8.7003" ModifiedDate="9/19/2018 4:41:57 PM" />
-				<Station Name="PUF2.Rotation.LoaderPutDown" Position="8.500501" ModifiedDate="9/19/2018 4:48:41 PM" />
-			</Stations>
-		</Axis>
-		<Axis Name="PUF2.Vertical">
-			<ToleranceDefault>0.5</ToleranceDefault>
+			<ToleranceDefault>0.1</ToleranceDefault>
 			<Stations>
-				<Station Name="PUF2.Vertical.Home" Position="-15" />
-				<Station Name="PUF2.Vertical.Flip" Position="-140" ModifiedDate="9/29/2018 3:15:47 PM" />
-				<Station Name="PUF2.Vertical.Robot" Position="-148" ModifiedDate="2024-08-09 13:47:40.203" />
-				<Station Name="PUF2.Vertical.Park" Position="-15" ModifiedDate="5/7/2015 11:15:42 PM" />
-				<Station Name="PUF2.Vertical.Loader" Position="-50" />
-				<Station Name="PUF2.Vertical.LoaderPickup" Position="-276.1" ModifiedDate="9/19/2018 4:44:11 PM" />
-				<Station Name="PUF2.Vertical.LoaderPutDown" Position="-273.5" ModifiedDate="9/19/2018 5:47:50 PM" />
+				<Station Name="PUF1.Rotation.Home" Position="22.146" ModifiedDate="8/27/2018 2:53:59 PM" />
+				<Station Name="PUF1.Rotation.Park" Position="22.146" ModifiedDate="8/27/2018 2:54:03 PM" />
+				<Station Name="PUF1.Rotation.Flip" Position="22.146" ModifiedDate="4/6/2015 8:34:18 PM" />
+				<Station Name="PUF1.Rotation.Robot" Position="22.146" ModifiedDate="7/31/2018 4:34:50 PM" />
+				<Station Name="PUF1.Rotation.LoaderPickup" Position="56.324" ModifiedDate="9/14/2018 2:13:39 PM" />
+				<Station Name="PUF1.Rotation.LoaderPutDown" Position="53.447" ModifiedDate="9/19/2018 4:32:00 PM" />
 			</Stations>
 		</Axis>
 	</Module>

+ 24 - 24
CyberX8_RT/Devices/Loader/LoaderInstallCRSRoutine.cs

@@ -161,7 +161,7 @@ namespace CyberX8_RT.Devices.Loader
                 .Run(InstallStep.ShuttleGotoMID, () => { return _shuttleAxis.PositionStation("MID", false); }, NullFun, _delay_1ms)
                 .WaitWithStopCondition(InstallStep.ShuttleGotoMIDWait, () => { return _shuttleAxis.Status == RState.End; }, 
                     () => { return _shuttleAxis.Status == RState.Failed; })
-                //17. Home LS Axis
+                //17. Home LS Axis,Goto
                 .Run(InstallStep.HomingLSAxis, () => { return _lsAxis.Home(); }, _delay_1ms)
                 .WaitWithStopCondition(InstallStep.HomingLSAxisWait, () => { return _lsAxis.Status == RState.End; }, 
                     () => { return _lsAxis.Status == RState.Failed; })
@@ -383,18 +383,18 @@ namespace CyberX8_RT.Devices.Loader
         {
             LoaderSideData sideData = _sideDevice.SideData;
             LoaderCommonData commonData = _loaderCommonDevice.CommonData;
-            //Bernoulli Bladder(WS Bladder on)
-            if (!sideData.BernoulliBladder)
-            {
-                NotifyError(eEvent.ERR_LOADER, "Bernoulli Bladder is off", -1);
-                return false;
-            }
-            //Bernoulli N2(BernoulliN2 off)
-            if (sideData.BernoulliN2)
-            {
-                NotifyError(eEvent.ERR_LOADER, "Bernoulli N2 is on", -1);
-                return false;
-            }
+            //Bernoulli Bladder(Bernoulli Bladder any state)
+            //if (!sideData.BernoulliBladder)
+            //{
+            //    NotifyError(eEvent.ERR_LOADER, "Bernoulli Bladder is off", -1);
+            //    return false;
+            //}
+            //Bernoulli N2(BernoulliN2 any state)
+            //if (sideData.BernoulliN2)
+            //{
+            //    NotifyError(eEvent.ERR_LOADER, "Bernoulli N2 is on", -1);
+            //    return false;
+            //}
             //CRS Vacuum检验(Vacuum off)
             if (sideData.CRSVacuum)
             {
@@ -407,18 +407,18 @@ namespace CyberX8_RT.Devices.Loader
                 LOG.WriteLog(eEvent.ERR_LOADER, Module, "Wafer Shuttle is absent");
                 return false;
             }
-            //WS Clamp On
-            if (!commonData.WaferHolderClamp)
-            {
-                NotifyError(eEvent.ERR_LOADER, "Wafer Shuttle Clamp is off", -1);
-                return false;
-            }
+            //WS Clamp On any state
+            //if (!commonData.WaferHolderClamp)
+            //{
+            //    NotifyError(eEvent.ERR_LOADER, "Wafer Shuttle Clamp is off", -1);
+            //    return false;
+            //}
             //WS Bladder off
-            if (sideData.WHBladder)
-            {
-                LOG.WriteLog(eEvent.ERR_LOADER, Module, "WS Bladder is on");
-                return false;
-            }
+            //if (sideData.WHBladder)
+            //{
+            //    LOG.WriteLog(eEvent.ERR_LOADER, Module, "WS Bladder is on");
+            //    return false;
+            //}
             //Drip Tray Fluid(正常)
             if (commonData.DripTrayFluid)
             {

+ 2 - 2
CyberX8_Simulator/Config/UILayout.xml

@@ -17,8 +17,8 @@
 	</Navigation>
 
 	<Navigation Id="Galil" Name="Galil">
-		<SubView Id="Galil" Name="Galil" ViewClass="CyberX8_Simulator.Views.GalilView" Assembly="CyberX8_Simulator" Port="58678"/>
-		<SubView Id="Gali2" Name="Gali2" ViewClass="CyberX8_Simulator.Views.GalilView" Assembly="CyberX8_Simulator" Port="58679"/>
+		<SubView Id="Galil1" Name="Galil1" ViewClass="CyberX8_Simulator.Views.GalilView" Assembly="CyberX8_Simulator" Port="58678"/>
+		<SubView Id="Galil2" Name="Galil2" ViewClass="CyberX8_Simulator.Views.GalilView" Assembly="CyberX8_Simulator" Port="58679"/>
 	</Navigation>
 	
 	<Navigation Id="Power" Name="Power" >		

+ 13 - 3
CyberX8_Simulator/Devices/FestoSocketSimulator.cs

@@ -80,8 +80,12 @@ namespace CyberX8_Simulator.Devices
                 if(startAddress >= FESTO_DO_START_ADDRESS)
                 {
                     //通知相关数据变化
-                    var result = DecodeDOData(startAddress, value);
-                    SimulatorCommManager.Instance.CheckDataChanged(result.Item1, result.Item2);
+                    bool changeFlag = true;
+                    var result = DecodeDOData(startAddress, value, out changeFlag);
+                    if (changeFlag)
+                    {                      
+                        SimulatorCommManager.Instance.CheckDataChanged(result.Item1, result.Item2);
+                    }                    
                     //modbus起始地址n为数据,n+1为诊断数据,取地址n下的数据
                     _festoOutputDataDic[(startAddress - FESTO_DO_START_ADDRESS) * 2] = value;
                     
@@ -189,9 +193,15 @@ namespace CyberX8_Simulator.Devices
         /// <param name="address"></param>
         /// <param name="value"></param>
         /// <returns></returns>
-        private (string, bool) DecodeDOData(ushort address, short value)
+        private (string, bool) DecodeDOData(ushort address, short value, out bool flag)
         {
+            flag = true;
             int index = (address - FESTO_DO_START_ADDRESS) * 2;
+            if (_festoOutputDataDic[index] == value) 
+            {
+                flag = false;
+                return ("", false);
+            } 
             int bitNum = (int)Math.Log(_festoOutputDataDic[index] ^ value, 2);
             bool valueBool = (value & (1 << bitNum)) != 0 ? true : false;
             string str = $"{address}-{bitNum}";

+ 300 - 60
CyberX8_Simulator/Devices/GalilSocketSimulator.cs

@@ -1,10 +1,6 @@
 using Aitex.Common.Util;
-using Aitex.Core.RT.DataCenter;
-using Aitex.Core.RT.Routine;
 using Aitex.Core.Util;
-using CyberX8_Core;
-using MECF.Framework.Common.CommonData.PUF;
-using MECF.Framework.Common.Device.Festo;
+using MECF.Framework.Common.Beckhoff.AxisProvider;
 using MECF.Framework.Common.Device.Galil;
 using MECF.Framework.Common.Net;
 using MECF.Framework.Common.Simulator;
@@ -13,19 +9,36 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Text;
-using Xceed.Wpf.Toolkit.Panels;
 
 namespace CyberX8_Simulator.Devices
 {
     public class GalilSocketSimulator : SocketDeviceSimulator
     {
+
         #region 常量
         //最大运动轴数量(abcdefg)
         private const int MAX_AXIS_NUM = 8;
         //GalilControllerData最大数据长度
-        private const int MAX_CONTROL_DATA_LENGTH = 264;
-        //GalilAxisData最大数据长度
-        private const int MAX_AXIS_DATA_LENGTH = 28;
+        private const int MAX_CONTROL_DATA_LENGTH_21 = 264;
+        private const int MAX_CONTROL_DATA_LENGTH_40 = 366;
+       //GalilAxisData最大数据长度
+       private const int MAX_AXIS_DATA_LENGTH_21 = 28;
+        private const int MAX_AXIS_DATA_LENGTH_40 = 36;
+
+        private const string TARGET_VELOCITY = "TargetVelocity";
+        private const string TARGET_ACCEL = "TargetAcceleration";
+        private const string TARGET_DECEL = "TargetDeceleration";
+        private const string TARGET_POSITION = "TargetPosition";
+        private const string SWITCH_SIGNAL = "SwitchSignal";
+        private const string ACTUAL_POSITION = "ActualPosition";
+        private const string AUXILIARY_POSITION = "AuxiliaryPosition";
+        private const string HOMING_SIGNAL = "HomingSignal";
+        private const string MOTION_SIGNAL = "MotionSignal";
+        private const string STOP_SIGNAL = "StopSignal";
+        private const double MOTOR_POSITION_FACTOR = 31.25;
+        private const string GALIL_21 = "Galil21";
+        private const string GALIL_40 = "Galil40";
+       
         #endregion
 
         #region 内部变量
@@ -39,10 +52,30 @@ namespace CyberX8_Simulator.Devices
         /// </summary>
         private Dictionary<string, int> _axisNameIndexDic = new Dictionary<string, int>();
         /// <summary>
+        /// Axis名称列表(index - axisName)
+        /// </summary>
+        private string[] _nameAxisList = new string[MAX_AXIS_NUM];
+        /// <summary>
         /// ModuleName
         /// </summary>
         /// <param name="port"></param>
         private string _moduleName;
+        /// <summary>
+        /// Galil Type
+        /// </summary>
+        private string _galilType;
+        /// <summary>
+        /// GalilControllerData数据长度
+        /// </summary>
+        private int _controlDataLength;
+        /// <summary>
+        /// GalilAxisDatas数据长度
+        /// </summary>
+        private int _axisDataLength;
+        /// <summary>
+        /// MotorPosition比例系数字典(index - motorPositionRate)
+        /// </summary>
+        private Dictionary<string, double> _motorPositionRateDic = new Dictionary<string, double>();
         #endregion
         /// <summary>
         /// 构造函数
@@ -94,13 +127,23 @@ namespace CyberX8_Simulator.Devices
         {
             //数据头(4 bytes)
             int headLength = 4;
-            byte[] result = new byte[headLength + MAX_CONTROL_DATA_LENGTH];
+            byte[] result = new byte[headLength + _controlDataLength];
             result[0] = 0x00;
             result[1] = 0x00;
-            short dataLength = (short)(headLength + MAX_CONTROL_DATA_LENGTH);
+            short dataLength = (short)(headLength + _controlDataLength);
             Array.Copy(byteTransform.GetBytes(dataLength), 0, result, 2, 2);
             //数据体(MAX_CONTROL_DATA_LENGTH bytes)
-            Array.Copy(CodeControlData(data), 0, result, 4, MAX_CONTROL_DATA_LENGTH);
+            switch (_galilType)
+            {
+                case GALIL_21:
+                    Array.Copy(CodeControlData21(data), 0, result, 4, MAX_CONTROL_DATA_LENGTH_21);
+                    break;
+                case GALIL_40:
+                    Array.Copy(CodeControlData40(data), 0, result, 4, MAX_CONTROL_DATA_LENGTH_40);
+                    break;
+                default:
+                    break;
+            }           
             return result;
         }
         /// <summary>
@@ -149,9 +192,9 @@ namespace CyberX8_Simulator.Devices
                 _galilControlData.GalilAxisDatas[i].Status = 0x01;
             }
             _galilControlData.Inputs  = new byte[10];
-            _galilControlData.Outputs = new byte[10];   
-            _galilControlData.SBlocks = new byte[8];   
-            _galilControlData.TBlocks = new byte[8];
+            _galilControlData.Outputs = new byte[10]; 
+            
+            
             //电机数据更新事件
             MotorSimulator.Instance.OnUpdateVariableValueChanged += UpdataRealTimeMotionData;
             //加载对应配置文件 GalilControllerCfg-Simulator.xml
@@ -163,23 +206,56 @@ namespace CyberX8_Simulator.Devices
                 if (port == config.Port)
                 {
                     _moduleName = config.Module;
+                    _galilType = config.GalilType;                   
                     foreach (GalilAxisConfig item in config.GalilAxises)
                     {
                         _axisNameIndexDic[$"{config.Module}.{item.Name}"] = item.Index;
+                        _nameAxisList[item.Index] = $"{config.Module}.{item.Name}";
                     }
                 }
             }
+            //加载AxisProviderCfg.xml
+            oldXmlPath = PathManager.GetCfgDir();
+            newXmlPath = oldXmlPath.Replace("CyberX8_Simulator", "CyberX8_RT") + "Devices\\AxisProviderCfg.xml";
+            BeckhoffAxisProviderCfg axisProviderCfg = CustomXmlSerializer.Deserialize<BeckhoffAxisProviderCfg>(new FileInfo(newXmlPath));
+            foreach(BeckhoffProviderAxis item in axisProviderCfg.Axes)
+            {
+                for (int i = 0; i < MAX_AXIS_NUM; i++)
+                {
+                    if (_nameAxisList[i] == item.Name)
+                    {
+                        _motorPositionRateDic[item.Name] = item.MotorPositionRate;
+                    }
+                }                   
+            }
+
+            if (_galilType == GALIL_40)
+            {
+                _controlDataLength = MAX_CONTROL_DATA_LENGTH_40;
+                _axisDataLength = MAX_AXIS_DATA_LENGTH_40;
+                _galilControlData.SBlocks = new byte[10];
+                _galilControlData.TBlocks = new byte[10];
+            }
+            else
+            {
+                _controlDataLength = MAX_CONTROL_DATA_LENGTH_21;
+                _axisDataLength = MAX_AXIS_DATA_LENGTH_21;
+                _galilControlData.SBlocks = new byte[8];
+                _galilControlData.TBlocks = new byte[8];
+            }
+            
         }
+        #region Galil编码
         /// <summary>
-        /// GalilControllerData编码
+        /// GalilControllerData编码(Galil21)
         /// </summary>
         /// <returns></returns>
-        private byte[] CodeControlData(GalilControllerData ctrlData)
+        private byte[] CodeControlData21(GalilControllerData ctrlData)
         {
-            byte[] result = new byte[MAX_CONTROL_DATA_LENGTH];
+            byte[] result = new byte[MAX_CONTROL_DATA_LENGTH_21];
             int index = 0;
             //Sample(2 bytes)
-            Array.Copy(byteTransform.GetBytes(ctrlData.Sample), 0, result, index, 2);
+            Array.Copy(BitConverter.GetBytes(ctrlData.Sample), 0, result, index, 2);
             index += 2;
             //Inputs(1*10 bytes)
             Array.Copy(ctrlData.Inputs, 0, result, index, 10);
@@ -189,10 +265,10 @@ namespace CyberX8_Simulator.Devices
             index += 10;
             //Error Code(1 bytes)         
             result[13] = ctrlData.ErrorCode;
-            index ++;
+            index++;
             //General Status(1 bytes)
             result[14] = ctrlData.Status;
-            index ++;
+            index++;
             //S Block(2+2+4=8 bytes)
             Array.Copy(ctrlData.SBlocks, 0, result, 15, 8);
             index += 8;
@@ -200,54 +276,159 @@ namespace CyberX8_Simulator.Devices
             Array.Copy(ctrlData.TBlocks, 0, result, 23, 8);
             index += 8;
             //Axis Datas(28 * 8 bytes)
-            for(int i = 0;i < MAX_AXIS_NUM; i++)
+            for (int i = 0; i < MAX_AXIS_NUM; i++)
             {
-                Array.Copy(CodeAxisData(ctrlData.GalilAxisDatas[i]), 0, result, index, MAX_AXIS_DATA_LENGTH);
-                index += MAX_AXIS_DATA_LENGTH;
-            }     
+                Array.Copy(CodeAxisData21(ctrlData.GalilAxisDatas[i]), 0, result, index, MAX_AXIS_DATA_LENGTH_21);
+                index += MAX_AXIS_DATA_LENGTH_21;
+            }
             return result;
         }
         /// <summary>
-        /// GalilAxisData编码
+        /// GalilAxisData编码(Galil21)
         /// </summary>
         /// <param name="axisData"></param>
         /// <returns></returns>
-        private byte[] CodeAxisData(GalilAxisData axisData)
+        private byte[] CodeAxisData21(GalilAxisData axisData)
         {
-            byte[] result = new byte[MAX_AXIS_DATA_LENGTH];
+            byte[] result = new byte[MAX_AXIS_DATA_LENGTH_21];
             int index = 0;
             //Status(2 bytes)
             Array.Copy(byteTransform.GetBytes(axisData.Status), 0, result, index, 2);
             index += 2;
             //Switches(1 bytes)
             result[index] = axisData.Switches;
-            index ++;
+            index++;
             //Stop Code(1 bytes)
             result[index] = axisData.StopCode;
-            index ++;
+            index++;
             //Reference Position(4 bytes)
-            Array.Copy(byteTransform.GetBytes(axisData.ReferencePosition), 0, result, index, 4);
+            Array.Copy(BitConverter.GetBytes(axisData.ReferencePosition), 0, result, index, 4);
             index += 4;
             //Motor Position(4 bytes)
-            Array.Copy(byteTransform.GetBytes(axisData.MotorPosition), 0, result, index, 4);
+            Array.Copy(BitConverter.GetBytes(axisData.MotorPosition), 0, result, index, 4);
             index += 4;
             //Position Error
-            Array.Copy(byteTransform.GetBytes(axisData.PositionError), 0, result, index, 4);
+            Array.Copy(BitConverter.GetBytes(axisData.PositionError), 0, result, index, 4);
             index += 4;
             //Auxiliary Position
-            Array.Copy(byteTransform.GetBytes(axisData.AuxiliaryPosition), 0, result, index, 4);
+            Array.Copy(BitConverter.GetBytes(axisData.AuxiliaryPosition), 0, result, index, 4);
             index += 4;
             //Velocity
-            Array.Copy(byteTransform.GetBytes(axisData.Velocity), 0, result, index, 4);
+            Array.Copy(BitConverter.GetBytes(axisData.Velocity), 0, result, index, 4);
             index += 4;
             //Torque
-            Array.Copy(byteTransform.GetBytes(axisData.Torque), 0, result, index, 2);
+            Array.Copy(BitConverter.GetBytes(axisData.Torque), 0, result, index, 2);
             index += 2;
             //Analog
-            Array.Copy(byteTransform.GetBytes(axisData.Res), 0, result, index, 2);
+            Array.Copy(BitConverter.GetBytes(axisData.Res), 0, result, index, 2);
+            return result;
+        }
+        /// <summary>
+        /// GalilControllerData编码(Galil40)
+        /// </summary>
+        /// <returns></returns>
+        private byte[] CodeControlData40(GalilControllerData ctrlData)
+        {
+            byte[] result = new byte[MAX_CONTROL_DATA_LENGTH_40];
+            int index = 0;
+            //Sample(2 bytes)
+            Array.Copy(BitConverter.GetBytes(ctrlData.Sample), 0, result, index, 2);
+            index += 2;
+            //Inputs(1*10 bytes)
+            Array.Copy(ctrlData.Inputs, 0, result, index, 10);
+            index += 10;
+            //Outputs(1*10 bytes)
+            Array.Copy(ctrlData.Outputs, 0, result, index, 10);
+            index += 10;
+            //reservers
+            byte[] reservers = new byte[16];
+            Array.Copy(reservers, 0, result, index, 16);
+            index += 16;
+            //ethernet
+            byte[] ethernet = new byte[8];
+            Array.Copy(ethernet, 0, result, index, 8);
+            index += 8;
+            //ethernet
+            //Error Code(1 bytes)         
+            result[13] = ctrlData.ErrorCode;
+            index++;
+            //General Status(1 bytes)
+            result[14] = ctrlData.Status;
+            index++;
+            //ampliferStatus
+            byte[] ampliferStatus = new byte[4];
+            Array.Copy(ampliferStatus, 0, result, index, 4);
+            index += 4;
+            //counterModel
+            byte[] counterModel = new byte[6];
+            Array.Copy(counterModel, 0, result, index, 6);
+            index += 6;
+            //S Block(10 bytes)
+            Array.Copy(ctrlData.SBlocks, 0, result, index, 10);
+            index += 10;
+            //T Block(10 bytes)
+            Array.Copy(ctrlData.TBlocks, 0, result, index, 10);
+            index += 10;
+            //Axis Datas(36 * 8 bytes)
+            for (int i = 0; i < MAX_AXIS_NUM; i++)
+            {
+                Array.Copy(CodeAxisData40(ctrlData.GalilAxisDatas[i]), 0, result, index, MAX_AXIS_DATA_LENGTH_40);
+                index += MAX_AXIS_DATA_LENGTH_40;
+            }
             return result;
         }
         /// <summary>
+        /// GalilAxisData编码(Galil40)
+        /// </summary>
+        /// <param name="axisData"></param>
+        /// <returns></returns>
+        private byte[] CodeAxisData40(GalilAxisData axisData)
+        {
+            byte[] result = new byte[MAX_AXIS_DATA_LENGTH_40];
+            int index = 0;
+            //Status(2 bytes)
+            Array.Copy(byteTransform.GetBytes(axisData.Status), 0, result, index, 2);
+            index += 2;
+            //Switches(1 bytes)
+            result[index] = axisData.Switches;
+            index++;
+            //Stop Code(1 bytes)
+            result[index] = axisData.StopCode;
+            index++;
+            //Reference Position(4 bytes)
+            Array.Copy(BitConverter.GetBytes(axisData.ReferencePosition), 0, result, index, 4);
+            index += 4;
+            //Motor Position(4 bytes)
+            Array.Copy(BitConverter.GetBytes(axisData.MotorPosition), 0, result, index, 4);
+            index += 4;
+            //Position Error
+            Array.Copy(BitConverter.GetBytes(axisData.PositionError), 0, result, index, 4);
+            index += 4;
+            //Auxiliary Position
+            Array.Copy(BitConverter.GetBytes(axisData.AuxiliaryPosition), 0, result, index, 4);
+            index += 4;
+            //Velocity
+            Array.Copy(BitConverter.GetBytes(axisData.Velocity), 0, result, index, 4);
+            index += 4;
+            //Torque
+            Array.Copy(BitConverter.GetBytes(axisData.Torque), 0, result, index, 4);
+            index += 4;
+            //Analog
+            Array.Copy(BitConverter.GetBytes(axisData.Res), 0, result, index, 2);
+            index += 2;
+            byte hallInput = 0x00;
+            result[index] = hallInput;
+            index ++;
+            byte reserved = 0x00;
+            result[index] = reserved;
+            index ++;
+            byte[] userVariables = new byte[4];
+            Array.Copy(userVariables, 0, result, index, 4);
+            return result;
+        }
+        #endregion
+
+        /// <summary>
         /// 解析指令(操作符, 运动轴, 操作数)
         /// </summary>
         /// <param name="cmd"></param>
@@ -304,33 +485,41 @@ namespace CyberX8_Simulator.Devices
         {
             switch (cmd)
             {
-                case "SH":
+                case "SH"://上电
                     SwitchMotor(axis, true);
                     break;
-                case "MO":
+                case "MO"://下电
                     SwitchMotor(axis, false);
                     break;
-                case "PR":
+                case "PR"://相对位置
                     SetTargetRelativePosition(axis, value);
                     break;
-                case "PA":
+                case "PA"://绝对位置
                     SetTargetAbsolutePosition(axis, value);
                     break;
-                case "SP":
+                case "SP"://速度
+                    SetSpeed(axis, value);
                     break;
-                case "AC":
+                case "AC"://加速度
+                    SetAcceleration(axis, value);
                     break;
-                case "DC":
+                case "DC"://减速度
+                    SetDeceleration(axis, value);
                     break;
-                case "ST":
+                case "ST"://停止
+                    ControlMotion(axis, false);
                     break;
-                case "BG":
+                case "BG"://启动
+                    ControlMotion(axis, true);
                     break;
-                case "HM":
+                case "HM"://回零
+                    Home(axis);
                     break;
-                case "DP":
+                case "DP"://设定motor position
+                    SetMotorPosition(axis, value);
                     break;
-                case "DE":
+                case "DE"://设定auxiliary position
+                    SetAuxiliaryPosition(axis, value);
                     break;
                 default:
                     break;
@@ -341,7 +530,7 @@ namespace CyberX8_Simulator.Devices
         /// 实时更新电机数据
         /// </summary>
         /// <param name="datasDic"></param>
-        private void UpdataRealTimeMotionData(Dictionary<string, CommandMotionData> datasDic)
+        private void UpdataRealTimeMotionData(Dictionary<string, SimulatorMotionData> datasDic)
         {
             foreach(var dataItem in datasDic)
             {
@@ -355,12 +544,13 @@ namespace CyberX8_Simulator.Devices
         /// 更新对应Axis数据
         /// </summary>
         /// <param name="index"></param>
-        private void UpdateAxisData(int index, CommandMotionData data)
+        private void UpdateAxisData(int index, SimulatorMotionData data)
         {
-            _galilControlData.GalilAxisDatas[index].Velocity = (int)data.ActualVelocity;
-            _galilControlData.GalilAxisDatas[index].MotorPosition = (int)data.MotorPosition;
-            _galilControlData.GalilAxisDatas[index].ReferencePosition = (int)data.TargetPosition;
-            _galilControlData.GalilAxisDatas[index].Torque = (short)data.ActualTorque;
+            _galilControlData.GalilAxisDatas[index].Velocity = data.ActualVelocity;
+            _galilControlData.GalilAxisDatas[index].MotorPosition = (int)(data.ActualPosition / _motorPositionRateDic[_nameAxisList[index]]);
+            _galilControlData.GalilAxisDatas[index].ReferencePosition = data.TargetPosition;
+            _galilControlData.GalilAxisDatas[index].Torque = data.ActualTorque;
+            _galilControlData.GalilAxisDatas[index].StopCode = data.StopCode;
         }
         #region AxisOperation
         /// <summary>
@@ -374,27 +564,77 @@ namespace CyberX8_Simulator.Devices
             data[0] &= 0xFE;
             data[0] |= (byte)(flag ? 0x00 : 0x01);
             _galilControlData.GalilAxisDatas[axis - 'A'].Status = byteTransform.TransUInt16(data, 0);
+            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], SWITCH_SIGNAL, flag);
         }
         /// <summary>
-        /// 设置目标位置
+        /// 设置速度
         /// </summary>
         private void SetSpeed(char axis, int value)
         {
-            _galilControlData.GalilAxisDatas[axis - 'A'].Velocity = value;
+            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], TARGET_VELOCITY, value);
+        }
+        /// <summary>
+        /// 设置加速度
+        /// </summary>
+        private void SetAcceleration(char axis, int value)
+        {
+            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], TARGET_ACCEL, value);
+        }
+        /// <summary>
+        /// 设置减速度
+        /// </summary>
+        private void SetDeceleration(char axis, int value)
+        {
+            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], TARGET_DECEL, value);
         }
         /// <summary>
-        /// 设置目标绝对位置
+        /// 设置目标绝对位置(设定位置)
         /// </summary>
         private void SetTargetAbsolutePosition(char axis, int value)
         {
             _galilControlData.GalilAxisDatas[axis - 'A'].ReferencePosition = value;
+            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], TARGET_POSITION, value);
         }
         /// <summary>
-        /// 设置目标相对位置
+        /// 设置目标相对位置(设定位置)
         /// </summary>
         private void SetTargetRelativePosition(char axis, int value)
         {
-            _galilControlData.GalilAxisDatas[axis - 'A'].ReferencePosition += value;
+            _galilControlData.GalilAxisDatas[axis - 'A'].ReferencePosition = _galilControlData.GalilAxisDatas[axis - 'A'].MotorPosition + value;
+            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], TARGET_POSITION, _galilControlData.GalilAxisDatas[axis - 'A'].ReferencePosition);
+        }
+        /// <summary>
+        /// 设置 Motor Position(实际位置)
+        /// </summary>
+        /// <param name="axis"></param>
+        /// <param name="value"></param>
+        private void SetMotorPosition(char axis, int value)
+        {
+            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], ACTUAL_POSITION, value);
+        }
+        /// <summary>
+        /// 设置 Auxiliary Position
+        /// </summary>
+        /// <param name="axis"></param>
+        /// <param name="value"></param>
+        private void SetAuxiliaryPosition(char axis, int value)
+        {
+            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], AUXILIARY_POSITION, value);
+        }
+        /// <summary>
+        /// 控制运动
+        /// </summary>
+        private void ControlMotion(char axis, bool value)
+        {
+            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], value ? MOTION_SIGNAL : STOP_SIGNAL, value);
+        }
+        /// <summary>
+        /// 电机回零
+        /// </summary>
+        /// <param name="axis"></param>
+        private void Home(char axis)
+        {
+            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], HOMING_SIGNAL, true);
         }
         #endregion
     }

+ 1 - 0
Framework/Common/Common.csproj

@@ -477,6 +477,7 @@
     <Compile Include="Simulator\MotorSimulator.cs" />
     <Compile Include="Simulator\SimulatorIOMapConfig.cs" />
     <Compile Include="Simulator\SimulatorIOMapItem.cs" />
+    <Compile Include="Simulator\SimulatorMotionData.cs" />
     <Compile Include="SubstrateTrackings\MaterialInfo.cs" />
     <Compile Include="RecipeCenter\RecipeNode.cs" />
     <Compile Include="RecipeCenter\RecipeNodeType.cs" />

+ 212 - 11
Framework/Common/Simulator/MotorSimulator.cs

@@ -1,26 +1,50 @@
 using Aitex.Common.Util;
 using Aitex.Core.Util;
-using MECF.Framework.Common.CommonData.PUF;
 using MECF.Framework.Common.Device.Galil;
+using System;
 using System.Collections.Generic;
 using System.IO;
+using System.Threading;
 
 namespace MECF.Framework.Common.Simulator
 {
+    
     /// <summary>
     /// 电机运动模拟器
     /// </summary>
     public class MotorSimulator : Singleton<MotorSimulator>
     {
+        
+        #region 常量
+        private const string TARGET_VELOCITY = "TargetVelocity";
+        private const string TARGET_ACCEL = "TargetAcceleration";
+        private const string TARGET_DECEL = "TargetDeceleration";
+        private const string TARGET_POSITION = "TargetPosition";
+        private const string SWITCH_SIGNAL = "SwitchSignal";
+        private const string ACTUAL_POSITION = "ActualPosition";
+        private const string AUXILIARY_POSITION = "AuxiliaryPosition";
+        private const string HOMING_SIGNAL = "HomingSignal";
+        private const string MOTION_SIGNAL = "MotionSignal";
+        private const string STOP_SIGNAL = "StopSignal";
+        /// <summary>
+        /// 定时器间隔(ms)
+        /// </summary>
+        private const int TIMER_INTERVAL = 10;
+        /// <summary>
+        /// motor step factor
+        /// </summary>
+        private const int MOTOR_STEP_FACTOR = 10;
+        #endregion
+
         #region 内部变量
         /// <summary>
         /// 定时器
         /// </summary>
-        private PeriodicJob _periodicJob;
+        private PeriodicJob _periodicJob;      
         /// <summary>
         /// 电机数据字典(key:Name(module.name),value:Datas)
         /// </summary>
-        private Dictionary<string, CommandMotionData> _motorNameDataDic = new Dictionary<string, CommandMotionData>();
+        private Dictionary<string, SimulatorMotionData> _motorNameDataDic = new Dictionary<string, SimulatorMotionData>();
         #endregion
 
         #region 属性
@@ -29,7 +53,7 @@ namespace MECF.Framework.Common.Simulator
 
         //delegate
         #region Delegate
-        public delegate void UpdateVariableValueChanged(Dictionary<string, CommandMotionData> datasDic);
+        public delegate void UpdateVariableValueChanged(Dictionary<string, SimulatorMotionData> datasDic);
         #endregion
 
         #region 事件
@@ -43,12 +67,11 @@ namespace MECF.Framework.Common.Simulator
         /// </summary>
         public void Initialize()
         {
-
-            _periodicJob = new PeriodicJob(100, OnTimer, "Motor Simulator Timer", false);//***打开
+            _periodicJob = new PeriodicJob(TIMER_INTERVAL, OnTimer, "Motor Simulator Timer", true);
             Init();
         }
         /// <summary>
-        /// 初始化
+        /// 初始化数据
         /// </summary>
         private void Init()
         {
@@ -60,7 +83,11 @@ namespace MECF.Framework.Common.Simulator
             {               
                 foreach (GalilAxisConfig item in config.GalilAxises)
                 {
-                    _motorNameDataDic[$"{config.Module}.{item.Name}"] = new CommandMotionData();
+                    _motorNameDataDic[$"{config.Module}.{item.Name}"] = new SimulatorMotionData();
+                    _motorNameDataDic[$"{config.Module}.{item.Name}"].FwdSoftLimit = item.ForwardSoftwareLimit;
+                    _motorNameDataDic[$"{config.Module}.{item.Name}"].RevSoftLimit = item.ReverseSoftwareLimit;
+                    _motorNameDataDic[$"{config.Module}.{item.Name}"].NegativeTorqueLimit = item.NegativeTorqueLimit;
+                    _motorNameDataDic[$"{config.Module}.{item.Name}"].PositiveTorqueLimit = item.PositiveTorqueLimit;
                 }
             }
         }
@@ -70,20 +97,194 @@ namespace MECF.Framework.Common.Simulator
         /// <returns></returns>
         private bool OnTimer()
         {
-            //电机运动物理模型
-
+            //电机运动模型
+            foreach(var motorItem in _motorNameDataDic)
+            {
+                //对应电机进行模拟
+                MotorMotionSimulator(motorItem);
+            }
+            //实时更新电机数据
+            UpdateVariableValue(_motorNameDataDic);
             return true;
         }
         /// <summary>
         /// 通知Galil模块数据变化
         /// </summary>
         /// <param name="data"></param>
-        private void UpdateVariableValue(Dictionary<string, CommandMotionData> datasDic)
+        private void UpdateVariableValue(Dictionary<string, SimulatorMotionData> datasDic)
         {
             if (OnUpdateVariableValueChanged != null)
             {
                 OnUpdateVariableValueChanged(datasDic);
             }
         }
+        /// <summary>
+        /// 设置电机数据
+        /// </summary>
+        /// <param name="axisName"></param>
+        /// <param name="type"></param>
+        /// <param name="value"></param>
+        public void SetMotionData(string axisName, string type, object value)
+        {
+            switch (type)
+            {
+                case TARGET_VELOCITY:
+                    _motorNameDataDic[axisName].TargetVelocity = (int)value;
+                    break;
+                case TARGET_ACCEL:
+                    _motorNameDataDic[axisName].TargetAccel = (int)value;
+                    break;
+                case TARGET_DECEL:
+                    _motorNameDataDic[axisName].TargetDecel = (int)value;
+                    break;
+                case TARGET_POSITION:
+                    _motorNameDataDic[axisName].TargetPosition = (int)value;
+                    break;
+                case ACTUAL_POSITION:
+                    _motorNameDataDic[axisName].ActualPosition = (int)value;
+                    break;
+                case SWITCH_SIGNAL:
+                    _motorNameDataDic[axisName].SwitchSignal = (bool)value;
+                    break;
+                case STOP_SIGNAL:
+                    _motorNameDataDic[axisName].StopSignal = true;
+                    break;               
+                case HOMING_SIGNAL:
+                    _motorNameDataDic[axisName].HomingSignal = true;
+                    break;
+                case MOTION_SIGNAL:
+                    _motorNameDataDic[axisName].MotionSignal = true;
+                    break;
+                case AUXILIARY_POSITION:
+                    //++
+                    break;
+                default:
+                    break;
+            }
+        }
+        /// <summary>
+        /// 运动模拟器
+        /// </summary>
+        private void MotorMotionSimulator(KeyValuePair<string, SimulatorMotionData> motor)
+        {
+            SimulatorMotionData motionData = motor.Value;
+            //上电检查
+            if (!motionData.SwitchSignal) return;
+            if (motionData.HomingSignal)
+            {
+                HomeOperation(motionData);
+            }
+            else
+            {
+                PositionOperation(motionData);
+            }            
+        }
+        
+        /// <summary>
+        /// Home操作
+        /// </summary>
+        /// <param name="data"></param>
+        private void HomeOperation(SimulatorMotionData motionData)
+        {
+            if (motionData.MotionSignal)
+            {
+                motionData.StopCode = 10;//HM操作停止码10
+                motionData.MotionSignal = false;
+                motionData.HomingSignal = false;
+                motionData.MotionPhase = MotionPhase.Accelerating;
+                //motionData.ActualPosition = 0;
+                motionData.ActualVelocity = 0;
+            }            
+        }
+        /// <summary>
+        /// GoToPosition操作
+        /// </summary>
+        /// <param name="data"></param>
+        private void PositionOperation(SimulatorMotionData motionData)
+        {
+            if (motionData.MotionSignal)
+            {
+                //正向运动
+                int motorStep = Math.Abs(motionData.ActualPosition - motionData.TargetPosition);
+                //motionData.ActualVelocity = TrapezoidalSpeedControl(motionData);
+                motionData.ActualVelocity = motionData.TargetVelocity;
+                if (motionData.ActualPosition < motionData.TargetPosition)
+                {
+                    //motionData.ActualPosition += (motionData.ActualVelocity * TIMER_INTERVAL / 1000);
+                    motionData.ActualPosition += (motorStep / MOTOR_STEP_FACTOR < 1 ? 1 : motorStep / MOTOR_STEP_FACTOR);
+                    bool fwdLimit = motionData.FwdSoftLimit != 0 ? motionData.ActualPosition >= motionData.FwdSoftLimit : false;
+                    if (fwdLimit || motionData.ActualPosition >= motionData.TargetPosition)
+                    {
+                        motionData.StopCode = 1;//正常运动停止码1
+                        motionData.MotionSignal = false;
+                        //motionData.MotionPhase = MotionPhase.Accelerating;
+                        motionData.ActualPosition = fwdLimit ? motionData.FwdSoftLimit : motionData.TargetPosition;
+                        motionData.ActualVelocity = 0;
+                    }
+                }
+                //反向运动
+                else if (motionData.ActualPosition > motionData.TargetPosition)
+                {
+                    motionData.ActualPosition -= (motorStep / MOTOR_STEP_FACTOR < 1 ? 1 : motorStep / MOTOR_STEP_FACTOR);
+                    //motionData.ActualPosition -= (motionData.ActualVelocity * TIMER_INTERVAL / 1000);
+                    bool revLimit = motionData.RevSoftLimit != 0 ? motionData.ActualPosition <= motionData.RevSoftLimit : false;
+                    if (revLimit || motionData.ActualPosition <= motionData.TargetPosition)
+                    {
+                        motionData.StopCode = 1;//正常运动停止码1
+                        motionData.MotionSignal = false;
+                        //motionData.MotionPhase = MotionPhase.Accelerating;
+                        motionData.ActualPosition = revLimit ? motionData.RevSoftLimit : motionData.TargetPosition;
+                        motionData.ActualVelocity = 0;
+                    }
+                }
+            }
+
+            //停止信号
+            if (motionData.StopSignal)
+            {
+                motionData.MotionSignal = false;
+                motionData.StopCode = 4;//ST操作停止码4
+                motionData.StopSignal = false;
+            }
+        }
+        /// <summary>
+        /// 梯形加减速运动控制
+        /// </summary>
+        private int TrapezoidalSpeedControl(SimulatorMotionData data)
+        {
+            int speed = 0;
+            //制动距离
+            int brakeDistance = (data.ActualVelocity * data.ActualVelocity) / (2 * data.TargetDecel);
+            int remainingDistance = Math.Abs(data.ActualPosition - data.TargetPosition);
+            if (brakeDistance >= remainingDistance)
+            {
+                data.MotionPhase = MotionPhase.Decelerating;
+            }
+            else if (data.ActualVelocity < data.TargetVelocity && data.MotionPhase != MotionPhase.Decelerating)
+            {
+                data.MotionPhase = MotionPhase.Accelerating;
+            }
+            else
+            {
+                data.MotionPhase = MotionPhase.ConstantSpeed;
+            }
+
+            // 速度更新
+            switch (data.MotionPhase)
+            {
+                case MotionPhase.Accelerating:
+                    speed = Math.Min(data.ActualVelocity + data.TargetAccel * TIMER_INTERVAL / 1000, data.TargetVelocity);
+                    break;
+                case MotionPhase.ConstantSpeed:
+                    speed = data.TargetVelocity;
+                    break;
+                case MotionPhase.Decelerating:
+                    //speed = Math.Max(data.ActualVelocity - data.TargetDecel * TIMER_INTERVAL / 1000, 10);
+                    speed = Math.Max(data.ActualVelocity / 100, 10);
+                    break;
+            }
+            return speed;
+        }
+
     }
 }

+ 223 - 0
Framework/Common/Simulator/SimulatorMotionData.cs

@@ -0,0 +1,223 @@
+using MECF.Framework.Common.CommonData;
+using System.Runtime.Serialization;
+
+namespace MECF.Framework.Common.Simulator
+{
+    /// <summary>
+    /// 电机运动阶段
+    /// </summary>
+    public enum MotionPhase
+    {
+        Accelerating,
+        Decelerating,
+        ConstantSpeed
+    };
+    [DataContract]
+    public class SimulatorMotionData : NotifiableItem
+    {
+        #region 属性   
+        [DataMember]
+        public bool SwitchSignal
+        {
+            get { return _switchSignal; }
+            set { _switchSignal = value; InvokePropertyChanged(nameof(SwitchSignal)); }
+        }
+
+        [DataMember]
+        public byte StopCode
+        {
+            get { return _stopCode; }
+            set { _stopCode = value; InvokePropertyChanged(nameof(StopCode)); }
+        }
+        [DataMember]
+        public int PositionError
+        {
+            get { return _positionError; }
+            set { _positionError = value; InvokePropertyChanged(nameof(StopCode)); }
+        }
+        [DataMember]
+        public int ActualPosition
+        {
+            get { return _actualPosition; }
+            set { _actualPosition = value; InvokePropertyChanged(nameof(ActualPosition)); }
+        }
+        [DataMember]
+        public int ActualVelocity
+        {
+            get { return _actualVelocity; }
+            set { _actualVelocity = value; InvokePropertyChanged(nameof(ActualVelocity)); }
+        }
+        [DataMember]
+        public int ActualAccel
+        {
+            get { return _actualAccel; }
+            set { _actualAccel = value; InvokePropertyChanged(nameof(ActualAccel)); }
+        }
+        [DataMember]
+        public int ActualDecel
+        {
+            get { return _actualDecel; }
+            set { _actualDecel = value; InvokePropertyChanged(nameof(ActualDecel)); }
+        }
+        [DataMember]
+        public short ActualTorque
+        {
+            get { return _actualTorque; }
+            set { _actualTorque = value; InvokePropertyChanged(nameof(ActualTorque)); }
+        }
+        [DataMember]
+        public int TargetPosition
+        {
+            get { return _targetPosition; }
+            set { _targetPosition = value; InvokePropertyChanged(nameof(TargetPosition)); }
+        }
+        [DataMember]
+        public int TargetVelocity
+        {
+            get { return _targetVelocity; }
+            set { _targetVelocity = value; InvokePropertyChanged(nameof(TargetVelocity)); }
+        }
+        [DataMember]
+        public int TargetAccel
+        {
+            get { return _targetAccel; }
+            set { _targetAccel = value; InvokePropertyChanged(nameof(TargetAccel)); }
+        }
+        [DataMember]
+        public int TargetDecel
+        {
+            get { return _targetDecel; }
+            set { _targetDecel = value; InvokePropertyChanged(nameof(TargetDecel)); }
+        }
+        [DataMember]
+        public short TargetTorque
+        {
+            get { return _targetTorque; }
+            set { _targetTorque = value; InvokePropertyChanged(nameof(TargetTorque)); }
+        }
+        [DataMember]
+        public int HomingVelocity
+        {
+            get { return _homingVelocity; }
+            set { _homingVelocity = value; InvokePropertyChanged(nameof(HomingVelocity)); }
+        }
+        [DataMember]
+        public int HomingOffSet
+        {
+            get { return _homingOffSet; }
+            set { _homingOffSet = value; InvokePropertyChanged(nameof(HomingOffSet)); }
+        }
+        [DataMember]
+        public int HomingTimeout
+        {
+            get { return _homingTimeOut; }
+            set { _homingTimeOut = value; InvokePropertyChanged(nameof(HomingTimeout)); }
+        }
+        [DataMember]
+        public int HomingAccel
+        {
+            get { return _homingAccel; }
+            set { _homingAccel = value; InvokePropertyChanged(nameof(HomingAccel)); }
+        }
+        [DataMember]
+        public int HomingDecel
+        {
+            get { return _homingDecel; }
+            set { _homingDecel = value; InvokePropertyChanged(nameof(HomingDecel)); }
+        }
+        [DataMember]
+        public int RevSoftLimit
+        {
+            get { return _revSoftLimit; }
+            set { _revSoftLimit = value; InvokePropertyChanged(nameof(RevSoftLimit)); }
+        }
+        [DataMember]
+        public int FwdSoftLimit
+        {
+            get { return _fwdSoftLimit; }
+            set { _fwdSoftLimit = value; InvokePropertyChanged(nameof(FwdSoftLimit)); }
+        }
+        [DataMember]
+        public int NegativeTorqueLimit
+        {
+            get { return _negativeTorqueLimit; }
+            set { _negativeTorqueLimit = value; InvokePropertyChanged(nameof(NegativeTorqueLimit)); }
+        }
+        [DataMember]
+        public int PositiveTorqueLimit
+        {
+            get { return _positiveTorqueLimit; }
+            set { _positiveTorqueLimit = value; InvokePropertyChanged(nameof(PositiveTorqueLimit)); }
+        }
+        [DataMember]
+        public bool HomingSignal
+        {
+            get { return _homingSignal; }
+            set { _homingSignal = value; InvokePropertyChanged(nameof(HomingSignal)); }
+        }
+        [DataMember]
+        public bool MotionSignal
+        {
+            get { return _motionSignal; }
+            set { _motionSignal = value; InvokePropertyChanged(nameof(MotionSignal)); }
+        }
+        [DataMember]
+        public MotionPhase MotionPhase
+        {
+            get { return _motionPhase; }
+            set { _motionPhase = value; InvokePropertyChanged(nameof(MotionPhase)); }
+        }
+        [DataMember]
+        public bool StopSignal
+        {
+            get { return _stopSignal; }
+            set { _stopSignal = value; InvokePropertyChanged(nameof(StopSignal)); }
+        }
+        #endregion
+
+        #region 内部变量
+
+        #region Signal
+        private bool _switchSignal;
+        private bool _homingSignal;
+        private bool _motionSignal;       
+        private bool _stopSignal;
+        private MotionPhase _motionPhase;
+        #endregion
+
+        private byte _stopCode;
+        private int _positionError;
+        /// <summary>
+        /// 实际参数
+        /// </summary>
+        private int _actualPosition;   
+        private int _actualVelocity;   
+        private int _actualAccel;
+        private int _actualDecel;
+        private short _actualTorque;
+        /// <summary>
+        /// 设定参数
+        /// </summary>
+        private int _targetPosition;
+        private int _targetVelocity;
+        private int _targetAccel;
+        private int _targetDecel;
+        private short _targetTorque;
+        /// <summary>
+        /// Home相关设定参数
+        /// </summary>
+        private int _homingVelocity;
+        private int _homingOffSet;
+        private int _homingTimeOut;
+        private int _homingAccel;
+        private int _homingDecel;
+
+        private int _revSoftLimit;
+        private int _fwdSoftLimit;
+        private int _negativeTorqueLimit;
+        private int _positiveTorqueLimit;
+
+        
+        #endregion
+    }
+}