WinForm之工作流程模块-WorkFlow

在这里插入图片描述
在这里插入图片描述

一 Work的单例模式

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WinForm之AOI外观检测.WorkFlow
{
 public class WorkFlowService
 {
     //1. 私有静态变量(在第四步供外界使用),创建类的实例
     //2. 私有构造函数,确保外部无法直接实例化(确保是单个实例)
     //3. 确定供外界调用的代码资源
     //4. 公开静态属性,供外界使用(把第一步类的实例,开放出去)
     //5. 外界使用


     //1. 私有静态变量(在第四步供外界使用),创建类的实例

     private static WorkFlowService intance = new WorkFlowService();

     //2. 私有构造函数,确保外部无法直接实例化(确保是单个实例)
     private WorkFlowService()
     {

     }

     //4. 公开静态属性,供外界使用(把第一步类的实例,开放出去)
     public static WorkFlowService Instance
     {
         get { return intance; }
     }


     //3. 确定供外界调用的代码资源



 }
}

二 定义和开启工作流程的线程

// 1.判别是否在在线状态
// 2.取图
// 3.调用算法模块
// 4.把检测结果发送上位机或PLC
// 5.NG图像显示
// 避免CPU过载:睡眠2ms

 #region 启动工作线程
 public void StartWorkFlow()
 {
     Task.Run(Working);
 }
 #endregion


 #region 工作线程
 private void  Working()
 {

     while (true) {




         Thread.Sleep(2);
     
     }




 }
 #endregion

三 定义全局变量类-GlobalParamters

   public class GlobalParamters
   {

       /// <summary>
       /// 是否在线模式
       /// </summary>
       public static bool IsOnline =false;
   }

四 在线状态赋值

        /// <summary>
        /// 判断是否在线模式
        /// </summary>
        private void IsOnLine_ToggledChanged()
        {
            // 在线模式
            if (IsOnLine.Toggled)
            {
                // 开始工作线程
  						  WorkFlowService.Instance.StartWorkFlow();
                GlobalParamters.IsOnline = true;
                CameraService.Instance.StartCameras1();
                rtb_Log.AppendText("相机已打开 \n");

            }
            else
            {
                GlobalParamters.IsOnline = false;
                CameraService.Instance.CloseDevice();
                rtb_Log.AppendText("相机已关闭 \n");

            }
        }

五 打开和关闭工作线程

        /// <summary>
        /// 在线和离线模式
        /// </summary>
        private void IsOnLine_ToggledChanged()
        {
            // 在线模式
            if (IsOnLine.Toggled)
            {
                // 开始工作线程
                WorkFlowService.Instance.StartWorkFlow();
                GlobalParamters.IsOnline = true;


                CameraService.Instance.StartCameras1();
                rtb_Log.AppendText("相机已打开 \n");

            }
            else
            {

                GlobalParamters.IsOnline = false;
                WorkFlowService.Instance.StopWorkFlow();
                CameraService.Instance.CloseDevice();
                rtb_Log.AppendText("相机已关闭 \n");

            }

        }
 //3. 确定供外界调用的代码资源

 #region 启动工作线程
 public void StartWorkFlow()
 {
     Task.Run(Working);
 }
 #endregion


 // 工作标志位
 private bool IsWorking = false;


 #region 关闭工作线程
 public void StopWorkFlow()
 {
     IsWorking = false;
 }
 #endregion


 #region 工作线程
 private void Working()
 {

     // 工作位为true
     IsWorking = true;

     while (IsWorking)
     {
         // 一 判别是否处于在线状态
         if (!GlobalParamters.IsOnline)
         {
             // 停止以后循环
             IsWorking = false;
             // 跳出当前循环
             break;

         }


         // 生产流程

         // 防止cpu过载
         Thread.Sleep(2);

     }




 }
 #endregion

六 定义图像信息类

 /// <summary>
 /// 图像信息类
 /// </summary>
 public class ImageInfo
 {

     public ImageInfo(string imageDate, string imageID, HObject image)
     {
         ImageDate = imageDate;
         ImageID = imageID;
         Image = image;
     }

     /// <summary>
     /// 图像日期
     /// </summary>
     public string ImageDate {  get; set; }

     /// <summary>
     /// 图像ID
     /// </summary>
     public string ImageID { get; set; }

     /// <summary>
     /// 图像(halcon)
     /// </summary>
     public HObject Image { get; set; }
 }

七 定义图像队列

// 定义图像队列
        private ConcurrentQueue<ImageInfo> ImageList1 = new ConcurrentQueue<ImageInfo>();
    /// <summary>
    /// 添加图像到图像队列
    /// </summary>
    /// <param name="info"></param>
    public void AddImageInfo1(ImageInfo info)
    {
        ImageList1.Enqueue(info);

        //($"相机1新增检测任务,任务ID = {info.TaskID}");
    }

八 添加图像到图像队列中

        /// <summary>
        /// 主窗口显示,并添加到图像队列中
        /// </summary>
        /// <param name="hImg"></param>

        private void CameraGrabHImage2(HObject hImg)
        {
            // 获取主窗体
            var mainForm = Application.OpenForms.OfType<MainForm>().FirstOrDefault();

            // 使用扩展方法更新UI
            mainForm.Invoke(new Action(() =>
            {
                HWindow_Final hWindow_Final1 = mainForm.Get_HWindow_Final1();
                hWindow_Final1.HobjectToHimage(hImg);
            }));

          // 获取当前时间
          DateTime dt = DateTime.Now;

          ImageInfo imgInfo = new ImageInfo(
              dt.ToString("yyyy_MM_dd"),
              DateTime.Now.ToString("HH_mm_ss_fff"),
              hImg);
          // 添加到图像队列中
          WorkFlowService.Instance.AddImageInfo1(imgInfo);

        }

九 工作线程实现(取图和算法处理)

// 一 判别是否处于在线状态
// 二 取图(如果取不出图,则跳过)
// 三 调用算法模块
// 四 将检测结果发送上位机
 //五 显示NG图像
    #region 工作线程

    // 工作标志位
    private bool IsWorking = false;
     
    private void  Working()
    {
        // 工作位为true
        IsWorking = true;

        while (IsWorking) {

            // 一 判别是否处于在线状态
            if(!GlobalParamters.IsOnline)
            {
                // 停止以后循环
                IsWorking = false;
                // 跳出当前循环
                break;

            }

            // 二 取图(如果取不出图,则跳过)
            if (!ImageList1.TryDequeue(out ImageInfo info))
            {
                Thread.Sleep(5);
                continue;
            }

            // 三 调用算法模块

            ZWModel zWModel = new ZWModel();
            // 读取XML文件
            if (File.Exists(@"D:\\AOI外观检测软件参数\\ZWModelParam.xml"))
            {
                zWModel = (ZWModel)XmlSerializerHelper.ReadXML(@"D:\\AOI外观检测软件参数\\ZWModelParam.xml", typeof(ZWModel));
            }
            HObject defectRegion =  AlgorithmService.Instance.DetectZW(info.Image, zWModel);

            // 四 将检测结果发送上位机

            if(defectRegion!=null)
            {

            }
            else
            {

            }
            // 避免cpu过载
            Thread.Sleep(2);
        
        }




    }
    #endregion

十 实现发送信息

在这里插入图片描述

    /// <summary>
    /// 发送数据utf8
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    public void SendMsg(string Content)
    {
        // 获取信息
        byte[] sendMsg = Encoding.UTF8.GetBytes(Content);

        // 对客户端发送信息
        foreach (var item in this.CurrentClientlist)
        {
            // 发送数据
            item.Value?.Send(sendMsg);
        }


    }
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="Content"></param>
        public void Send(string Content)
        {
            httpSever.SendMsg(Content);
        }

        
              // 四 将检测结果发送上位机

              if(defectRegion!=null)
              {
                  CommunicateService.Instance.Send("NG");
              }
              else
              {
                  CommunicateService.Instance.Send("OK");

              }

十一 显示NG图像

        public HWindow_Final Get_hWindow_NGImage()
        {
            return hWindow_NGImage;
        }
             // 四 将检测结果发送上位机

             if(defectRegion!=null)
             {
                 CommunicateService.Instance.Send("NG");

                 // 五 显示NG图像
                 // 获取主窗体
                 var mainForm = Application.OpenForms.OfType<MainForm>().FirstOrDefault();

                 // 使用扩展方法更新UI
                 mainForm.Invoke(new Action(() =>
                 {
                     HWindow_Final hWindow_Final_NGImage = mainForm.Get_hWindow_NGImage();
                     hWindow_Final_NGImage.HobjectToHimage(info.Image);
                     hWindow_Final_NGImage.DispObj(defectRegion,"red");
                 }));

             }
             else
             {
                 CommunicateService.Instance.Send("OK");

             }

在这里插入图片描述

十二 窗口关闭

        /// <summary>
        /// 窗口关闭
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            GlobalParamters.IsOnline = false;
            CameraService.Instance.CloseDevice();

            WorkFlowService.Instance.StopWorkFlow();
        }

十三 添加发送日志

在这里插入图片描述

 if (defectRegion != null)
 {
     CommunicateService.Instance.Send("NG");

     // 五 显示NG图像
     // 获取主窗体
     var mainForm = Application.OpenForms.OfType<Form1>().FirstOrDefault();

     // 使用扩展方法更新UI
     mainForm.Invoke(new Action(() =>
     {
         mainForm.hWindow_Final2.HobjectToHimage(info.Image);
         mainForm.hWindow_Final2.DispObj(defectRegion, "red");
         mainForm.rtb_Log.AppendText($"图像ID:{info.ImageID}已发送:NG\n");
     }));


 }
 else
 {
     CommunicateService.Instance.Send("OK");
     var mainForm = Application.OpenForms.OfType<Form1>().FirstOrDefault();

     // 使用扩展方法更新UI
     mainForm.Invoke(new Action(() =>
     {
    
         mainForm.rtb_Log.AppendText($"图像ID:{info.ImageID}已发送:OK\n");
     }));


 }

十四 机械手操作指令

十五 实操

0.视觉判断OK和NG

1.回零

machinestart\nDeviceUp\n

2.设置避让位:安全位置

start\nG01 X117 Y-100 Z81 C0 F3000\n

3.设置抓取位置

start\nG01 X220 Y-43 Z6.4 C0 F3000\n

抬升

start\nG01 X220 Y-43 Z36.4 C0 F3000\n

4.开启吸嘴,吸附物料

start\nM3S5000\n

5.移动到固定区域

NG:

start\nG01 X202 Y151  Z36.4 C0 F3000\n

下降

start\nG01 X202 Y151 Z8.4 C0 F3000\n

OK:

start\nG01 X86 Y183  Z36.4 C0 F3000\n
start\nG01 X86 Y183 Z8.4 C0 F3000\n

6.关闭吸嘴

start\nm5\n

7.回到避免位

nG01 X117 Y-100 Z81 C0 F3000\n
Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐