C++源码 运动控制源码 对话式示教编程 编程简单 控制卡 mfc 运动控制参考源码 运动流程可以在线编辑,支持输入输出,回原点,插补运动,等待。 程序编辑区域,可以实现对各个命令的编辑,灵活配置。 支持多轴联动和圆弧插补 跳转等功能 支持各个规格的保存和切换。 支持手动操作。 在线编辑警告语设置。 厂家的信息设置。 管理员密码设置。 这些设置好了后,保存到控制卡里面,就生效了。

在工业自动化领域摸爬滚打多年,发现运动控制系统的开发总绕不开几个硬核需求。最近用MFC撸了个控制卡程序,核心功能是让设备按编辑好的运动流程执行动作。这里分享几个关键实现点,附上部分源码解析。

先看运动指令的基类设计,这是整个系统的骨架:

class MotionCommand {
public:
    virtual void Execute() = 0;
    virtual void Serialize(CArchive& ar) = 0;
    virtual CString GetDisplayText() = 0;
    virtual ~MotionCommand() {}
};

每个具体指令(回原点、插补等)继承这个基类。比如圆弧插补的实现:

class ArcInterpolation : public MotionCommand {
    double centerX_, centerY_, endX_, endY_;
    bool clockwise_;
public:
    void Execute() override {
        // 核心算法:Bresenham圆弧插补
        double radius = sqrt(pow(endX_ - centerX_, 2) + ...);
        // 硬件通信接口调用
        MotorController::GetInstance()->SetArcParams(...);
    }
};

这种设计模式让新增指令类型变得容易,调试时在列表控件里直接显示指令参数:

void CCommandListCtrl::AddCommand(MotionCommand* cmd) {
    int nIndex = InsertItem(GetItemCount(), cmd->GetDisplayText());
    SetItemData(nIndex, (DWORD_PTR)cmd); 
}

在线编辑的难点在于实时校验。当用户修改运动参数时,立即触发校验逻辑:

void CParamEditor::OnEnChangeSpeed() {
    CString str;
    m_editSpeed.GetWindowText(str);
    double speed = _ttof(str);
    if(speed > MAX_DEVICE_SPEED) {
        ShowWarning(_T("速度值超出设备上限!"));  // 调用预设的警告语
        m_btnApply.EnableWindow(FALSE);
    }
}

权限管理采用策略模式,不同操作对应不同验证级别:

class SecurityPolicy {
public:
    virtual bool CheckAccess(int cmdType) = 0;
};

class OperatorPolicy : public SecurityPolicy {
    bool CheckAccess(int cmdType) override {
        return (cmdType != ADMIN_SETTINGS); // 普通操作员不能修改系统设置
    }
};

保存配置到控制卡时采用二进制协议打包:

void SaveToController() {
    CByteArray data;
    CMemFile file;
    CArchive ar(&file, CArchive::store);
    
    ar << APP_VERSION;  // 写入协议版本
    m_commandList.Serialize(ar);  // 序列化所有运动指令
    
    // 计算校验和
    BYTE checksum = CalculateChecksum(file.GetBuffer());
    ar << checksum;

    // 通过USB发送数据包
    ControllerDriver::SendData(file.Detach(), file.GetLength());
}

开发时踩过的坑:圆弧插补的坐标系转换要特别注意控制卡的实际脉冲当量,曾经因为漏算减速比导致机械臂画圆变成椭圆。后来在参数保存时增加了单位自动转换:

// 脉冲量转实际距离
double PulseToMetric(long pulses) {
    return pulses * leadScrewPitch_ / encoderResolution_;
}

这个架构最大的优势是扩展性强,最近客户提出要支持新型Delta机械手,只需继承MotionCommand实现新的运动算法,界面层几乎不用改动。不过实时性要求高的场景还是得用RTX之类的实时扩展库,这是后话了。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐