OOP · 架构设计

TwinCAT 3 OOP 轴控:INTERFACE · 继承 · 工厂模式分层架构工程实践

OOP INTERFACE FB_AxisBase 工厂模式 2025-10-22 · 尚工

一、为什么要用 OOP 封装轴控

传统做法:每个轴复制一套 MC_MoveAbsolute / MC_Home 代码,修改一处需改多处,新增轴型(步进/伺服)需大改逻辑。OOP 封装后:新增轴只需继承基类、重写差异部分,主程序调用统一接口,完全解耦。

这套架构已在多个半导体设备项目中验证,可管理 16 轴以上的复杂运控系统。

二、I_Axis 通用接口定义

INTERFACE I_Axis
    // 使能/复位
    METHOD Enable  : BOOL
    METHOD Reset   : BOOL
    // 回零
    METHOD Home    : BOOL
    // 运动命令
    METHOD MoveAbs : BOOL
        VAR_INPUT fPos : LREAL; fVel : LREAL; END_VAR
    METHOD MoveRel : BOOL
        VAR_INPUT fDist : LREAL; fVel : LREAL; END_VAR
    METHOD Jog     : BOOL
        VAR_INPUT bFwd : BOOL; bBwd : BOOL; END_VAR
    METHOD Stop    : BOOL
    // 状态属性(只读)
    PROPERTY IsReady   : BOOL GET
    PROPERTY IsMoving  : BOOL GET
    PROPERTY ActPos    : LREAL GET
    PROPERTY HasError  : BOOL GET
    PROPERTY ErrorID   : UDINT GET

三、FB_AxisBase 基类实现(核心)

FUNCTION_BLOCK FB_AxisBase IMPLEMENTS I_Axis
VAR
    _axis      : AXIS_REF;
    _fbPower   : MC_Power;
    _fbHome    : MC_Home;
    _fbMoveAbs : MC_MoveAbsolute;
    _fbMoveRel : MC_MoveRelative;
    _fbJog     : MC_Jog;
    _fbStop    : MC_Stop;
    _fbReset   : MC_Reset;
    _eState    : E_AxisState;
END_VAR

// MoveAbs 方法实现
METHOD MoveAbs : BOOL
VAR_INPUT fPos : LREAL; fVel : LREAL; END_VAR
    _fbMoveAbs(
        Axis     := _axis,
        Position := fPos,
        Velocity := fVel,
        Execute  := TRUE
    );
    MoveAbs := _fbMoveAbs.Done;

四、子类扩展——以 FB_GrindingAxis 为例

// 晶圆研磨下压轴:继承基类,扩展压力闭环切换能力
FUNCTION_BLOCK FB_GrindingAxis EXTENDS FB_AxisBase
VAR
    _fbPressureCtrl : FB_PressureLoop;
    _bPressureMode  : BOOL;
END_VAR

// 重写 Stop —— 增加压力控制器关闭逻辑
METHOD Stop : BOOL
    _fbPressureCtrl.Enable := FALSE;  // 先关压力控制
    SUPER^.Stop();                     // 再调用基类停止逻辑
    Stop := TRUE;

五、主程序统一调用(工厂模式)

// 用接口数组管理所有轴,主程序无需关心具体轴型
VAR
    fbLinearAxis   : FB_LinearAxis;
    fbGrindAxis    : FB_GrindingAxis;
    arrAxes        : ARRAY[0..1] OF I_Axis;
END_VAR

arrAxes[0] := fbLinearAxis;
arrAxes[1] := fbGrindAxis;

// 统一回零:无论直线轴还是研磨轴,调用相同接口
FOR i := 0 TO 1 DO
    arrAxes[i].Home();
END_FOR

💡 FB_EXTENDS 继承深度建议不超过 3 层:TwinCAT 3 在深度继承链(4 层以上)中可能出现 SUPER^ 调用栈溢出。复杂场景优先考虑组合(Composition)而非深度继承。

完整 OOP 轴控套件(含 I_Axis / FB_AxisBase / FB_LinearAxis / FB_RotaryAxis)已开源,见 github.com/tc3-engineer