运动控制卡初学(二)
目录
- 运动控制卡初学(二)
- 一、引言:
- 二、直线插补
- 二、圆弧插补(绝对3点定圆弧插补运动)
- 三、圆弧定位法(圆心定位)
- 四、编写代码如下:
一、引言:
插补(Interpolation),即机床数控系统依照一定方法确定刀具运动轨迹的过程。也可以说,已知曲线上的某些数据,按照某种算法计算已知点之间的中间点的方法,也称为“数据点的密化”;数控装置根据输入的零件程序的信息,将程序段所描述的曲线的起点、终点之间的空间进行数据密化,从而形成要求的轮廓轨迹,这种“数据密化”机能就称为“插补”。
插补(Interpolation)在数控机床中,刀具不能严格地按照要求加工的曲线运动,只能用折线轨迹逼近所要加工的曲线。
运动控制卡涉及到到的插补主要分为两种:直线插补和圆弧插补。
直线插补:为了生成一条直线轨迹的算法。具体信息,可以参考一个B站视频,里面讲解的非常清楚,我自己了解的不是十分的透彻就不瞎说了。
[直线插补算法讲解](https://www.bilibili.com/video/BV1P5411Y7oa/?vd_source=e8855b8e314cdd528d36827fb0e1dd8b)
圆弧插补:为了生成一条带有弧度曲线痕迹的算法。具体信息也请参考如下链接
二、直线插补
这里我们着重讲解下多轴绝对直线插补
第一步:先看官方的例程和手册(模仿写不容易踩坑)
- 先看例程,发现有写好的直线插补。那么我们观察代码的逻辑信息
点击启动后查看代码如下:
private void Button_start_Click(object sender, EventArgs e)
{
if (g_handle == (IntPtr)0)
{
MessageBox.Show("未链接到控制器!", "提示");
}
else
{
int[] axislist = {0,1,2,3};
float[] poslist = { Convert.ToSingle(destpos1.Text), Convert.ToSingle(destpos2.Text), Convert.ToSingle(destpos3.Text), Convert.ToSingle(destpos4.Text)};
float[] midlist = { Convert.ToSingle(midpos1.Text), Convert.ToSingle(midpos2.Text), Convert.ToSingle(midpos3.Text), Convert.ToSingle(midpos4.Text) };
float[] endmove = { 0,0,0,0 }; //相当绝对转换
zmcaux.ZAux_Direct_Base(g_handle, 4, axislist); //选择运动轴列表
//插补运动使用的是主轴参数,及BASE的第一个轴
zmcaux.ZAux_Direct_SetSpeed(g_handle, axislist[0],Convert.ToSingle(textBox_speed.Text));
zmcaux.ZAux_Direct_SetAccel(g_handle, axislist[0], Convert.ToSingle(textBox_acc.Text));
zmcaux.ZAux_Direct_SetDecel(g_handle, axislist[0], Convert.ToSingle(textBox_dec.Text));
if (run_mode == 1) //绝对
{
switch (move_mode)
{
case 1: //XY直线
zmcaux.ZAux_Direct_MoveAbs(g_handle, 2, axislist, poslist);
break;
case 2: //XY圆弧
zmcaux.ZAux_Direct_MoveCirc2Abs(g_handle,2,axislist, midlist[0], midlist[1],poslist[0], poslist[1]);
break;
case 3: //XYZU直线
zmcaux.ZAux_Direct_MoveAbs(g_handle, 4,axislist, poslist);
break;
case 4: //空间圆弧 XYZ空间圆弧插补U螺旋 没有绝对指令,需要用ENDMOVE_BUFF转相对
for (int i = 0; i < 4; i++)
{
zmcaux.ZAux_Direct_GetEndMoveBuffer(g_handle, i, ref endmove[i]); //计算相对位移
poslist[i] = poslist[i] - endmove[i];
midlist[i] = midlist[i] - endmove[i];
}
zmcaux.ZAux_Direct_MSpherical(g_handle, 4,axislist, poslist[0], poslist[1], poslist[2], midlist[0], midlist[1], midlist[2], 0, poslist[3], 0);
break;
default:
break;
}
}
else
{
switch (move_mode)
{
case 1:
zmcaux.ZAux_Direct_Move(g_handle, 2, axislist, poslist);
break;
case 2:
zmcaux.ZAux_Direct_MoveCirc2(g_handle, 2, axislist, midlist[0], midlist[1], poslist[0], poslist[1]);
break;
case 3:
zmcaux.ZAux_Direct_Move(g_handle, 4, axislist, poslist);
break;
case 4:
zmcaux.ZAux_Direct_MSpherical(g_handle, 4, axislist, poslist[0], poslist[1], poslist[2], midlist[0], midlist[1], midlist[2], 0, poslist[3], 0);
break;
default:
break;
}
}
}
}
仅仅看XY直线在绝对运动下的功能函数这段代码的工作如下:
- 存储了目的坐标信息到poslist。设置了base主轴的参数信息(速度,加速度,减速带)
- 调用了 ZAux_Direct_MoveAbs功能函数执行运动。很简单就能实现
那么分析代码,发现如果需要三轴运动,仅仅需要修改:poslist中的目的点个数。ZAux_Direct_Move中的参与运动轴个数即可。
二、圆弧插补(绝对3点定圆弧插补运动)
看例程以后,发现圆弧中间点信息存储在 float[] midlist中,目的点信息仍旧存储在float[] poslist中。代码中调用了
zmcaux.ZAux_Direct_MoveCirc2Abs()功能函数。
该函数在手册里是这么写的
三、圆弧定位法(圆心定位)
四、编写代码如下:
含有以下6个功能函数:
多轴相对直线插补、多轴绝对直线插补
XY圆弧相对插补(圆心定位)、XY圆弧绝对插补(圆心定位)
XY圆弧相对插补(中点定位)、XY圆弧绝对插补(中点定位)
/// <summary>
/// 多轴相对直线插补
/// </summary>
/// <param name="axis"></param>
/// <param name="distance"></param>
/// <param name="vel"></param>
/// <param name="acc"></param>
/// <param name="dec"></param>
/// <returns></returns>
public OperationResult MoveLineRelative(int[] axis, float[] distance, float vel, float acc, float dec)
{
if (axis.Length >= 2 && axis.Length == distance.Length)
{
OperationResult result = new OperationResult();
//判断每个轴是否满足要求
foreach (var item in axis)
{
result = CommonMotionValidate((short)item);
if (!result.IsSuccess) return result;
}
int error = 0;
try
{
//选择 BASE 轴列表
error = zmcaux.ZAux_Direct_Base(Handle, axis.Length, axis);
ErrorHandler("ZAux_Direct_Base", error);
error = zmcaux.ZAux_Direct_SetSpeed(Handle, axis[0], vel);
ErrorHandler("ZAux_Direct_SetSpeed", error);
error = zmcaux.ZAux_Direct_SetAccel(Handle, axis[0], acc);
ErrorHandler("ZAux_Direct_SetAccel", error);
error = zmcaux.ZAux_Direct_SetDecel(Handle, axis[0], dec);
ErrorHandler("ZAux_Direct_SetDecel", error);
error = zmcaux.ZAux_Direct_Move(Handle, axis.Length, axis, distance);
ErrorHandler("ZAux_Direct_Move", error);
return OperationResult.CreateSuccessResult();
}
catch (Exception ex)
{
result.IsSuccess = false;
result.ErrorMsg = ex.Message;
return result;
}
}
return new OperationResult()
{
IsSuccess = false,
ErrorMsg = "传递参数不正确"
};
}
/// <summary>
/// 多轴绝对直线插补
/// </summary>
/// <param name="axis"></param>
/// <param name="distance"></param>
/// <param name="vel"></param>
/// <param name="acc"></param>
/// <param name="dec"></param>
/// <returns></returns>
public OperationResult MoveLineAbs(int[] axis, float[] pos, float vel, float acc, float dec)
{
if (axis.Length >= 2 && axis.Length == pos.Length)
{
OperationResult result = new OperationResult();
//判断每个轴是否满足要求
foreach (var item in axis)
{
result = CommonMotionValidate((short)item);
if (!result.IsSuccess) return result;
}
int error = 0;
try
{
//选择 BASE 轴列表
error = zmcaux.ZAux_Direct_Base(Handle, axis.Length, axis);
ErrorHandler("ZAux_Direct_Base", error);
error = zmcaux.ZAux_Direct_SetSpeed(Handle, axis[0], vel);
ErrorHandler("ZAux_Direct_SetSpeed", error);
error = zmcaux.ZAux_Direct_SetAccel(Handle, axis[0], acc);
ErrorHandler("ZAux_Direct_SetAccel", error);
error = zmcaux.ZAux_Direct_SetDecel(Handle, axis[0], dec);
ErrorHandler("ZAux_Direct_SetDecel", error);
error = zmcaux.ZAux_Direct_MoveAbs(Handle, axis.Length, axis, pos);
ErrorHandler("ZAux_Direct_Move", error);
return OperationResult.CreateSuccessResult();
}
catch (Exception ex)
{
result.IsSuccess = false;
result.ErrorMsg = ex.Message;
return result;
}
}
return new OperationResult()
{
IsSuccess = false,
ErrorMsg = "传递参数不正确"
};
}
/// <summary>
/// XY圆弧相对插补(圆心定位)
/// </summary>
/// <param name="axis"></param>
/// <param name="distance"></param>
/// <param name="circlecenter"></param>
/// <param name="vel"></param>
/// <param name="acc"></param>
/// <param name="dec"></param>
/// <param name="dir"></param>
/// <returns></returns>
public OperationResult MoveCircleRelative(int[] axis, float[] distance, float[] circlecenter, float vel, float acc, float dec,int dir)
{
if (axis.Length == 2 && axis.Length == distance.Length)
{
OperationResult result = new OperationResult();
//判断每个轴是否满足要求
foreach (var item in axis)
{
result = CommonMotionValidate((short)item);
if (!result.IsSuccess) return result;
}
int error = 0;
try
{
//选择 BASE 轴列表
error = zmcaux.ZAux_Direct_Base(Handle, axis.Length, axis);
ErrorHandler("ZAux_Direct_Base", error);
error = zmcaux.ZAux_Direct_SetSpeed(Handle, axis[0], vel);
ErrorHandler("ZAux_Direct_SetSpeed", error);
error = zmcaux.ZAux_Direct_SetAccel(Handle, axis[0], acc);
ErrorHandler("ZAux_Direct_SetAccel", error);
error = zmcaux.ZAux_Direct_SetDecel(Handle, axis[0], dec);
ErrorHandler("ZAux_Direct_SetDecel", error);
error = zmcaux.ZAux_Direct_MoveCirc(Handle, axis.Length, axis, distance[0], distance[1],circlecenter[0],circlecenter[1],dir);
ErrorHandler("ZAux_Direct_MoveCirc", error);
return OperationResult.CreateSuccessResult();
}
catch (Exception ex)
{
result.IsSuccess = false;
result.ErrorMsg = ex.Message;
return result;
}
}
return new OperationResult()
{
IsSuccess = false,
ErrorMsg = "传递参数不正确"
};
}
/// <summary>
/// XY圆弧绝对插补(圆心定位)
/// </summary>
/// <param name="axis"></param>
/// <param name="distance"></param>
/// <param name="circlecenter"></param>
/// <param name="vel"></param>
/// <param name="acc"></param>
/// <param name="dec"></param>
/// <param name="dir"></param>
/// <returns></returns>
public OperationResult MoveCircleAbs(int[] axis, float[] distance, float[] circlecenter, float vel, float acc, float dec, int dir)
{
if (axis.Length == 2 && axis.Length == distance.Length)
{
OperationResult result = new OperationResult();
//判断每个轴是否满足要求
foreach (var item in axis)
{
result = CommonMotionValidate((short)item);
if (!result.IsSuccess) return result;
}
int error = 0;
try
{
//选择 BASE 轴列表
error = zmcaux.ZAux_Direct_Base(Handle, axis.Length, axis);
ErrorHandler("ZAux_Direct_Base", error);
error = zmcaux.ZAux_Direct_SetSpeed(Handle, axis[0], vel);
ErrorHandler("ZAux_Direct_SetSpeed", error);
error = zmcaux.ZAux_Direct_SetAccel(Handle, axis[0], acc);
ErrorHandler("ZAux_Direct_SetAccel", error);
error = zmcaux.ZAux_Direct_SetDecel(Handle, axis[0], dec);
ErrorHandler("ZAux_Direct_SetDecel", error);
error = zmcaux.ZAux_Direct_MoveCircAbs(Handle, axis.Length, axis, distance[0], distance[1], circlecenter[0], circlecenter[1], dir);
ErrorHandler("ZAux_Direct_MoveCircAbs", error);
return OperationResult.CreateSuccessResult();
}
catch (Exception ex)
{
result.IsSuccess = false;
result.ErrorMsg = ex.Message;
return result;
}
}
return new OperationResult()
{
IsSuccess = false,
ErrorMsg = "传递参数不正确"
};
}
/// <summary>
/// XY圆弧相对插补(中点定位)
/// </summary>
/// <param name="axis"></param>
/// <param name="distance"></param>
/// <param name="midpos"></param>
/// <param name="vel"></param>
/// <param name="acc"></param>
/// <param name="dec"></param>
/// <returns></returns>
public OperationResult MoveCircle2Relative(int[] axis, float[] distance, float[] midpos, float vel, float acc, float dec)
{
if (axis.Length == 2 && axis.Length == distance.Length)
{
OperationResult result = new OperationResult();
//判断每个轴是否满足要求
foreach (var item in axis)
{
result = CommonMotionValidate((short)item);
if (!result.IsSuccess) return result;
}
int error = 0;
try
{
//选择 BASE 轴列表
error = zmcaux.ZAux_Direct_Base(Handle, axis.Length, axis);
ErrorHandler("ZAux_Direct_Base", error);
error = zmcaux.ZAux_Direct_SetSpeed(Handle, axis[0], vel);
ErrorHandler("ZAux_Direct_SetSpeed", error);
error = zmcaux.ZAux_Direct_SetAccel(Handle, axis[0], acc);
ErrorHandler("ZAux_Direct_SetAccel", error);
error = zmcaux.ZAux_Direct_SetDecel(Handle, axis[0], dec);
ErrorHandler("ZAux_Direct_SetDecel", error);
error = zmcaux.ZAux_Direct_MoveCirc2(Handle, axis.Length, axis, midpos[0], midpos[1], distance[0], distance[1]);
ErrorHandler("ZAux_Direct_MoveCirc", error);
return OperationResult.CreateSuccessResult();
}
catch (Exception ex)
{
result.IsSuccess = false;
result.ErrorMsg = ex.Message;
return result;
}
}
return new OperationResult()
{
IsSuccess = false,
ErrorMsg = "传递参数不正确"
};
}
/// <summary>
/// XY圆弧绝对插补(中点定位)
/// </summary>
/// <param name="axis"></param>
/// <param name="distance"></param>
/// <param name="midpos"></param>
/// <param name="vel"></param>
/// <param name="acc"></param>
/// <param name="dec"></param>
/// <returns></returns>
public OperationResult MoveCircle2Abs(int[] axis, float[] distance, float[] midpos, float vel, float acc, float dec)
{
if (axis.Length == 2 && axis.Length == distance.Length)
{
OperationResult result = new OperationResult();
//判断每个轴是否满足要求
foreach (var item in axis)
{
result = CommonMotionValidate((short)item);
if (!result.IsSuccess) return result;
}
int error = 0;
try
{
//选择 BASE 轴列表
error = zmcaux.ZAux_Direct_Base(Handle, axis.Length, axis);
ErrorHandler("ZAux_Direct_Base", error);
error = zmcaux.ZAux_Direct_SetSpeed(Handle, axis[0], vel);
ErrorHandler("ZAux_Direct_SetSpeed", error);
error = zmcaux.ZAux_Direct_SetAccel(Handle, axis[0], acc);
ErrorHandler("ZAux_Direct_SetAccel", error);
error = zmcaux.ZAux_Direct_SetDecel(Handle, axis[0], dec);
ErrorHandler("ZAux_Direct_SetDecel", error);
error = zmcaux.ZAux_Direct_MoveCirc2Abs(Handle, axis.Length, axis, midpos[0], midpos[1],distance[0], distance[1] );
ErrorHandler("ZAux_Direct_MoveCirc2Abs", error);
return OperationResult.CreateSuccessResult();
}
catch (Exception ex)
{
result.IsSuccess = false;
result.ErrorMsg = ex.Message;
return result;
}
}
return new OperationResult()
{
IsSuccess = false,
ErrorMsg = "传递参数不正确"
};
}