Bläddra i källkod

Add unuploaded files

zhouhr 1 år sedan
förälder
incheckning
b2e38c8ff3

+ 54 - 0
Venus/Framework/Common/ControlDataContext/OffsetItem.cs

@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MECF.Framework.Common.ControlDataContext
+{
+    [DataContract]
+    [Serializable]
+    public class OffsetItem : INotifyPropertyChanged
+    {
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        public void InvokePropertyChanged(string propertyName)
+        {
+            if (PropertyChanged != null)
+            {
+                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+            }
+        }
+
+        [DataMember]
+        public string Guid;
+        [DataMember]
+        public string SourceModule;
+        [DataMember]
+        public int SourceSlot;
+        [DataMember]
+        public string DestinationModule;
+        [DataMember]
+        public int DestinationSlot;
+        [DataMember]
+        public string OriginModule;
+        [DataMember]
+        public int OriginSlot;
+        [DataMember]
+        public string ArmPosition;
+        [DataMember]
+        public string ArmPan;
+        [DataMember]
+        public double OffsetX;
+        [DataMember]
+        public double OffsetY;
+        [DataMember]
+        public double OffsetD;
+        [DataMember]
+        public DateTime StartTime;
+        [DataMember]
+        public DateTime EndTime;
+    }
+}

+ 112 - 0
Venus/Framework/Common/DBCore/OffsetDataRecorder.cs

@@ -0,0 +1,112 @@
+using Aitex.Core.RT.DBCore;
+using Aitex.Sorter.Common;
+using MECF.Framework.Common.ControlDataContext;
+using MECF.Framework.Common.Equipment;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Venus_Core;
+
+namespace MECF.Framework.Common.DBCore
+{
+    public class OffsetDataRecorder
+    {
+
+        //数据库结构
+        //"\"guid\",",
+        //"\"source_module\",",
+        //"\"source_slot\",",
+        //"\"destination_module\",",
+        //"\"destination_slot\",",
+        //"\"origin_module\",",
+        //"\"origin_slot\",",
+        //"\"arm_position\",",
+        //"\"arm_pan\",",
+        //"\"offset_x\",",
+        //"\"offset_y\",",
+        //"\"offset_d\",",
+        //"\"start_time\",",
+        //"\"end_time\",",
+        public static void RecordOffsetData(
+            string guid,
+            ModuleName source_module, int source_slot,
+            ModuleName destination_module, int destination_slot,
+            string origin_module, int origin_slot,
+            Hand arm_position, RobotArmPan arm_pan,
+            double offset_x, double offset_y, double offset_d,
+            DateTime start_time, DateTime end_time)
+        {
+
+            string sql = string.Format(
+                "INSERT INTO \"offset_data\"(" +
+                "\"guid\"," +
+                "\"source_module\"," +
+                "\"source_slot\"," +
+                "\"destination_module\"," +
+                "\"destination_slot\"," +
+                "\"origin_module\"," +
+                "\"origin_slot\"," +
+                "\"arm_position\"," +
+                "\"arm_pan\"," +
+                "\"offset_x\"," +
+                "\"offset_y\"," +
+                "\"offset_d\"," +
+                "\"start_time\"," +
+                "\"end_time\"" +
+                ")VALUES (" +
+                $"'{guid}'," +
+                $"'{source_module}'," +
+                $"'{source_slot + 1}'," +
+                $"'{destination_module}'," +
+                $"'{destination_slot + 1}'," +
+                $"'{origin_module}'," +
+                $"'{origin_slot + 1}'," +
+                $"'{arm_position}'," +
+                $"'{arm_pan}'," +
+                $"'{offset_x}'," +
+                $"'{offset_y}'," +
+                $"'{offset_d}'," +
+                $"'{start_time.ToString("yyyy/MM/dd HH:mm:ss.fff")}'," +
+                $"'{end_time.ToString("yyyy/MM/dd HH:mm:ss.fff")}'" +
+                ");");
+            DB.Insert(sql);
+        }
+
+        public static List<OffsetItem> QueryOffsetDataByTime(string moduleName, DateTime from_time, DateTime to_time)
+        {
+            List<OffsetItem> result = new List<OffsetItem>();
+            string sql = string.Format($"SELECT * FROM \"offset_data\" WHERE \"start_time\" >= '{from_time}' AND \"start_time\" <= '{to_time}' AND \"destination_module\" = '{moduleName}' ");
+            DataSet ds = DB.ExecuteDataset(sql);
+            if (ds == null)
+                return result;
+
+            for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
+            {
+                result.Add(new OffsetItem()
+                {
+                    Guid = ds.Tables[0].Rows[i]["guid"].ToString(),
+                    SourceModule = ds.Tables[0].Rows[i]["source_module"].ToString(),
+                    DestinationModule = ds.Tables[0].Rows[i]["destination_module"].ToString(),
+                    OriginModule = ds.Tables[0].Rows[i]["origin_module"].ToString(),
+                    SourceSlot = Convert.ToInt16(ds.Tables[0].Rows[i]["source_slot"]),
+                    DestinationSlot = Convert.ToInt16(ds.Tables[0].Rows[i]["destination_slot"]),
+                    OriginSlot = Convert.ToInt16(ds.Tables[0].Rows[i]["origin_slot"]),
+                    ArmPosition = ds.Tables[0].Rows[i]["arm_position"].ToString(),
+                    ArmPan = ds.Tables[0].Rows[i]["arm_pan"].ToString(),
+                    OffsetX = Convert.ToDouble(ds.Tables[0].Rows[i]["offset_x"]),
+                    OffsetY = Convert.ToDouble(ds.Tables[0].Rows[i]["offset_y"]),
+                    OffsetD = Convert.ToDouble(ds.Tables[0].Rows[i]["offset_d"]),
+                    StartTime = (DateTime)ds.Tables[0].Rows[i]["start_time"],
+                    EndTime = (DateTime)ds.Tables[0].Rows[i]["end_time"],
+                });
+            }
+
+            ds.Clear();
+
+            return result;
+        }
+    }
+}

+ 16 - 0
Venus/Venus_Core/RobotArmPan.cs

@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Venus_Core
+{
+    public enum RobotArmPan
+    {
+        Left,
+        Right,
+        Both,
+        None
+    }
+}

+ 211 - 0
Venus/Venus_MainPages/ViewModels/WaferOffsetViewModel.cs

@@ -0,0 +1,211 @@
+using Aitex.Core.UI.View.Common;
+using MECF.Framework.Common.ControlDataContext;
+using MECF.Framework.Common.DataCenter;
+using MECF.Framework.Common.Equipment;
+using Prism.Commands;
+using Prism.Mvvm;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Venus_MainPages.Views;
+
+namespace Venus_MainPages.ViewModels
+{
+    public class WaferOffsetViewModel : BindableBase
+    {
+        #region 私有变量
+        private DateTime m_fromdateTime;//开始时间
+        private DateTime m_todateTime;//结束时间
+        private bool m_PMAIsInstalled;//模块安装用于show
+        private bool m_PMBIsInstalled;//模块安装用于show
+        private bool m_PMCIsInstalled;//模块安装用于show
+        private bool m_PMDIsInstalled;//模块安装用于show
+        private bool m_LLAIsInstalled;//模块安装用于show
+        private bool m_LLBIsInstalled;//模块安装用于show
+        private List<AwcModule> m_AwcModulesList;
+        private WaferOffsetView m_waferoffset;
+        private DelegateCommand<object> _LoadCommandPD;
+        #endregion
+        #region 公开变量
+        public bool PMAIsInstalled
+        {
+            get { return m_PMAIsInstalled; }
+            set { SetProperty(ref m_PMAIsInstalled, value); }
+        }
+        public bool PMBIsInstalled
+        {
+            get { return m_PMBIsInstalled; }
+            set { SetProperty(ref m_PMBIsInstalled, value); }
+        }
+        public bool PMCIsInstalled
+        {
+            get { return m_PMCIsInstalled; }
+            set { SetProperty(ref m_PMCIsInstalled, value); }
+        }
+        public bool PMDIsInstalled
+        {
+            get { return m_PMDIsInstalled; }
+            set { SetProperty(ref m_PMDIsInstalled, value); }
+        }
+        public bool LLAIsInstalled
+        {
+            get { return m_LLAIsInstalled; }
+            set { SetProperty(ref m_LLAIsInstalled, value); }
+        }
+        public bool LLBIsInstalled
+        {
+            get { return m_LLBIsInstalled; }
+            set { SetProperty(ref m_LLBIsInstalled, value); }
+        }
+
+
+        public DateTime FromDateTime 
+        { 
+            get => m_fromdateTime; 
+            set 
+            { 
+                SetProperty(ref m_fromdateTime, value);
+            } 
+        }
+        public DateTime ToDateTime
+        {
+            get => m_todateTime;
+            set
+            {
+                SetProperty(ref m_todateTime, value);
+            }
+        }
+        public List<AwcModule> AwcModulesList
+        {
+            get { return m_AwcModulesList; }
+            set { SetProperty(ref m_AwcModulesList, value); }
+        }
+        public DelegateCommand<object> LoadCommandPD =>
+            _LoadCommandPD ?? (_LoadCommandPD = new DelegateCommand<object>(OnLoadPd));
+
+        #endregion
+
+        #region 私有方法
+
+        private void OnLoadPd(object obj)
+        {
+            m_waferoffset = (WaferOffsetView)obj; 
+            m_waferoffset.TimeFrom.ValueChanged += TimeFrom_ValueChanged;
+            m_waferoffset.TimeTo.ValueChanged += TimeFrom_ValueChanged;
+            m_waferoffset.TimeFrom.Value = DateTime.Today;
+            m_waferoffset.TimeTo.Value = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 23, 59, 59, 999);
+
+        }
+
+        private void TimeFrom_ValueChanged(object sender, EventArgs e)
+        {
+            if (AwcModulesList.Count > 0)
+            {
+                for (int i = 0; i < AwcModulesList.Count; i++)
+                {
+                    AwcModulesList[i].From_date = m_waferoffset.TimeFrom.Value;
+                    AwcModulesList[i].End_date = m_waferoffset.TimeTo.Value;
+                }
+            }
+        }
+
+        #endregion
+
+        //public ObservableCollection<> 
+
+        public WaferOffsetViewModel()
+        {
+            string allModules = QueryDataClient.Instance.Service.GetConfig($"System.InstalledModules").ToString();
+            AwcModulesList = new List<AwcModule>();
+            if (allModules.Contains("PMA"))
+                AwcModulesList.Add(new AwcModule() { Module_Name = ModuleName.PMA.ToString(), From_date = FromDateTime, End_date = ToDateTime, OffsetItems = new List<OffsetItem>() });
+            if (allModules.Contains("PMB"))
+                AwcModulesList.Add(new AwcModule() { Module_Name = ModuleName.PMB.ToString(), From_date = FromDateTime, End_date = ToDateTime, OffsetItems = new List<OffsetItem>() });
+            if (allModules.Contains("PMC"))
+                AwcModulesList.Add(new AwcModule() { Module_Name = ModuleName.PMC.ToString(), From_date = FromDateTime, End_date = ToDateTime, OffsetItems = new List<OffsetItem>() });
+            if (allModules.Contains("PMD"))
+                AwcModulesList.Add(new AwcModule() { Module_Name = ModuleName.PMD.ToString(), From_date = FromDateTime, End_date = ToDateTime, OffsetItems = new List<OffsetItem>() });
+            if (allModules.Contains("LLA"))
+                AwcModulesList.Add(new AwcModule() { Module_Name = ModuleName.LLA.ToString(), From_date = FromDateTime, End_date = ToDateTime, OffsetItems = new List<OffsetItem>() });
+            if (allModules.Contains("LLB"))
+                AwcModulesList.Add(new AwcModule() { Module_Name = ModuleName.LLB.ToString(), From_date = FromDateTime, End_date = ToDateTime, OffsetItems = new List<OffsetItem>() });
+            }
+
+    }
+
+    //用于散点展示的数据结构
+    public class AwcModule : INotifyPropertyChanged
+    {
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        public void InvokePropertyChanged(string propertyName)
+        {
+            if (PropertyChanged != null)
+            {
+                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+            }
+        }
+        private string _modulename;
+        private DelegateCommand _GetDataCommand;
+        private DelegateCommand _RemoveDataCommand;
+        private List<OffsetItem> _OffsetItems;
+        private DateTime _From_date;
+        private DateTime _End_date;
+        private List<(double x, double y, int arm, string info)> _PositionInfo;
+
+
+        public string Module_Name { get => _modulename; set { _modulename = value; InvokePropertyChanged("Module_Name"); } }
+        public DateTime From_date { get => _From_date; set { _From_date = value; InvokePropertyChanged("From_date"); } }
+        public DateTime End_date { get => _End_date; set { _End_date = value; InvokePropertyChanged("End_date"); } }
+        public List<OffsetItem> OffsetItems { get => _OffsetItems; set { _OffsetItems = value; InvokePropertyChanged("OffsetItems"); } }
+
+        public List<(double x, double y, int arm, string info)> PositionInfo
+        {
+            get => _PositionInfo;
+            set
+            {
+                _PositionInfo = value;
+                InvokePropertyChanged("PositionInfo");
+            }
+        }
+
+        public DelegateCommand GetDataCommand =>
+            _GetDataCommand ?? (_GetDataCommand = new DelegateCommand(getdata));
+        public DelegateCommand RemoveDataCommand =>
+            _RemoveDataCommand ?? (_RemoveDataCommand = new DelegateCommand(() => PositionInfo = new List<(double x, double y, int arm, string info)>()));
+        private void getdata()
+        {
+            OffsetItems = QueryDataClient.Instance.Service.QueryOffsetDataByTime(Module_Name, From_date, End_date);
+            List<(double x, double y, int arm, string info)> posInfo = new List<(double x, double y, int arm, string info)>();
+            foreach (OffsetItem item in OffsetItems)
+            {
+                int armPt;
+                if (item.ArmPosition == "Blade1")
+                    armPt = 1;
+                else
+                    armPt = 0;
+
+                string content = string.Format(
+                    $"OriginModule:{item.OriginModule}\r\n" +
+                    $"OriginSlot:{item.OriginSlot}\r\n" +
+                    $"SourceModule:{item.SourceModule}\r\n" +
+                    $"SourceSlot:{item.SourceSlot}\r\n" +
+                    $"DestinationModule:{item.DestinationModule}\r\n" +
+                    $"DestinationSlot:{item.DestinationSlot}\r\n" +
+                    $"ArmPosition:{item.ArmPosition}\r\n" +
+                    $"ArmPan:{item.ArmPan}\r\n" +
+                    $"OffsetX:{item.OffsetX}\r\n" +
+                    $"OffsetY:{item.OffsetY}\r\n" +
+                    $"OffsetD:{item.OffsetD}\r\n" +
+                    $"StartTime:{item.StartTime}\r\n" +
+                    $"EndTime:{item.EndTime}\r\n"
+                    );
+                posInfo.Add((item.OffsetX, item.OffsetY, armPt, content));
+            }
+            PositionInfo = posInfo;
+        }
+    }
+}

+ 117 - 0
Venus/Venus_MainPages/Views/WaferOffsetView.xaml

@@ -0,0 +1,117 @@
+<UserControl x:Class="Venus_MainPages.Views.WaferOffsetView"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:Venus_MainPages.Views"
+             xmlns:sys="clr-namespace:System;assembly=mscorlib"
+             xmlns:wfi ="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration" 
+             xmlns:wf ="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
+             mc:Ignorable="d"
+             xmlns:ctrls="clr-namespace:Venus_Themes.UserControls;assembly=Venus_Themes"
+             xmlns:prism="http://prismlibrary.com/" 
+             xmlns:viewmodels="clr-namespace:Venus_MainPages.ViewModels"
+             xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
+             d:DataContext="{d:DesignInstance Type=viewmodels:WaferOffsetViewModel}"
+             prism:ViewModelLocator.AutoWireViewModel="True"
+             x:Name="waferOffsetView"
+             d:DesignHeight="450" d:DesignWidth="800">
+    <i:Interaction.Triggers>
+        <i:EventTrigger EventName="Loaded">
+            <i:InvokeCommandAction Command="{Binding LoadCommandPD}" CommandParameter="{Binding ElementName=waferOffsetView}"/>
+        </i:EventTrigger>
+    </i:Interaction.Triggers>
+    <UserControl.Resources>
+        <ControlTemplate x:Key="CustomDatePick" TargetType="TextBox">
+            <Border BorderThickness=".5" BorderBrush="LightGray" Padding="0">
+                <StackPanel MinWidth="126" Orientation="Horizontal">
+                    <!--<TextBox FontSize="10" BorderBrush="{x:Null}" BorderThickness="0" Height="20" HorizontalAlignment="Left" VerticalAlignment="Center" VerticalContentAlignment="Center">2023</TextBox>
+                    <Label Background="White" Height="20" Margin="-2,0" Panel.ZIndex="1" VerticalContentAlignment="Center"  HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="9" Padding="1">/</Label>
+                    <TextBox FontSize="10" BorderBrush="{x:Null}" BorderThickness="0" Height="20" HorizontalAlignment="Left" VerticalAlignment="Center" VerticalContentAlignment="Center">12</TextBox>
+                    <Label Background="White" Height="20" Margin="-2,0" Panel.ZIndex="1" VerticalContentAlignment="Center"  HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="9" Padding="1">/</Label>
+                    <TextBox FontSize="10" BorderBrush="{x:Null}" BorderThickness="0" Height="20" HorizontalAlignment="Left" VerticalAlignment="Center" VerticalContentAlignment="Center">31</TextBox>-->
+                    
+                    <TextBox FontSize="10" BorderBrush="{x:Null}" BorderThickness="0" Height="20" HorizontalAlignment="Left" VerticalAlignment="Center" VerticalContentAlignment="Center"></TextBox>
+                    <TextBox FontSize="10" BorderBrush="{x:Null}" BorderThickness="0" Height="20" HorizontalAlignment="Left" VerticalAlignment="Center" VerticalContentAlignment="Center">23</TextBox>
+                    <Label Background="White" Height="20" Margin="-2,0" Panel.ZIndex="1" VerticalContentAlignment="Center"  HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="9" Padding="1">:</Label>
+                    <TextBox FontSize="10" BorderBrush="{x:Null}" BorderThickness="0" Height="20" HorizontalAlignment="Left" VerticalAlignment="Center" VerticalContentAlignment="Center">59</TextBox>
+                    <Label Background="White" Height="20" Margin="-2,0" Panel.ZIndex="1" VerticalContentAlignment="Center"  HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="9" Padding="1">:</Label>
+                    <TextBox FontSize="10"  BorderBrush="{x:Null}" BorderThickness="0" Height="20" HorizontalAlignment="Left" VerticalAlignment="Center" VerticalContentAlignment="Center">59</TextBox>
+                    <DatePicker SelectedDate="{x:Static sys:DateTime.Now}" Name="st_date" DisplayDate="2019-01-01" Margin="-13,0,0,0" FontSize="1" Panel.ZIndex="-1" BorderBrush="Transparent" Height="24" Width="40" Foreground="Transparent" HorizontalAlignment="Left" VerticalAlignment="Center"></DatePicker>
+                </StackPanel>
+            </Border>
+            <ControlTemplate.Triggers>
+                
+            </ControlTemplate.Triggers>
+        </ControlTemplate>
+    </UserControl.Resources>
+    <Grid>
+        <Grid.RowDefinitions>
+            <RowDefinition Height="50"/>
+            <RowDefinition Height="*"/>
+        </Grid.RowDefinitions>
+        <Grid.ColumnDefinitions>
+            <ColumnDefinition Width="*"/>
+        </Grid.ColumnDefinitions>
+        <!-- 选项栏-->
+        <Grid>
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="30"></ColumnDefinition>
+                <ColumnDefinition Width="400"></ColumnDefinition>
+                <ColumnDefinition Width="*"></ColumnDefinition>
+                <ColumnDefinition Width="200" MinWidth="90"></ColumnDefinition>
+            </Grid.ColumnDefinitions>
+            <StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center" Height="25">
+                <!--<TextBlock VerticalAlignment="Center" Text="Time From "></TextBlock>
+                <TextBox Template="{StaticResource CustomDatePick}"></TextBox>-->
+                <Label Content="Time From:"/>
+                <wfi:WindowsFormsHost FontSize="13" FontFamily="Arial" Width="150" Height="20" VerticalAlignment="Center">
+                    <wf:DateTimePicker x:Name="TimeFrom" Value="{x:Static sys:DateTime.Now}" CustomFormat="yyyy/MM/dd HH:mm:ss" Format="Custom"></wf:DateTimePicker>
+                </wfi:WindowsFormsHost>
+                <TextBlock VerticalAlignment="Center" Text=" To "></TextBlock>
+                <wfi:WindowsFormsHost FontSize="13" FontFamily="Arial" Width="150" Height="20" VerticalAlignment="Center">
+                    <wf:DateTimePicker x:Name="TimeTo" Value="{x:Static sys:DateTime.Now}" CustomFormat="yyyy/MM/dd HH:mm:ss" Format="Custom"></wf:DateTimePicker>
+                </wfi:WindowsFormsHost>
+            </StackPanel>
+            <StackPanel Grid.Column="3" Orientation="Horizontal" VerticalAlignment="Center">
+                <Ellipse Fill="Yellow" Width="10" Height="10"></Ellipse>
+                <TextBlock Margin="5,0"> : Upper ARM</TextBlock>
+                <Ellipse Fill="#2e849b" Width="10" Height="10"></Ellipse>
+                <TextBlock Margin="5,0"> : Lower ARM</TextBlock>
+            </StackPanel>
+        </Grid>
+        <!-- 数据wafer offset栏 -->
+        <ListBox Grid.Column="1" Grid.Row="1" Margin="40,0,0,0" ItemsSource="{Binding AwcModulesList}" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
+            <ListBox.ItemContainerStyle>
+                <Style TargetType="ListBoxItem">
+                    <Setter Property="IsSelected" Value="{Binding Content.IsSelected, Mode=TwoWay, RelativeSource={RelativeSource Self}}"/>
+                    <Setter Property="Template">
+                        <Setter.Value>
+                            <ControlTemplate TargetType="ListBoxItem">
+                                <ContentPresenter/>
+                            </ControlTemplate>
+                        </Setter.Value>
+                    </Setter>
+                </Style>
+            </ListBox.ItemContainerStyle>
+            <ListBox.ItemsPanel>
+                <ItemsPanelTemplate>
+                    <WrapPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="40,0" ScrollViewer.CanContentScroll="True"/>
+                </ItemsPanelTemplate>
+            </ListBox.ItemsPanel>
+            <ListBox.ItemTemplate>
+                <DataTemplate>
+                    <Canvas Width="400" Height="350" Margin="10,0">
+                        <TextBlock Canvas.Top="0" Canvas.Left="165" Text="{Binding Module_Name,UpdateSourceTrigger=PropertyChanged}"></TextBlock>
+
+                        <ctrls:Axes2D Canvas.Top="15" Canvas.Left="30" AxesHeight="300" AxesWidth="300" WaferRadius="300" SafeRadius="100" PositionAndKey="{Binding PositionInfo,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"></ctrls:Axes2D>
+                        <Button Canvas.Right="10" Canvas.Bottom="70" Padding="3,2" Command="{Binding GetDataCommand}">Draw</Button>
+                        <Button Canvas.Right="10" Canvas.Bottom="40" Padding="3,2" Command="{Binding RemoveDataCommand}">Clear</Button>
+                    </Canvas>
+
+                </DataTemplate>
+            </ListBox.ItemTemplate>
+        </ListBox>
+        <!---->
+    </Grid>
+</UserControl>

+ 28 - 0
Venus/Venus_MainPages/Views/WaferOffsetView.xaml.cs

@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Venus_MainPages.Views
+{
+    /// <summary>
+    /// WaferOffsetView.xaml 的交互逻辑
+    /// </summary>
+    public partial class WaferOffsetView : UserControl
+    {
+        public WaferOffsetView()
+        {
+            InitializeComponent();
+        }
+    }
+}

+ 55 - 44
Venus/Venus_RT/Devices/TM/SIASUNRobot.cs

@@ -36,6 +36,7 @@ namespace Venus_RT.Devices
 
         private RState _status;
         private bool _IsHomed;
+        private bool _HasReceiveMsg;
         public RState Status { get { return _status; } }
         public bool IsHomed { get { return _IsHomed; } }
         private double offset_x = 0;
@@ -115,6 +116,7 @@ namespace Venus_RT.Devices
             offset_y = 0;
             _currentOP = OPStep.QueryAwc;
             _status = RState.Running;
+            _HasReceiveMsg = false;
             return _SendCommand("RQ WAF_CEN DATA");
         }
 
@@ -174,7 +176,7 @@ namespace Venus_RT.Devices
             _currentOP = OPStep.PlaceExtent;
             _status = RState.Running;
             SetRobotMovingInfo(RobotAction.Retracting, hand, chamber);
-            
+
             return _SendCommand($"PLACE {_StationNumbers[chamber]} SLOT {slot + 1} ARM {Hand2Arm(hand)} STRT NR");
         }
         public bool Pick(ModuleName station, int slot, Hand hand)
@@ -206,17 +208,17 @@ namespace Venus_RT.Devices
 
         private bool CheckRobotStatus()
         {
-            if(Status == RState.Init)
+            if (Status == RState.Init)
             {
                 LOG.Write(eEvent.ERR_TM_ROBOT, ModuleName.TMRobot, "TM Robot is not homed, please home first.");
                 return false;
             }
-            else if(Status == RState.Running)
+            else if (Status == RState.Running)
             {
                 LOG.Write(eEvent.ERR_TM_ROBOT, ModuleName.TMRobot, "TM Robot is busy, please wait a minute");
                 return false;
             }
-            else if(Status == RState.Failed || Status == RState.Timeout)
+            else if (Status == RState.Failed || Status == RState.Timeout)
             {
                 LOG.Write(eEvent.ERR_TM_ROBOT, ModuleName.TMRobot, "TM Robot has a error, please check and fix the hardware issue and home it");
                 return false;
@@ -284,7 +286,7 @@ namespace Venus_RT.Devices
                     break;
                 case OPStep.CheckLoad_ArmA:
                     {
-                        if(_rex_check_load.IsMatch(RevMsg))
+                        if (_rex_check_load.IsMatch(RevMsg))
                         {
                             GetCheckLoadResult(RevMsg);
 
@@ -307,37 +309,7 @@ namespace Venus_RT.Devices
                     }
                     break;
                 case OPStep.QueryAwc:
-                    {
-                        //不沾包
-                        if (RevMsg.Trim() == "_RDY")
-                        {
-                            _currentOP = OPStep.Idle;
-                            _status = RState.End;
-                        }
-                        //单条查询处理
-                        GetAwcMsg(RevMsg);
-                        //沾包
-                        if (RevMsg.Trim() != "_RDY" && RevMsg.Contains("_RDY"))
-                        {
-                            if (!RevMsg.Contains("_ERR"))
-                            {
-                                foreach (string msg in RevMsg.Split('\n'))
-                                    GetAwcMsg(msg);
-
-                                _currentOP = OPStep.Idle;
-                                _status = RState.End;
-                            }
-                            else
-                            {
-                                foreach (string msg in RevMsg.Split('\n'))
-                                    if (msg.Contains("_ERR"))
-                                        ErrorMessageHandler(_rex_error_code.Match(RevMsg.Trim()).Value);
-
-                                _currentOP = OPStep.Idle;
-                                _status = RState.Failed;
-                            }
-                        }
-                    }
+                    QueryAwcData(RevMsg);
                     break;
                 default:
                     if (!RevMsg.Contains("_EVENT"))
@@ -354,7 +326,7 @@ namespace Venus_RT.Devices
 
             string Arm = result.Groups[1].Value;
             string WaferStatus = result.Groups[2].Value;
-            if(WaferStatus == "ON")
+            if (WaferStatus == "ON")
             {
                 WaferManager.Instance.CreateWafer(ModuleName.TMRobot, Arm == "A" ? 0 : 1, Aitex.Core.Common.WaferStatus.Unknown);
             }
@@ -375,7 +347,7 @@ namespace Venus_RT.Devices
         {
             int ErrCode;
             string ErrorInfo;
-            if(int.TryParse(errCode, out ErrCode))
+            if (int.TryParse(errCode, out ErrCode))
             {
                 switch (ErrCode)
                 {
@@ -695,13 +667,52 @@ namespace Venus_RT.Devices
             }
         }
 
-        
+        private void QueryAwcData(string revMsg)
+        {
+            //不沾包
+            if (revMsg.Trim() == "_RDY")
+            {
+                if (_HasReceiveMsg)
+                {
+                    _currentOP = OPStep.Idle;
+                    _status = RState.End;
+                }
+                else
+                {
+                    _status = RState.Failed;
+                    LOG.Write(eEvent.ERR_TM_ROBOT, ModuleName.TMRobot, $"Query Awc failed because not find valided data");
+                }
+            }
+            //单条查询处理
+            GetAwcMsg(revMsg);
+            //沾包
+            if (revMsg.Trim() != "_RDY" && revMsg.Contains("_RDY"))
+            {
+                if (!revMsg.Contains("_ERR"))
+                {
+                    foreach (string msg in revMsg.Split('\n'))
+                        GetAwcMsg(msg);
+                    _currentOP = OPStep.Idle;
+                    _status = RState.End;
+                }
+                else
+                {
+                    foreach (string msg in revMsg.Split('\n'))
+                        if (msg.Contains("_ERR"))
+                            ErrorMessageHandler(_rex_error_code.Match(revMsg.Trim()).Value);
+
+                    _currentOP = OPStep.Idle;
+                    _status = RState.Failed;
+                }
+            }
+        }
 
         private void GetAwcMsg(string revMsg)
         {
             revMsg = revMsg.Trim();
             if (_rex_query_awc.IsMatch(revMsg))
             {
+                _HasReceiveMsg = true;
                 string offset_r_t = _rex_query_getoffset.Match(revMsg).Value;
                 //最大仅6位 不超过int范围
                 int offset_r;
@@ -710,17 +721,17 @@ namespace Venus_RT.Devices
                 {
                     // 9/26 新松暂未提供转换公式 暂时使用相关数据
                     offset_x = offset_r * Math.Cos(offset_t);
-                    offset_y = offset_t * Math.Sin(offset_t);
+                    offset_y = offset_r * Math.Sin(offset_t);
                 }
                 else
                 {
                     LOG.Write(eEvent.ERR_TM_ROBOT, ModuleName.TMRobot, $"TM Robot returned illegal offset data! Raw Data:{revMsg}");
                 }
             }
-            //else
-            //{
-            //    LOG.Write(eEvent.ERR_TM_ROBOT, ModuleName.TMRobot, $"The awc parameter format returned by TM Robot is incorrect! Raw Data:{revMsg}");
-            //}
+            else if(!_HasReceiveMsg)
+            {
+                LOG.Write(eEvent.ERR_TM_ROBOT, ModuleName.TMRobot, $"The awc parameter format returned by TM Robot is incorrect! Raw Data:{revMsg}");
+            }
         }
     }
 }

+ 2 - 3
Venus/Venus_RT/Modules/ResourceMonitor.cs

@@ -152,8 +152,8 @@ namespace Venus_RT.Modules
 
                 LOG.Write(eEvent.INFO_WINRESOURCE, ModuleName.System,
                     rtmonoitor +
-                    uimonoitor +
-                    systemMonitor
+                    ' ' * 56 + uimonoitor +
+                    ' ' * 56 + systemMonitor
                 );
                 //没有就不做任何操作
 
@@ -218,7 +218,6 @@ namespace Venus_RT.Modules
                 if (pro.PagedMemorySize64 / 1048576 >= threshold)
                 {
                     LOG.Write(eEvent.WARN_WINRESOURCE, ModuleName.System, $"警告!进程 {processname} 内存异常增长,超过{threshold}MB阈值!");
-                    MessageBox.Show($"警告!进程 {processname} 内存异常增长,超过{threshold}MB阈值!");
                 }
             }
             return monitor;

+ 13 - 0
Venus/Venus_Themes/UserControls/Axes2D.xaml

@@ -0,0 +1,13 @@
+<UserControl x:Class="Venus_Themes.UserControls.Axes2D"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:Venus_Themes.UserControls"
+             mc:Ignorable="d" 
+             d:DesignHeight="200" d:DesignWidth="200" x:Name="axes" Loaded="axes_Loaded">
+    <Grid>
+        <Canvas Height="{Binding AxesHeight}" Width="{Binding AxesWidth}" x:Name="CanvasInPath">
+        </Canvas>
+    </Grid>
+</UserControl>

+ 277 - 0
Venus/Venus_Themes/UserControls/Axes2D.xaml.cs

@@ -0,0 +1,277 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Venus_Themes.UserControls
+{
+    /// <summary>
+    /// Axes2D.xaml 的交互逻辑
+    /// </summary>
+    public partial class Axes2D : UserControl
+    {
+        bool flag = false;
+        public Axes2D()
+        {
+            InitializeComponent();
+        }
+
+        private void axes_Loaded(object sender, RoutedEventArgs e)
+        {
+            //仅触发一次绘制 不允许重复绘制
+            if (!flag)
+            {
+                DrawAxisAndText();
+                flag = true;
+            }
+            //DrawPoint();
+        }
+        //晶圆实际半径
+        public double WaferRadius
+        {
+            get
+            {
+                return (double)GetValue(WaferRadiusProperty);
+            }
+            set
+            {
+                SetValue(WaferRadiusProperty, value);
+            }
+        }
+        //传送安全半径阈值
+        public double SafeRadius
+        {
+            get
+            {
+                return (double)GetValue(SafeRadiusProperty);
+            }
+            set
+            {
+                SetValue(SafeRadiusProperty, value);
+            }
+        }
+
+        public double AxesWidth
+        {
+            get { return (double)GetValue(AxesWidthProperty); }
+            set
+            {
+                SetValue(AxesWidthProperty, value);
+            }
+        }
+        public double AxesHeight
+        {
+            get { return (double)GetValue(AxesHeightProperty); }
+            set
+            {
+                SetValue(AxesHeightProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// 存储x,y,点位信息的List 
+        /// </summary>
+        public List<(double x, double y, int arm, string info)> PositionAndKey
+        {
+            get { return (List<(double x, double y, int arm, string info)>)GetValue(PositionAndKeyProperty); }
+            set
+            {
+                SetValue(PositionAndKeyProperty, value);
+                //在更新的同时 对点位数据进行重新绘制
+                if (value != null)
+                    DrawPoint();
+            }
+        }
+
+        private void DrawPoint()
+        {
+            List<UIElement> needdelete = new List<UIElement>();
+            foreach (UIElement child in CanvasInPath.Children)
+            {
+                if (child.GetType() == typeof(Ellipse)) needdelete.Add(child);
+            }
+            foreach (UIElement i in needdelete)
+                CanvasInPath.Children.Remove(i);
+
+            float rc = 5;
+            foreach ((double x, double y, int arm, string info) point in PositionAndKey)
+            {
+                Ellipse ellipse = new Ellipse()
+                {
+                    Width = rc,
+                    Height = rc,
+                    ToolTip = point.info,
+                    Fill = point.arm == 1 ? new SolidColorBrush(Colors.Blue) : new SolidColorBrush(Colors.Yellow),
+                };
+                Canvas.SetZIndex(ellipse, 10);//显示层级
+                double bottom = (point.y / 10000 + 5) * (CanvasInPath.Height) / 10 - rc / 2 - .8;
+                double left = (point.x / 10000 + 5) * (CanvasInPath.Width) / 10 - rc / 2 + .4;
+                Canvas.SetLeft(ellipse, left);//x位置
+                Canvas.SetBottom(ellipse, bottom);//y位置
+                CanvasInPath.Children.Add(ellipse);
+            }
+
+            //晶圆半径示意图
+            if (WaferRadius > 0)
+            {
+                double radius = (WaferRadius / 100) * (CanvasInPath.Width) / 10 * 2;
+                Ellipse wafer = new Ellipse()
+                {
+                    Width = radius,
+                    Height = radius,
+                    Stroke = new SolidColorBrush(Colors.Blue),
+                    StrokeThickness = 1
+                };
+                Canvas.SetLeft(wafer, (WaferRadius / 100 + 5) * (CanvasInPath.Width) / 10 - radius);
+                Canvas.SetTop(wafer, (WaferRadius / 100 + 5) * (CanvasInPath.Height) / 10 - radius);
+                Canvas.SetZIndex(wafer, 1);
+                CanvasInPath.Children.Add(wafer);
+            }
+
+            if (SafeRadius > 0)
+            {
+                double radius = SafeRadius / 100 * (CanvasInPath.Width) / 10 * 2;
+                Ellipse safer = new Ellipse()
+                {
+                    Width = radius,
+                    Height = radius,
+                    Stroke = new SolidColorBrush(Colors.Yellow),
+                    StrokeThickness = 1
+                };
+                Canvas.SetLeft(safer, (SafeRadius / 100 + 5) * (CanvasInPath.Width) / 10 - radius);
+                Canvas.SetTop(safer, (SafeRadius / 100 + 5) * (CanvasInPath.Height) / 10 - radius);
+                Canvas.SetZIndex(safer, 1);
+                CanvasInPath.Children.Add(safer);
+            }
+
+        }
+
+        public static readonly DependencyProperty AxesWidthProperty = DependencyProperty.Register(
+                "AxesWidth", typeof(double), typeof(Axes2D));
+        public static readonly DependencyProperty AxesHeightProperty = DependencyProperty.Register(
+                "AxesHeight", typeof(double), typeof(Axes2D));
+        public static readonly DependencyProperty WaferRadiusProperty = DependencyProperty.Register(
+                "WaferRadius", typeof(double), typeof(Axes2D));
+        public static readonly DependencyProperty SafeRadiusProperty = DependencyProperty.Register(
+                "SafeRadius", typeof(double), typeof(Axes2D));
+        public static readonly DependencyProperty PositionAndKeyProperty = DependencyProperty.Register(
+                "PositionAndKey", typeof(List<(double, double, int, string)>), typeof(Axes2D),
+                new PropertyMetadata(null, OnDataPropertyChanged));
+        private static void OnDataPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            if (d is Axes2D axes2)
+            {
+                if (e.NewValue is List<(double x, double y, int arm, string info)> postiondata)
+                {
+                    axes2.PositionAndKey = postiondata;
+                }
+            }
+        }
+
+        private void DrawAxisAndText()
+        {
+            CanvasInPath.Width = AxesWidth;
+            CanvasInPath.Height = AxesHeight;
+
+            //笛卡尔坐标系
+            for (int i = 0; i < 11; ++i)
+            {
+                //坐标线
+                Line lineX = new Line()
+                {
+                    X1 = (double)((decimal)CanvasInPath.Width / 10) * i,
+                    X2 = (double)((decimal)CanvasInPath.Width / 10) * i,
+                    Y1 = 0,
+                    Y2 = CanvasInPath.Height,
+                    Stroke = new SolidColorBrush(Colors.DarkGray),
+                    StrokeThickness = 1,
+                };
+                Line lineY = new Line()
+                {
+                    X1 = 0,
+                    X2 = CanvasInPath.Width,
+                    Y1 = (double)((decimal)CanvasInPath.Height / 10) * i,
+                    Y2 = (double)((decimal)CanvasInPath.Height / 10) * i,
+                    Stroke = new SolidColorBrush(Colors.DarkGray),
+                    StrokeThickness = 1,
+                };
+                //中心和边缘线换色加重
+                if (i == 0 || i == 10 || i == 5)
+                {
+                    lineX.Stroke = new SolidColorBrush(Colors.Black);
+                    lineY.Stroke = new SolidColorBrush(Colors.Black);
+                    lineX.StrokeThickness = 1;
+                    lineY.StrokeThickness = 1;
+                }
+                else
+                {
+                    lineX.StrokeDashArray = new DoubleCollection() { 2, 2 };
+                    lineY.StrokeDashArray = new DoubleCollection() { 2, 2 };
+                }
+                Canvas.SetZIndex(lineX, 0);
+                Canvas.SetZIndex(lineY, 0);
+                CanvasInPath.Children.Add(lineX);
+                CanvasInPath.Children.Add(lineY);
+
+
+                //刻度
+                if (i < 11)
+                {
+                    TextBlock xblock = new TextBlock();
+                    xblock.Foreground = new SolidColorBrush(Colors.Black);
+                    xblock.FontSize = 10;
+                    TranslateTransform translateTransform = new TranslateTransform(0, xblock.ActualHeight);
+                    ScaleTransform scaleTransform = new ScaleTransform();
+                    scaleTransform.ScaleY = -1;
+
+                    xblock.Text = (i - 5) + "";
+                    Canvas.SetLeft(xblock, TransFromX((i) * 10));
+                    Canvas.SetTop(xblock, CanvasInPath.Width + 12);
+                    CanvasInPath.Children.Add(xblock);
+                    Canvas.SetZIndex(xblock, 1);
+
+                    TextBlock yblock = new TextBlock();
+                    yblock.Foreground = new SolidColorBrush(Colors.Black);
+                    yblock.FontSize = 10;
+                    translateTransform = new TranslateTransform(0, yblock.ActualHeight);
+                    scaleTransform = new ScaleTransform();
+                    scaleTransform.ScaleY = -1;
+
+                    yblock.Text = -(i - 5) + "";
+                    Canvas.SetLeft(yblock, -12);
+                    Canvas.SetTop(yblock, TransFromY((i) * 10));
+                    CanvasInPath.Children.Add(yblock);
+                    Canvas.SetZIndex(yblock, 1);
+                }
+            }
+
+
+
+        }
+
+        private double TransFromX(double value)
+        {
+            return (double)(((decimal)value / 10) * (decimal)(CanvasInPath.Width) / 10 - (decimal)5);
+        }
+        private double TransFromY(double value)
+        {
+            return (double)(((decimal)value / 10) * (decimal)(CanvasInPath.Height) / 10 - (decimal)3);
+        }
+
+        protected override void OnRender(DrawingContext drawingContext)
+        {
+            base.OnRender(drawingContext);
+        }
+
+    }
+}