如果按照图 7-17 (b)所示的速度规划,即在拐角处不减速,则加工精度一定会较低,而且可能在拐弯 时对刀具和零件造成较大冲击。如果按照图 7-17 (c)所示的速度规划,即在拐角处减速为 0,可以最大限度 保证加工精度,但加工速度就会慢下来。如果按照图 7-17(d)所示的速度规划,在拐角处将速度减到一个合 理值,既可以满足加工精度又能提高加工速度,就是一个好的速度规划。 为了实现类似图 7-17 (d)所示的好的速度规划,前瞻预处理模块不仅要知道当前运动的位置参数,还
要提前知道后面若干段运动的位置参数,这就是所谓的前瞻。例如在对图 7-17 (a)中的轨迹做前瞻预处理 时,我们设定控制器预先读取 50 段运动轨迹到缓存区中,则它会自动分析出在第 30 段将会出现拐点,并依据用户设定的拐弯时间计算在拐弯处的终点速度。前瞻预处理模块也会依照用户设定的最大加速度值计 算速度规划,使任何加减速过程都不会超过这个值,防止对机械部分产生破坏性冲击力。 从下图 7-18 可以直观地了解,使用前瞻预处理功能模块来规划速度,在小线段加工过程中的对速度的 显著提升。前瞻预处理流程图如图 7-19 所示

private void motionDO1_Click(object sender, EventArgs e){// TCrdPrm结构体变量,该结构体定义了坐标系GTN.mc.TCrdPrm crdprm;short sRtn = GTN.mc.GTN_GetCrdPrm(1, 1, out crdprm);crdprm.dimension = 2; // 坐标系为二维坐标系crdprm.synVelMax = 800; // 最大合成速度:500pulse/mscrdprm.synAccMax = 8; // 最大加速度:1pulse/ms^2crdprm.evenTime = 50; // 最小匀速时间:50mscrdprm.profile1 = 1; // 规划器1对应到X轴crdprm.profile2 = 2; // 规划器2对应到Y轴crdprm.setOriginFlag = 1; // 需要指定坐标系的原点坐标的规划位置crdprm.originPos1 = 0; // 坐标系的原点坐标的规划位置为(100, 100)crdprm.originPos2 = 0;sRtn = GTN.mc.GTN_SetCrdPrm(1, 1, ref crdprm);Task.Run(LookAheadTest);}private static void LookAheadTest(){short sRtn;int space;GTN.mc.TCrdData[] crdData = new GTN.mc.TCrdData[200]; //前瞻缓冲区int[] posTest = new int[2];// 初始化坐标系1的FIFO0的前瞻模块sRtn = GTN.mc.GTN_InitLookAhead(1, //core1, //crd 0, //fifo5, //T //拐弯时间7, //accMax 200, //nref crdData[0]); // 定义前瞻缓存区内存区//压插补数据:小线段加工posTest[0] = 0;posTest[1] = 0;{sRtn = mc.GTN_LnXY( //向前瞻缓冲区冲写入数据共300段1, //core1, //crd0 + posTest[0], //x0 + posTest[1], //y800, //vel6, //acc0, //velend0); //fifoif (0 != sRtn){do{// 查询运动缓存区空间,直至空间不为0sRtn = GTN.mc.GTN_CrdSpace(1, 1, out space, 0);} while (0 == space);// 重新调用上次失败的插补指令sRtn = GTN.mc.GTN_LnXY(1, 1, 0 + posTest[0], 0 + posTest[1], 800, 6, 0, 0);}posTest[0] = 3000000;posTest[1] = 0;sRtn = mc.GTN_LnXY( //向前瞻缓冲区冲写入数据第2段1, //core1, //crd0 + posTest[0], //x0 + posTest[1], //y800, //vel6, //acc0, //velend0); //fifoif (0 != sRtn){do{// 查询运动缓存区空间,直至空间不为0sRtn = GTN.mc.GTN_CrdSpace(1, 1, out space, 0);} while (0 == space);// 重新调用上次失败的插补指令sRtn = GTN.mc.GTN_LnXY(1, 1, 0 + posTest[0], 0 + posTest[1], 800, 6, 0, 0);}posTest[0] = 3000000;posTest[1] = 3000000;sRtn = mc.GTN_LnXY( //向前瞻缓冲区冲写入数据第3段1, //core1, //crd0 + posTest[0], //x0 + posTest[1], //y800, //vel6, //acc0, //velend0); //fifoif (0 != sRtn){do{// 查询运动缓存区空间,直至空间不为0sRtn = GTN.mc.GTN_CrdSpace(1, 1, out space, 0);} while (0 == space);// 重新调用上次失败的插补指令sRtn = GTN.mc.GTN_LnXY(1, 1, 0 + posTest[0], 0 + posTest[1], 800, 6, 0, 0);}posTest[0] = 0;posTest[1] = 3000000;sRtn = mc.GTN_LnXY( //向前瞻缓冲区冲写入数据第4段1, //core1, //crd0 + posTest[0], //x0 + posTest[1], //y800, //vel6, //acc0, //velend0); //fifoif (0 != sRtn){do{// 查询运动缓存区空间,直至空间不为0sRtn = GTN.mc.GTN_CrdSpace(1, 1, out space, 0);} while (0 == space);// 重新调用上次失败的插补指令sRtn = GTN.mc.GTN_LnXY(1, 1, 0 + posTest[0], 0 + posTest[1], 800, 6, 0, 0);}posTest[0] = 0;posTest[1] = 0;sRtn = mc.GTN_LnXY( //向前瞻缓冲区冲写入数据第5段1, //core1, //crd0 + posTest[0], //x0 + posTest[1], //y600, //vel5, //acc0, //velend0); //fifoif (0 != sRtn){do{// 查询运动缓存区空间,直至空间不为0sRtn = GTN.mc.GTN_CrdSpace(1, 1, out space, 0);} while (0 == space);// 重新调用上次失败的插补指令sRtn = GTN.mc.GTN_LnXY(1, 1, 0 + posTest[0], 0 + posTest[1], 800, 6, 0, 0);}}// 将前瞻缓存区中的数据压入控制器IntPtr crdDataNULL = new IntPtr();sRtn = GTN.mc.GTN_CrdData(1, 1, crdDataNULL, 0);// 启动运动sRtn = GTN.mc.GTN_CrdStart(1, 1, 0); //mask bit0 对应坐标系 1,bit1 对应坐标系 2,0:不启动该坐标系,1:启动该坐标系。}
拐弯时间(T):
GTN_InitLookAhead 指令的第三个参数,单位:ms。T 的经验范围是:1ms~10ms, T 越大,计算出来的终点速度越大,但却降低了加工精度;反之,提高了加工的精度,但计算出 的终点速度偏低。因此要合理选择 T 值。
最大加速度(accMax):
GTN_InitLookAhead 指令的第四个参数,单位:pulse/ms2。系统能承受的 最大加速度,根据不同的机械系统和电机驱动器取值不同。
前瞻缓存区(pLookAheadBuf):
前瞻缓存区是用户在应用程序中自己定义的,用于存放描述运动轨 迹的数组。用户应根据自己的需要以及计算机的条件定义合适的缓存区大小,并且要在 GTN_InitLookAhead 指令的第五个参数中说明数组的大小
运动缓存区:插补缓存区是运动控制器内部专门用于插补运动的缓存区资源,大小 4096 段,每
一段可以放一条指令。 当前瞻缓存区的段数不为 0 时,用户调用缓存区指令传递的插补数据先进入前瞻缓存区,当前瞻 缓存区放满之后,如果再有新的数据传入,最先进入前瞻缓存区的数据,则会进入插补缓存区。 如果用户所有的插补数据已经输入完毕,前瞻缓存区中还有数据没有进入插补缓存区,这时,需 要调用 GTN_CrdData(1, NULL, 0),运动控制器会将前瞻缓存区的数据依次传递给插补缓存区, 直到前瞻缓存区被清空为止。 在数据量比较大的时候,用户需要配合 GTN_CrdSpace 指令查询插补缓存区的剩余空间,在有空 间的时候再调用缓存区指令传递数据,如果插补缓存区已满,调用缓存区指令将会返回错误,说 明该段插补数据没有输入成功,需要再次输入该段插补数据。