ProCon说明   快速入门   运动控制   EtherCAT   实时程序   API函数   控件库   硬件说明   问题排查   示例代码  
  

自定义运动算法

本节主要介绍内容如下:


       注意
        

相关函数

          

YKM_EnableAxisBuffer 启用运动缓冲区模式
YKM_DisableAxisBuffer 停用运动缓冲区模式
YKM_StartAxisBuffer 启动运动缓冲区
YKM_StartMultiAxisBuffer 同时启动多轴的运动缓冲区
YKM_WriteAxisBufferData 向运动缓冲区写入位置数据
YKM_GetAxisBufferStatus 获取运动缓冲区状态


重点说明

        
  • 用户自定义算法,物理轴测试,必须在Notime中实现,且写数据线程扫描时间需要小于总线周期,以保证运动稳定性。算法开发阶段,可以在Windows下测试,仅用于测试用户程序功能,不做性能评估。
  • 当轴的缓冲区模式启用时,停止、启动规划均由用户实现,相应的停止、启动等指令调用将无效。
  • 当轴的缓冲区模式启用时,依然可以读取轴状态、位置等信息。
  • 若轴Done信号有效,再次执行运动,需要重新启动运动缓冲区。
  • 需先写数据,再启动运动缓冲区。
  • 当缓冲区数据执行完后,轴Done信号会有效。



  •        注意
            

      当轴工作于运动缓冲区模式,软限位、外部停止信号、机械补偿等功能将无效。
      缓冲区写入位置为当量单位,轴配置的当量信息依然有效。
      若轨迹规划算法耗时较长,推荐分周期计算,无需一个周期计算完。
      若轨迹规划算法耗时较长,可边运动,边计算,保证缓冲区有有效数据即可。
      YKM_StartAxisBuffer调用后,需要等到下一个周期YKM_AxisBufferStatus.start_tick才会记录,马上调用YKM_GetAxisBufferStatus,会出现为0的情况。
      YKM_AxisBufferStatus.heart_tick在runtime启动时记录.
      YKM_AxisBufferStatus.idel最大值=设置缓冲区深度-1。



    流程图

            

    程序编写

              

      以下代码展示核心功能,完整例程目录:安装目录\doc\example\notime\UserBuffer
      例程规划的运动为简单的线性增量运动,完整的运动需要实现加减速过程。

    double[] axisCMDPos = new double[32];
    int nAxisNum = 3;
    int nBufferDepth = 128;
    RetCode retCode = RetCode.RET_OK;
    double dbPosTemp = 0;
    for (int i = 0; i < 32; i++)
    {
     ProCon.YKM_ReadCommandPosition((uint)i, out dbPosTemp);
     axisCMDPos[i] = dbPosTemp;
    }
    YKM_AxisBufferStatus axisBufferStatus = new YKM_AxisBufferStatus();
    while (!mCancel)
    {
     NoSys.NOS_SleepUs(250);
     nAxisNum = MemOper.pConfig->nAxisNum;
     nAxisNum = nAxisNum > 32 ? 32 : nAxisNum;
     nBufferDepth = MemOper.pConfig->BufferDepth;
     if (0 != MemOper.GetExit())
      break;
     //启用缓冲区运动,Active信号=0x8000
     if (MemOper.pConfig->EnableBuffer == 1)
     {
      for (int i = 0; i < nAxisNum; i++)
      {
       retCode = ProCon.YKM_EnableAxisBuffer((uint)i, (uint)nBufferDepth);
       ShowMessage(retCode);
      }
      MemOper.pConfig->EnableBuffer = 0;
     }

     //禁用缓冲区运动
     if (MemOper.pConfig->DisableBuffer == 1)
     {
      for (int i = 0; i < nAxisNum; i++)
      {
       ProCon.YKM_GetAxisBufferStatus((uint)i, out axisBufferStatus);
       if (axisBufferStatus.Done != 0)
       {
        retCode = ProCon.YKM_DisableAxisBuffer((uint)i);
       }
      }
      MemOper.pConfig->DisableBuffer = 0;
     }

     //停止缓冲区运动
     if (MemOper.pConfig->StopBufferMotion == 1)
      bool bIsStop = true;
      MemOper.pConfig->WriteAxisBuffer = 0;
      for (int i = 0; i < nAxisNum; i++)
      {
       ProCon.YKM_ReadAxisStatus((uint)i, out axisStatus);
       if (axisStatus.Done == 0)
       {
        bIsStop = false;
       }
      }
      if (bIsStop)
      {
       MemOper.pConfig->StopBufferMotion = 0;
      }
     }

     //分轴启动缓冲区运动,先写数据,再启动
     if (MemOper.pConfig->StartAxisBuffer == 1)
     {
      for (int i = 0; i < nAxisNum; i++)
      {
       ProCon.YKM_GetAxisBufferStatus((uint)i, out axisBufferStatus);
       retCode = ProCon.YKM_StartAxisBuffer((uint)i);
       MemOper.pConfig->StartAxisBuffer = 0;
       ShowMessage(retCode);
      }
     }

     //同步启动多轴缓冲区运动,先写数据,再启动
     if (MemOper.pConfig->StartAllAxisBuffer == 1)
     {
     UInt32[] axisList = new uint[nAxisNum];
     for (int i = 0; i < nAxisNum; i++)
     {
      ProCon.YKM_GetAxisBufferStatus((uint)i, out axisBufferStatus);
      axisList[i] = (UInt32)i;
     }
     retCode = ProCon.YKM_StartMultiAxisBuffer((uint)nAxisNum, axisList);
     MemOper.pConfig->StartAllAxisBuffer = 0;
     }

     //缓冲区运动指令位置更新,当发送完成,轴Done信号为非0,继续写数据,Done信号会OFF
     if (MemOper.pConfig->WriteAxisBuffer == 1)
     {
      for (int i = 0; i < nAxisNum; i++)
      {
       ProCon.YKM_GetAxisBufferStatus((uint)i, out axisBufferStatus);
       if (axisBufferStatus.idel > 64)
       {
        for (int j = 0; j < 64; j++)
        {
         retCode = ProCon.YKM_WriteAxisBufferData((uint)i, axisCMDPos[i]);
         if (retCode == RetCode.RET_OK)
         {
          axisCMDPos[i] += MemOper.pConfig->Increment;
         }
        }
       }
      }
     }
    }


    常见问题及说明

              

     

      
    Copyright © 2015 深圳市优易控软件有限公司 www.proutech.com