import static lib.mtn_lib20.*;
import static lib.mtn_lib20_com.*;
import static lib.mtn_lib20_ext.*;
import static lib.mtn_lib20_oem.*;
import static lib.mtn_lib20_err.*;
import com.sun.jna.*;
import com.sun.jna.ptr.*;

public class Main {
    static {
        String libPath = System.getProperty("user.dir") + "\\lib";
        System.setProperty("java.library.path", libPath);
        System.load(libPath + "\\msvcr100.dll");
        System.load(libPath + "\\msvcp100.dll");
        System.load(libPath + "\\nmc_lib20.dll");
    }
    private static void checkError(short rtn, String operation) {
        if (rtn != 0) {
            System.err.printf("错误: %s (代码: %d)\n", operation, rtn);
//            System.exit(1);
        }
    }
    public static void main(String[] args) {

        short rtn;// 指令返回值
        short axisNum = 0;// 轴号，从0开始
        HAND devHandle = new HAND();// 设备句柄
        PHAND pDevHandle = new PHAND();
        HAND axisHandle = new HAND();// 轴句柄
        PHAND pAxisHandle = new PHAND();
        HAND crdHandle = new HAND();// 坐标系句柄
        PHAND pcrdHandle = new PHAND();

        short[] devCount = new short[1];
        TDevInfo[] devInfoList = new TDevInfo[10];
        rtn = NMC_DevSearch(TSearchMode.Ethernet, devCount, devInfoList);
        checkError(rtn,"搜索设备出错");
        rtn = NMC_DevOpen(devInfoList[0].address, pDevHandle);				//打开控制器
        checkError(rtn,"打开控制器出错");
        devHandle = pDevHandle.getHandle();
        rtn = NMC_MtOpen(devHandle, axisNum, pAxisHandle); // 打开轴
        checkError(rtn,"打开轴出错");
        axisHandle = pAxisHandle.getHandle();
        rtn = NMC_MtSetSvOn(axisHandle);//打开轴使能(根据实际情况使用)
        checkError(rtn,"轴使能出错");
        rtn = NMC_CrdOpen(devHandle, pcrdHandle);			//打开坐标系
        checkError(rtn,"打开坐标系出错");
        crdHandle = pcrdHandle.getHandle();

        TCrdConfig crdCfg = new TCrdConfig();
        crdCfg.axCnts = 3;			// 配置三个轴
        crdCfg.pAxArray[0] = 0;		// 坐标系运动X轴为第一轴
        crdCfg.pAxArray[1] = 1;		// 坐标系运动Y轴为第二轴
        crdCfg.pAxArray[2] = 2;		// 坐标系运动Z轴为第三轴
        crdCfg.pAxArray[3] = -1;	// 坐标系运动A轴为第四轴,-1为不使用
        crdCfg.port[0] = 0;			// 端口为0
        crdCfg.port[1] = 0;			// 端口为0
        crdCfg.port[2] = 0;			// 端口为0
        crdCfg.port[3] = 0;			// 端口为0
        rtn = NMC_CrdConfig(crdHandle, crdCfg);	// Crd系统配置
        checkError(rtn,"Crd系统配置出错");

        TCrdPara crdPrm = new TCrdPara();
        crdPrm.orgFlag = 1;			// 设置坐标系原点为机械原点(0,0,0)
        crdPrm.synAccMax = 10;		// 最大合成加速度p/m^2
        crdPrm.synVelMax = 50;		// 最大合成速度,在轴允许的范围内，尽可能的大一些
        crdPrm.offset[0] = 0;		// 第一轴原点为0
        crdPrm.offset[1] = 0;		// 第二轴原点为0
        crdPrm.offset[2] = 0;		// 第三轴原点为0
        crdPrm.offset[3] = 0;		// 第四轴原点为0
        rtn = NMC_CrdSetPara(crdHandle, crdPrm);	// Crd系统参数配置
        checkError(rtn,"Crd系统参数配置出错");
        rtn = NMC_CrdBufClr(crdHandle);				// 清空缓冲区数据
        checkError(rtn,"清空缓冲区数据出错");

        double mmToPluse = 1000;
        double endVel, vel, acc, rotVel;
        endVel = 0;
        vel = 10;
        acc = 1;
        rotVel = 3;
        double m_l = 100;									//圆角矩形的长为mm
        double m_w = 60;									//圆角矩形的宽为mm
        double m_r = 5;										//圆角矩形的倒角半径为mm
        //旋转轴为轴,旋转一圈脉冲数为，旋转中心为(,15000)
        rtn = NMC_CrdSetTransRotate(crdHandle, (short) 3, (2 * 3.1415926) / 10000, new NativeLong(0), new NativeLong(15000) );
        checkError(rtn,"使能旋转转换处理出错");
        rtn = NMC_CrdBufClr(crdHandle);//指令缓冲区清空
        checkError(rtn,"指令缓冲区清空出错");


        NativeLongByReference rotPos = new NativeLongByReference(new NativeLong(-2500));
//        NativeLong[] rotPos = { new NativeLong(-2500)};
        NativeLong[] posArray = { new NativeLong(0),new NativeLong(0),new NativeLong(0),new NativeLong(0) };
        NativeLong segNo = new NativeLong(0);
        //插补轨迹第一条得指定旋转变换的轴，这条跟随位移是
        rtn = NMC_CrdBufAxMoveRel(crdHandle, segNo, (short) 8, new NativeLongByReference(posArray[0]), (short) 0, (short) 1);
        checkError(rtn,"指定旋转变换的轴出错");
        segNo = new NativeLong(segNo.longValue() + 1);
        rtn = NMC_CrdLineXYZEx(crdHandle, segNo, (short) 15, posArray, endVel, vel, acc, (short) 0);//运动到原点
        checkError(rtn,"运动到原点出错");
        segNo = new NativeLong(segNo.longValue() + 1);
        rtn = NMC_CrdBufSetPtpMovePara(crdHandle, segNo, (short) 3, rotVel, 1.0, (short) 0);//缓冲区单轴移动参数设置
        checkError(rtn,"缓冲区单轴移动参数设置出错");
        segNo = new NativeLong(segNo.longValue() + 1);
        posArray[0] = new NativeLong((long) ((0.5 * m_l - m_r) * mmToPluse));
        rtn = NMC_CrdLineXYZEx(crdHandle, segNo, (short) 3, posArray, endVel, vel, acc, (short) 0);// 直线插补
        checkError(rtn,"直线插补出错");
        segNo = new NativeLong(segNo.longValue() + 1);
        rtn = NMC_CrdBufAxMoveRel(crdHandle, segNo, (short) 8, rotPos, (short) 0, (short) 1);//缓冲区单轴移动(相对位移移动)
        checkError(rtn,"缓冲区单轴移动出错");
        segNo = new NativeLong(segNo.longValue() + 1);
        posArray[0] = new NativeLong((long) ((0.5 * m_l) * mmToPluse));
        posArray[1] = new NativeLong((long) ((m_r)*mmToPluse));
        // XY平面圆弧插补：终点位置、半径、方向
        rtn = NMC_CrdArcRadiusEx(crdHandle, segNo, posArray, (m_r)*mmToPluse, (short) 1, endVel, vel, acc, (short) 0);
        checkError(rtn,"圆弧插补出错");
        segNo = new NativeLong(segNo.longValue() + 1);
        posArray[0] = new NativeLong((long) ((0.5 * m_l) * mmToPluse));
        posArray[1] = new NativeLong((long) ((m_w - m_r) * mmToPluse));
        rtn = NMC_CrdLineXYZEx(crdHandle, segNo, (short) 3, posArray, endVel, vel, acc, (short) 0);// 直线插补
        checkError(rtn,"直线插补出错");
        segNo = new NativeLong(segNo.longValue() + 1);
        rtn = NMC_CrdBufAxMoveRel(crdHandle, segNo, (short) 8, rotPos, (short) 0, (short) 1);//缓冲区单轴移动(相对位移移动)
        checkError(rtn,"缓冲区单轴移动出错");
        segNo = new NativeLong(segNo.longValue() + 1);
        posArray[0] =  new NativeLong((long) ((0.5 * m_l - m_r) * mmToPluse));
        posArray[1] = new NativeLong((long) ((m_w)*mmToPluse));
        // XY平面圆弧插补：终点位置、半径、方向
        rtn = NMC_CrdArcRadiusEx(crdHandle, segNo, posArray, (m_r)*mmToPluse, (short) 1, endVel, vel, acc, (short) 0);
        checkError(rtn,"圆弧插补出错");
        segNo = new NativeLong(segNo.longValue() + 1);
        posArray[0] = new NativeLong((long) ((-0.5 * m_l + m_r) * mmToPluse));
        posArray[1] = new NativeLong((long) ((m_w)*mmToPluse));
        rtn = NMC_CrdLineXYZEx(crdHandle, segNo, (short) 3, posArray, endVel, vel, acc, (short) 0); // 直线插补
        checkError(rtn,"直线插补出错");
        segNo = new NativeLong(segNo.longValue() + 1);
        rtn = NMC_CrdBufAxMoveRel(crdHandle, segNo, (short) 8, rotPos, (short) 0, (short) 1); // 缓冲区单轴移动(相对位移移动)
        checkError(rtn,"缓冲区单轴移动出错");
        segNo = new NativeLong(segNo.longValue() + 1);
        posArray[0] = new NativeLong((long) ((-0.5 * m_l) * mmToPluse));
        posArray[1] = new NativeLong((long) ((m_w - m_r) * mmToPluse));
        //  XY平面圆弧插补：终点位置、半径、方向
        rtn = NMC_CrdArcRadiusEx(crdHandle, segNo, posArray, (m_r)*mmToPluse, (short) 1, endVel, vel, acc, (short) 0);
        checkError(rtn,"圆弧插补出错");
        segNo = new NativeLong(segNo.longValue() + 1);
        posArray[0] = new NativeLong((long) ((-0.5 * m_l) * mmToPluse));
        posArray[1] = new NativeLong((long) ((m_r)*mmToPluse));
        rtn = NMC_CrdLineXYZEx(crdHandle, segNo, (short) 3, posArray, endVel, vel, acc, (short) 0);// 直线插补
        checkError(rtn,"直线插补出错");
        segNo = new NativeLong(segNo.longValue() + 1);
        rtn = NMC_CrdBufAxMoveRel(crdHandle, segNo, (short) 8, rotPos, (short) 0, (short) 1);	//缓冲区单轴移动(相对位移移动)
        checkError(rtn,"缓冲区单轴移动出错");
        segNo = new NativeLong(segNo.longValue() + 1);
        posArray[0] = new NativeLong((long) ((-0.5 * m_l + m_r) * mmToPluse));
        posArray[1] = new NativeLong(0);
        // XY平面圆弧插补：终点位置、半径、方向
        rtn = NMC_CrdArcRadiusEx(crdHandle, segNo, posArray, (m_r)*mmToPluse, (short) 1, endVel, vel, acc, (short) 0);
        checkError(rtn,"圆弧插补出错");
        segNo = new NativeLong(segNo.longValue() + 1);
        posArray[0] = new NativeLong(0);
        posArray[1] = new NativeLong(0);
        rtn = NMC_CrdLineXYZEx(crdHandle, segNo, (short) 3, posArray, endVel, vel, acc, (short) 0);	// 直线插补
        checkError(rtn,"直线插补出错");
        segNo = new NativeLong(segNo.longValue() + 1);
        rtn = NMC_CrdEndMtn(crdHandle);				//结束缓冲区
        checkError(rtn,"结束缓冲区出错");
        rtn = NMC_CrdStartMtn(crdHandle);			//启动缓冲区插补
        checkError(rtn,"启动缓冲区插补出错");
    }
}
