2. 读取机床坐标位置

任务目标

通过 FOCAS 以太网连接 FANUC 数控系统,读取机床当前各轴的坐标、相对坐标和机械坐标,并将结果输出到控制台。

环境与依赖

  • FANUC 数控系统(具备以太网功能,启用 FOCAS 接口)
  • 开发语言:C#(.NET 6/8)或 C(二者选一即可)
  • FOCAS 库:Fwlib32.dll(Windows)或 libfwlib32.so(Linux)
  • 需在项目中引用 FOCAS 官方头文件 fwlib32.h(C)或通过 P/Invoke 调用(C#)

实现原理

FOCAS 提供 cnc_rdposition 函数,一次调用即可同时获取所有轴的坐标、相对坐标、机械坐标及剩余进给量。该函数返回每个轴的位置数据(以脉冲为单位),需结合机床各轴的计数方向(cnc_get_axis 或参数)转换为实际坐标值。本案例直接使用该函数并输出原始脉冲值及转换后的毫米值(假设公制机床,脉冲当量由参数 No.1004 决定,通常为 1μm 或 0.1μm)。

关键完整代码(C# 实现)

using System;
using System.Runtime.InteropServices;

class FocasPositionReader
{
    // FOCUS 数据结构定义
    [StructLayout(LayoutKind.Sequential)]
    struct ODBPOS
    {
        public short dummy;          // 预留
        public short type;           // 坐标类型
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public int[] absolute;       // 坐标(脉冲)
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public int[] machine;        // 机械坐标(脉冲)
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public int[] relative;       // 相对坐标(脉冲)
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public int[] distance;       // 剩余进给量
    }

    // 导入 FOCAS 库函数
    [DllImport("Fwlib32.dll", EntryPoint = "cnc_allclibhndl3")]
    public static extern short cnc_allclibhndl3(string ip, ushort port, int timeout, out ushort handle);

    [DllImport("Fwlib32.dll", EntryPoint = "cnc_rdposition")]
    public static extern short cnc_rdposition(ushort handle, int type, out ODBPOS position);

    [DllImport("Fwlib32.dll", EntryPoint = "cnc_freelibhndl")]
    public static extern short cnc_freelibhndl(ushort handle);

    // 轴名称映射(FANUC 标准:0=X, 1=Y, 2=Z, 3=A, 4=B, 5=C)
    static readonly string[] AxisNames = { "X", "Y", "Z", "A", "B", "C" };

    static void Main(string[] args)
    {
        if (args.Length < 1)
        {
            Console.WriteLine("用法: FocasPositionReader <机床IP地址> [端口=8193]");
            return;
        }

        string ip = args[0];
        ushort port = args.Length > 1 ? ushort.Parse(args[1]) : (ushort)8193;
        ushort handle;

        // 建立连接
        short ret = cnc_allclibhndl3(ip, port, 10, out handle);
        if (ret != 0)
        {
            Console.WriteLine($"连接失败,错误码: {ret}");
            return;
        }

        try
        {
            // 读取所有轴位置(type=1 表示读所有轴)
            ODBPOS pos;
            ret = cnc_rdposition(handle, 1, out pos);
            if (ret != 0)
            {
                Console.WriteLine($"读取位置失败,错误码: {ret}");
                return;
            }

            // 输出表头
            Console.WriteLine("轴\t坐标(脉冲)\t相对坐标(脉冲)\t机械坐标(脉冲)");

            // 遍历前6个轴(实际轴数可通过 cnc_rdaxisname 获取,此处简化)
            for (int i = 0; i < 6; i++)
            {
                // 判断该轴是否存在(机械坐标不为0或坐标不为0通常表示已配置)
                if (pos.machine[i] == 0 && pos.absolute[i] == 0 && pos.relative[i] == 0)
                    continue;

                Console.WriteLine($"{AxisNames[i]}\t{pos.absolute[i]}\t\t{pos.relative[i]}\t\t{pos.machine[i]}");
            }
        }
        finally
        {
            cnc_freelibhndl(handle);
        }
    }
}

编译与运行

  1. 将上述代码保存为 PositionReader.cs。
  2. 将 Fwlib32.dll 放置于程序输出目录(或系统 PATH)。
  3. 编译:csc PositionReader.cs(.NET Framework)或 dotnet build(.NET 6+)。
  4. 运行:PositionReader.exe 192.168.1.50(替换为实际机床 IP)。

验证方法

  • 连接成功:程序无报错,输出表头及至少一个轴的坐标数据。
  • 数据正确性:手动操作机床移动 X 轴 10mm(假设脉冲当量 1μm),再次运行程序,X 轴坐标脉冲值应变化约 10000。
  • 坐标类型区分:在机床面板上切换相对坐标清零,程序输出的相对坐标脉冲值应归零,而坐标和机械坐标不变。

常见问题

  • 错误码 -17:IP 地址无法访问,检查网络及机床端 FOCAS 服务是否启用。
  • 错误码 -8:连接超时,确认端口号(默认 8193)及机床防火墙设置。
  • 输出全为 0:可能轴未配置或处于未回零状态,机械坐标在未回零前可能显示 0。