////**********************************************************************************************************
//
//  Copyright(c) 2017, Shenzhen Gaochuan Industrial Automation Co.,Ltd
//
//  Moudle Name :   nmc_lib20.h
//
//  Abstract    :   GaoChuan Motion 2.0 User Header
//
//  Note        :   1.结构体定义中所有的'reservedxxx'的成员都是保留参数,为保持向后兼容性,请设置为0。
//                  2.无特别说明,所有API返回RTN_CMD_SUCCESS（即0值）表示执行成功,其他则表示错误代码,见mtn_lib20_err.h。
//                  3.所有的API参数中,无特别说明,axisHandle表示操作轴的句柄,devHandle表示目标控制器的句柄,
//                    crdHandle表示目标坐标系组句柄。
//                  4.若无特别说明,所有API的参数中,牵涉到序号则从0开始,比如NMC_MtOpen中的itemNo参数,0表示第一个轴。
//                  5.mtn_lib20中所有的结构体都是以四字节对齐方式编译，为了避免结构体对齐引起的问题，请将编译环境设置为四字节对齐
// Modification History :
//
////**********************************************************************************************************
#ifndef _H_NMC_LIB20_H_
#define _H_NMC_LIB20_H_

// 结构体初始化构造函数启用
#define MTN_ST_INIT_EN

#ifdef MTN_ST_INIT_EN
#include "string.h"
#endif 

#ifdef __cplusplus
extern "C" {
#endif

//------------------------------------------------------------------------------------------------------------
//
//              宏定义
//
//------------------------------------------------------------------------------------------------------------
// 编译控制
#ifndef MTN_API
    #ifdef WIN32 
        #ifdef NMC_LIB_EXPORTS
            #define MTN_API __declspec(dllexport)
        #else
            #define MTN_API __declspec(dllimport)
        #endif
    #else
        #define MTN_API 
        #define __stdcall 
    #endif    
#endif

// 类型定义
typedef     unsigned short*     PHAND;
typedef     unsigned short      HAND;
#ifndef Int8
    typedef     char              Int8;
#endif
#ifndef UInt8
    typedef     unsigned char     UInt8;
#endif
#ifndef Int16
    typedef     short              Int16;
#endif
#ifndef UInt16
    typedef     unsigned short     UInt16;
#endif
#ifndef Int32
    typedef     long              Int32;
#endif
#ifndef UInt32
    typedef     unsigned long     UInt32;
#endif
#ifndef Int64
    typedef     long long               Int64;
#endif
#ifndef UInt64
    typedef     unsigned long long     UInt64;
#endif
#ifndef F32
    typedef     float              F32;
#endif
#ifndef F64
    typedef     double              F64;
#endif


//------------------------------------------------------------------------------------------------------------
//
//           指令分组索引
//
//------------------------------------------------------------------------------------------------------------
//  1.控制器连接、关闭
//  2.单轴配置
//  3.单轴控制
//  4.单轴状态读取
//  5.IO控制及外部资源读写
//  6.坐标系配置
//  7.坐标系控制
//  8.坐标系及运动缓冲区状态读取
//  9.缓冲区插补运动和IO控制
//  10.回零
//  11.电子齿轮
//  12.电子凸轮
//------------------------------------------------------------------------------------------------------------
//
//          1.控制器连接、关闭
//
//------------------------------------------------------------------------------------------------------------
// 通讯模式设置
typedef enum { USB=0, Ethernet, RS485 } TSearchMode;

//设备信息结构
typedef struct TDevInfo
{
    UInt16 address;     // 在上位机系统中的设备序号,
    char  idStr[16];            // 识别字符串
    char  description[64];      // 描述符
    UInt16 ID;          // 板上的ID(未用)
}TDevInfo;

// 板卡搜寻
// 参数: mode:通讯模式,保留，无意义。通讯模式由nmc_lib20.dll文件版本决定。
// pDevNo : 返回设备的数目
// pInfoList：返回设备信息
MTN_API Int16 __stdcall NMC_DevSearch( TSearchMode mode, UInt16 *pDevNo, TDevInfo *pInfoList );

// 板卡打开（根据序号）
// devNo: 设备序号,取值范围[0,n]； pDevHandle: 返回设备操作句柄
MTN_API Int16 __stdcall NMC_DevOpen       ( Int16 devNo, PHAND pDevHandle );

// 板卡关闭
// pDevHandle : 设备句柄指针
MTN_API Int16 __stdcall NMC_DevClose(PHAND pDevHandle );

// 板卡复位
MTN_API Int16 __stdcall NMC_DevReset(HAND devHandle );

// 打开单轴
// devHandle : 设备句柄
// itemNo：轴号,取值范围[0,n]
// pCrdHandle：坐标系组句柄
MTN_API Int16  __stdcall NMC_MtOpen(HAND devHandle, Int16 itemNo, PHAND pAxisHandle ); 

// 关闭单轴
// devHandle : 设备句柄指针
MTN_API Int16  __stdcall NMC_MtClose(PHAND pAxisHandle );

// 打开坐标系组(支持多坐标系)
// itemNo：坐标系号,取值范围[0,1]
// pCrdHandle：返回坐标系组句柄
MTN_API Int16 __stdcall NMC_CrdOpenEx( HAND devHandle,Int16 itemNo, PHAND pCrdHandle );

// 关闭坐标系组
// pCrdHandle：坐标系组句柄
MTN_API Int16 __stdcall NMC_CrdClose(PHAND pCrdHandle );

// 读取当前的进程标号
MTN_API short  __stdcall NMC_GetCurProcessIndex(Int16* pIndex);

//------------------------------------------------------------------------------------------------------------
//
//          2.单轴配置
//
//------------------------------------------------------------------------------------------------------------
// 系统扩展资源的起始ID,包括扩展编码器／模拟量输入输出
#define EXT_RES_START_INDEX  256

// 编码器模式：定义信号源,信号类型,取反,,编码器分频等 
// Bit7:0 分频系数,数值为0~255。对应分频数值 1~256
// Bit9:8 信号号源选择
//   00：外部信号输入
//   01: 轴脉冲输入
//   10：自动产生信号（正脉冲）
//   11：自动产生信号（负脉冲）
// Bit11:10 信号类型（外部）
//  00：AB相,90度差
//  01：脉冲+方向
//  10：正脉冲+负脉冲
//  11：保留
// Bit12 输入A、B交换（外部） 0：不交换,1：交换
// Bit13 输入A取反（外部） 0：不取反,1：取反
// Bit14 输入B取反（外部） 0：不取反,1：取反
// Bti15 编码器饱和,0：最大最小值翻转,1：不翻转
// 设置编码器模式
// encId: 编码器ID,对于轴编码器通道,取值范围[0,n],
//                对于扩展编码器通道,256表示第一个扩展编码器通道,257表示第二个,以此类推
// encMode:编码器模式,参考宏定义
MTN_API Int16  __stdcall NMC_SetEncMode( HAND devHandle, Int16 encId,  Int16 encMode );

// 设置编码器参数
// encSrc:信号号源选择 0:外部编码器信号 1:内部编码器信号
// encType:编码器信号类型,0：AB相,90度差 1：脉冲+方向 2：正脉冲+负脉冲
// inverse:信号取反，0:不取反 1:取反
// coe:分频系数
MTN_API short  __stdcall NMC_MtSetEncMode(HAND axisHandle, short encSrc, short encType, short inverse, short coe);
MTN_API short  __stdcall NMC_MtGetEncMode(HAND axisHandle, short* encSrc, short* encType, short* inverse, short* coe);

// 设置编码器的滤波等级
// coe:滤波等级，取值范围[0,3],0表示没有滤波,各数值对应的最大输入频率(AB向四倍频)如下：0-16M 1-9.6M；2-3.6M；3-1.3M
MTN_API Int16  __stdcall NMC_SetEncFilter(HAND devHandle, Int16 encId, Int16 coe);
MTN_API Int16  __stdcall NMC_GetEncFilter(HAND devHandle, Int16 encId, Int16 *pCoe);

// 设置轴脉冲高速输出模式
// mode:脉冲速度模式，取值[0,1],0:低速模式，最大输出频率4.5M，默认；1：高速模式，最大输出频率18M
MTN_API Int16  __stdcall NMC_SetStepHiSpeedMode(HAND devHandle, Int16 mode);
MTN_API Int16  __stdcall NMC_GetStepHiSpeedMode(HAND devHandle, Int16* pMode);


// 设置软件限位是否停止运动
// enable：软件限位触发允许设置,1为允许,0为禁止
MTN_API Int16  __stdcall NMC_MtSwLmtOnOff  ( HAND axisHandle, Int16 swt );

// 设置软件限位数值
// posLmt：正向软件限位设置值
// negLmt：负向软件限位设置值。单位为脉冲数
MTN_API Int16  __stdcall NMC_MtSwLmtValue  ( HAND axisHandle, Int32 posLmt,Int32 negLmt );

//轴运动安全参数
typedef struct TSafePara
{
    double estpDec;     // 急停加速度
    double maxVel;      // 最大速度
    double maxAcc;      // 最大加速度
    
    #ifdef MTN_ST_INIT_EN
    TSafePara(){
     estpDec = 1000;
     maxVel = 1000;
     maxAcc = 1000;
    }
    #endif
}TSafePara;
// 设置轴安全参数
// TSafePara：包含急停减速度、最大允许速度、最大允许加速度
MTN_API Int16  __stdcall NMC_MtSetSafePara( HAND axisHandle, TSafePara *pPara );

// 设置脉冲输出模式
// inv, 1：取反,0：不取反
// mode 0：脉冲方向 1：正负脉冲,2:虚拟脉冲模式
MTN_API Int16  __stdcall NMC_MtSetStepMode ( HAND axisHandle, Int16 inv, Int16 mode );

// 设置轴速度滤波参数
// 注：filterCoef系数在0~5之间,值越大,速度越平滑，默认值为0
MTN_API Int16 __stdcall NMC_MtSetAxisVelFilter(HAND axisHandle,Int16 filterCoef);

// 硬件限位配置
// posLmtEnable: 正向限位触发允许设置,1为允许,0为禁止
// negLmtEnable: 负向限位触发允许设置,1为允许,0为禁止
// posLmtSns: 正向限位触发电平,1为高电平触发,0为低电平触发
// negLmtSns: 正向限位触发电平,1为高电平触发,0为低电平触发
MTN_API Int16 __stdcall NMC_MtSetLmtCfg( HAND axisHandle, Int16 posLmtEnable,Int16 negLmtEnable,Int16 posLmtSns,Int16 negLmtSns );

// 伺服报警配置
// alarmEnable: 伺服报警触发允许设置,1为允许,0为禁止
// alarmSns:     伺服报警触发电平,1为高电平触发,0为低电平触发
MTN_API Int16 __stdcall NMC_MtSetAlarmCfg( HAND axisHandle, Int16 alarmEnable,Int16 alarmSns );

// 设置脉冲输出滤波
// coe系数： 范围0~65535,0不滤波,数值越大滤波效果越明显。
MTN_API Int16  __stdcall NMC_MtSetStepFilter ( HAND axisHandle, UInt16  coe );

// DI type
#define DI_TYPE_LIMIT_POSITIVE               0        // 正向限位
#define DI_TYPE_LIMIT_NEGATIVE               1        // 负向限位
#define DI_TYPE_ALARM                        2        // 驱动报警
#define DI_TYPE_HOME                         3        // 原点
#define DI_TYPE_GPI                          4        // 通用输入
#define DI_TYPE_ARRIVE                       5        // 到位
#define DI_TYPE_LIMIT_POSITIVE_LOG           10        // 正向限位:逻辑电平
#define DI_TYPE_LIMIT_NEGATIVE_LOG           11        // 负向限位:逻辑电平
#define DI_TYPE_ALARM_LOG                    12        // 驱动报警:逻辑电平
#define DI_TYPE_HOME_LOG                     13        // 原点:逻辑电平


//------------------------------------------------------------------------------------------------------------
//
//          3.单轴控制指令
//
//------------------------------------------------------------------------------------------------------------
// 各轴的规划模式
#define MT_NONE_PRF_MODE        (-1)            // 无效
#define MT_PTP_PRF_MODE         (0)             // 梯形规划
#define MT_JOG_PRF_MODE         (1)             // 连续速度模式
#define MT_CRD_PRF_MODE         (3)             // 坐标系
#define MT_GANTRY_MODE          (4)             // 龙门跟随模式
#define MT_PT_PRF_MODE            (5)                // PT模式
#define MT_MULTI_LINE_MODE        (6)                // 多轴直线插补
#define MT_GEAR_PRF_MODE        (7)                // 电子齿轮模式
#define MT_FOLLOW_PRF_MODE        (8)                // Follow跟随模式
#define MT_PVT_PRF_MODE            (9)                // PVT
#define MT_PSP_PRF_MODE            (10)            // PSP

// 设置单轴规划模式
// mode：单轴运动模式
MTN_API Int16 __stdcall NMC_MtSetPrfMode(HAND axisHandle,Int16 mode);

// 单轴PTP运动参数结构
typedef struct TPtpPara
{
    double acc;         // 加速度
    double dec;         // 减速度
    double startVel;    // 起跳速度
    double endVel;      // 终止速度
    Int16 smoothCoef;   // 平滑系数,取值范围[0,199]
    Int16 reserved[3];      // 保留
    
    #ifdef MTN_ST_INIT_EN
    TPtpPara(){
     acc = 0.5;
     dec = 0.5;
     startVel = 0;
     endVel = 0;
     smoothCoef = 0;
     memset(reserved,0,sizeof(Int16)*3);
    }
    #endif
}TPtpPara;
// 设置多个参数, 并更新。
// pAxPara：参数,参考结构定义。
MTN_API Int16 __stdcall NMC_MtSetPtpPara( HAND axisHandle, TPtpPara *pAxPara );

typedef struct TTrapTime
{
   double totalTime;    // 当前点位运动的总时间，单位:ms
   double leftTime;        // 当前点位运动的剩余时间，单位:ms
   double reseved[2];    // 保留
    
    #ifdef MTN_ST_INIT_EN
    TTrapTime(){
     totalTime = 0;
     leftTime = 0;
     reseved[0] = reseved[1] = 0;
    }
    #endif
}TTrapTime;

// 获取当前点位运动执行时间参数
MTN_API Int16  __stdcall  NMC_MtGetTrapTime(HAND axisHandle,TTrapTime *pTrapTime);

// 单轴JOG运动参数结构
typedef struct TJogPara
{
    double acc;         // 加速度
    double dec;         // 减速度
    double smoothCoef;  // 平滑系数,取值范围[0,199],数值越大则速度变化越平滑
    
    #ifdef MTN_ST_INIT_EN
    TJogPara(){
     acc = 0.5;
     dec = 0.5;
     smoothCoef = 0;
    }
    #endif
}TJogPara;
// 设置Jog运动参数
// pAxPara：参数,参考结构定义。
MTN_API Int16 __stdcall NMC_MtSetJogPara   ( HAND axisHandle, TJogPara *pAxPara );

// 设置目标运动速度,只针对PTP和Jog：PTP模式下只接受正数,Jog模式下正负号标识运动方向
// vel: 目标速度（最大速度）,单位是 脉冲/ms
MTN_API Int16 __stdcall NMC_MtSetVel( HAND axisHandle, double vel );

// 设置目标运动位置,只针对PTP
// pos: 目标位置,单位是 脉冲
MTN_API Int16 __stdcall NMC_MtSetPtpTgtPos( HAND axisHandle, Int32 pos );

// 参数更新, 只针对PTP和Jog
MTN_API Int16 __stdcall NMC_MtUpdate( HAND axisHandle );

// 单轴运动停止
// 注：运动会按设定的减速度停止。
MTN_API Int16 __stdcall NMC_MtStop( HAND axisHandle );

// 单轴急停，不会置起急停标志位
// 注：运动会按设定的急停加速度停止。如果没有设置,则会立即停止。
MTN_API Int16 __stdcall NMC_MtAbruptStop( HAND axisHandle );

// 单轴位置系统清零,规划以及编码器
MTN_API Int16 __stdcall NMC_MtZeroPos( HAND axisHandle);

// 设置伺服报警清除输出的状态
// swt: 设置开关有效状态。0, 有效（输出低电平）,1,无效（输出高电平）
MTN_API Int16  __stdcall NMC_MtSetSvClr( HAND axisHandle, Int16 swt );

// 设置伺服ON, 轴静止时执行,如果后面是update指令,需要延时一个周期
MTN_API Int16  __stdcall NMC_MtSetSvOn( HAND axisHandle );

// 设置伺服OFF, 轴静止时执行,如果后面是update指令,需要延时一个周期
MTN_API Int16  __stdcall NMC_MtSetSvOff( HAND axisHandle );

// 清除轴错误状态
MTN_API Int16  __stdcall NMC_MtClrError ( HAND axisHandle );

// 清除轴错误状态,按位清除
// stsMask:对应位为1表明需要清除对应位的错误状态
MTN_API Int16  __stdcall NMC_MtClrStsByBits(HAND axisHandle , Int16 stsMask);

// 单轴点位运动,包含NMC_MtSetPrfMode,NMC_MtSetPtpPara,NMC_MtSetVel,NMC_MtSetPtpTgtPos,NMC_MtUpdate
// acc:加速度,dec：减速度,startVel:起跳速度,endVel:终止速度,smoothCoef:平滑系数
// maxVel：最大速度
// tgtPos:目标位置,单位：脉冲
MTN_API Int16  __stdcall NMC_MtMovePtpAbs(HAND axisHandle,double acc,double dec,double startVel,double endVel,double maxVel,Int16 smoothCoef,Int32 tgtPos);

// 单轴连续速度运动
// acc:加速度,dec：减速度,smoothCoef:平滑系数
// maxVel：最大速度
// clrStsFlag:是否运动前先清除轴状态，0：不清除，1：清除
MTN_API Int16  __stdcall NMC_MtMoveJog(HAND axisHandle,double acc,double dec,double maxVel,
                                        Int16 smoothCoef,Int16 clrStsFlag);
typedef struct TMovePtpPack8
{
    Int16 axisMask;            // 轴掩码，对应bit为1表示该轴参与运动
    Int16 clrStsFlag;        // 是否运动前先清除轴状态，0：不清除，1：清除
    Int16 reserved[2];        // 保留
    double acc[8];            // 加速度
    double dec[8];            // 减加速度
    double startVel[8];        // 起跳速度
    double endVel[8];        // 终止速度
    double maxVel[8];        // 最大速度
    Int16  smoothCoef[8];    // 平滑系数
    Int32 tgtPos[8];            // 位置，单位:脉冲
    
    #ifdef MTN_ST_INIT_EN
    TMovePtpPack8(){
     memset(this,0,sizeof(TMovePtpPack8));
    }
    #endif
}TMovePtpPack8;
// 单轴点位运动打包(绝对运动)
// axisFirstHandle:数组的第一个轴句柄
// pPackData:打包参数
// 注意：1.如果某轴存在无法运动的错误状态，则所有轴不会启动运动
MTN_API Int16  __stdcall NMC_MtMovePtpAbsPack8(HAND axisFirstHandle,TMovePtpPack8 * pPackData);

// 单轴点位运动打包(相对运动)
// axisFirstHandle:数组的第一个轴句柄
// pPackData:打包参数
// 注意：1.如果某轴存在无法运动的错误状态，则所有轴不会启动运动
MTN_API Int16  __stdcall NMC_MtMovePtpRelPack8(HAND axisFirstHandle,TMovePtpPack8 * pPackData);

// 单轴点位运动,相对运动
// acc:加速度,dec：减速度,startVel:起跳速度,endVel:终止速度,smoothCoef:平滑系数
// maxVel：最大速度
// relPos:相对当前位置的移动量,单位：脉冲
MTN_API Int16  __stdcall NMC_MtMovePtpRel(HAND axisHandle,double acc,double dec,double startVel,double endVel,double maxVel,Int16 smoothCoef,Int32 relPos);

// 多轴同步运动（通过PTP实现）
// axisMask:参与轴的掩码
// acc,dev:加速度,减速度
// sVel,eVel，maxVel:启动速度,终点速度，最大速度
// smooth:平滑系数
// pPosArray:目标位置数组
MTN_API Int16 __stdcall NMC_MtMultiMoveAbs(HAND devHandle,Int16 axisMask,double acc,double dec,double sVel,
    double eVel,double maxVel,Int16 smooth,Int32 *pPosArray);

// PTP两段速运动参数
typedef struct  TPtpTwoStagePrm
{ 
    double acc;         // 加速度
    double dec;         // 减速度
    double startVel;    // 启动速度
    double endVel;      // 终点速度
    double maxVel;      // 最大速度
    Int32 tgtPos;        // 目标位置
    Int16 reserved;      // 保留参数
    Int16 smoothCoef;   // 平滑系数
    Int16 inType;       // 输入类型：0：通用DI，1：Home信号;2:规划位置,3:保留，4:模拟量输入 5:编码器位置
    Int16 inIdx;        //  输入信号通道号
    Int16 inTrigLevel;    // 触发电平，0：低电平，1：高电平
                        // 对于数值类型的输入：0：小于指定数值，1：大于指定数值
    Int16 action;       // 触发后的动作，0：不动作，1：更新目标速度,
                                                // 2.更新目标位置
                                                // 3:更新目标位置（位置为相对触发点的相对位置）
                                                // 4:急停
    double prm1;        // action=1时表示更新的目标速度
    double prm2;        // action=2，3时表示更新的目标位置
    double prm3;        // 保留
    double prm4;        // 对于数值类型的输入，prm4代表比较数值
    
    #ifdef MTN_ST_INIT_EN
     TPtpTwoStagePrm(){
     acc = 0;
     dec = 0;
     startVel = 0;
     endVel = 0;
     maxVel = 0;
     tgtPos = 0;
     reserved = 0;
     smoothCoef = 0;
     inType = 0;
     inIdx = 0;
     inTrigLevel = 0;
     action = 0;
     prm1 = 0;
     prm2 = 0;
     prm3 = 0;
     prm4 = 0;
    }
    #endif
} TPtpTwoStagePrm;

// 两段速PTP运动
MTN_API Int16  __stdcall NMC_MtMovePtpAbsTwoStage(HAND axisHandle,TPtpTwoStagePrm *pPrm);


//------------------------------------------------------------------------------------------------------------
//
//         4.单轴状态读取
//
//------------------------------------------------------------------------------------------------------------
// 读取规划坐标系的位置
// pPos : 返回位置,单位是 脉冲
MTN_API Int16 __stdcall NMC_MtGetPrfPos   ( HAND axisHandle, Int32 *pPos );

// 读当前轴规划速度
// pVel: 返回速度,单位是 脉冲/ms
MTN_API Int16 __stdcall NMC_MtGetPrfVel   ( HAND axisHandle, double *pVel );

// 读当前轴规划加速度
// count:数量，可以获取多个轴的规划加速度，axisHandle为第一个轴的句柄
// pAcc: 返回加速度,单位是 脉冲/ms.ms
MTN_API Int16 __stdcall NMC_MtGetPrfAcc( HAND axisHandle, double *pAcc,Int16 count);

// 读取打包轴状态（4轴）
#define PACK_AXIS_NUM   4
typedef struct TAxisStsPack
{
    Int32 prfPos[PACK_AXIS_NUM];     // 规划位置
    Int32 encPos[PACK_AXIS_NUM];     // 实际位置
    float prfVel[PACK_AXIS_NUM];    // 规划速度
    Int32 motionIO[PACK_AXIS_NUM];   // 轴专用IO
    Int16 sts[PACK_AXIS_NUM];       // 轴状态
    Int32 gpo;                       // 通用输出
    Int32 gpi;                       // 通用输入
    
}TAxisStsPack;
// 打包读取多个轴的状态,从第一个轴开始读取后续四个轴的状态
// axisFirstHandle : 第一个轴句柄
// count:读取状态的轴数量,取值范围：[1,4]
// pPackSts: 打包的状态数据,参考结构体定义
MTN_API Int16  __stdcall NMC_MtGetStsPack  ( HAND axisFirstHandle, Int16 count,TAxisStsPack *pPackSts );

// 读取打包轴状态（12轴）
typedef struct TAxisStsPack12Ex
{
    Int16          mtSts[12];          // 单轴状态，位定义参考NMC_MtGetSts
    Int16          mtMio[12];          // 单轴专用IO,位定义参考NMC_MtGetMotionIO
    Int16          mtMioLog[12];       // 单轴专用IO:逻辑电平,位定义参考NMC_MtGetMotionIOLogical
    Int32           mtPrfPos[12];       // 单轴规划位置
    Int32           mtEncPos[12];       // 单轴实际位置
    float          mtPrfVel[12];       // 单轴规划速度

    Int16          crdSts[2];          // 坐标系状态
    float          crdPrfVel[2];       // 坐标系运动速度
    Int32           crdUserSeg[2];      // 坐标系运行的缓冲区段号
    Int32           crdFreeSpace[2];    // 坐标系缓冲区剩余空间
    Int32           crdUsedSpace[2];    // 坐标系缓冲区使用空间

    Int32           gpi;                // 通用输入
    Int32           gpo;                // 通用输出
    Int32           crdLeftLen[2];      // 坐标系缓冲区剩余段长，单位:脉冲
    Int32           crdAllCmdCnt[2];    // 坐标系缓冲区总共压入的指令数目
    Int32           extDi[6];           // 扩展模块输入，2号站~8号站
    Int32           extDo[6];           // 扩展模块输出，2号站~8号站
    Int16           adc[4];               // 模拟量输入值 0~4通道
    Int16           adcAux[2];           // 扩展模拟量输入值 0~1通道
    Int16           dac[4];               // 模拟量输出值 0~4通道
    Int16           dacAux[2];           // 扩展模拟量输出值 0~1通道
    Int32           reserved[10];       // 预留

}TAxisStsPack12Ex;
// 打包读取12个轴的状态
// axisFirstHandle : 第一个轴句柄
// pPackSts: 打包的状态数据,参考结构体定义
MTN_API Int16  __stdcall NMC_MtGetStsPack12Ex  ( HAND axisFirstHandle, TAxisStsPack12Ex *pPackSts );

// 快速读取打包状态 ，注意：仅对PCIE卡
typedef struct TMcStsPackEx
{
    Int16 sts[8];                    // 轴状态
    Int16 crdSts[2];                // 坐标系状态
}TMcStsPackEx;
// 打包读取控制器状态
// devHandle : 控制器句柄
// pPackSts: 打包的状态数据,参考结构体定义
MTN_API Int16  __stdcall NMC_MtGetStsPackEx  ( HAND devHandle, TMcStsPackEx *pPackSts );

// 快速读取打包状态 
typedef struct TMcStsPackEx2
{
    Int16 sts[8];                    // 轴状态
    Int16 crdSts[2];                // 坐标系状态
    Int16 extSts[3];                // 扩展高速状态
}TMcStsPackEx2;
// 打包读取控制器状态，注意：仅对PCIE卡
// devHandle : 控制器句柄
// pPackSts: 打包的状态数据,参考结构体定义
MTN_API Int16  __stdcall NMC_MtGetStsPackEx2  ( HAND devHandle, TMcStsPackEx2 *pPackSts );

// 快速读取轴状态，注意：仅对PCIE卡
MTN_API Int16  __stdcall NMC_MtGetStsEx( HAND axisHandle, Int16 *pStsWord );

// 快速读取坐标系状态，注意：仅对PCIE卡
MTN_API Int16 __stdcall NMC_CrdGetStsEx2( HAND crdHandle, Int16  *pStsWord );

// 启用扩展的状态读取指令功能，注意：仅对PCIE卡
// enFlag:是否启用，1-启用，0-关闭，默认为关闭状态
MTN_API Int16 __stdcall NMC_DevSetStsExCmdEn( HAND devHandle, Int16  enFlag );


// 读当前轴编码器通道
// pPos:返回编码器数值
MTN_API Int16  __stdcall NMC_MtGetEncPos   ( HAND axisHandle, Int32 *pPos );

// 读轴编码器速度(单位是：脉冲/ms)
MTN_API Int16  __stdcall NMC_GetEncVel( HAND devHandle, Int16 encId, double *pVel);

// 轴状态字位定义 
#define BIT_AXIS_BUSY           (0x00000001)    // bit 0  , 运动:1 ,静止 0       
#define BIT_AXIS_POSREC         (0x00000002)    // bit 1 , 伺服位置到达,步进模式时位置到达,伺服模式时实际位置到达误差限 
#define BIT_AXIS_MVERR          (0x00000004)    // bit 2 , 上次运动出错,或当前无法启动运动,需要调用NMC_MtClrError清除
#define BIT_AXIS_SVON           (0x00000008)    // bit 3  , 伺服允许        
#define BIT_AXIS_CRD            (0x00000010)    // bit 4 , 坐标系模式      
#define BIT_AXIS_STEP           (0x00000020)    // bit 5  , 步进/伺服       
#define BIT_AXIS_LMTP           (0x00000040)    // bit 6  , 正向限位，反向离开会自动清除        
#define BIT_AXIS_LMTN           (0x00000080)    // bit 7  , 负面限位，反向离开会自动清除
#define BIT_AXIS_SOFTPOSLMT     (0x00000100)    // bit 8  , 正向软限位触发  
#define BIT_AXIS_SOFTNEGLMT     (0x00000200)    // bit 9  , 负向软限位触发  
#define BIT_AXIS_ALM            (0x00000400)    // bit 10  , 伺服报警,需要调用NMC_MtClrError清除
#define BIT_AXIS_POSERR         (0x00000800)    // bit 11  , 位置超限,需要调用NMC_MtClrError清除 
#define BIT_AXIS_ESTP           (0x00001000)    // bit 12 , 急停,需要调用NMC_MtClrError清除
#define BIT_AXIS_HWERR          (0x00002000)    // bit 13 , 硬件错误 
#define BIT_AXIS_CAPTSET        (0x00004000)    // bit 14  , 捕获触发       
// 读当前轴状态
// pStsWord: 返回轴状态字。参考位定义
MTN_API Int16  __stdcall NMC_MtGetSts( HAND axisHandle, Int16 *pStsWord );

// 专用IO定义,arrive,alm : home : limit+ , limit- servoClr
#define BIT_AXMTIO_LMTN     (0x00000001)    // bit 0  ,负向限位  
#define BIT_AXMTIO_LMTP     (0x00000002)    // bit 1  ,正向限位  
#define BIT_AXMTIO_HOME     (0x00000004)    // bit 2  ,原点  
#define BIT_AXMTIO_ALARM    (0x00000008)    // bit 3  ,驱动报警 
#define BIT_AXMTIO_ARRIVE   (0x00000010)    // bit 4  ,电机到位 
#define BIT_AXMTIO_CAPT     (0x00000020)    // bit 5  ,捕获源信号
#define BIT_AXMTIO_SVRCLR   (0x00000100)    // bit 8  ,伺服清除信号
// 读运动控制专用IO
// pIoValue : 返回专用IO的状态,原点,限位,报警，伺服清除输出等。参考位定义。对应位为0为低电平,1为高电平。
MTN_API Int16 __stdcall NMC_MtGetMotionIO ( HAND axisHandle, Int32 *pIoValue );

// 读运动控制专用IO,逻辑电平
// pIoValue : 返回专用IO的状态,原点,限位,报警。参考位定义。对应位为0为低电平,1为高电平。
MTN_API Int16 __stdcall NMC_MtGetMotionIOLogical ( HAND axisHandle, Int32 *pIoValue );




//------------------------------------------------------------------------------------------------------------
//
//        5.IO控制及外部资源读写
//
//------------------------------------------------------------------------------------------------------------
// 设置通用输出(按通道,支持超过32位),带默认group
// value: 设置通用数字量输出。1, 输出高电平,0,输出低电平
// groupID:DO组,取值范围[0,n],具体需要看控制器是否存在多组数字量输出
MTN_API Int16  __stdcall NMC_SetDOGroup( HAND devHandle, Int32 value, Int16 groupID) ;

// 读通用输入(按通道,支持超过32位) ,带默认group
// pInValue: 通用数字量输入值。1, 高电平,0,低电平
// groupID:DI组,取值范围[0,n],0: 本地DI31~DI0, 1: 本地DI63~DI32,其他指扩展IO模块
MTN_API Int16 __stdcall NMC_GetDIGroup( HAND devHandle, Int32 *pInValue, Int16 groupID);

// 读取通用输出(按通道,支持超过32位),带默认group
// pDoValue: 设置通用数字量输出。1, 高电平,0,低电平
// groupID:DO组,取值范围[0,n],,0: 本地DO31~DO0, 1: 本地DO63~DO32,其他指扩展IO模块
MTN_API Int16  __stdcall NMC_GetDOGroup( HAND devHandle, Int32 *pDoValue, Int16 groupID);

// 按位设置通用输出
// bitIndex:取值范围[0,n],位序号,前64位为本地的通用输出,大于64为扩展DO
// value: 设置通用数字量输出。1, 输出高电平,0,输出低电平
MTN_API Int16  __stdcall NMC_SetDOBit( HAND devHandle, Int16 bitIndex, Int16 value );

// 按位读输出 
MTN_API Int16  __stdcall NMC_GetDOBit( HAND devHandle,Int16 bitIndex, Int16 *bitValue);

// 按位读通用输入 
// 读通用输入(按通道,支持超过32位) 
// bitIndex:取值范围[0,n],位序号
// pBitValue: 通用数字量输入值。1, 高电平,0,低电平
MTN_API Int16  __stdcall NMC_GetDIBit( HAND devHandle,Int16 bitIndex, Int16 *pBitValue );

// 读取扩展IO模块的状态
// sts:io模块状态
MTN_API Int16  __stdcall NMC_GetIOModuleSts(HAND devHandle, UInt32 *sts);

// 设置扩展IO模块有效（默认为IO64模块）
// chDevId:设备ID
MTN_API Int16  __stdcall NMC_SetIOModuleEn( HAND devHandle, UInt8 chDevId);

// 扩展模块类型定义
#define IOMODULE_TYPE_IO64        1        // 32DI32DO模块（包括16DI16DO模块）
#define IOMODULE_TYPE_IO32_DA    2        // 4AD4DA模块

// 设置扩展IO模块有效(带模块类型)
// chDevId:设备ID
// chDevType:模块类型，见宏定义
MTN_API Int16  __stdcall NMC_IOModuleSetEn( HAND devHandle, UInt8 chDevId,Int16 chDevType);

// 读取扩展IO模块类型
// chDevId:设备ID
// pChDevType:返回的模块类型，见宏定义
MTN_API Int16  __stdcall NMC_IOModuleGetType( HAND devHandle, UInt8 chDevId,Int16 *pChDevType);

// 扩展IO模块通道写，8位长度
// chDevId：设备站号
// offset:数据偏移
MTN_API Int16  __stdcall NMC_IOModuleWr8Bit( HAND devHandle, UInt8 chDevId,UInt8 offset,UInt8 data);

// 扩展IO模块通道写，16位长度
MTN_API Int16  __stdcall NMC_IOModuleWr16Bit( HAND devHandle, UInt8 chDevId,UInt8 offset,UInt16 data);

// 扩展IO模块通道写，32位长度
MTN_API Int16  __stdcall NMC_IOModuleWr32Bit( HAND devHandle, UInt8 chDevId,UInt8 offset,UInt32 data);

// 扩展IO模块通道读输出，8位长度
// chDevId：设备站号
// offset:数据偏移
MTN_API Int16  __stdcall NMC_IOModuleRdOut8Bit( HAND devHandle, UInt8 chDevId,UInt8 offset,UInt8 *pData);

// 扩展IO模块通道读输出，16位长度
MTN_API Int16  __stdcall NMC_IOModuleRdOut16Bit( HAND devHandle, UInt8 chDevId,UInt8 offset,UInt16 *pData);

// 扩展IO模块通道读输出，32位长度
MTN_API Int16  __stdcall NMC_IOModuleRdOut32Bit( HAND devHandle, UInt8 chDevId,UInt8 offset,UInt32 *pData);

// 扩展IO模块通道读，8位长度
// chDevId：设备站号
// offset:数据偏移
MTN_API Int16  __stdcall NMC_IOModuleRd8Bit( HAND devHandle, UInt8 chDevId,UInt8 offset,UInt8 *pData);

// 扩展IO模块通道读，16位长度
MTN_API Int16  __stdcall NMC_IOModuleRd16Bit( HAND devHandle, UInt8 chDevId,UInt8 offset,UInt16 *pData);

// 扩展IO模块通道读，32位长度
MTN_API Int16  __stdcall NMC_IOModuleRd32Bit( HAND devHandle, UInt8 chDevId,UInt8 offset,UInt32 *pData);

// 设置模拟量输出
// slv:从站号，取值[2,n];chn:通道号，取值范围[0,n]
// vol:输出模拟量电压值
MTN_API Int16  __stdcall NMC_IODacSet(HAND devHandle,UInt8 slv,UInt8 chn,double vol);
// 缓冲区:设置模拟量输出
MTN_API Int16  __stdcall NMC_CrdBufIODacSet(HAND crdHandle,Int32 segNo,UInt8 slv,UInt8 chn,double vol);

//------------------------------------------------------------------------------------------------------------
//
//        6.坐标系配置
//
//------------------------------------------------------------------------------------------------------------
#define CRD_MAX_DIMENSION 4

// 坐标系配置
typedef struct TCrdConfig
{
    Int16 axCnts;       // 参与的轴数量
    Int16 reserved[3];  // 保留
    Int16 pAxArray[4];  // 坐标系轴映射表,轴序号取值范围[0,n]
    Int16 port[4];      // 坐标系端口映射表,统一设为0
    
    #ifdef MTN_ST_INIT_EN
    TCrdConfig(){
     axCnts = 2;
     reserved[0] = reserved[1] = reserved[2] = 0;
     pAxArray[0] = 0;
     pAxArray[1] = 1;
     pAxArray[2] = 2;
     pAxArray[3] = 3;
     port[0] =port[1] =port[2] =port[3] = 0;
    }
    #endif
}TCrdConfig;
// 建立插补坐标系系统(必须)
// pConfig:坐标系配置,参考结构体定义
MTN_API Int16 __stdcall NMC_CrdConfig( HAND crdHandle, TCrdConfig *pConfig );

//缓冲区运动安全参数
typedef struct TCrdSafePara
{
    double estpDec;     // 急停加速度
    double maxVel;      // 最大速度
    double maxAcc;      // 最大加速度
    
    #ifdef MTN_ST_INIT_EN
    TCrdSafePara(){
     estpDec = 1000;
     maxVel = 1000;
     maxAcc = 1000;
    }
    #endif
}TCrdSafePara;
// 设置轴缓冲区运动安全参数
// pPara：包含急停减速度、最大允许速度、最大允许加速度
MTN_API Int16  __stdcall NMC_CrdSetSafePara( HAND crdHandle, TCrdSafePara *pPara );

// 设置轴缓冲区运动偏移
// count:设置偏移的轴数
// pOffsetArray：缓冲区运动偏移,long数组
// 注：会同时修改坐标系内相关轴的运动偏移！
MTN_API Int16  __stdcall NMC_CrdSetOffset( HAND crdHandle,Int16 count, Int32 *pOffsetArray );

// 删除坐标系
MTN_API Int16 __stdcall NMC_CrdDelete(  HAND crdHandle );


//------------------------------------------------------------------------------------------------------------
//
//        7.坐标系运行控制
//
//------------------------------------------------------------------------------------------------------------
// 坐标系缓冲运动启动  
MTN_API Int16 __stdcall NMC_CrdStartMtn( HAND crdHandle );

// 立即平滑停止运动
// 注：立即停止运动。并不清空指令缓冲区。需要再次启动才能继续运行缓冲区指令。
MTN_API Int16 __stdcall NMC_CrdStopMtn( HAND crdHandle );

// 急停
// 并不清空指令缓冲区
MTN_API Int16 __stdcall NMC_CrdEstopMtn( HAND crdHandle );

// 结束缓冲区运动（等待运动完后才结束区运动,并置空闲标志）
// 注：缓冲区运动结束并不立即停止运动。把指令缓冲区全部执行完后,结束缓冲区运动状态。
MTN_API Int16 __stdcall NMC_CrdEndMtn   ( HAND crdHandle );
// allCmdDone:是否全部加工数据都传送完成
MTN_API short __stdcall NMC_CrdEndMtnEx(HAND crdHandle, Int16 allCmdDone);

// 返回缓冲区运动的断点
// vel:返回时使用的速度
// acc:返回时使用的加速度
MTN_API Int16 __stdcall NMC_CrdGotoBreak( HAND crdHandle,double acc,double vel);


//------------------------------------------------------------------------------------------------------------
//
//        8.坐标系及运动缓冲区状态读取
//
//------------------------------------------------------------------------------------------------------------
// 坐标系状态字位定义 
#define BIT_CORD_BUSY           (0x00000001)    // bit 0 , 运动:1 ,静止 0,立即运动下运动停止,完成 
#define BIT_CORD_MVERR          (0x00000002)    // bit 1 , 运动出错,或当前运动指令无法启动,需要软件复位    
#define BIT_CORD_EMPTY          (0x00000004)    // bit 2 , 缓冲区空　       
#define BIT_CORD_FULL           (0x00000008)    // bit 3 , 缓冲区满　               
#define BIT_CORD_NODATASTOP     (0x00000010)    // bit 4 , 缓冲区空异常停止或者急停　    
#define BIT_CORD_SDRAM_HWERR    (0x00000020)    // bit 5, 插补缓冲区硬件或者其他错误  
#define BIT_CORD_POSREC         (0x00000040)    // bit 6 , 伺服位置到达,步进模式时位置到达,伺服模式时实际位置到达误差限    
// 读取坐标系状态
// pStsWord：返回状态字,参考宏定义
MTN_API Int16 __stdcall NMC_CrdGetSts( HAND crdHandle, Int16  *pStsWord );

typedef struct TPackedCrdSts4
{
    Int16 crdSts;          // 坐标系状态
    Int16 axSts[4];        // 坐标系里各轴状态
    Int32  prfPos[4];       // 用户坐标系下的规划位置
    Int32  axisPos[4];      // 机械坐标系下的规划位置
    Int32  encPos[4];        // 编码器位置
    Int32  userSeg;         // 运行的缓冲区段号
    double  prfVel;         // 运动速度
    Int32  gpDi;             // 通用输入0~31
    Int32  gpDo;             // 通用输出0~31
    Int16  motDi[4];        // 限位、原点、报警。请参考专用IO位定义( 搜索 BIT_AXMTIO_LMTN )
    Int16  reserved;        // 保留
    Int32 crdFreeSpace;      // 缓冲区剩余空间
    Int32 crdUsedSpace;
   
}TPackedCrdSts4;
// 坐标系运动模式下,打包读取控制器状态
MTN_API Int16 __stdcall NMC_CrdGetStsPack4( HAND crdHandle, TPackedCrdSts4 *pPackSts );

// 清坐标系运动错误状态,同时清除所包含轴的错误状态
MTN_API Int16 __stdcall NMC_CrdClrError   ( HAND crdHandle );

// 读取指令缓冲区空闲长度
// pRes：返回空闲的长度
MTN_API Int16 __stdcall NMC_CrdBufGetFree ( HAND crdHandle, Int32 *pRes );

// 读取指令缓冲区已用长度
// pLen: 长度。缓冲区中还未执行的指令个数。
MTN_API Int16 __stdcall NMC_CrdBufGetUsed  ( HAND crdHandle, Int32 *pLen );

// 获取插补缓冲区中尚未完成的总位移量
// pLen: 长度
MTN_API Int16 __stdcall NMC_CrdGetBufLeftLength(HAND crdHandle, double *pLen);

// 指令缓冲区清空
MTN_API Int16 __stdcall NMC_CrdBufClr( HAND crdHandle );

// 设置坐标系剩余位移量，用于控制激光能量跟随后的关闭波形输出
// group:波形数组组号
// ch:激光通道号
MTN_API Int16  __stdcall NMC_CrdSetLeftLenForLaserWaveOff ( HAND crdHandle,double length ,Int16 group,Int16 ch);

// 缓冲设置坐标系剩余位移量，用于控制激光能量跟随后的关闭波形输出
MTN_API Int16  __stdcall NMC_CrdBufSetLeftLenForLaserWaveOff( HAND crdHandle,Int32 segNo,double length,Int16 group,Int16 ch);

// 缓冲设置坐标系剩余位移量，用于控制BufDoExForLeftLen的提前输出
MTN_API short  __stdcall OEM_CrdBufSetLeftLenForDoOut( HAND crdHandle,long segNo,double length);

// 缓冲区DO,延时输出
// segNo:段号
// gourp:Do组别,见宏定义
// doMask：位掩码
// doValue：输出值
MTN_API short  __stdcall OEM_CrdBufDoExForLeftLen(HAND crdHandle,long segNo,short group,long doMask,long doValue);


// 读段号
// pSegNo：返回的当前段号
MTN_API Int16 __stdcall NMC_CrdGetUserSegNo  ( HAND crdHandle, Int32 *pSegNo);

//  读取总共压了多少条指令
//  pCnt:返回的指令数
MTN_API Int16 __stdcall NMC_CrdGetBufAllCmdCnt ( HAND crdHandle, Int32 *pCnt);

//  读取执行了多少条指令
//  pCnt:返回的指令数
MTN_API Int16 __stdcall NMC_CrdGetBufDoneCmdCnt ( HAND crdHandle, Int32 *pCnt);

// 开始计算缓冲区执行时间
// 注意:1.如果需要计算执行时间，需要使用上位机前瞻
//     2.开始后，所有的缓冲区指令，都不会压入控制器
MTN_API Int16 __stdcall NMC_CrdStartExeTimeCalc(void);

// 读取缓冲区指令的执行时间，并停止计算，单位:ms
MTN_API Int16 __stdcall NMC_CrdGetExeTime(double *pTime);

// 读取缓冲区指令的执行时间，并停止计算，单位:ms
// pCurveLen:段长
MTN_API short __stdcall NMC_CrdGetExeTimeEx(HAND crdHandle, double* pTime, double* pCurveLen);

// 设置立即指令属性功能开关
// onOff:是否开启，默认为不开启，0:不开启; >0:开启，指前端缓存指令系数，越大则提前可以越多；取值范围[0,64)
// errHandleFlag:错误处理标志位，bit0:对于提前指令，如果无法提前到指定位置，是否直接返回错误
MTN_API short  __stdcall NMC_CrdPreOPPropOnOff(HAND crdHandle,Int16 onOff,Int32 errHandleFlag);

// 设置上一条立即指令的时间属性
// timeUs:延时或者提前工作时间，大于0：延时滞后输出  小于0：提前输出，单位:us
// 注意:仅支持上位机前瞻，且需要通过NMC_CrdPreOPPropOnOff开启该功能
MTN_API short  __stdcall NMC_CrdBufPreOPSetTimeProp(HAND crdHandle,Int32 segNo,double timeUs);

// 设置上一条立即指令的距离属性
// dist:提前或滞后的距离，大于0：滞后指定距离输出  小于0：提前指定距离输出，单位:pulse
// 注意:仅支持上位机前瞻，且需要通过NMC_CrdPreOPPropOnOff开启该功能
MTN_API short  __stdcall NMC_CrdBufPreOPSetDistanceProp(HAND crdHandle,Int32 segNo,double dist);

// 设置坐标系缓冲区等待超时的处理模式
// mode:处理模式，0：继续，默认，1:立即停止坐标系运动
// param:保留参数
MTN_API Int16 __stdcall NMC_CrdSetWaitTimeOutMode(HAND crdHandle, Int16 mode, Int16 param);
MTN_API Int16 __stdcall NMC_CrdGetWaitTimeOutMode(HAND crdHandle,Int16 *pMode, Int16 *pParam);

// 设置缓冲区等待位置的容差范围，包括NMC_CrdBufWaitPos.默认1个脉冲
MTN_API Int16 __stdcall NMC_CrdSetWaitPosErrZone(HAND devHandle, double errZone);
MTN_API Int16 __stdcall NMC_CrdGetWaitPosErrZone(HAND devHandle, double* pErrZone);


//------------------------------------------------------------------------------------------------------------
//
//        9.缓冲区插补运动和IO控制
//
//------------------------------------------------------------------------------------------------------------

// 四轴直线插补
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// crdAxMask:参与的轴,按位表示
// endVel,vel,synAcc:终点速度，最大速度，插补加速度
// pTgPosArray：目标位置数组
// lookaheadDis:是否使用前瞻,0：使用前瞻,则控制器自动计算终点速度,1：禁用前瞻,使用设定的终点速度（endVel）
MTN_API Int16 __stdcall NMC_CrdLineXYZA(  HAND crdHandle,  Int32 segNo, Int16 crdAxMask,
    Int32 *pTgPosArray, double endVel, double vel,double synAcc ,Int16 lookaheadDis);

// 设置4维插补下，A轴的最大容忍转弯速度，若大于该速度，则需要进行降速处理
MTN_API Int16  __stdcall NMC_CrdSetFourthAxisTolTurnVel(HAND crdHandle,double tolVel);

// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// crdAxMask:参与的轴,按位表示
// pTgPosArray：目标位置数组,长度为3
// lookaheadDis:是否使用前瞻,0：使用前瞻,则控制器自动计算终点速度,1：禁用前瞻,使用设定的终点速度（endVel）
MTN_API Int16 __stdcall NMC_CrdLineXYZEx(  HAND crdHandle,  Int32 segNo, Int16 crdAxMask,Int32 *pTgPosArray,
    double endVel, double vel,double synAcc,Int16 lookaheadDis );

// 多轴直线插补（最多支持8轴）
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// crdAxmask:坐标系中参与的轴,按位表示
// extAxMask:其他参与轴,按位表示,不能包括坐标系中
// pTgPosArray：目标位置数组,长度为所有参与运动的轴的数量,
//              索引小的是坐标系内的轴的坐标（按crdAxMask位排列）。索引大的是其它联动轴的坐标（按extAxMask位排列）
// lookaheadDis:是否使用前瞻(仅仅适用与坐标系中的轴的运动),0：使用前瞻,则控制器自动计算终点速度,1：禁用前瞻,使用设定的终点速度（endVel）
MTN_API Int16 __stdcall NMC_CrdLineXYZD8(  HAND crdHandle, Int32 segNo, 
    Int32 crdAxmask, Int32 extAxMask, Int32 *pTgPosArray,
    double endVel, double vel,double synAcc,Int16 lookaheadDis );

// 8轴插补打包单元结构体
typedef struct TCrdLineXYZD8Unit
{
    Int32 segNo;         // 用户自定义段号
    Int16 crdAxMask;
    Int16 extAxMask;
    Int32  tgPos[8];     // 目标位置
    float vel;         // 最大速度
    float endVel;      // 终点速度
    float acc;            // 插补加速度
    Int16 lookaheadDis;    // 是否使用前瞻
    Int16 reserved;        // 保留
    
    #ifdef MTN_ST_INIT_EN
    TCrdLineXYZD8Unit(){
     segNo = 0;
	 memset(tgPos,0,sizeof(Int32)*8);
     crdAxMask = 0;
     extAxMask = 0;
     lookaheadDis = 0;
     reserved = 0;
	 vel = endVel = acc = 0.1f;
    }
    #endif
}TCrdLineXYZD8Unit;

// 打包的多轴直线插补
// count:打包指令数,取值范围[1,18]
// pCmdArray:指令列表
MTN_API Int16 __stdcall NMC_CrdLineXYZD8Pack(  HAND crdHandle, Int16 count,  TCrdLineXYZD8Unit *pCmdArray);


// 4轴插补打包单元结构体
typedef struct TCrdLineXYZD4Unit
{
    Int32 segNo;         // 用户自定义段号
    Int16 crdAxMask;
    Int16 extAxMask;
    Int32  tgPos[4];     // 目标位置
    float vel;         // 最大速度
    float endVel;      // 终点速度
    float acc;      // 插补加速度
    Int16 lookaheadDis;    // 是否使用前瞻
    Int16 reserved;        // 保留
    
    #ifdef MTN_ST_INIT_EN
    TCrdLineXYZD4Unit(){
     segNo = 0;
     crdAxMask = 0;
     extAxMask = 0;
	 memset(tgPos,0,sizeof(Int32)*4);
     lookaheadDis = 0;
     reserved = 0;
	 vel = endVel = acc = 0.1f;
    }
    #endif
}TCrdLineXYZD4Unit;

// 打包的4轴直线插补
// count:打包指令数,取值范围[1,25]
// pCmdArray:指令列表
MTN_API Int16 __stdcall NMC_CrdLineXYZD4Pack(  HAND crdHandle, Int16 count,  TCrdLineXYZD4Unit *pCmdArray);

typedef struct TCrdLineXYZUnit
{
    Int32 segNo;         // 用户自定义段号
    Int32  tgPos[3];     // 目标位置
    double endVel;      // 终点速度
    double vel;         // 最大速度
    double synAcc;      // 插补加速度
    Int16 mask;         // 参与的轴,按位表示
    Int16 lookaheadDis;    // 是否使用前瞻
    Int16 reserved[2];  // 保留
    
    #ifdef MTN_ST_INIT_EN
    TCrdLineXYZUnit(){
     segNo = 0;
     memset(tgPos,0,sizeof(Int32)*3);
     endVel = 0;
     vel = 0;
     synAcc = 0;
     mask = 0;
     lookaheadDis = 0;
     reserved[0] = reserved[1] = 0;
    }
    #endif
}TCrdLineXYZUnit;
// 打包的直线插补
// count:打包指令数,取值范围[1,20]
// pCmdArray:指令列表
MTN_API Int16 __stdcall NMC_CrdLineXYZPack(  HAND crdHandle, Int16 count,  TCrdLineXYZUnit *pCmdArray);

// XY平面圆弧插补：终点位置、半径、方向
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// radius:圆弧半径,大于0表示劣弧,小于0表示优弧
// pTgPosArray：目标位置数组（二维数组,分别表示XY的位置）
// circleDir:圆弧方向,0表示顺时针方向,1表示逆时针方向
MTN_API Int16 __stdcall NMC_CrdArcRadius(  HAND crdHandle, Int32 segNo,Int32 *pTgPosArray, double radius, Int16 circleDir,double endVel, double vel,double synAcc );

// YZ平面圆弧插补：终点位置、半径、方向
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// radius:圆弧半径,大于0表示劣弧,小于0表示优弧
// pTgPosArray：目标位置数组（二维数组,分别表示YZ的位置）
// circleDir:圆弧方向,0表示顺时针方向,1表示逆时针方向
MTN_API Int16 __stdcall NMC_CrdArcRadiusYZ(  HAND crdHandle, Int32 segNo,
    Int32 *pTgPos, double radius, Int16 circleDir,double velEnd, double vel,double synAcc );

// ZX平面圆弧插补：终点位置、半径、方向
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// radius:圆弧半径,大于0表示劣弧,小于0表示优弧
// pTgPosArray：目标位置数组（二维数组,分别表示ZX的位置）
// circleDir:圆弧方向,0表示顺时针方向,1表示逆时针方向
MTN_API Int16 __stdcall NMC_CrdArcRadiusZX(  HAND crdHandle, Int32 segNo,
    Int32 *pTgPos, double radius, Int16 circleDir,double velEnd, double vel,double synAcc );

// XY平面圆弧插补：终点位置、半径、方向
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// radius:圆弧半径,大于0表示劣弧,小于0表示优弧
// pTgPosArray：目标位置数组（二维数组,分别表示XY的位置）
// circleDir:圆弧方向,0表示顺时针方向,1表示逆时针方向
// lookaheadDis:是否使用前瞻,0：使用前瞻,则控制器自动计算终点速度,1：禁用前瞻,使用设定的终点速度（endVel）
MTN_API Int16 __stdcall NMC_CrdArcRadiusEx(  HAND crdHandle, Int32 segNo,Int32 *pTgPosArray, double radius, 
                                Int16 circleDir,double endVel, double vel,double synAcc ,Int16 lookaheadDis);

// YZ平面圆弧插补：终点位置、半径、方向
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// radius:圆弧半径,大于0表示劣弧,小于0表示优弧
// pTgPosArray：目标位置数组（二维数组,分别表示YZ的位置）
// circleDir:圆弧方向,0表示顺时针方向,1表示逆时针方向
// lookaheadDis:是否使用前瞻,0：使用前瞻,则控制器自动计算终点速度,1：禁用前瞻,使用设定的终点速度（endVel）
MTN_API Int16 __stdcall NMC_CrdArcRadiusYZEx(  HAND crdHandle, Int32 segNo,Int32 *pTgPos, double radius, 
    Int16 circleDir,double velEnd, double vel,double synAcc ,Int16 lookaheadDis);

// ZX平面圆弧插补：终点位置、半径、方向
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// radius:圆弧半径,大于0表示劣弧,小于0表示优弧
// pTgPosArray：目标位置数组（二维数组,分别表示ZX的位置）
// circleDir:圆弧方向,0表示顺时针方向,1表示逆时针方向
// lookaheadDis:是否使用前瞻,0：使用前瞻,则控制器自动计算终点速度,1：禁用前瞻,使用设定的终点速度（endVel）
MTN_API Int16 __stdcall NMC_CrdArcRadiusZXEx(  HAND crdHandle, Int32 segNo,Int32 *pTgPos, double radius, 
    Int16 circleDir,double velEnd, double vel,double synAcc ,Int16 lookaheadDis);

// XY平面圆弧插补：终点位置、圆心、方向
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// pCenterPosArray:圆心坐标（二维数组,分别表示XY轴相对于起点的圆心位置）,注意：圆心坐标为相对于起点的相对位置
// pTgPosArray：目标位置（二维数组,分别表示XY轴的目标位置）
// circleDir:圆弧方向,0表示顺时针方向,1表示逆时针方向
MTN_API Int16 __stdcall NMC_CrdArcCenter(  HAND crdHandle, Int32 segNo,Int32 *pTgPosArray, Int32 *pCenterPosArray,Int16 circleDir,double endVel, double vel,double synAcc );

// YZ平面圆弧插补：终点位置、圆心、方向
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// pCenterPosArray:圆心坐标（二维数组,分别表示YZ轴相对于起点的圆心位置）,注意：圆心坐标为相对于起点的相对位置
// pTgPosArray：目标位置（二维数组,分别表示YZ轴的目标位置）
// circleDir:圆弧方向,0表示顺时针方向,1表示逆时针方向
MTN_API Int16 __stdcall NMC_CrdArcCenterYZ(  HAND crdHandle, Int32 segNo,Int32 *pTgPos, 
    Int32 *pCenterPos,Int16 circleDir,double velEnd, double vel,double synAcc );

// ZX平面圆弧插补：终点位置、圆心、方向
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// pCenterPosArray:圆心坐标（二维数组,分别表示ZX轴相对于起点的圆心位置）,注意：圆心坐标为相对于起点的相对位置
// pTgPosArray：目标位置（二维数组,分别表示ZX轴的目标位置）
// circleDir:圆弧方向,0表示顺时针方向,1表示逆时针方向
MTN_API Int16 __stdcall NMC_CrdArcCenterZX(  HAND crdHandle, Int32 segNo,Int32 *pTgPos, 
    Int32 *pCenterPos,Int16 circleDir,double velEnd, double vel,double synAcc );

// XY平面圆弧插补：终点位置、圆心、方向
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// pCenterPosArray:圆心坐标（二维数组,分别表示XY轴相对于起点的圆心位置）,注意：圆心坐标为相对于起点的相对位置
// pTgPosArray：目标位置（二维数组,分别表示XY轴的目标位置）
// circleDir:圆弧方向,0表示顺时针方向,1表示逆时针方向
// lookaheadDis:是否使用前瞻,0：使用前瞻,则控制器自动计算终点速度,1：禁用前瞻,使用设定的终点速度（endVel）
MTN_API Int16 __stdcall NMC_CrdArcCenterEx(  HAND crdHandle, Int32 segNo,Int32 *pTgPosArray, Int32 *pCenterPosArray,
                                        Int16 circleDir,double endVel, double vel,double synAcc ,Int16 lookaheadDis);

// XY平面圆弧插补：终点位置、圆心、方向、带是否整圆标记
// isCircle:是否为整圆，0:圆弧  1:整圆
MTN_API Int16 __stdcall NMC_CrdArcCenterEx2(  HAND crdHandle, Int32 segNo,Int32 *pTgPosArray, Int32 *pCenterPosArray,
                                        Int16 circleDir,double endVel, double vel,double synAcc ,Int16 lookaheadDis,Int16 isCircle);

// YZ平面圆弧插补：终点位置、圆心、方向
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// pCenterPosArray:圆心坐标（二维数组,分别表示ZX轴相对于起点的圆心位置）,注意：圆心坐标为相对于起点的相对位置
// pTgPosArray：目标位置（二维数组,分别表示YZ轴的目标位置）
// circleDir:圆弧方向,0表示顺时针方向,1表示逆时针方向
// lookaheadDis:是否使用前瞻,0：使用前瞻,则控制器自动计算终点速度,1：禁用前瞻,使用设定的终点速度（endVel）
MTN_API Int16 __stdcall NMC_CrdArcCenterYZEx(  HAND crdHandle, Int32 segNo,Int32 *pTgPos, Int32 *pCenterPos,
    Int16 circleDir,double velEnd, double vel,double synAcc ,Int16 lookaheadDis);

// ZX平面圆弧插补：终点位置、圆心、方向
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// pCenterPosArray:圆心坐标（二维数组,分别表示ZX轴相对于起点的圆心位置）,注意：圆心坐标为相对于起点的相对位置
// pTgPosArray：目标位置（二维数组,分别表示ZX轴的目标位置）
// circleDir:圆弧方向,0表示顺时针方向,1表示逆时针方向
// lookaheadDis:是否使用前瞻,0：使用前瞻,则控制器自动计算终点速度,1：禁用前瞻,使用设定的终点速度（endVel）
MTN_API Int16 __stdcall NMC_CrdArcCenterZXEx(  HAND crdHandle, Int32 segNo,Int32 *pTgPos, Int32 *pCenterPos,
    Int16 circleDir,double velEnd, double vel,double synAcc ,Int16 lookaheadDis);

// XY平面圆弧插补：起点（当前点）、中点、终点
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// pMidPosArray:中间位置点坐标（二维数组,分别表示中间点的XY轴的位置）
// pTgPosArray：终点位置坐标（二维数组,分别表示终点的XY轴的位置）
MTN_API Int16 __stdcall NMC_CrdArcPPP(  HAND crdHandle,Int32 segNo, Int32 *pMidPosArray, Int32 *pTgPosArray, double endVel, double vel,double synAcc);

// XY平面整圆插补：起点（当前点）、中点、终点
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// planeIdx:平面类型，0:XY 1:YZ,2:ZX,目前只支持XY平面
// pMidPosArray:中间位置点坐标（二维数组,分别表示中间点的XY轴的位置）
// pTgPosArray：终点位置坐标（二维数组,分别表示终点的XY轴的位置）
MTN_API Int16 __stdcall NMC_CrdCirclePPP(  HAND crdHandle,Int32 segNo, Int16 planeIdx,Int32 *pStPos, Int32 *pMidPosArray, Int32 *pTgPosArray, double endVel, double vel,double synAcc ,Int16 lookaheadDis );

// XY平面圆弧插补：起点（当前点）、中点、终点
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// pMidPosArray:中间位置点坐标（二维数组,分别表示中间点的XY轴的位置）
// pTgPosArray：终点位置坐标（二维数组,分别表示终点的XY轴的位置）
// lookaheadDis:是否使用前瞻,0：使用前瞻,则控制器自动计算终点速度,1：禁用前瞻,使用设定的终点速度（endVel）
MTN_API Int16 __stdcall NMC_CrdArcPPPEx(  HAND crdHandle,Int32 segNo, Int32 *pMidPosArray, Int32 *pTgPosArray, 
                                                double endVel, double vel,double synAcc ,Int16 lookaheadDis);

// XY平面圆弧插补：起点（当前点）、中点、终点 带浮点位置
MTN_API Int16 __stdcall NMC_CrdArcPPPDbEx(  HAND crdHandle,Int32 segNo, double *pMidPosArray, double *pTgPosArray, 
                                                double endVel, double vel,double synAcc ,Int16 lookaheadDis);

// 椭圆插补，默认不参与速度前瞻，起始和终止速度为0（注意！椭圆为整圆）
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// pCenterPos：椭圆圆心点位置（二维数组,分别表示中点的XY轴的位置）。注意！起点位置到圆心位置为长轴的
// abRatio:表示椭圆AB轴的长度比例值 值范围：[0.05,1]
// ellipseDir:椭圆绘画方向,0表示顺时针方向,1表示逆时针方向
MTN_API Int16 __stdcall NMC_CrdEllipse(  HAND crdHandle, Int32 segNo,double abRatio, Int32 *pCenterPos,Int16 ellipseDir, double vel,double synAcc);

// 椭圆弧插补
// a:长轴长度
// b:短轴长度
// rotAng:椭圆绕圆心逆时针方向旋转的角度，单位:度
// pCenterPos:椭圆圆心点位置（二维数组,分别表示中点的XY轴的位置）,注意：这里是绝对位置
// ellipseDir:椭圆绘画方向,0表示顺时针方向,1表示逆时针方向
// pTgPosArray:目标位置
MTN_API Int16 __stdcall NMC_CrdEllipseArcRot(  HAND crdHandle, Int32 segNo,double a,double b, double rotAng,double *pCenterPos,double *pTgPosArray,
    Int16 ellipseDir, double endVel, double vel,double synAcc);

// 椭圆弧插补
// a:长轴长度
// b:短轴长度
// pCenterPos:椭圆圆心点位置（二维数组,分别表示中点的XY轴的位置）,注意：这里是绝对位置
// ellipseDir:椭圆绘画方向,0表示顺时针方向,1表示逆时针方向
// pTgPosArray:目标位置
MTN_API Int16 __stdcall NMC_CrdEllipseArc(  HAND crdHandle, Int32 segNo,double a,double b, double *pCenterPos,double *pTgPosArray,
    Int16 ellipseDir, double endVel, double vel,double synAcc);

// 涡旋线插补
// pCenterPos:中心位置,XY二维位置
// pTgtPos:目标位置，XYZ三维
// rounds:圈数
// circleDir:圆弧方向,0表示顺时针方向,1表示逆时针方向
MTN_API Int16 __stdcall NMC_CrdVortexCenter(  HAND crdHandle, Int32 segNo, Int32 *pCenterPos, Int32 *pTgtPos, 
    Int16 circleDir,double rounds,double endVel,double vel,double synAcc);

// 涡旋线插补
// rounds:圈数，整数圈，小数部分自动根据起点等参数计算
// 其他参数等同NMC_CrdVortexCenter
MTN_API short __stdcall NMC_CrdVortexCenterEx(  HAND crdHandle, Int32 segNo, double *pCenterPos, 
    double *pTgPos, short circleDir,Int32 rounds,double velEnd,double vel,double synAcc);

// 螺旋线插补
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// pTgPosArray：目标位置（三维数组,分别表示终点的XYZ轴的位置）
// pCenterPosArray:圆心位置（二维数组,分别表示XY轴相对于起点的圆心位置）,注意：圆心坐标为相对于起点的相对位置
// rounds: Z方向圈数
MTN_API Int16 __stdcall NMC_CrdHelixCenter(  HAND crdHandle, Int32 segNo, Int32 *pTgPosArray, Int32 *pCenterPosArray,Int16 circleDir,double rounds, double endVel, double vel,double synAcc );

// 螺旋线插补
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// pTgPosArray：目标位置（三维数组,分别表示终点的XYZ轴的位置）
// pCenterPosArray:圆心位置（二维数组,分别表示XY轴相对于起点的圆心位置）,注意：圆心坐标为相对于起点的相对位置
// rounds: Z方向圈数
// lookaheadDis:是否使用前瞻,0：使用前瞻,则控制器自动计算终点速度,1：禁用前瞻,使用设定的终点速度（endVel）
MTN_API Int16 __stdcall NMC_CrdHelixCenterEx(  HAND crdHandle, Int32 segNo, Int32 *pTgPosArray, Int32 *pCenterPosArray,Int16 circleDir,
                                                        double rounds, double endVel, double vel,double synAcc ,Int16 lookaheadDis);

// 3D圆弧插补
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// pMidPos：中点位置（三维数组,分别表示中点的XYZ轴的位置）
// pTgPos:终点位置（三维数组,分别表示终点的XYZ轴的位置）
MTN_API Int16 __stdcall NMC_CrdArc3D(  HAND crdHandle,Int32 segNo, Int32 *pMidPos, Int32 *pTgPos,
                                    double velEnd, double vel,double synAcc );

// 3D圆弧插补
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// pMidPos：中点位置（三维数组,分别表示中点的XYZ轴的位置）
// pTgPos:终点位置（三维数组,分别表示终点的XYZ轴的位置）
// lookaheadDis:是否使用前瞻,0：使用前瞻,则控制器自动计算终点速度,1：禁用前瞻,使用设定的终点速度（endVel）
MTN_API Int16 __stdcall NMC_CrdArc3DEx(  HAND crdHandle,Int32 segNo, Int32 *pMidPos, Int32 *pTgPos,
                                    double velEnd, double vel,double synAcc ,Int16 lookaheadDis);
MTN_API Int16 __stdcall NMC_CrdArc3DDbEx(  HAND crdHandle,Int32 segNo, double *pMidPos, double *pTgPos,
                                            double velEnd, double vel,double synAcc ,Int16 lookaheadDis);
// 3D圆弧插补(整圆)
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// pMidPos：中点位置（三维数组,分别表示中点的XYZ轴的位置）
// pTgPos:终点位置（三维数组,分别表示终点的XYZ轴的位置）
// lookaheadDis:是否使用前瞻,0：使用前瞻,则控制器自动计算终点速度,1：禁用前瞻,使用设定的终点速度（endVel）
MTN_API Int16 __stdcall NMC_CrdCircle3DEx(  HAND crdHandle,Int32 segNo, Int32 *pMidPos, Int32 *pTgPos,
                                    double velEnd, double vel,double synAcc ,Int16 lookaheadDis);
// 3D 圆弧平面类型
#define ARC3D_PLANE_XYZ        0        // xyz
#define ARC3D_PLANE_XYA        1        // xya
#define ARC3D_PLANE_XZA        2        // xza
#define ARC3D_PLANE_YZA        3        // yza

// 3D圆弧插补
// segNo:段号；endVel:终点速度;vel:最大速度;synAcc:合成加速度
// planeType:平面，0:xyz 1:x
// pMidPos：中点位置（三维数组,分别表示中点的XYZ轴的位置）
// pTgPos:终点位置（三维数组,分别表示终点的XYZ轴的位置）
MTN_API Int16 __stdcall NMC_CrdArc3DPlane(  HAND crdHandle,Int32 segNo, Int16 planeType,Int16 isCircle,Int32 *pMidPos, Int32 *pTgPos,
    double velEnd, double vel,double synAcc ,Int16 lookaheadDis);

// 缓冲区输出DO组定义
#define CRD_BUFF_DO_MOTOR_ENABLE            1   // 电机使能
#define CRD_BUFF_DO_MOTOR_CLEAR             2   // 电机报警清除
#define CRD_BUFF_DO_GPDO1                   3   // 通用输出1
#define CRD_BUFF_DO_GPDO2                   4   // 通用输出2
#define CRD_BUFF_DO_EXTDO1                    5    // 扩展模块1
#define CRD_BUFF_DO_EXTDO2                    6    // 扩展模块2
#define CRD_BUFF_DO_EXTDO3                    7    // 扩展模块3
#define CRD_BUFF_DO_EXTDO4                    8    // 扩展模块4
#define CRD_BUFF_DO_EXTDO5                    9    // 扩展模块5
#define CRD_BUFF_DO_EXTDO6                    10    // 扩展模块6
#define CRD_BUFF_DO_HSIO                    20    // 高速Gate

// 缓冲区DO
// segNo:段号
// doType:Do类型,见宏定义
// ch：位序号,取值范围[0,31]
// value：输出值,取值范围[0,1]
MTN_API Int16 __stdcall NMC_CrdBufDo( HAND crdHandle, Int32 segNo, Int16 doType,   Int32  ch,  Int32  value);

// 缓冲区DO
// segNo:段号
// gourp:Do组别,见宏定义
// doMask：位掩码
// doValue：输出值
MTN_API Int16  __stdcall NMC_CrdBufDoEx(HAND crdHandle,Int32 segNo,Int16 group,Int32 doMask,Int32 doValue);

// 通用输出宏类型
#define BUF_OUT_GROUP_DA        (0)             // 模拟量输出
#define BUF_OUT_GROUP_PWM       (1)             // PWM输出
#define BUF_OUT_GROUP_INNER_VAR (2)             // 内部变量
// 缓冲区输出
// segNo:段号
// gourp:组别,见宏定义
// ch：通道号,取值范围[0,n]
// value：输出值
MTN_API Int16 __stdcall NMC_CrdBufOut( HAND crdHandle,  Int32 segNo, Int16 group, Int16 ch, Int32  value);

// 缓冲区DI等待
// index:通道号,取值范围[0,127],前64通道代表通用DI，后64通道代表扩展IO
// diValue：等待值
// waitLastTime：超时,单位：毫秒
MTN_API Int16 __stdcall NMC_CrdBufWaitDI(HAND crdHandle, Int32 segNo,Int16 index,Int16 diValue,Int32 waitLastTime);

// waitType
#define BUF_WAIT_TYPE_VAR       0        // 内部变量
#define BUF_WAIT_TYPE_DO        1        // DO状态
#define BUF_WAIT_TYPE_HS2D      2        // 位置比较触发计数，大于等于
#define BUF_WAIT_TYPE_ADC_HI    3        // ADC大于等于设定值
#define BUF_WAIT_TYPE_ADC_LO    4        // ADC小于等于设定值

// 缓冲区等待
// waitType:等待类型，0：内部变量，1：DO状态
// index:通道号，对于内部变量，取值范围[0,maxVarCnt),对于DO，取值范围[0,63]
// waitValue：等待值
// waitTimeInMs：超时,单位：毫秒
MTN_API Int16 __stdcall NMC_CrdBufWait(HAND crdHandle, Int32 segNo,Int16 waitType,Int16 index,Int32 waitValue,Int32 waitTimeInMs);

// 功能:缓冲区等待电机运动到位
// segNo:段号
// axisMask:需要等待到位的轴掩码（按位对应轴号,不能超出控制器的最大轴数）
// overTime:等待到位超时的时间，单位：ms
MTN_API Int16  __stdcall NMC_CrdBufWaitEncInPosition(HAND crdHandle,Int32 segNo,Int32 axisMask,Int32 overTime);

// 功能:缓冲区等待特定位置，满足条件才执行下一条指令
// segNo:段号
// axisNo:需要等待到位的轴号
// condition:到位条件，0：小于等于设定位置  1：大于等于设定位置
// pos:设定位置
// posSrc:等待规划还是编码器，0：规划 1:轴编码器,2:编码器
// overTime:等待到位超时的时间，单位：ms
MTN_API Int16  __stdcall NMC_CrdBufWaitPos(HAND crdHandle,Int32 segNo,Int16 axisNo,
    Int16 condition,Int32 pos,Int16 posSrc,Int32 overTime);

// 缓冲区延时单位
#define CRD_BUFF_DELAY_SCALE_MS             0   // 毫秒
#define CRD_BUFF_DELAY_SCALE_SECAND         1   // 秒
// 缓冲区延时
// segNo:段号
// scale:延时单位,0表示单位为毫秒,1表示单位为秒
// count：延时时长
MTN_API Int16 __stdcall NMC_CrdBufDelay( HAND crdHandle, Int32 segNo, Int16 scale, Int32  count);

// 缓冲区单轴移动(绝对位移移动)
// segNo:段号
// axisMask:参与的轴
// pTgPos：目标位置
// blockEn:是否为阻塞模式
// synEn：是否为同步模式,如果synEn和blockEn同时为1,则同步优先
MTN_API Int16 __stdcall NMC_CrdBufAxMove( HAND crdHandle,  Int32 segNo, Int16 axisMask,Int32 *pTgPos,Int16 blockEn ,Int16 synEn);

// 缓冲区单轴移动(带参数)
// segNo:段号
// axisMask:参与的轴
// pTgPos：目标位置
// vel:速度
// acc:加速度
// blockEn:是否为阻塞模式
// synEn：是否为同步模式,如果synEn和blockEn同时为1,则同步优先
MTN_API Int16  __stdcall NMC_CrdBufAxMoveEx(HAND crdHandle,Int32 segNo,Int16 axisMask,Int32 *pTgPos,
    double vel,double acc,Int16 blockEn ,Int16 synEn);

// 缓冲区单轴停止
// axisMask:需要停止的轴掩码
// flag:保留
// 注意：暂时停止非同步或者自由运动的轴
MTN_API Int16  __stdcall NMC_CrdBufAxStop(HAND crdHandle,Int32 segNo,Int32 axisMask,Int32 flag);

// 缓冲区单轴移动(带参数，支持高位轴)
// segNo:段号
// axisCnt:参与的轴的数量，取值范围[1,6]
// pAxList:参与的轴列表
// pTgPos：目标位置
// isRelMove:是否为相对运动
// blockEn:是否为阻塞模式
// synEn：是否为同步模式,如果synEn和blockEn同时为1,则同步优先
MTN_API Int16  __stdcall NMC_CrdBufAxMoveEx2(HAND crdHandle,Int32 segNo,short axisCnt,short *pAxList,Int32 *pTgPos,short isRelMove,short blockEn ,short synEn);

// 缓冲区单轴移动(相对位移移动)
// segNo:段号
// axisMask:参与的轴
// pRelPos：相对移动位置
// blockEn:是否为阻塞模式
// synEn：是否为同步模式,如果synEn和blockEn同时为1,则同步优先
MTN_API Int16 __stdcall NMC_CrdBufAxMoveRel( HAND crdHandle,  Int32 segNo, Int16 axisMask,Int32 *pRelPos,Int16 blockEn ,Int16 synEn);

// 缓冲区单轴移动参数设置
// segNo:段号
// axisNo：轴号,[0,n]
// vel:运动速度
// acc:运动加速度
// smoothCoef:平滑系数
MTN_API Int16 __stdcall NMC_CrdBufSetPtpMovePara(HAND crdHandle, Int32 segNo,Int16 axisNo,double vel,double acc,Int16 soomthCoef);

// 缓冲区跟随
// segNo:段号
// onOff:开关
MTN_API Int16 __stdcall NMC_CrdBufValueFollow ( HAND crdHandle ,  Int32 segNo, Int16 onOff );

// 缓冲区设置加工幅面范围，超出范围则停止运动
// crdAxMask:是否激活幅面限制    按位进行判断 ，bit0~2，分别对应XYZ轴 1：开启，0 关闭
// pXMax: pXMax[0]为X的最小行程边界    pXMax[1]为X的最大行程边界  pXMax[2]为X发生干涉时等待的参考位置
// pYMax和pZMax 同pXMax说明
MTN_API Int16 __stdcall NMC_CrdBufSetScaleLimit ( HAND crdHandle,Int32 segNo,
    Int16 crdAxMask,Int32 *pXMax,Int32 *pYMax,Int32 *pZMax);

// 设置跟随运动前的运动补偿量
// axis:轴号  0~N
//relDistance：相对补偿位移量
//vel：补偿速度
MTN_API Int16  __stdcall NMC_CrdBufBeforeAxSyncMove(HAND crdHandle, Int32 segNo,Int16 axis,Int32 relDistance,double vel);

// 设置坐标系速度倍率
// overRide：坐标系速度倍率,取值范围(0,10)
MTN_API Int16 __stdcall NMC_CrdSetOverRide( HAND crdHandle, double overRide );

// 设置坐标系剩余空间自动检查，当空间不足设定值，则返回RTN_MC_CrdLeftSpaceNotEnough错误
// onOff:是否启用检查
// leftSpace:剩余空间数量
MTN_API Int16 __stdcall NMC_CrdSetLeftSpaceCheck(HAND crdHandle,Int16 onOff,Int16 leftSpace);

// 设置坐标系等待指令超时的处理方法
// mode:处理方法，0:继续执行，默认 1:停止坐标系运动
MTN_API Int16 __stdcall NMC_CrdSetWaitTimeOutMode(HAND crdHandle, Int16 mode, Int16 param);
MTN_API Int16 __stdcall NMC_CrdGetWaitTimeOutMode(HAND crdHandle, Int16* pMode, Int16* pParam);


//------------------------------------------------------------------------------------------------------------
//
//        10.回零
//
//------------------------------------------------------------------------------------------------------------
// 回零类型定义                                                 
// 回零模式    单原点      单限位     单Z相    原点+Z相 原点+ -Z相  限位+ -Z相
typedef enum { HM_MODE1=0, HM_MODE2, HM_MODE3, HM_MODE4, HM_MODE5, HM_MODE6 } THomeMode;

// 回零参数设置
typedef struct  THomeSetting
{
    Int16  mode;                    // 模式,HM_MODE1 ~ HM_MODE6 （必须）
    Int16  dir;                     // 搜寻零点方向（必须）, 0:负向,1：正向,其它值无意义
    Int32    offset;                 // 原点偏移（必须）
    double  scan1stVel;             // 基本搜寻速度（必须）
    double  scan2ndVel;             // 低速（两次搜寻时需要）
    // 当usePreSetPtpPara=0时,回零运动的减加速度默认等于acc,起跳速度、终点速度、平滑系数默认为0
    double  acc;                    // 加速度
    
    UInt8 reScanEn;         // 是否两次搜寻零点（可选,不用时设为0）
    UInt8 homeEdge;         // 原点,触发沿（默认下降沿）
    UInt8 lmtEdge;          // 限位,触发沿（默认下降沿）
    UInt8 zEdge;            // 限位,触发沿（默认下降沿）
    UInt32 iniRetPos;        // 起始反向运动距离（可选,不用时设为0）
    UInt32 retSwOffset;      // 反向运动时离开开关距离（可选,不用时设为0）
    UInt32 safeLen;          // 安全距离,回零时最远搜寻距离（可选,不用时设为0,不限制距离）
    UInt8 usePreSetPtpPara; // 为1表示用户需要在启动回零前,自己设置回零运动（点到点）的参数
    UInt8 reserved[3];      // 保留
    Int32 reserved2;                 // HM_MODE7时，复用为di的序号，支持扩展di，序号请参考NMC_GetDIBit
    
    #ifdef MTN_ST_INIT_EN
	THomeSetting(){
		mode = 0;
		dir = 0;
		offset = 0;
		scan1stVel = 0;
		scan2ndVel = 0;
		acc = 0;
		reScanEn = 0;
		homeEdge = 0;
		lmtEdge = 0;
		zEdge = 0;
		iniRetPos = 0;
		retSwOffset = 0;
		safeLen = 0;
		usePreSetPtpPara = 0;
		reserved[0] = reserved[1] = reserved[2] = 0;
		reserved2 = 0;
    }
    #endif
} THomeSetting;
// 设置回零参数
// pHomePara: 回零参数结构,参考结构定义
MTN_API Int16 __stdcall NMC_MtSetHomePara( HAND axisHandle, THomeSetting *pHomePara );

// 回零状态字位定义 
#define BIT_AXHOME_BUSY         (0x00000001)    // bit 0  , 忙    
#define BIT_AXHOME_OK           (0x00000002)    // bit 1  , 成功  
#define BIT_AXHOME_FAIL         (0x00000004)    // bit 2  , 失败  
#define BIT_AXHOME_ERR_MV       (0x00000008)    // bit 3  , 错误：运动参数出错导致不动 
#define BIT_AXHOME_ERR_SWT      (0x00000010)    // bit 4  , 错误：搜寻过程中开关没触发 
// 读回零状态
// pStsWord: 返回状态字。参数宏定义,高8位为错误代码
MTN_API Int16 __stdcall NMC_MtGetHomeSts(HAND axisHandle, Int16 *pStsWord );

// 启动回零
MTN_API Int16 __stdcall NMC_MtHome(HAND axisHandle );

// 尝试性回零（测试回零误差,不清位置）
MTN_API Int16 __stdcall NMC_MtTryHome( HAND axisHandle );

// 终止回零
MTN_API Int16 __stdcall NMC_MtHomeStop(HAND axisHandle );

// 读新回零位置和历史回零位置的差值
// pErrPos: 回零位置偏差
// 注：回零成功时才有意义
MTN_API Int16 __stdcall NMC_MtGetHomeError( HAND axisHandle, Int32 *pErrPos );





//------------------------------------------------------------------------------------------------------------
//
//        11.电子齿轮
//
//------------------------------------------------------------------------------------------------------------
// 设置Gear跟随方向
// dir：  0:双向跟随，<0负向跟随， >0正向跟随
MTN_API Int16  __stdcall NMC_MtGearSetDir(HAND axisHandle,Int16 dir);

// 获取Gear跟随方向
// pDir：  0:双向跟随，<0负向跟随， >0正向跟随
MTN_API Int16  __stdcall NMC_MtGearGetDir(HAND axisHandle,Int16 *pDir);

// 设置Gear主轴参数
// axisHandle：从轴跟随轴号
// masterNo：  主轴序列号（0~N）
// masterType：  主轴类型  1:AXIS规划值  2：AXIS反馈值 3：编码器值,4:混合位置
MTN_API Int16  __stdcall NMC_MtGearSetMaster(HAND axisHandle,Int16 masterNo,Int16 masterType);

// 获取Gear主轴参数
// pMasterNo：  主轴序列号（0~N）
// pMasterType：  主轴类型
MTN_API Int16  __stdcall NMC_MtGearGetMaster(HAND axisHandle,Int16 *pMasterNo,Int16 *pMasterType);

// 设置Gear跟随倍率
// axisHandle：从轴跟随轴号
// masterEven： 传动比系数，主轴位移
// slaveEven：  传动比系数，从轴位移
// masterSlope：主轴离合区位移,必须大于0，同时不能等于1
MTN_API Int16  __stdcall NMC_MtGearSetRatio(HAND axisHandle,Int32 masterEven,Int32 slaveEven,Int32 masterSlope);

// 获取Gear跟随倍率
// axisHandle：从轴跟随轴号
// pMasterEven： 传动比系数，主轴位移
// pSlaveEven：  传动比系数，从轴位移
// pMasterSlope：主轴离合区位移,必须大于0，同时不能等于1
MTN_API Int16  __stdcall NMC_MtGearGetRatio(HAND axisHandle,Int32 *pMasterEven,Int32 *pSlaveEven,Int32 *pMasterSlope);

// 启动Gear运动
// syncCount： 不包括axisHandle 的其他同步启动轴数量
// pSyncAxisArray: 其他同步启动轴的序号：0~N    
// 注：同步的轴必须属于同一个控制器
MTN_API Int16  __stdcall NMC_MtGearStartMtn(HAND axisHandle,Int16 syncAxCnts,Int16 *pSyncAxArray);

// 设置Gear主轴参数
// axisHandle：从轴跟随轴号
// masterNo：  主轴序列号（0~N）
// masterType：  主轴类型  1:AXIS规划值  2：AXIS反馈值 3：编码器值,4:混合位置
// mixPrfProp:混合位置跟随下，规划位置的比例
MTN_API Int16  __stdcall OEM_MtGearSetMasterEx(HAND axisHandle,Int16 masterNo,Int16 masterType,double mixPrfProp);

// 缓冲区 设置Gear跟随倍率
MTN_API short  __stdcall NMC_CrdBufGearSetRatio(HAND crdHandle,Int32 segNo,Int16 axIdx,Int32 masterEven,Int32 slaveEven,Int32 masterSlope);

// 缓冲区 设置Gear参数
MTN_API short  __stdcall OEM_CrdBufGearSetPara(HAND crdHandle,Int32 segNo,Int16 axIdx,Int16 mstAx,Int16 mastAxType,Int16 dir,double mixPrfProp,
        Int32 masterEven,Int32 slaveEven,Int32 masterSlope);

// 缓冲区 启动Gear运动
// axMask:启动轴掩码
// flag:保留
MTN_API short  __stdcall NMC_CrdBufGearStart(HAND crdHandle,Int32 segNo,Int32 axMask,Int32 flag);

//------------------------------------------------------------------------------------------------------------
//
//        12.电子凸轮
//
//------------------------------------------------------------------------------------------------------------

// 单轴FOLLOW运动参数结构
typedef struct TFollowPara
{
    double smoothDec;        // 停止减速度
    double abruptDec;        // 急停减速度，暂时保留
    double reserved1[2];    // 保留
    Int32 reserved2[4];      // 保留
    
    #ifdef MTN_ST_INIT_EN
    TFollowPara(){
     smoothDec = 0.5;
     abruptDec = 1000;
     reserved1[0] = reserved1[1] = 0;
     reserved2[0] = reserved2[1] = reserved2[2] = reserved2[3] = 0;
    }
    #endif
}TFollowPara;
// 设置PT运动的相关参数 
// pPara：参数,参考结构定义
MTN_API Int16 __stdcall NMC_MtFollowSetPara( HAND axisHandle, TFollowPara *pPara );
MTN_API Int16 __stdcall NMC_MtFollowGetPara( HAND axisHandle, TFollowPara *pPara );


// 设置FOLLOW跟随方向
// dir：  0:双向跟随，<0负向跟随， >0正向跟随
MTN_API Int16  __stdcall NMC_MtFollowSetDir(HAND axisHandle,Int16 dir);

// 获取FOLLOW跟随方向
// pDir：  0:双向跟随，<0负向跟随， >0正向跟随
MTN_API Int16  __stdcall NMC_MtFollowGetDir(HAND axisHandle,Int16 *pDir);

// FOLLOW跟随的主轴类型
#define PROFILE_FOLLOW_MASTER_NONE           (0)    // 0:无效
#define PROFILE_FOLLOW_MASTER_AXIS_PRF     (1)    // 1:AXIS规划值
#define PROFILE_FOLLOW_MASTER_AXIS_ENC     (2)    // 2：AXIS反馈值
#define PROFILE_FOLLOW_MASTER_ENC          (3)    // 3：编码器值

// 设置FOLLOW主轴参数
// axisHandle：从轴跟随轴号
// masterNo：  主轴序列号（0~N）
// masterType：  主轴类型  见上面宏定义
MTN_API Int16  __stdcall NMC_MtFollowSetMaster(HAND axisHandle,Int16 masterNo,Int16 masterType);

// 获取FOLLOW主轴参数
// axisHandle：从轴跟随轴号
// pMasterNo：  主轴序列号（0~N）
// pMasterType：  主轴类型  见上面宏定义
MTN_API Int16  __stdcall NMC_MtFollowGetMaster(HAND axisHandle,Int16 *pMasterNo,Int16 *pMasterType);

// 设置FOLLOW的循环执行次数
// loopCnt：循环
MTN_API Int16  __stdcall NMC_MtFollowSetLoopCount(HAND axisHandle,Int32 loopCnt);

// 获取FOLLOW的循环执行次数
// pLoopCnt：循环
MTN_API Int16  __stdcall NMC_MtFollowGetLoopCount(HAND axisHandle,Int32 *pLoopCnt);

// FOLLOW跟随事件
#define PROFILE_FOLLOW_EVENT_START        (1)    // 立即启动
#define PROFILE_FOLLOW_EVENT_PASS         (2)    // 主轴穿越设定位置以后启动跟随

// 设置FOLLOW的的启动事件
// eventType：1 表示调用启动指令以后    立即启动，2表示    主轴穿越设定位置以后启动跟随
// masterDir:穿越启动时，主轴的运动方向，1 主轴正向运动，-1 主轴负向运动
// pos:穿越位置
MTN_API Int16  __stdcall NMC_MtFollowSetEvent(HAND axisHandle,Int16 eventType,Int16 masterDir,Int32 pos);

// 获取FOLLOW的启动事件
// pEvent：1 表示调用启动指令以后立即启动，2表示主轴穿越设定位置以后启动跟随
// pMasterDir:穿越启动时，主轴的运动方向，1 主轴正向运动，-1 主轴负向运动
// pPos:穿越位置
MTN_API Int16  __stdcall NMC_MtFollowGetEvent(HAND axisHandle,Int16 *pEvent,Int16 *pMasterDir,Int32 *pPos);

// 获取FOLLOW的fifo剩余空间
// pSpace：空间大小
// fifoNo:fifo号，0或1
MTN_API Int16  __stdcall NMC_MtFollowGetSpace(HAND axisHandle,Int16 *pSpace,Int16 fifoNo);

// FOLLOW的段类型
#define PROFILE_FOLLOW_SEGMENT_NORMAL        (0)    // 0普通段
#define PROFILE_FOLLOW_SEGMENT_EVEN          (1)    // 1匀速段
#define PROFILE_FOLLOW_SEGMENT_STOP          (2)    // 2停止段
#define PROFILE_FOLLOW_SEGMENT_CONTINUE      (3)    // 3连续段

// 设置FOLLOW的数据
// masterPos：主轴位移
// slavePos:从轴位移
// type:数据段类型：0普通段，默认；1匀速段；2 减速到 0 段；3保持 FIFO 之间速度连续
// fifoNo:fifo号，0或1
MTN_API Int16  __stdcall NMC_MtFollowPushData(HAND axisHandle,Int32 masterPos,double slavePos,Int16 type,Int16 fifoNo);

// 清除FOLLOW对应fifo号的数据
// fifoNo:fifo号，0或1
MTN_API Int16  __stdcall NMC_MtFollowClear(HAND axisHandle,Int16 fifoNo);

// 启动Follow运动
// syncCount： 不包括axisHandle 的其他同步启动轴数量
// pSyncAxisArray: 其他同步启动轴的序号：0~N    
MTN_API Int16  __stdcall NMC_MtFollowStart(HAND axisHandle,Int16 syncAxCnts,Int16 *pSyncAxArray);

// 切换Follow运动的fifo号
// syncCount： 不包括axisHandle 的其他同步进行fifo切换的轴数量
// pSyncAxisArray: 其他同步进行fifo切换的轴的序号：0~N    
MTN_API Int16  __stdcall NMC_MtFollowSwitch(HAND axisHandle,Int16 syncAxCnts,Int16 *pSyncAxArray);


#ifdef __cplusplus
}
#endif


#endif  // _H_NMC_LIB20_H_
