zl程序教程

您现在的位置是:首页 >  后端

当前栏目

【愚公系列】2023年04月 WPF运动控制平台-002.运动控制平台知识点学习

WPF控制知识点平台学习 系列 2023 愚公
2023-06-13 09:18:27 时间

前言

运动控制(Motion Control)通常是指在复杂条件下,将预定的控制方案、规划指令转变成期望的机械运动,实现机械运动精确的位置控制、速度控制、加速度控制、转矩或力的控制。

运动控制主要可分为以下几点:

  • 电动机作为动力源的电气运动控制
  • 气体和流体作为动力源的气液控制
  • 燃料(煤、油等)作为动力源的热机运动控制

电气运动控制是由电机拖动发展而来的,电力拖动或电气传动是以电动机为对象的控制系统的通称。运动控制系统多种多样,但从基本结构上看,一个典型的现代运动控制系统的硬件主要由上位机、运动控制器、功率驱动装置、电动机、执行机构和传感器反馈检测装置等部分组成。其中的运动控制器是指以中央逻辑控制单元为核心、以传感器为信号敏感元件、以电机或动力装置和执行单元为控制对象的一种控制装置。

这里运动控制器就是控制电动机的运行方式的专用控制器:比如电动机在由行程开关控制交流接触器而实现电动机拖动物体向上运行达到指定位置后又向下运行,或者用时间继电器控制电动机正反转或转一会停一会再转一会再停。运动控制在机器人和数控机床的领域内的应用要比在专用机器中的应用更复杂,因为后者运动形式更简单,通常被称为通用运动控制(GMC)。

一、知识点学习

1.MCT2008软件配置限位生效并导出配置文件

在运动控制器管理软件 Motion Controller Toolkit 2008(以下简称 MCT2008) 中包括一个系统配置的组件,用户可以利用该组件来对运动控制器进行配置,配置完成之后,生成相应的配置文件*.cfg,用户在编程时,调用相关的指令,将配置信息传递给运动控制器,即可完成整个运动控制器的配置工作。用户也可以利用相关的指令完成运动控制器的配置。

总之,以固高卡为例子,先使用它自带的软件,完成控制器的配置,生成配置文件,用户可以调用 GT_LoadConfig()指令将配置文件里的配置信息下载到运动控制器中。然后调用它提供的库函数,进行编程。

2.轴卡的初始化功能实现

1、打开控制器

/// <summary>
/// 打开运动控制器
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Btn_Open_Click(object sender, EventArgs e)
{
    // 调用GT_Open打开运动控制器
    short rtn = GT_Open(0, 1);
    if (rtn == 0) 
    {
        flag = true;
        MessageBox.Show("打开成功");
    }
    else 
    {
        MessageBox.Show("打开失败");
    }
}

2、重置控制器【把控制所有设置还原到出厂】

/// <summary>
/// 重置控制器
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Btn_Reset_Click(object sender, EventArgs e)
{
    if (!flag) 
    {
        MessageBox.Show("必须控制器打开后操作");
        return;
    }

    short rtn = GT_Reset();
    if (rtn == 0) 
    {
        MessageBox.Show("复位控制器成功");
    }
    else
    {
        MessageBox.Show("复位控制器失败");
    }
}

3、重新加载轴配置文件

/// <summary>
/// 重新加载配置
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Btn_Load_Click(object sender, EventArgs e)
{
    if (!flag)
    {
        MessageBox.Show("必须控制器打开后操作");
        return;
    }

    short rtn = GT_LoadConfig("GTS800-Motion.cfg");
    if (rtn == 0)
    {
        MessageBox.Show("加载配置成功");
    }
    else
    {
        MessageBox.Show("加载配置失败");
    }
}

4、清除状态信息【限位,伺服报警】

/// <summary>
/// 清除轴卡状态
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Btn_Clr_Click(object sender, EventArgs e)
{
    if (!flag)
    {
        MessageBox.Show("必须控制器打开后操作");
        return;
    }

    short rtn = GT_ClrSts(1, 1);
    if (rtn == 0)
    {
        MessageBox.Show("清除轴卡状态成功");
    }
    else
    {
        MessageBox.Show("清除轴卡状态失败");
    }
}

5、关闭控制器

/// <summary>
/// 关闭控制器
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Btn_Close_Click(object sender, EventArgs e)
{
    if (!flag)
    {
        MessageBox.Show("必须控制器打开后操作");
        return;
    }

    short rtn = GT_Close();
    if (rtn == 0)
    {
        flag = false;
        MessageBox.Show("关闭控制器成功");
    }
    else
    {
        MessageBox.Show("关闭控制器失败");
    }
}

3.轴卡的点位运动功能实现

1、点位运动功能需要指令列表及对参数说明

2、点位运动界面设计

  • 轴卡初始化(打开,重置,加载,清除)
/// <summary>
/// 初始化运动控制器轴卡
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Btn_InitCard_Click(object sender, EventArgs e)
{
    // 1. 打开轴卡
    CheckStatus(GT_Open(0, 1));
    // 2. 复位轴卡
    CheckStatus(GT_Reset());
    // 3. 重新加载配置
    CheckStatus(GT_LoadConfig("GTS800-Motion.cfg"));
    // 4. 清除限位及报警状态
    CheckStatus(GT_ClrSts(1,1));
}

private void CheckStatus(short rtn)
{
    if (rtn != 0) 
    {
        throw new Exception($"调用过程中遇到错误,错误码为:{rtn}");
    }

}
  • 点位运动
/// <summary>
/// 启动点位运动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Btn_TrapMotion_Click(object sender, EventArgs e)
{
    // 1. 设置当前规划轴为点位运动模式
    CheckStatus(GT_PrfTrap(1));
    // 2. 设置点位运动参数
    var trapPrm = new TTrapPrm();
    // 设置点位参数对象的属性值
    // 设置加速度
    trapPrm.acc = Convert.ToDouble(Txt_AccVel.Text);
    // 设置减速度
    trapPrm.dec= Convert.ToDouble(Txt_DecVel.Text);
    // 设置启动速度
    trapPrm.velStart = Convert.ToDouble(Txt_StartVel.Text);
    // 设置平滑时间
    trapPrm.smoothTime = Convert.ToInt16(Txt_Smoothtime.Text);
    CheckStatus(GT_SetTrapPrm(1, ref trapPrm));
    // 3. 设置点位运动目标位置
    var pos = Convert.ToInt32(Txt_Pos.Text);
    CheckStatus(GT_SetPos(1, pos));
    // 4. 设置点位运动的目标速度
    var vel = Convert.ToDouble(Txt_Vel.Text);
    CheckStatus(GT_SetVel(1, vel));
    // 5. 启动点位运动
    // 0000 0001
    CheckStatus(GT_Update(1));
}

/// <summary>
/// 改变位置与速度
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Btn_ChangeVelAndPos_Click(object sender, EventArgs e)
{
    // 3. 设置点位运动目标位置
    var pos = Convert.ToInt32(Txt_Pos.Text);
    CheckStatus(GT_SetPos(1, pos));
    // 4. 设置点位运动的目标速度
    var vel = Convert.ToDouble(Txt_Vel.Text);
    CheckStatus(GT_SetVel(1, vel));
    // 5. 启动点位运动
    // 0000 0001
    CheckStatus(GT_Update(1));
}

/// <summary>
/// 指定轴的运动停止
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Btn_Stop_Click(object sender, EventArgs e)
{
    CheckStatus(GT_Stop(1, 0));
}

4.轴卡的限位+Home回原功能实现

/// <summary>
/// 启动回原功能实现
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Btn_Home_Click(object sender, EventArgs e)
{
    int direction; // 1 代表正方向  -1 带负方向
    int offset = 3000;
    /*
        电机从所在位置以较高的速度往限位方向运动,如果
        碰到限位,则反方向运动并启动高速硬件捕获,在设定的搜索范围内搜索 Home
        当触发 Home开关后,电机会以较低的速度运动到捕获的位置处
     */
    // 获取输入搜索距离
    int searchDis = Convert.ToInt32(Txt_SearchDistance.Text);
    // 设置当前运行的方向
    direction = searchDis > 0 ? 1 : -1;
    // 创建一个点位运动参数对象
    TTrapPrm trapPrm;
    trapPrm.acc = 0.2;
    trapPrm.dec = 0.2;
    trapPrm.velStart = 0;
    trapPrm.smoothTime = 30;
    // 执行点位运动
    TrapMove(1, trapPrm, searchDis, 8, "运动到限位处");
    // 等待轴碰到限位开关【轴停止代表碰到限位】
    int axisStatus;
    do
    {
        // 获取轴1的状态值
        Check(GT_GetSts(1, out axisStatus, 1, out uint clk), "GT_GetSts");
    } while ((axisStatus & 0x400) != 0);
    // 轴停止之后就执行反向查找Home的逻辑
    // 设置运行方向
    direction = -direction;
    // 清除限位状态
    Check(GT_ClrSts(1, 1), "GT_ClrSts");
    // 启动高速硬件捕获
    Check(GT_SetCaptureMode(1, CAPTURE_HOME), "GT_SetCaptureMode");
    // 执行反向查找点位运动
    TrapMove(1, trapPrm, direction * 99999999, 8, "反向查找Home位置");
    // 等待捕获到Home信号
    short capture;
    int orginPos;
    do
    {
        // 如果capture=1代表捕获到了原点信号
        Check(GT_GetCaptureStatus(1, out capture, out orginPos, 1, out uint clk), "GT_GetCaptureStatus");
    } while (capture != 1);
    // 捕获到原点后继续运行offset距离,在低速回到原点位置
    TrapMove(1, trapPrm, orginPos + direction * offset, 8, "捕获后往前运动一段距离");
    Debug.WriteLine($"捕获到原点位置:{orginPos},运行距离为:{orginPos + direction * offset}");
    // 必须运动到偏移量位置,停止之后在低速回到原点位置
    do
    {
        // 获取轴1的状态值
        Check(GT_GetSts(1, out axisStatus, 1, out uint clk), "偏移==>GT_GetSts");
    } while ((axisStatus & 0x400) != 0);

    // 清除限位状态
    Check(GT_ClrSts(1, 1), "GT_ClrSts");
    // 低速回到原点位置
    TrapMove(1, trapPrm, orginPos, 3, "低速回原");
    // 等待回原完成后判断编码器位置是否与捕获原点位置相同
    double encPos;
    do
    {
        // 获取轴1的状态值
        Check(GT_GetSts(1, out axisStatus, 1, out uint clk), "GT_GetSts");
        // 获取编码器位置
        Check(GT_GetEncPos(1, out encPos, 1, out clk), "GT_GetEncPos");
    } while ((axisStatus & 0x400) != 0);

    if (encPos == orginPos)
    {
        GT_ClrSts(1, 1);
        // 把当前位置设置为物理原点
        Check(GT_ZeroPos(1, 1), "GT_ZeroPos");
        MessageBox.Show("回原完成");
    }
}

/// <summary>
/// 封装回原操作的点位运动方法
/// </summary>
/// <param name="axis">点位运动轴号</param>
/// <param name="trapPrm">点位运动参数</param>
/// <param name="pos">目标位置</param>
/// <param name="vel">点位运动的速度</param>
private void TrapMove(short axis, TTrapPrm trapPrm, int pos, double vel, string chapter)
{
    Debug.WriteLine($"执行到{chapter}阶段 开始");
    Check(GT_PrfTrap(axis), "TrapMove=>GT_PrfTrap");
    GT_SetTrapPrm(axis, ref trapPrm);
    // 包一层就报错
    //Check(GT_SetTrapPrm(axis, ref trapPrm), "GT_SetTrapPrm");
    Check(GT_SetPos(axis, pos), "TrapMove=>GT_SetPos");
    Check(GT_SetVel(axis, vel), "TrapMove=>GT_SetVel");
    // 启动点位运动
    // 0000 0010
    Check(GT_Update(1 << (axis - 1)), "TrapMove=>GT_Update");
    Debug.WriteLine($"执行到{chapter}阶段 结束");
}