
package com.example;

import static com.example.mtnlib.nmc_lib20.*;
import static com.example.mtnlib.nmc_lib20_ext.*;
import static com.example.mtnlib.nmc_lib20_oem.*;
import static com.example.mtnlib.nmc_lib20_err.*;
import com.example.mtnlib.nmc_lib20_com.*;
import com.sun.jna.ptr.*;


public class Main {
    // 错误处理工具类
    private static class ErrorHandler {
        /**
         * 检查返回值并处理错误
         * @param rtn 函数返回值
         * @throws RuntimeException 如果返回值不是0(成功)
         */
        public static void checkError(short rtn) {
            if (rtn != 0) {
                throw new RuntimeException(String.format("操作失败，错误代码: %d", rtn));
            }
        }
    }

    public static void main(String[] args) {
        System.out.println("单轴状态查询测试开始...");

        try {
            // 使用设备0和轴0
            short devNum = 0;
            short axisNum = 0;
            
            //打开控制器
            PHAND pDevHandle = new PHAND();
            short rtn = NMC_DevOpen(devNum, pDevHandle);
            ErrorHandler.checkError(rtn);
            System.out.println("打开设备 - 成功");
            
            //打开轴,并获得轴句柄
            HAND devHandle = pDevHandle.getHandle();
            PHAND pAxisHandle = new PHAND();
            rtn = NMC_MtOpen(devHandle, axisNum, pAxisHandle);
            ErrorHandler.checkError(rtn);
            System.out.println("打开轴 - 成功");
            
            HAND axisHandle = pAxisHandle.getHandle();

            // 伺服使能
            rtn = NMC_MtSetSvOn(axisHandle);
            ErrorHandler.checkError(rtn);
            System.out.println("伺服使能 - 成功");

            // 轴的状态
            ShortByReference axisSts = new ShortByReference();
            // 电机的理论值位置
            NativeLongByReference axisPos = new NativeLongByReference(); 
            // 电机的实际位置
            NativeLongByReference encPos = new NativeLongByReference();
            // 轴的规划速度
            DoubleByReference axisVel = new DoubleByReference();

            // 状态查询循环
            System.out.println("\n开始状态查询循环(按Ctrl+C退出)...");
            while (true) {

                rtn = NMC_MtGetSts(axisHandle, axisSts);     //读取单轴的状态标志
                ErrorHandler.checkError(rtn);

                //包括是否正在运动、是否限位触发报警,是否限位等，请参考头文件对应位定义
                if ((axisSts.getValue() & BIT_AXIS_BUSY) != 0) {}        // 轴正在运动
                if ((axisSts.getValue() & BIT_AXIS_ALM) != 0) {}         // 伺服报警触发
                if ((axisSts.getValue() & BIT_AXIS_LMTP) != 0) {}        // 正向限位触发


                // 解析状态位
                boolean isRunning = (axisSts.getValue() & BIT_AXIS_BUSY) != 0;
                boolean isArrived = (axisSts.getValue() & BIT_AXIS_POSREC) != 0;
                boolean isError = (axisSts.getValue() & BIT_AXIS_MVERR) != 0;
                boolean isAxisOn = (axisSts.getValue() & BIT_AXIS_SVON) != 0;
                boolean isAlarm = (axisSts.getValue() & BIT_AXIS_ALM) != 0;
                boolean isPosLimit = (axisSts.getValue() & BIT_AXIS_LMTP) != 0;
                boolean isNegLimit = (axisSts.getValue() & BIT_AXIS_LMTN) != 0;
                boolean isPosSoftLimit = (axisSts.getValue() & BIT_AXIS_SOFTPOSLMT) != 0;
                boolean isNegSoftLimit = (axisSts.getValue() & BIT_AXIS_SOFTNEGLMT) != 0;

                // 读取电机当前的理论位置
                rtn = NMC_MtGetAxisPos(axisHandle, axisPos);     
                ErrorHandler.checkError(rtn);

                // 读取电机当前的实际位置
                rtn = NMC_MtGetEncPos(axisHandle, encPos);
                ErrorHandler.checkError(rtn);
                
                // 读取当前规划的速度
                rtn = NMC_MtGetPrfVel(axisHandle, axisVel);
                ErrorHandler.checkError(rtn);

                // 打印状态信息
                System.out.println("\n===== 轴状态信息 =====");
                System.out.printf("理论位置: %d\n", axisPos.getValue().longValue());
                System.out.printf("实际位置: %d\n", encPos.getValue());
                System.out.printf("规划速度: %.2f\n", axisVel.getValue());
System.out.printf("状态位: %d (0x%04X, 二进制: %s)\n",axisSts.getValue() & 0xFFFF,axisSts.getValue() & 0xFFFF,Integer.toBinaryString(axisSts.getValue() & 0xFFFF));
                System.out.println("  运动状态: " + (isRunning ? "运动中" : "静止"));
                System.out.println("  位置到达: " + (isArrived ? "已到达" : "未到达"));
                System.out.println("  错误状态: " + (isError ? "有错误" : "正常"));
                System.out.println("  使能状态: " + (isAxisOn ? "已使能" : "未使能"));
                System.out.println("  报警状态: " + (isAlarm ? "有报警" : "无报警"));
                System.out.println("  限位状态: " + 
                    (isPosLimit ? "正限位触发" : "") + 
                    (isNegLimit ? "负限位触发" : "") + 
                    (!isPosLimit && !isNegLimit ? "无限位触发" : ""));
                System.out.println("  软限位状态: " + 
                    (isPosSoftLimit ? "正软限位触发" : "") + 
                    (isNegSoftLimit ? "负软限位触发" : "") + 
                    (!isPosSoftLimit && !isNegSoftLimit ? "无软限位触发" : ""));

                // 暂停1秒
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    break;
                }
            }
        } catch (Exception e) {
            System.err.println("测试过程中发生错误: " + e.getMessage());
            e.printStackTrace();
        } finally {
            // 确保资源被释放
            System.out.println("\n释放资源...");
        }
    }
}

