• 运动控制卡应用开发教程之调用激光振镜控制


    ✨博主介绍

    💂 个人主页:苏州程序大白

    💂 个人社区:CSDN全国各地程序猿

    🤟作者介绍:中国DBA联盟(ACDU)成员,CSDN全国各地程序猿(媛)聚集地管理员。目前从事工业自动化软件开发工作。擅长C#、Java、机器视觉、底层算法等语言。2019年成立柒月软件工作室,2021年注册苏州凯捷智能科技有限公司

    💅 有任何问题欢迎私信,看到会及时回复

    👤 微信号:stbsl6,微信公众号:苏州程序大白

    💬如果文章对你有帮助,欢迎关注、点赞、收藏(一键三连)

    🎯 想加入技术交流群的可以加我好友,群里会分享学习资料

    前言

    今天,运动控制卡分享一下应用C++开发一个激光振镜的运动控制例程。

    我们主要从新建MFC项目,添加函数库讲起,最后通过项目实战——激光振镜打标例程讲解,来让大家熟悉它的项目开发。

    振镜轴:
    在这里插入图片描述
    ZMC420SCAN支持XY2-100振镜协议,支持运动控制与振镜联合插补运动。

    上位机通过网口与控制器相连,获取对应控制器的句柄,通过XY2-100协议控制振镜轴,通过总线协议或者脉冲模式控制伺服或步进轴。

    在这里插入图片描述
    本地轴号4/5可以ATYPE=21 配置为第1个振镜, 本地轴号6/7可以ATYPE=21 配置为第2个振镜,可通过 AXIS_ADDRESS 配置轴号。

    激光振镜控制开发流程

    1、新建MFC项目 添加函数库(net最新再4.0以上版本)

    在VS2017菜单“文件”→“新建”→“项目”,启动创建项目向导。
    在这里插入图片描述

    2、选择开发语言为“Visual C++”和程序类型“MFC/ATL”中的“MFC应用程序”。

    在这里插入图片描述

    3、选择类型为“基于对话框”,下一步或者完成。下一步则往后继续配置,完成就直接完成即可。把类型选好,其他的可以在项目中编辑:
    在这里插入图片描述
    4、找到厂家提供的光盘资料,路径如下(64位库为例):

    A、进入光盘资料找到PC函数文件夹。

    B、选择函数库2.1。

    C、Windows平台。

    在这里插入图片描述
    D、根据需要选择对应的函数库这里选择64位库。

    E、解压C++的压缩包,里面有C++对应的函数库。

    在这里插入图片描述
    F、函数库具体路径如下:
    在这里插入图片描述
    5、将厂商提供的C++的库文件和相关头文件复制到新建的项目里面。

    在这里插入图片描述
    6、在项目中添加静态库和相关头文件。

    静态库:zauxdll.lib, zmotion.lib

    相关头文件:zauxdll2.h, zmotion.h

    A、先右击头文件,接着依次选择:“添加”→“现有项”。

    在这里插入图片描述

    B、在弹出的窗口中依次添加静态库和相关头文件。

    在这里插入图片描述

    7、声明用到的头文件和定义控制器连接句柄。
    在这里插入图片描述
    引用项目至此项目新建完成。

    查看PC函数手册 了解其用法

    1、函数手册也在光盘资料里面,具体路径如下:
    在这里插入图片描述
    2、PC编程,一般先根据控制器连接方式选择对应的连接函数连接控制器,返回控制器句柄。接着用返回的控制器句柄,实现对控制器的控制。

    3、比如通过网口连接控制器,先使用ZAux_OpenEth()链接控制器,获取控制器句柄handle。

    在这里插入图片描述

    4、通过获取到的控制器句柄handle,对控制器进行激光振镜轴类型的设置。
    在这里插入图片描述
    第三个参数的值有以下的模式选择,使用振镜轴需选择轴类型为21的模式,设置轴为振镜轴类型,振镜轴类型系统周期与刷新周期都要比普通轴快很多。
    在这里插入图片描述

    5、通过获取到的控制器句柄handle,控制控制器的振镜轴进行多轴运动控制,可以进行搭配振镜轴与普通轴进行混合插补运动。
    在这里插入图片描述

    项目实操之激光振镜打标例程

    1、例程以建立板卡的连接,并设置振镜轴的拐角减速以及速度参数,对内部进行设置的运动轨迹进行处理完成对圆形的打标。
    在这里插入图片描述

    2、例程简易流程图
    在这里插入图片描述
    3、通过网口连接控制器,获取控制器连接句柄

    //ip连接
    void CMarkDemoDlg::OnBnClickedButton2()
    {
      // TODO: 在此添加控件通知处理程序代码
      char   buffer[256];
      char   item[256] = {0};
      float ftemp = 0.0;
      char  atemp[256] = {0};          //存放控制器型号
      uint32 uitemp = 0;
      int32 iresult;
      if(NULL != g_handle)
      {
        ZMC_Close(g_handle);
        g_handle = NULL;
      }
      GetDlgItemText(IDC_IP_COMBO,buffer,255);  //获取当前框内的IP地址
      buffer[255] = '\0';
      iresult = ZMC_OpenEth(buffer, &g_handle);  //获取与控制器建立连接的结果
      if(ERR_SUCCESS != iresult)
      {
        g_handle = NULL;
        MessageBox(_T("Connect Failed"));
        SetWindowText(_T("ZControlTest-Connect Failed"));
        return;
      }
      SetWindowText("succse");
      //
      CComboBox   *m_pEthList;
      m_pEthList = (CComboBox *)GetDlgItem(IDC_IP_COMBO);    //获取ip地址
      if(NULL == m_pEthList)
      {
        return;
      }
      //
      if(CB_ERR != m_pEthList->FindString(0, buffer))
      {
        return;
      }
      //加入
      m_pEthList->AddString(buffer);  //将ip地址加入框内
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    4、通过串口连接控制器,获取控制器连接句柄。

    
    void CMarkDemoDlg::OnBnClickedButton4()
    {
      // TODO: 在此添加控件通知处理程序代码
      int32 iresult;
      uint8 icomid;
      float ftemp = 0.0;
      char  atemp[256] = {0};      //存放控制器型号
      uint32 uitemp = 0;
      int m_icombaud;
      if(NULL != g_handle)
      {
        ZMC_Close(g_handle);
        g_handle = NULL;
      }
      CComboBox        *m_pParityList;
      m_pParityList = (CComboBox *)GetDlgItem(IDC_COMBO_PARITY);
      m_icombaud = GetDlgItemInt(IDC_BAUD_COMBO);
      ZMC_SetComDefaultBaud(m_icombaud, 8, m_pParityList->GetCurSel(), ONESTOPBIT);
      icomid = GetDlgItemInt(IDC_PORT_COMBO);
      iresult = ZMC_OpenCom(icomid, &g_handle);
      if(ERR_SUCCESS != iresult)
      {
        g_handle = NULL;
        MessageBox(_T("Connect Failed"));
        return;                
      }
      SetWindowText("success");
      CString Comname;
      CComboBox   *m_pComList;
      m_pComList = (CComboBox *)GetDlgItem(IDC_PORT_COMBO);
      if(NULL == m_pComList)
      {
        return;
      }
      Comname.Format("%d",icomid);
      //
      if(CB_ERR != m_pComList->FindString(0, Comname))
      {
        return;
      }
      //加入
      m_pComList->AddString(Comname);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    5、利用生成的句柄进行配置轴参数,轴类型等

    
    int axislist[2] = {4,5};
      char cbuf[32]  = {};
      //设置主轴
      ZAux_Direct_Base(g_handle, 2, axislist);
      //获取编辑框内要设置的参数
      int MachSpeed = GetDlgItemInt(IDC_EDIT_SPEED);
      int MachAddSpeed = GetDlgItemInt(IDC_EDIT_ADDSPEED);
      int MachDecSpeed = GetDlgItemInt(IDC_EDIT_DECSPEED);
      float MachDecAngle = GetDlgItemInt(IDC_EDIT_DECANGLE) * 3.14 / 180;
      float MachStopAngle = GetDlgItemInt(IDC_EDIT_STOPANGLE) * 3.14 / 180;
      //轴初始化
      for (int i = 4; i <= 5; i++)
      {
        //设置轴类型为振镜轴类型
        ZAux_Direct_SetAtype(g_handle, i, 21);
        //设置每圈脉冲数
        ZAux_Direct_SetUnits(g_handle, i, 300);
        //设置速度
        ZAux_Direct_SetSpeed(g_handle, i, MachSpeed);
        //设置加速度
        ZAux_Direct_SetAccel(g_handle, i, MachAddSpeed);
        //设置减速度
        ZAux_Direct_SetDecel(g_handle, i, MachDecSpeed);
        //打开振镜轴连续插补
        ZAux_Direct_SetMerge(g_handle, i, 1);
        //设置拐角减速模式以及自动倒角模式
        ZAux_Direct_SetCornerMode(g_handle, i, 32+2);
        //设置拐角半径
        ZAux_Direct_SetZsmooth(g_handle, i, 0.1);
    //设置小圆限速半径
        ZAux_Direct_SetFullSpRadius(g_handle, i, 20);
    //设置减速角度
        ZAux_Direct_SetDecelAngle(g_handle, i, MachDecAngle);
    //设置停止角度
        ZAux_Direct_SetStopAngle(g_handle, i, MachStopAngle);
    //设置SP速度
        ZAux_Direct_SetForceSpeed(g_handle, i, 5000);
      }
      //打开精准输出功能
      ZAux_DirectCommand(g_handle, "AXIS_ZSET(4)=2", cbuf, 32);
      ZAux_Direct_SetOp(g_handle, 11, 1);
      ZAux_Direct_Base(g_handle, 2, axislist);
    ZAux_Direct_SetOp(g_handle, 1, 1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    6、本例程的轨迹移动数据都是以小线段的模式自己输入的,运行的过程中利用了多段小线段进行圆弧拟合的方式进行加快速度的处理操作。

    单个圆CAD轨迹图:
    在这里插入图片描述
    对应部分轨迹数据以及使用代码如下:

    
    //单个圆相对
    double x1[] = {-0.038000, -0.113000, -0.184000, -0.250000, -0.308000, -0.357000, -0.395000, -0.421000, -0.434000, -0.434000, -0.421000, -0.395000, -0.357000, -0.308000, -0.250000, -0.184000, -0.113000, -0.038000, 0.038000, 0.113000, 0.184000, 0.250000, 0.308000, 0.357000, 0.395000, 0.421000, 0.434000, 0.434000, 0.421000, 0.395000, 0.357000, 0.308000, 0.250000, 0.184000, 0.113000, 0.038000};
    
    double yh1[] = {0.434000, 0.421000, 0.395000, 0.357000, 0.308000, 0.250000, 0.184000, 0.113000, 0.038000, -0.038000, -0.113000, -0.184000, -0.250000, -0.308000, -0.357000, -0.395000, -0.421000, -0.434000, -0.434000, -0.421000, -0.395000, -0.357000, -0.308000, -0.250000, -0.184000, -0.113000, -0.038000, 0.038000, 0.113000, 0.184000, 0.250000, 0.308000, 0.357000, 0.395000, 0.421000, 0.434000};
    
    • 1
    • 2
    • 3
    • 4
    • 5

    小线段转圆弧函数说明:

    
    /*************************************************************
    Description:    //小线段变为圆弧
    Input:          //handle:连接的控制器句柄
                    //pXPos:线段的x坐标数组
                                    //pYPos:线段的y坐标数组
                                    //nMaxNum:最大点数
                                    //nMaxFitNum:最大拟合段数(100~1000)
                                    //nAbs:1=绝对;0=相对;表示传入的x、y坐标数据为绝对还是相对
                                    //refDistance:参考精度
    Output:         //
    Return:         //错误码
    *************************************************************/
    int __stdcall ZGraphProcess_SegFitArc(ZMC_HANDLE handle, double *pXPos, double *pYPos, int nMaxNum, int nMaxFitNum, int nAbs, double refDistance);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    使用此函数将多段小线段拟合成圆弧简化操作步骤,不用单独进行每段小线段的插补运动操作。

    代码中利用单个圆拟合进行横纵循环打标阵列圆的方式进行打标。

    int axislist[2] = {4,5};
    char cbuf[32]  = {};
    //设置主轴
    ZAux_Direct_Base(g_handle, 2, axislist);
    for (int k = 0; k < 1; k++)
      {
        for (int i = 0; i < 5; i++)
        {
    //移动到一个指定位置
          ZAux_DirectCommand(g_handle, "MOVE (0, -15)", cbuf, 32);
          for (int j = 0; j < 5; j++)
          {
            ZAux_DirectCommand(g_handle, "MOVE (-15, 0)", cbuf, 32);
            ZAux_Direct_MoveOp(g_handle, 0, 1);
            //进行小线段转圆弧
            int err_seg = ZGraphProcess_SegFitArc(g_handle, x1, yh1, sizeof(x1)/sizeof(double), 1000, 0, 0.01);
            ZAux_Direct_MoveOp(g_handle, 0, 0);
          }
          ZAux_DirectCommand(g_handle, "MOVE (75, 0)", cbuf, 32);
        }
        ZAux_DirectCommand(g_handle, "MOVE (0, 75)", cbuf, 32);
        
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    7、编译运行演示:

    1、编译运行示教例程:
    在这里插入图片描述
    2、同时通过ZDevelop软件连接同一个控制器,对运动控制的轴参数进行监控。
    在这里插入图片描述
    标刻25个圆形用时以及示波器显示图形如下:
    在这里插入图片描述

  • 相关阅读:
    23模式---原型模式(浅拷贝和深拷贝)
    Faster R-CNN详解
    Shell揭秘——程序退出状态码
    治疗 | 如何识别和处理消极想法
    Spring AOP使用
    开箱即用,这些 Vue3 后台管理系统模板绝对让你爽歪歪!
    Java8 Lambda.stream.sorted() 方法使用浅析分享
    【✨十五天搞定电工基础】一阶电路的暂态分析
    速卖通平台的API支持哪些开发语言和工具?
    pinia的常用知识点及搭配“script setup”的使用
  • 原文地址:https://blog.csdn.net/weixin_46931877/article/details/125906049