应用示例:通信数据收发控制

本章节以“通过脚本控制通信数据收发”为例,介绍脚本模块如何在方案中应用,以及方案最终实现效果。

本节内容包含:

方案需求

假设某视觉业务场景需要满足如下需求:

表 1 方案需求

需求

描述

需求1

VM接收到TCP客户端发送的任意字符串(string)型数据时,触发VM执行流程。

需求2

流程执行完成时,VM输出int、float、string、IMAGE、byte和ROIBOX这6种类型的数据。

需求3

需求2中提及的各类型数据,需输出回至TCP客户端。

方案思路

思路框架

基于上述需求,方案搭建的思路框架如下:

图 1 方案思路框架

思路详解

  • 针对需求1

    • 可在VM的通信管理中将TCP客户端作为通信设备启用,并在流程中调用接收数据模块,接收TCP客户端发送的数据。

    • 可将全局触发的触发模式设置为字符串触发,且将匹配模式设置为不匹配不匹配表示VM不对接收到的字符串进行匹配,默认接收到字符串就触发执行流程。

  • 针对需求2需求3

    • 可在流程中调用脚本模块,并自行开发脚本逻辑,定义上述6种类型数据的收发。

    • 可将发送数据模块作为脚本模块的后置模块,用于接收脚本模块输出的数据。

    • 可将发送数据模块的输出对象配置为TCP客户端,并定义具体输出的数据。

方案搭建

基于上述方案思路,可按以下四大步骤搭建该方案。

 

步骤1:配置TCP客户端

为实现接收TCP客户端发送的数据,需在VM中启用TCP客户端并完成其IP地址和端口号等配置。

已启用TCP客户端。

说明:

本示例中假设目标TCP客户端的IP地址为127.0.0.1,端口号为7920

  1. 在软件主界面单击快捷工具条上的打开通信管理窗口。
    1. 在主界面单击快捷工具条上的打开通信管理窗口。
    2. 配置TCP的IP地址和端口号,并开启数据上传自动重连,同时确保设备列表中的TCP客户端已开启。
  2. 配置TCP的IP地址和端口号,并开启数据上传自动重连,同时确保设备列表中的TCP客户端已开启。
    目标IP

    TCP客户端的IP地址。

    目标端口

    TCP客户端的端口号。

    数据上传

    开启后,VM软件界面上的数据会根据通信模块接收的数据实时更新。

    自动重连

    开启后,VM与TCP客户端断开连接时将自动重连。

    图 2 TCP客户端通信配置
     

步骤2:搭建流程

  1. 接收数据模块作为流程的首个模块,并配置该模块的如下参数。

    该模块用于接收TCP客户端发送的数据。

    数据源

    选择通信设备(如下图所示)。

    通信设备

    选择TCP客户端(如下图所示)。

    图 3 接收TCP客户端数据的配置
  2. 接收数据模块后调用图像源模块,并完成该模块图像源参数的配置。
  3. 图像源模块后,按需调用多个模块。

    此处调用的多个模块,可任意搭配。整体可输出int、float、string、IMAGE、byte和ROIBOX这6种类型数据的模块即可。

  4. 调用脚本模块,并完成如下配置。

    脚本模块在流程中的作用为,接收流程上游的特定数据,并控制最终输出的数据。

    1. 定义脚本模块的输入变量(如下图所示)。
    2. 定义脚本模块的输出变量(如下图所示)。
    图 4 脚本输出输出配置
  5. 调用发送数据模块,并对该模块做如下配置。
    1. 将输出目标设置为TCP客户端。
      图 5 设置输出目标
    2. 将该模块发送的数据设置为脚本模块输出的int、float、string、IMAGE、byte和ROIBOX这6种类型的数据,并可启用数据的分隔符。
      图 6 配置输出数据

至此,流程搭建完成。

图 7 流程搭建结果
 

步骤3:开发脚本代码

已在流程中调用脚本模块,且已在该模块定义其输入/输出变量。

  1. 双击脚本模块打开脚本配置窗口。
  2. 在该窗口的C#编程区调用Init方法,在该方法中实现变量初始化。
  3. 调用Process方法,并在该方法中调用如下获取和输出数据的方法,完成对各类型变量输入和变量值的定义。
    表 2 获取/输出数据的方法

    获取数据

    输出数据

    以其中的GetIntValueSetIntValue方法为例,上述方法的调用形式如下:

    //1.int数据测试
    int na = 0, ncount = 0;
    GetIntValue("in0", ref na);
    SetIntValue("out0", na);

    该示例中的in0out0,即脚本模块输入/输出变量中所配置的int0和out0,如下图所示。

    图 8 脚本输入/输出变量中的int0和out0
  4. 调用ShowMessageBox方法,实现在脚本代码运行异常时弹窗提示。

以上步骤的示例代码如下:

using System;
using System.Text;
using System.Windows.Forms;
using Script.Methods;
public partial class UserScript : ScriptMethods, IProcessMethods
{
    //the count of process
    //执行次数计数
    int processCount;

    /// <summary>
    /// Initialize the field's value when compiling
    /// 预编译时变量初始化
    /// </summary>
    public void Init()
    {
        //You can add other global fields here
        //变量初始化,其余变量可在该函数中添加
        processCount = 0;

    }

    /// <summary>
    /// Enter the process function when running code once
    /// 流程执行一次进入Process函数
    /// </summary>
    /// <returns></returns>
    public bool Process()
    {
        try
        {
            //1.int数据测试
            int na = 0, ncount = 0;
            GetIntValue("in0", ref na);
            SetIntValue("out0", na);

            int[] narry = new int[5];
            //获取int数组
            GetIntArrayValue("in5", ref narry, out ncount);
            //设置int数组方式1
            for (int i = 0; i < Math.Min(ncount, 5); i++)
            {
                SetIntValueByIndex("out5", narry[i], i, Math.Min(ncount, 5));
            }
            //设置int数组方式2
            //SetIntArrayValue("out5",narry,0,narry.Length);

            //2.float数据测试
            float fa = 0;
            int fcount = 0;
            GetFloatValue("in1", ref fa);
            SetFloatValue("out1", fa);

            float[] farry = new float[5];
            //获取float数组
            GetFloatArrayValue("in6", ref farry, out fcount);
            //设置float数组方式1
            for (int i = 0; i < Math.Min(fcount, 5); i++)
            {
                SetFloatValueByIndex("out6", farry[i], i, Math.Min(fcount, 5));
            }
            //设置float数组方式2
            //SetFloatArrayValue("out6",farry,0,farry.Length);


            //3.string数据测试
            string stra = ""; int strcount = 0;
            GetStringValue("in2", ref stra);
            SetStringValue("out2", stra);

            string[] strarry = new string[5];
            //获取string数组
            GetStringArrayValue("in7", ref strarry, out strcount);
            //设置string数组方式1
            for (int i = 0; i < Math.Min(strcount, 5); i++)
            {
                SetStringValueByIndex("out7", strarry[i], i, Math.Min(strcount, 5));
            }
            //设置string数组方式2
            //SetStringArrayValue("out7",strarry,0,strarry.Length);

            //6.设置/获取16进制数据
            byte[] tempBytes = new byte[] { };
            GetBytesValue("in4", ref tempBytes);
            SetBytesValue("out4", tempBytes);

            //7.设置/获取图像数据
            ImageData imagedata = new ImageData();
            int n1 = GetImageValue("in3", ref imagedata);
            int n = SetImageValue("out3", imagedata);

            //8.获取roibox数据
            RoiboxData roibox = new RoiboxData();
            GetRoiboxValue("in8", ref roibox);
            SetRoiboxValue("out8",roibox);
            //获取roi数组
            RoiboxData[] roiboxArray = new RoiboxData[100];
            int boxcount = 0;
            GetRoiBoxArrayValue("in8", ref roiboxArray, out boxcount);
            SetRoiBoxArrayValue("out9", roiboxArray, 0, boxcount);

        }
        catch (Exception ex)
        {
            ShowMessageBox(ex.ToString());
        }
        return true;
    }
}
 

步骤4:配置全局触发

为了实现在VM接收到TCP客户端发送的字符串时触发流程执行,需配置全局触发。全局触发是VM的配置工具,用于配置针对方案的全局触发规则。

已完成流程搭建。

  1. 在软件主界面的快捷工具条单击,打开全局触发窗口。
  2. 选择字符串触发页签,并单击添加字符串触发规则,完成规则配置。
    匹配模式

    设置为不匹配不匹配表示VM不对接收到的字符串进行匹配,默认接收到字符串就触发执行流程。

    触发命令类型

    设置为执行流程,即在符合该触发规则时触发流程的执行。

    触发配置

    选择已搭建的流程。

    图 9 字符串触发配置

    至此,方案已搭建完成。

方案效果测试

完成方案搭建后,可使用市面上的网络调试工具对方案效果进行测试。

从以下两张截图可见,VM的流程最终输出的int、float、string、IMAGE、byte和ROIBOX这6种类型的数据,发送到了TCP客户端。该方案最终实现了业务需求:“VM接收到TCP客户端发送的任意字符串时,触发流程执行,并将流程输出的6中类型的数据发送至TCP客户端”。

图 10 流程最终发出的数据
图 11 TCP客户端的数据收发(截取自某网络调试工具)