From a987bb05357a451c8476098067573059287dc008 Mon Sep 17 00:00:00 2001
From: C3204 <zhengyabo@lanpucloud.cn>
Date: 星期五, 16 一月 2026 12:21:32 +0800
Subject: [PATCH] 添加运动控制菜单

---
 LB_VisionProcesses/Cameras/LBCameras/LBCamera.cs                         |  149 +++++++++-
 LB_VisionProcesses/MotionControl/IMotionControl.cs                       |   42 +++
 LB_VisionProcesses/Cameras/HRCameras/HRCamera.cs                         |  134 +++++++++-
 LB_VisionProcesses/MotionControl/MotionControlConfig.cs                  |  189 ++++++++++++++
 LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.Designer.cs |  153 +++++++---
 LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.cs          |   50 ++-
 LB_VisionProcesses/MotionControl/BaseMotionControl.cs                    |   49 +++
 7 files changed, 661 insertions(+), 105 deletions(-)

diff --git a/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.Designer.cs b/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.Designer.cs
index e008eb3..6f861c8 100644
--- a/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.Designer.cs
+++ b/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.Designer.cs
@@ -36,10 +36,12 @@
             txtSendMsg = new TextBox();
             grpSetting = new GroupBox();
             txtAddress = new TextBox();
+            cmbVarType = new ComboBox();
             cmbType = new ComboBox();
             txtIP = new TextBox();
             txtPort = new TextBox();
             lblPort = new Label();
+            lbVarType = new Label();
             cmbIP = new ComboBox();
             lblType = new Label();
             lblAddress = new Label();
@@ -63,9 +65,10 @@
             label3.AutoSize = true;
             label3.Dock = DockStyle.Fill;
             label3.ForeColor = Color.CornflowerBlue;
-            label3.Location = new Point(3, 100);
+            label3.Location = new Point(4, 125);
+            label3.Margin = new Padding(4, 0, 4, 0);
             label3.Name = "label3";
-            label3.Size = new Size(655, 20);
+            label3.Size = new Size(819, 25);
             label3.TabIndex = 18;
             label3.Text = "鍙戦�佷俊鎭�";
             label3.TextAlign = ContentAlignment.BottomLeft;
@@ -81,14 +84,15 @@
             tableLayoutPanel1.Controls.Add(label3, 0, 1);
             tableLayoutPanel1.Dock = DockStyle.Fill;
             tableLayoutPanel1.Location = new Point(0, 0);
+            tableLayoutPanel1.Margin = new Padding(4);
             tableLayoutPanel1.Name = "tableLayoutPanel1";
             tableLayoutPanel1.RowCount = 5;
-            tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 100F));
-            tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
-            tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 30F));
-            tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 40F));
+            tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 125F));
+            tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 25F));
+            tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 38F));
+            tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 50F));
             tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel1.Size = new Size(661, 322);
+            tableLayoutPanel1.Size = new Size(827, 402);
             tableLayoutPanel1.TabIndex = 26;
             // 
             // grpReceive
@@ -96,9 +100,11 @@
             grpReceive.Controls.Add(txtReceiveMsg);
             grpReceive.Dock = DockStyle.Fill;
             grpReceive.ForeColor = Color.CornflowerBlue;
-            grpReceive.Location = new Point(3, 193);
+            grpReceive.Location = new Point(4, 242);
+            grpReceive.Margin = new Padding(4);
             grpReceive.Name = "grpReceive";
-            grpReceive.Size = new Size(655, 126);
+            grpReceive.Padding = new Padding(4);
+            grpReceive.Size = new Size(819, 156);
             grpReceive.TabIndex = 30;
             grpReceive.TabStop = false;
             grpReceive.Text = "閫氳璁板綍";
@@ -106,142 +112,180 @@
             // txtReceiveMsg
             // 
             txtReceiveMsg.Dock = DockStyle.Fill;
-            txtReceiveMsg.Location = new Point(3, 17);
+            txtReceiveMsg.Location = new Point(4, 21);
+            txtReceiveMsg.Margin = new Padding(4);
             txtReceiveMsg.Multiline = true;
             txtReceiveMsg.Name = "txtReceiveMsg";
             txtReceiveMsg.ReadOnly = true;
             txtReceiveMsg.ScrollBars = ScrollBars.Both;
-            txtReceiveMsg.Size = new Size(649, 106);
+            txtReceiveMsg.Size = new Size(811, 131);
             txtReceiveMsg.TabIndex = 0;
             // 
             // txtSendMsg
             // 
             txtSendMsg.Dock = DockStyle.Fill;
-            txtSendMsg.Location = new Point(3, 123);
+            txtSendMsg.Location = new Point(4, 154);
+            txtSendMsg.Margin = new Padding(4);
             txtSendMsg.Name = "txtSendMsg";
-            txtSendMsg.Size = new Size(655, 21);
+            txtSendMsg.Size = new Size(819, 24);
             txtSendMsg.TabIndex = 29;
             // 
             // grpSetting
             // 
             grpSetting.BackColor = Color.FromArgb(32, 41, 50);
             grpSetting.Controls.Add(txtAddress);
+            grpSetting.Controls.Add(cmbVarType);
             grpSetting.Controls.Add(cmbType);
             grpSetting.Controls.Add(txtIP);
             grpSetting.Controls.Add(txtPort);
             grpSetting.Controls.Add(lblPort);
+            grpSetting.Controls.Add(lbVarType);
             grpSetting.Controls.Add(cmbIP);
             grpSetting.Controls.Add(lblType);
             grpSetting.Controls.Add(lblAddress);
             grpSetting.Controls.Add(lblIP);
             grpSetting.Dock = DockStyle.Fill;
             grpSetting.ForeColor = Color.CornflowerBlue;
-            grpSetting.Location = new Point(3, 3);
-            grpSetting.MinimumSize = new Size(261, 61);
+            grpSetting.Location = new Point(4, 4);
+            grpSetting.Margin = new Padding(4);
+            grpSetting.MinimumSize = new Size(326, 76);
             grpSetting.Name = "grpSetting";
-            grpSetting.Size = new Size(655, 94);
+            grpSetting.Padding = new Padding(4);
+            grpSetting.Size = new Size(819, 117);
             grpSetting.TabIndex = 28;
             grpSetting.TabStop = false;
             grpSetting.Text = "閫氳閰嶇疆";
             // 
             // txtAddress
             // 
-            txtAddress.Location = new Point(251, 60);
+            txtAddress.Location = new Point(314, 75);
+            txtAddress.Margin = new Padding(4);
             txtAddress.Name = "txtAddress";
-            txtAddress.Size = new Size(100, 21);
+            txtAddress.Size = new Size(124, 24);
             txtAddress.TabIndex = 9;
             txtAddress.TextChanged += txtAddress_TextChanged;
+            // 
+            // cmbVarType
+            // 
+            cmbVarType.DropDownStyle = ComboBoxStyle.DropDownList;
+            cmbVarType.FormattingEnabled = true;
+            cmbVarType.Location = new Point(533, 32);
+            cmbVarType.Margin = new Padding(4);
+            cmbVarType.Name = "cmbVarType";
+            cmbVarType.Size = new Size(124, 26);
+            cmbVarType.TabIndex = 8;
+            cmbVarType.SelectedIndexChanged += cmbVarType_SelectedIndexChanged;
             // 
             // cmbType
             // 
             cmbType.DropDownStyle = ComboBoxStyle.DropDownList;
             cmbType.FormattingEnabled = true;
-            cmbType.Location = new Point(251, 23);
+            cmbType.Location = new Point(314, 29);
+            cmbType.Margin = new Padding(4);
             cmbType.Name = "cmbType";
-            cmbType.Size = new Size(100, 23);
+            cmbType.Size = new Size(124, 26);
             cmbType.TabIndex = 8;
             // 
             // txtIP
             // 
-            txtIP.Location = new Point(79, 22);
+            txtIP.Location = new Point(99, 28);
+            txtIP.Margin = new Padding(4);
             txtIP.Name = "txtIP";
-            txtIP.Size = new Size(100, 21);
+            txtIP.Size = new Size(124, 24);
             txtIP.TabIndex = 7;
             // 
             // txtPort
             // 
-            txtPort.Location = new Point(79, 60);
+            txtPort.Location = new Point(99, 75);
+            txtPort.Margin = new Padding(4);
             txtPort.Name = "txtPort";
-            txtPort.Size = new Size(100, 21);
+            txtPort.Size = new Size(124, 24);
             txtPort.TabIndex = 6;
             // 
             // lblPort
             // 
             lblPort.AutoSize = true;
-            lblPort.Location = new Point(13, 63);
+            lblPort.Location = new Point(16, 79);
+            lblPort.Margin = new Padding(4, 0, 4, 0);
             lblPort.Name = "lblPort";
-            lblPort.Size = new Size(31, 15);
+            lblPort.Size = new Size(38, 18);
             lblPort.TabIndex = 4;
             lblPort.Text = "绔彛";
+            // 
+            // lbVarType
+            // 
+            lbVarType.AutoSize = true;
+            lbVarType.Location = new Point(463, 35);
+            lbVarType.Margin = new Padding(4, 0, 4, 0);
+            lbVarType.Name = "lbVarType";
+            lbVarType.Size = new Size(68, 18);
+            lbVarType.TabIndex = 0;
+            lbVarType.Text = "鍙橀噺绫诲瀷";
             // 
             // cmbIP
             // 
             cmbIP.FormattingEnabled = true;
-            cmbIP.Location = new Point(79, 21);
+            cmbIP.Location = new Point(99, 26);
+            cmbIP.Margin = new Padding(4);
             cmbIP.Name = "cmbIP";
-            cmbIP.Size = new Size(100, 23);
+            cmbIP.Size = new Size(124, 26);
             cmbIP.TabIndex = 1;
             // 
             // lblType
             // 
             lblType.AutoSize = true;
-            lblType.Location = new Point(205, 26);
+            lblType.Location = new Point(246, 32);
+            lblType.Margin = new Padding(4, 0, 4, 0);
             lblType.Name = "lblType";
-            lblType.Size = new Size(31, 15);
+            lblType.Size = new Size(38, 18);
             lblType.TabIndex = 0;
             lblType.Text = "鍨嬪彿";
             // 
             // lblAddress
             // 
             lblAddress.AutoSize = true;
-            lblAddress.Location = new Point(205, 63);
+            lblAddress.Location = new Point(242, 79);
+            lblAddress.Margin = new Padding(4, 0, 4, 0);
             lblAddress.Name = "lblAddress";
-            lblAddress.Size = new Size(31, 15);
+            lblAddress.Size = new Size(68, 18);
             lblAddress.TabIndex = 0;
-            lblAddress.Text = "鍦板潃";
+            lblAddress.Text = "鍙橀噺鍦板潃";
             // 
             // lblIP
             // 
             lblIP.AutoSize = true;
-            lblIP.Location = new Point(13, 26);
+            lblIP.Location = new Point(16, 32);
+            lblIP.Margin = new Padding(4, 0, 4, 0);
             lblIP.Name = "lblIP";
-            lblIP.Size = new Size(31, 15);
+            lblIP.Size = new Size(38, 18);
             lblIP.TabIndex = 0;
             lblIP.Text = "鍦板潃";
             // 
             // tableLayoutPanel2
             // 
             tableLayoutPanel2.ColumnCount = 3;
-            tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 80F));
-            tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 80F));
+            tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 100F));
+            tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 100F));
             tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
             tableLayoutPanel2.Controls.Add(btnRuleSend, 1, 0);
             tableLayoutPanel2.Controls.Add(btnSend, 0, 0);
             tableLayoutPanel2.Dock = DockStyle.Fill;
-            tableLayoutPanel2.Location = new Point(3, 153);
+            tableLayoutPanel2.Location = new Point(4, 192);
+            tableLayoutPanel2.Margin = new Padding(4);
             tableLayoutPanel2.Name = "tableLayoutPanel2";
             tableLayoutPanel2.RowCount = 1;
             tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel2.Size = new Size(655, 34);
+            tableLayoutPanel2.Size = new Size(819, 42);
             tableLayoutPanel2.TabIndex = 27;
             // 
             // btnRuleSend
             // 
             btnRuleSend.Dock = DockStyle.Fill;
             btnRuleSend.ForeColor = Color.CornflowerBlue;
-            btnRuleSend.Location = new Point(83, 3);
+            btnRuleSend.Location = new Point(104, 4);
+            btnRuleSend.Margin = new Padding(4);
             btnRuleSend.Name = "btnRuleSend";
-            btnRuleSend.Size = new Size(74, 28);
+            btnRuleSend.Size = new Size(92, 34);
             btnRuleSend.TabIndex = 14;
             btnRuleSend.Text = "鏍¢獙鍙戦��";
             btnRuleSend.UseVisualStyleBackColor = true;
@@ -251,9 +295,10 @@
             // 
             btnSend.Dock = DockStyle.Fill;
             btnSend.ForeColor = Color.CornflowerBlue;
-            btnSend.Location = new Point(3, 3);
+            btnSend.Location = new Point(4, 4);
+            btnSend.Margin = new Padding(4);
             btnSend.Name = "btnSend";
-            btnSend.Size = new Size(74, 28);
+            btnSend.Size = new Size(92, 34);
             btnSend.TabIndex = 12;
             btnSend.Text = "鍙戦��";
             btnSend.UseVisualStyleBackColor = true;
@@ -268,11 +313,12 @@
             themeForm_Communicator.Font = new Font("Microsoft Sans Serif", 9F);
             themeForm_Communicator.Image = (Image)resources.GetObject("themeForm_Communicator.Image");
             themeForm_Communicator.Location = new Point(0, 0);
+            themeForm_Communicator.Margin = new Padding(4);
             themeForm_Communicator.Name = "themeForm_Communicator";
-            themeForm_Communicator.Padding = new Padding(10, 70, 10, 9);
+            themeForm_Communicator.Padding = new Padding(12, 88, 12, 11);
             themeForm_Communicator.RoundCorners = true;
             themeForm_Communicator.Sizable = true;
-            themeForm_Communicator.Size = new Size(681, 401);
+            themeForm_Communicator.Size = new Size(851, 501);
             themeForm_Communicator.SmartBounds = true;
             themeForm_Communicator.StartPosition = FormStartPosition.WindowsDefaultLocation;
             themeForm_Communicator.TabIndex = 27;
@@ -288,7 +334,8 @@
             controlBox1.EnableMaximizeButton = true;
             controlBox1.EnableMinimizeButton = true;
             controlBox1.ForeColor = Color.FromArgb(155, 155, 155);
-            controlBox1.Location = new Point(581, 18);
+            controlBox1.Location = new Point(726, 18);
+            controlBox1.Margin = new Padding(4);
             controlBox1.MaximizeHoverColor = Color.FromArgb(74, 74, 74);
             controlBox1.MinimizeHoverColor = Color.FromArgb(63, 63, 65);
             controlBox1.Name = "controlBox1";
@@ -300,19 +347,21 @@
             // 
             panel_CommunicatorForm.Controls.Add(tableLayoutPanel1);
             panel_CommunicatorForm.Dock = DockStyle.Fill;
-            panel_CommunicatorForm.Location = new Point(10, 70);
+            panel_CommunicatorForm.Location = new Point(12, 88);
+            panel_CommunicatorForm.Margin = new Padding(4);
             panel_CommunicatorForm.Name = "panel_CommunicatorForm";
-            panel_CommunicatorForm.Size = new Size(661, 322);
+            panel_CommunicatorForm.Size = new Size(827, 402);
             panel_CommunicatorForm.TabIndex = 27;
             // 
             // CommunicatorForm
             // 
-            AutoScaleDimensions = new SizeF(96F, 96F);
+            AutoScaleDimensions = new SizeF(120F, 120F);
             AutoScaleMode = AutoScaleMode.Dpi;
-            ClientSize = new Size(681, 401);
+            ClientSize = new Size(851, 501);
             Controls.Add(themeForm_Communicator);
             FormBorderStyle = FormBorderStyle.None;
-            MinimumSize = new Size(261, 61);
+            Margin = new Padding(4);
+            MinimumSize = new Size(326, 76);
             Name = "CommunicatorForm";
             Text = "閫氳璁剧疆";
             TransparencyKey = Color.Fuchsia;
@@ -351,5 +400,7 @@
         private ComboBox cmbType;
         private Label lblAddress;
         private TextBox txtAddress;
+        private ComboBox cmbVarType;
+        private Label lbVarType;
     }
 }
\ No newline at end of file
diff --git a/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.cs b/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.cs
index 0e70eb0..ab9629a 100644
--- a/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.cs
+++ b/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.cs
@@ -28,10 +28,14 @@
         {
             InitializeComponent();
             cmbType.Items.Clear();
-
             if (communicator != null && !string.IsNullOrEmpty(communicator.CommunicatorConnections["鍨嬪彿"]?.ToString()))
             {
                 cmbType.Items.Add(communicator.CommunicatorConnections["鍨嬪彿"]?.ToString());
+            }
+            cmbVarType.Items.Clear();
+            if (!string.IsNullOrEmpty(communicator.CommunicatorConnections["鍙橀噺绫诲瀷"]?.ToString()))
+            {
+                cmbVarType.Items.Add(communicator.CommunicatorConnections["鍙橀噺绫诲瀷"]?.ToString());
             }
         }
 
@@ -39,42 +43,37 @@
         {
             InitializeComponent();
             if (communicator == null)
+            {
                 return;
-
+            }
             cmbIP.Enabled = false;
             txtIP.Enabled = false;
             txtPort.Enabled = false;
-
-
             lblType.Visible = false;
             lblAddress.Visible = false;
             cmbType.Visible = false;
             txtAddress.Visible = false;
-
-
+            lbVarType.Visible = false;
+            cmbVarType.Visible = false;
             this.Text = name;
-
             if (communicator is UARTPort)
             {
                 //缁熻鍙敤绔彛
                 SerialPortStream temp = new SerialPortStream();
                 string[] ArryPort = temp.GetPortNames();
                 for (int i = 0; i < ArryPort.Length; i++)
+                {
                     cmbIP.Items.Add(ArryPort[i]);
-
+                }
                 cmbIP.Text = communicator.CommunicatorConnections["鍦板潃"]?.ToString();
                 txtPort.Text = communicator.CommunicatorConnections["绔彛"]?.ToString();
                 txtIP.Visible = false;
                 cmbIP.Visible = true;
-
                 this.btnRuleSend.Visible = true;
-
-
                 lblType.Visible = false;
                 lblAddress.Visible = false;
                 cmbType.Visible = false;
                 txtAddress.Visible = false;
-
                 lblIP.Text = "COM鍙�";
                 lblPort.Text = "娉㈢壒鐜�";
             }
@@ -84,15 +83,11 @@
                 txtPort.SelectedText = communicator.CommunicatorConnections["绔彛"]?.ToString();
                 txtIP.Visible = true;
                 cmbIP.Visible = false;
-
                 this.btnRuleSend.Visible = false;
-
-
                 lblType.Visible = false;
                 lblAddress.Visible = false;
                 cmbType.Visible = false;
                 txtAddress.Visible = false;
-
                 lblIP.Text = "鍦板潃";
                 lblPort.Text = "绔彛";
             }
@@ -101,7 +96,6 @@
                 txtIP.Text = communicator.CommunicatorConnections["鍦板潃"]?.ToString();
                 txtPort.Text = communicator.CommunicatorConnections["绔彛"]?.ToString();
                 cmbType.Items.Clear();
-
                 if (!string.IsNullOrEmpty(communicator.CommunicatorConnections["鍨嬪彿"]?.ToString()))
                 {
                     cmbType.Items.Add(communicator.CommunicatorConnections["鍨嬪彿"]?.ToString());
@@ -111,15 +105,20 @@
                 {
                     txtAddress.Text = communicator.CommunicatorConnections["鍙橀噺鍦板潃"]?.ToString();
                 }
+                if (!string.IsNullOrEmpty(communicator.CommunicatorConnections["鍙橀噺绫诲瀷"]?.ToString()))
+                {
+                    cmbVarType.Items.Add(communicator.CommunicatorConnections["鍙橀噺绫诲瀷"]?.ToString());
+                    cmbVarType.Text = communicator.CommunicatorConnections["鍙橀噺绫诲瀷"]?.ToString();
+                }
+                lbVarType.Visible = true;
+                cmbVarType.Visible = true;
                 txtIP.Visible = true;
                 cmbIP.Visible = false;
                 this.btnRuleSend.Visible = false;
-
                 lblType.Visible = true;
                 lblAddress.Visible = true;
                 cmbType.Visible = true;
                 txtAddress.Visible = true;
-
                 lblIP.Text = "IP";
                 lblPort.Text = "妲�";
             }
@@ -267,5 +266,18 @@
                 communicatorChanged(communicator);
             }
         }
+
+        private void cmbVarType_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            if (communicator != null && !communicator.CommunicatorConnections.Contains("鍙橀噺绫诲瀷"))
+            {
+                communicator.CommunicatorConnections.Add("鍙橀噺绫诲瀷", cmbVarType.Text);
+            }
+            else if (communicator != null)
+            {
+                communicator.CommunicatorConnections["鍙橀噺绫诲瀷"] = cmbVarType.Text;
+                communicatorChanged(communicator);
+            }
+        }
     }
 }
diff --git a/LB_VisionProcesses/Cameras/HRCameras/HRCamera.cs b/LB_VisionProcesses/Cameras/HRCameras/HRCamera.cs
index ea8b86d..f176eab 100644
--- a/LB_VisionProcesses/Cameras/HRCameras/HRCamera.cs
+++ b/LB_VisionProcesses/Cameras/HRCameras/HRCamera.cs
@@ -1,5 +1,6 @@
 锘縰sing HalconDotNet;
 using LB_SmartVisionCommon;
+using LB_VisionProcesses.Cameras.LBCameras;
 using MVSDK_Net;
 using System;
 using System.Collections.Generic;
@@ -28,6 +29,8 @@
         private Thread _callbackThread; // 鍥炶皟澶勭悊绾跨▼
         private List<IMVDefine.IMV_Frame> _frameList; // 鍥惧儚缂撳瓨鍒楄〃
         private readonly object _frameLock = new object(); // 甯х紦瀛橀攣
+        // 鏂板锛欳ollectedImages鎿嶄綔閿侊紝淇濊瘉绾跨▼瀹夊叏
+        private readonly object _collectedImagesLock = new object();
         private IMVDefine.IMV_EPixelType type = IMVDefine.IMV_EPixelType.gvspPixelMono8;
         private IMVDefine.IMV_PixelConvertParam stPixelConvertParam = new IMVDefine.IMV_PixelConvertParam();
 
@@ -217,30 +220,135 @@
             }
             try
             {
+                // 1. 灏嗗抚杞崲涓築itmap
                 Bitmap bitmap = ConvertFrameToBitmap(frame);
-                // 閲婃斁甯ф暟鎹�
-                // release frame
+                // 閲婃斁鍘熷甯ф暟鎹紙SDK灞傞潰閲婃斁锛�
                 _camera.IMV_ReleaseFrame(ref frame);
-                Task.Factory.StartNew(() =>
+
+                // 2. 绌哄�兼牎楠岋細杞崲澶辫触鍒欑洿鎺ヨ繑鍥�
+                if (bitmap == null)
                 {
-                    CallBackImg = (Bitmap)bitmap.Clone();
-                    if (CallBackImg == null)
+                    AsyncLogHelper.Warn(SN + "甯ц浆鎹负Bitmap澶辫触锛岃烦杩囧鐞�");
+                    return;
+                }
+                // 3. 绾跨▼瀹夊叏鍦板皢Bitmap娣诲姞鍒癈ollectedImages瀛楀吀
+                lock (_collectedImagesLock)
+                {
+                    // 纭繚褰撳墠鐩告満SN瀵瑰簲鐨勫垪琛ㄥ瓨鍦�
+                    if (!CollectedImages.ContainsKey(SN))
                     {
-                        return;
+                        CollectedImages[SN] = new List<Bitmap>();
                     }
-                    if (GetTriggerMode(out TriggerMode mode, out TriggerSource source))
-                    {
-                        if (mode == TriggerMode.On && source != TriggerSource.Software)
-                            TriggerRunMessageReceived?.Invoke(SN, source.ToString());  // 瑙﹀彂杩愯浜嬩欢
-                    }
-                    bitmap.Dispose();
-                });
+                    CollectedImages[SN].Add(bitmap);
+                    AsyncLogHelper.Info(SN + $"鍥惧儚宸插姞鍏ョ紦瀛橈紝褰撳墠缂撳瓨鏁伴噺锛歿CollectedImages[SN].Count}");
+                }
+
+                // 4. 澶勭悊CollectedImages涓殑鍥惧儚锛氶亶鍘嗘秷璐瑰垪琛ㄧ涓�涓厓绱犵洿鍒颁负绌�
+                ProcessCollectedImages();
+                //Task.Factory.StartNew(() =>
+                //{
+                //    CallBackImg = (Bitmap)bitmap.Clone();
+                //    if (CallBackImg == null)
+                //    {
+                //        return;
+                //    }
+                //    if (GetTriggerMode(out TriggerMode mode, out TriggerSource source))
+                //    {
+                //        if (mode == TriggerMode.On && source != TriggerSource.Software)
+                //            TriggerRunMessageReceived?.Invoke(SN, source.ToString());  // 瑙﹀彂杩愯浜嬩欢
+                //    }
+                //    bitmap.Dispose();
+                //});
             }
             catch { }
             AsyncLogHelper.Info(SN + "Get frame blockId = {0}" + frame.frameInfo.blockId);
         }
 
         /// <summary>
+        /// 澶勭悊CollectedImages涓殑缂撳瓨鍥惧儚
+        /// 鏍稿績閫昏緫锛氶亶鍘嗗彇绗竴涓浘鍍� -> 璧嬪�肩粰CallBackImg -> 瑙﹀彂浜嬩欢 -> 閲婃斁骞剁Щ闄�
+        /// </summary>
+        private void ProcessCollectedImages()
+        {
+            Task.Factory.StartNew(() =>
+            {
+                // 鍔犻攣淇濊瘉绾跨▼瀹夊叏锛岄槻姝㈠绾跨▼鍚屾椂鎿嶄綔鍒楄〃
+                lock (_collectedImagesLock)
+                {
+                    // 鏍¢獙褰撳墠鐩告満鐨勫浘鍍忓垪琛ㄦ槸鍚﹀瓨鍦ㄤ笖鏈夋暟鎹�
+                    if (!CollectedImages.ContainsKey(SN) || CollectedImages[SN].Count == 0)
+                    {
+                        AsyncLogHelper.Info(SN + "褰撳墠鏃犵紦瀛樺浘鍍忥紝璺宠繃澶勭悊");
+                        return;
+                    }
+                    // 寰幆澶勭悊锛氱洿鍒板垪琛ㄤ负绌�
+                    while (CollectedImages[SN].Count > 0)
+                    {
+                        try
+                        {
+                            // 1 鍙栧垪琛ㄧ涓�涓储寮曠殑鍥惧儚璧嬪�肩粰CallBackImg
+                            Bitmap firstBitmap = CollectedImages[SN][0];
+                            ImageGrabbed?.Invoke(this, new LBCameraEventArgs(SN, firstBitmap, true));
+                            CallBackImg = (Bitmap)firstBitmap.Clone(); // 鍏嬮殕閬垮厤鍘熷璞¤閲婃斁鍚庡紩鐢ㄥけ鏁�
+
+                            // 2 鑾峰彇瑙﹀彂妯″紡骞跺垽鏂槸鍚﹁Е鍙戣繍琛屼簨浠�
+                            if (GetTriggerMode(out TriggerMode mode, out TriggerSource source))
+                            {
+                                // 纭Е鍙戞ā寮忎笅瑙﹀彂杩愯浜嬩欢
+                                if (mode == TriggerMode.On && source != TriggerSource.Software)
+                                {
+                                    AsyncLogHelper.Info(SN + $"瑙﹀彂纭Е鍙戜簨浠讹紝瑙﹀彂婧愶細{source}");
+                                    TriggerRunMessageReceived?.Invoke(SN, source.ToString());
+                                }
+                            }
+                            else
+                            {
+                                AsyncLogHelper.Warn(SN + "鑾峰彇瑙﹀彂妯″紡澶辫触锛岃烦杩囦簨浠惰Е鍙�");
+                            }
+
+                            // 3 閲婃斁绗竴涓浘鍍忚祫婧愬苟浠庡垪琛ㄧЩ闄�
+                            // 鍏堥噴鏀綛itmap鍐呭瓨锛屽啀绉婚櫎鍒楄〃鍏冪礌
+                            firstBitmap.Dispose();
+                            CollectedImages[SN].RemoveAt(0);
+                            AsyncLogHelper.Info(SN + $"宸叉秷璐圭紦瀛樺浘鍍忥紝鍓╀綑缂撳瓨鏁伴噺锛歿CollectedImages[SN].Count}");
+                        }
+                        catch (Exception ex)
+                        {
+                            AsyncLogHelper.Error(SN + $"澶勭悊缂撳瓨鍥惧儚寮傚父锛歿ex.Message}", ex);
+                            // 鍗曚釜鍥惧儚澶勭悊澶辫触鏃讹紝绉婚櫎璇ュ浘鍍忛伩鍏嶉樆濉炲悗缁鐞�
+                            if (CollectedImages[SN].Count > 0)
+                            {
+                                try
+                                {
+                                    CollectedImages[SN][0]?.Dispose(); // 灏濊瘯閲婃斁
+                                    CollectedImages[SN].RemoveAt(0);
+                                }
+                                catch (Exception innerEx)
+                                {
+                                    AsyncLogHelper.Error(SN + $"娓呯悊寮傚父鍥惧儚澶辫触锛歿innerEx.Message}", innerEx);
+                                }
+                            }
+                            // 鍗曚釜鍥惧儚澶勭悊澶辫触涓嶇粓姝㈠惊鐜紝缁х画澶勭悊涓嬩竴涓�
+                            // 4. 鎵�鏈夊浘鍍忓鐞嗗畬鎴愬悗锛屾竻绌篊allBackImg
+                            if (CallBackImg != null)
+                            {
+                                CallBackImg.Dispose();
+                                CallBackImg = null;
+                            }
+                            continue;
+                        }
+                        // 4. 鎵�鏈夊浘鍍忓鐞嗗畬鎴愬悗锛屾竻绌篊allBackImg
+                        if (CallBackImg != null)
+                        {
+                            CallBackImg.Dispose();
+                            CallBackImg = null;
+                        }
+                    }
+                }
+            });
+        }
+
+        /// <summary>
         /// 鍥惧儚鏄惁涓篗ono鏍煎紡
         /// </summary>
         /// <param name="enType"></param>
diff --git a/LB_VisionProcesses/Cameras/LBCameras/LBCamera.cs b/LB_VisionProcesses/Cameras/LBCameras/LBCamera.cs
index c03ddab..810ffd3 100644
--- a/LB_VisionProcesses/Cameras/LBCameras/LBCamera.cs
+++ b/LB_VisionProcesses/Cameras/LBCameras/LBCamera.cs
@@ -51,6 +51,8 @@
         // 涓存椂琛岀紦鍐诧紝鐢ㄤ簬鎺ユ敹鍥炶皟鏁版嵁
         private byte[] _tempLineBuffer = null;
         private bool _isContinuous = false;
+        // 鏂板锛欳ollectedImages鎿嶄綔閿侊紝淇濊瘉绾跨▼瀹夊叏
+        private readonly object _collectedImagesLock = new object();
 
         public LBCamera()
         {
@@ -568,37 +570,140 @@
 
                 _frameCount++;
                 AsyncLogHelper.Info($"LBCamera[{SN}]: Frame {_frameCount} generated ({width}x{height})");
-
-                // 寮傛瑙﹀彂浜嬩欢锛岄伩鍏嶉樆濉濻DK鍥炶皟绾跨▼
-                Task.Factory.StartNew(() => 
+                //绌哄�兼牎楠岋細杞崲澶辫触鍒欑洿鎺ヨ繑鍥�
+                if (bmp == null)
                 {
-                    try
+                    AsyncLogHelper.Warn(SN + "甯ц浆鎹负Bitmap澶辫触锛岃烦杩囧鐞�");
+                    return;
+                }
+                // 绾跨▼瀹夊叏鍦板皢Bitmap娣诲姞鍒癈ollectedImages瀛楀吀
+                lock (_collectedImagesLock)
+                {
+                    // 纭繚褰撳墠鐩告満SN瀵瑰簲鐨勫垪琛ㄥ瓨鍦�
+                    if (!CollectedImages.ContainsKey(SN))
                     {
-                        ImageGrabbed?.Invoke(this, new LBCameraEventArgs(SN, bmp, true));
-                        CallBackImg = (Bitmap)bmp.Clone();
-                        if (CallBackImg == null)
-                        {
-                            return;
-                        }
-                        if (GetTriggerMode(out TriggerMode mode, out TriggerSource source))
-                        {
-                            if (mode == TriggerMode.On && source != TriggerSource.Software)
-                                TriggerRunMessageReceived?.Invoke(SN, source.ToString());  // 瑙﹀彂杩愯浜嬩欢
-                        }
-                        bmp.Dispose();
+                        CollectedImages[SN] = new List<Bitmap>();
                     }
-                    catch (Exception ex)
-                    {
-                        AsyncLogHelper.Error($"LBCamera: Event Invoke error - {ex.Message}");
-                        bmp.Dispose(); // 寮傚父鏃堕噴鏀捐祫婧�
-                    }
-                });
+                    CollectedImages[SN].Add(bmp);
+                    AsyncLogHelper.Info(SN + $"鍥惧儚宸插姞鍏ョ紦瀛橈紝褰撳墠缂撳瓨鏁伴噺锛歿CollectedImages[SN].Count}");
+                }
+
+                // 澶勭悊CollectedImages涓殑鍥惧儚锛氶亶鍘嗘秷璐瑰垪琛ㄧ涓�涓厓绱犵洿鍒颁负绌�
+                ProcessCollectedImages();
+                //// 寮傛瑙﹀彂浜嬩欢锛岄伩鍏嶉樆濉濻DK鍥炶皟绾跨▼
+                //Task.Factory.StartNew(() => 
+                //{
+                //    try
+                //    {
+                //        ImageGrabbed?.Invoke(this, new LBCameraEventArgs(SN, bmp, true));
+                //        CallBackImg = (Bitmap)bmp.Clone();
+                //        if (CallBackImg == null)
+                //        {
+                //            return;
+                //        }
+                //        if (GetTriggerMode(out TriggerMode mode, out TriggerSource source))
+                //        {
+                //            if (mode == TriggerMode.On && source != TriggerSource.Software)
+                //                TriggerRunMessageReceived?.Invoke(SN, source.ToString());  // 瑙﹀彂杩愯浜嬩欢
+                //        }
+                //        bmp.Dispose();
+                //    }
+                //    catch (Exception ex)
+                //    {
+                //        AsyncLogHelper.Error($"LBCamera: Event Invoke error - {ex.Message}");
+                //        bmp.Dispose(); // 寮傚父鏃堕噴鏀捐祫婧�
+                //    }
+                //});
             }
             catch (Exception ex)
             {
                 AsyncLogHelper.Error($"LBCamera: CreateBitmap error - {ex.Message}");
             }
         }
+        /// <summary>
+        /// 澶勭悊CollectedImages涓殑缂撳瓨鍥惧儚
+        /// 鏍稿績閫昏緫锛氶亶鍘嗗彇绗竴涓浘鍍� -> 璧嬪�肩粰CallBackImg -> 瑙﹀彂浜嬩欢 -> 閲婃斁骞剁Щ闄�
+        /// </summary>
+        private void ProcessCollectedImages()
+        {
+            Task.Factory.StartNew(() =>
+            {
+                // 鍔犻攣淇濊瘉绾跨▼瀹夊叏锛岄槻姝㈠绾跨▼鍚屾椂鎿嶄綔鍒楄〃
+                lock (_collectedImagesLock)
+                {
+                    // 鏍¢獙褰撳墠鐩告満鐨勫浘鍍忓垪琛ㄦ槸鍚﹀瓨鍦ㄤ笖鏈夋暟鎹�
+                    if (!CollectedImages.ContainsKey(SN) || CollectedImages[SN].Count == 0)
+                    {
+                        AsyncLogHelper.Info(SN + "褰撳墠鏃犵紦瀛樺浘鍍忥紝璺宠繃澶勭悊");
+                        return;
+                    }
+                    // 寰幆澶勭悊锛氱洿鍒板垪琛ㄤ负绌�
+                    while (CollectedImages[SN].Count > 0)
+                    {
+                        try
+                        {
+                            // 1 鍙栧垪琛ㄧ涓�涓储寮曠殑鍥惧儚璧嬪�肩粰CallBackImg
+                            Bitmap firstBitmap = CollectedImages[SN][0];
+                            ImageGrabbed?.Invoke(this, new LBCameraEventArgs(SN, firstBitmap, true));
+                            CallBackImg = (Bitmap)firstBitmap.Clone(); // 鍏嬮殕閬垮厤鍘熷璞¤閲婃斁鍚庡紩鐢ㄥけ鏁�
+
+                            // 2 鑾峰彇瑙﹀彂妯″紡骞跺垽鏂槸鍚﹁Е鍙戣繍琛屼簨浠�
+                            if (GetTriggerMode(out TriggerMode mode, out TriggerSource source))
+                            {
+                                // 纭Е鍙戞ā寮忎笅瑙﹀彂杩愯浜嬩欢
+                                if (mode == TriggerMode.On && source != TriggerSource.Software)
+                                {
+                                    AsyncLogHelper.Info(SN + $"瑙﹀彂纭Е鍙戜簨浠讹紝瑙﹀彂婧愶細{source}");
+                                    TriggerRunMessageReceived?.Invoke(SN, source.ToString());
+                                }
+                            }
+                            else
+                            {
+                                AsyncLogHelper.Warn(SN + "鑾峰彇瑙﹀彂妯″紡澶辫触锛岃烦杩囦簨浠惰Е鍙�");
+                            }
+
+                            // 3 閲婃斁绗竴涓浘鍍忚祫婧愬苟浠庡垪琛ㄧЩ闄�
+                            // 鍏堥噴鏀綛itmap鍐呭瓨锛屽啀绉婚櫎鍒楄〃鍏冪礌
+                            firstBitmap.Dispose();
+                            CollectedImages[SN].RemoveAt(0);
+                            AsyncLogHelper.Info(SN + $"宸叉秷璐圭紦瀛樺浘鍍忥紝鍓╀綑缂撳瓨鏁伴噺锛歿CollectedImages[SN].Count}");
+                        }
+                        catch (Exception ex)
+                        {
+                            AsyncLogHelper.Error(SN + $"澶勭悊缂撳瓨鍥惧儚寮傚父锛歿ex.Message}", ex);
+                            // 鍗曚釜鍥惧儚澶勭悊澶辫触鏃讹紝绉婚櫎璇ュ浘鍍忛伩鍏嶉樆濉炲悗缁鐞�
+                            if (CollectedImages[SN].Count > 0)
+                            {
+                                try
+                                {
+                                    CollectedImages[SN][0]?.Dispose(); // 灏濊瘯閲婃斁
+                                    CollectedImages[SN].RemoveAt(0);
+                                }
+                                catch (Exception innerEx)
+                                {
+                                    AsyncLogHelper.Error(SN + $"娓呯悊寮傚父鍥惧儚澶辫触锛歿innerEx.Message}", innerEx);
+                                }
+                            }
+                            // 鍗曚釜鍥惧儚澶勭悊澶辫触涓嶇粓姝㈠惊鐜紝缁х画澶勭悊涓嬩竴涓�
+                            // 4. 鎵�鏈夊浘鍍忓鐞嗗畬鎴愬悗锛屾竻绌篊allBackImg
+                            if (CallBackImg != null)
+                            {
+                                CallBackImg.Dispose();
+                                CallBackImg = null;
+                            }
+                            continue;
+                        }
+                        // 4. 鎵�鏈夊浘鍍忓鐞嗗畬鎴愬悗锛屾竻绌篊allBackImg
+                        if (CallBackImg != null)
+                        {
+                            CallBackImg.Dispose();
+                            CallBackImg = null;
+                        }
+                    }
+                }
+            });
+        }
+
 
         private void SyncConfigFromCamera()
         {
diff --git a/LB_VisionProcesses/MotionControl/BaseMotionControl.cs b/LB_VisionProcesses/MotionControl/BaseMotionControl.cs
new file mode 100644
index 0000000..90ea277
--- /dev/null
+++ b/LB_VisionProcesses/MotionControl/BaseMotionControl.cs
@@ -0,0 +1,49 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LB_VisionProcesses.MotionControl
+{
+    public class BaseMotionControl : IMotionControl
+    {
+        /// <summary>
+        /// 杩愬姩鎺у埗鍚嶇О
+        /// </summary>
+        public string MotionControlName { get; set; } = string.Empty;
+        /// <summary>
+        /// 鏄惁杩炴帴
+        /// </summary>
+        public bool bConnected = true;
+        public bool Connect()
+        {
+            throw new NotImplementedException();
+        }
+
+        public bool Disconnect()
+        {
+            throw new NotImplementedException();
+        }
+
+        public void Dispose()
+        {
+            throw new NotImplementedException();
+        }
+
+        public string ReceiveMsg()
+        {
+            throw new NotImplementedException();
+        }
+
+        public void SendHeartbeat()
+        {
+            throw new NotImplementedException();
+        }
+
+        public bool SendMessage(string message)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}
diff --git a/LB_VisionProcesses/MotionControl/IMotionControl.cs b/LB_VisionProcesses/MotionControl/IMotionControl.cs
new file mode 100644
index 0000000..e77a3ff
--- /dev/null
+++ b/LB_VisionProcesses/MotionControl/IMotionControl.cs
@@ -0,0 +1,42 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LB_VisionProcesses.MotionControl
+{
+    public interface IMotionControl : IDisposable
+    {
+        /// <summary>
+        /// 杩炴帴閫氳
+        /// </summary>
+        /// <returns></returns>
+        bool Connect();
+
+        /// <summary>
+        /// 鏂紑杩炴帴
+        /// </summary>
+        /// <returns></returns>
+        bool Disconnect();
+
+        /// <summary>
+        /// 鎺ユ敹娑堟伅
+        /// </summary>
+        /// <returns></returns>
+        string ReceiveMsg();
+
+        /// <summary>
+        /// 鍙戦�佹秷鎭�
+        /// </summary>
+        /// <param name="message"></param>
+        /// <returns></returns>
+        bool SendMessage(string message);
+
+        /// <summary>
+        /// 鍙戦�佸績璺充俊鍙�
+        /// </summary>
+        void SendHeartbeat();
+
+    }
+}
diff --git a/LB_VisionProcesses/MotionControl/MotionControlConfig.cs b/LB_VisionProcesses/MotionControl/MotionControlConfig.cs
new file mode 100644
index 0000000..7beb5bc
--- /dev/null
+++ b/LB_VisionProcesses/MotionControl/MotionControlConfig.cs
@@ -0,0 +1,189 @@
+锘縰sing LB_VisionProcesses.Communicators;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LB_VisionProcesses.MotionControl
+{
+    [Serializable]
+    [Process("杩愬姩鎺у埗妯″潡", Category = "杩愬姩鎺у埗宸ュ叿", Description = "鍒涘缓杩愬姩鎺у埗宸ュ叿")]
+    public class MotionControlConfig : IProcess
+    {
+        /// <summary>
+        /// 杩愬姩鎺у埗妯″潡闆嗗悎(Key:閫氳鍚嶏紝Value:閫氳鍙ユ焺)
+        /// </summary>
+        public ConcurrentDictionary<string, BaseMotionControl> dicMotionControls { get; set; }
+
+        /// <summary>
+        /// 閫氳闆嗗悎(Key:閫氳鍚嶏紝Value:閫氳鍙ユ焺)
+        /// </summary>
+        public ConcurrentDictionary<string, BaseCommunicator> dicCommunicators { get; set; }
+
+        public MotionControlConfig(ConcurrentDictionary<string, BaseMotionControl> dicMotionControl)
+        {
+            this.dicMotionControls = dicMotionControl;
+            strProcessClass = "LB_VisionProcesses.Communicators.MotionControlConfig";
+
+            Params.Inputs.Add("杩愬姩鎺у埗鍚嶇О", "");
+            //Params.Inputs.Add("X杞碢LC鍦板潃", "");
+            //Params.Inputs.Add("X杞存娴嬩綅缃�", "");
+            //Params.Inputs.Add("Y杞碢LC鍦板潃", "");
+            //Params.Inputs.Add("Z杞碢LC鍦板潃", "");
+            //Params.Inputs.Add("W杞碢LC鍦板潃", "");
+            Params.Outputs.Add("鏀跺埌鐨勪俊鎭�", "");
+        }
+
+        public override object Clone()
+        {
+            return MemberwiseClone();
+        }
+
+        public override void Dispose()
+        {
+            return;
+        }
+
+        public override void InitRunParams()
+        {
+            Result = true;
+            Msg = "";
+
+            if (Record != null)
+            {
+                Record.Dispose();
+            }
+        }
+        /// <summary>
+        /// 鍔犺浇绠楁硶
+        /// </summary>
+        /// <param name="fullPath">瀹屾暣璺緞甯�.json</param>
+        /// <returns></returns>
+        public override bool Load(string fullPath)
+        {
+            try
+            {
+                if (string.IsNullOrEmpty(fullPath))
+                    return false;
+
+                if (!fullPath.Contains(".json"))
+                {
+                    Debug.WriteLine("鏂囦欢璺緞涓嶅畬鏁�");
+                    return false;
+                }
+                if (string.IsNullOrEmpty(fullPath) || fullPath.Trim() == "")
+                {
+                    Debug.WriteLine("鏂囦欢璺緞涓嶅畬鏁�");
+                    return false;
+                }
+
+                // 鑾峰彇涓嶅甫鏂囦欢鍚嶇殑鐩綍璺緞
+                string directoryPath = Path.GetDirectoryName(fullPath);
+                strProcessName = Path.GetFileNameWithoutExtension(fullPath);
+
+                if (!File.Exists(fullPath))
+                {
+                    Debug.WriteLine("鏂囦欢涓嶅瓨鍦ㄥ垱寤虹┖鏂囦欢");
+                    Save(directoryPath);
+                    return true;
+                }
+
+                string strJson = string.Empty;
+                using (StreamReader streamReader = new StreamReader(fullPath, Encoding.UTF8))
+                {
+                    strJson = streamReader.ReadToEnd();
+                    streamReader.Close();
+                }
+                Params = JsonConvert.DeserializeObject<ProcessParams>(strJson);
+                if (Params == null)
+                    return false;
+
+                Params.FixDeserializedData();
+                return true;
+            }
+            catch { return false; }
+        }
+
+        public override bool Run()
+        {
+            InitRunParams();
+            Params.Outputs["鏀跺埌娑堟伅"] = "";
+            string MotionControlName = Params.Inputs["杩愬姩鎺у埗鍚嶇О"].ToString();
+            if (!dicMotionControls.ContainsKey(MotionControlName))
+            {
+                Msg = $"杩愬姩鎺у埗[{MotionControlName}]涓嶅瓨鍦�";
+                Result = false;
+                return Result;
+            }
+            BaseMotionControl BaseMotionControl = dicMotionControls[MotionControlName];
+
+            if (BaseMotionControl == null)
+            {
+                Msg = $"杩愬姩鎺у埗[{MotionControlName}]鏈疄渚嬪寲";
+                Result = false;
+                return Result;
+            }
+
+            if (!BaseMotionControl.bConnected)
+            {
+                Msg = $"杩愬姩鎺у埗[{MotionControlName}]鏈繛鎺�";
+                Result = false;
+                return Result;
+            }
+
+            return true;
+        }
+
+        /// <summary>
+        /// 淇濆瓨绠楁硶
+        /// </summary>
+        /// <param name="filePath">涓嶅甫.json</param>
+        /// <returns></returns>
+        public override bool Save(string filePath = null)
+        {
+            try
+            {
+                if (string.IsNullOrEmpty(filePath) || filePath.Trim() == "")
+                {
+                    Debug.WriteLine("鏂囦欢璺緞涓嶅畬鏁�");
+                    return false;
+                }
+
+                string strJson = string.Empty;
+                var settings = new JsonSerializerSettings
+                {
+                    Formatting = Newtonsoft.Json.Formatting.Indented,
+                    // 鑷畾涔夌缉杩涳紙4绌烘牸锛�
+                    ContractResolver = new DefaultContractResolver
+                    {
+                        NamingStrategy = new CamelCaseNamingStrategy()
+                    }
+                };
+                strJson = JsonConvert.SerializeObject(Params, settings);
+
+                Params = JsonConvert.DeserializeObject<ProcessParams>(strJson);
+                if (Params == null)
+                    return false;
+
+                //鍒ゆ柇鏂囦欢澶规槸鍚﹀瓨鍦紝闃插憜杈撳叆涓烘枃浠跺悕绉�
+                if (!Directory.Exists(filePath))
+                {
+                    try
+                    {
+                        Directory.CreateDirectory(filePath);
+                    }
+                    catch (Exception)
+                    { }
+                }
+                File.WriteAllText(filePath + "//" + strProcessName + ".json", strJson, Encoding.UTF8);
+                return true;
+            }
+            catch { return false; }
+        }
+    }
+}

--
Gitblit v1.9.3