无文件指令运行
运动队列的创建,运行,暂停,删除等
创建
插入无文件指令前,首先调用函数 NRC_CreateNoFlieRunqueue();创建一个无文件运行队列,创建一个无文件运行队列后,然后调用运动队列插入指令函数后,调用开始运行无文件运行队列函数即可进行一条或多条指令运动队列。
运行
调用函数NRC_StartRunNoFlieRunqueue()
开始运行无文件运行队列,开始运行后,若要添加新的运行指令,请在本次运行结束后重新重新创建一个无文件运行队列,成功调用该函数后,机器人将开始运动,请注意安全。
暂停
通过调用函数NRC_PauseRunNoFlieRunqueue()
暂停运行无文件运行队列,暂停运行无文件运行队列,调用 NRC_StartRunNoFlieRunqueue();将继续运行。
停止
调用函数NRC_StopRunNoFlieRunqueue()
停止运行无文件运行队列,停止后,和暂停运行无文件队列不同的是若要继续运行,请重新创建一个无文件运行队列。
停止并不下使能
在接口NRC_StopRunNoFlieRunqueueNotPoweroff()
被调用后表示停止运行无文件运行队列并且不下使能,停止后,若要继续运行,请重新创建一个无文件运行队列。
运动队列运行的行号
若要获取当前运行队列运行的行号则调用函数NRC_GetRunqueueCurrentRunLine()
实现,函数返回当前运动队列运行的行号。
运动队列中插入运动控制类指令
插入 MOVJ
调用该函数前,请先调用NRC_CreateNoFlieRunqueue()
创建一个无文件运行队列。使用关节插补的方式移动到目标点。在机器人向目标点移动中,在不受轨迹约束的区间使 用。 调用函数NRC_RunqueueInsertMOVJ(int vel, int acc, int dec, const NRC_Position& target, int pl=0)
实现在运动队列中插入 MOVJ 指令。
- 参数 vel 是机器人的运行速度,为机器人最大速度的百分比,参数范围:0 < vel <= 100。
- 参数 acc 表示机器人运行加速度,为机器人各关节最大加速度的百分比,参数范围:0 < vel <= 100。
- 参数 target 机器人运动目标位置,详见 NRC_Position。
- 参数 dec 表示机器人运行减速度,为机器人各关节最大减速度的百分比,参数范围:0 < vel <= 100。
- 参数 pl 表示平滑度,将和后面一条移动指令进行平滑过渡,数值越大,越平滑,轨迹偏差也越大,参数范围:0 <= pl <= 5。
插入 MOVL
调用该函数前,请先调用NRC_CreateNoFlieRunqueue()
创建一个无文件运行。使用直线插补的方式移动到目标点。在机器人向目标点移动的过程中,机器人末端姿态不 变。调用函数NRC_RunqueueInsertMOVL(int vel, int acc, int dec, const NRC_Position& target, int pl=0)
实现运行队列插入 MOVL 指令。
- 参数 vel 是机器人的运行速度,为机器人末端位置点绝对运行速度,单位为 毫米每秒(mm/s),参数范围:vel > 1。
- 参数 acc 表示机器人运行加速度,为机器人各关节最大加速度的百分比,参数范围:0 < vel <= 100。
- 参数 target 机器人运动目标位置,详见 NRC_Position。
- 参数 dec 表示机器人运行减速度,为机器人各关节最大减速度的百分比,参数范围:0 < vel <= 100。
- 参数 pl 表示平滑度,将和后面一条移动指令进行平滑过渡,数值越大,越平滑,轨迹偏差也越大,参数范围:0 <= pl <= 5。
插入 MOVC
调用该函数前,请先调用NRC_CreateNoFlieRunqueue()
创建一个无文件运行。调用函数NRC_RunqueueInsertMOVC(int vel, int acc, int dec, const NRC_Position& target,int pl = 0)
实现运行队列插入 MOVC 指令。
- 参数 vel 表示机器人的运行速度,为机器人末端位置点绝对运行速度,单位为 毫米每秒(mm/s),参数范围:vel > 1。
- 参数 acc 表示机器人运行加速度,为机器人各关节最大加速度的百分比,参数范围:0 < vel <= 100。
- 参数 target 机器人运动目标位置,详见 NRC_Position。
- 参数 dec 表示机器人运行减速度,为机器人各关节最大减速度的百分比,参数范围:0 < vel <= 100。
- 参数 pl 表示平滑度,将和后面一条移动指令进行平滑过渡,数值越大,越平滑,轨迹偏差也越大,参数范围:0 <= pl <= 5。
运行队列插入 MOVC 指令示例:
//以100mm/s的速度以圆弧插补方式经过pos1点到达pos2点,
NRC_RunqueueInsertMOVC(100,50,50,pos1, 0);
NRC_RunqueueInsertMOVC(100,50,50,pos2, 0);
插入 IMOV
调用该函数前,请先调用NRC_CreateNoFlieRunqueue()
创建一个无文件运行。该函数是指以关节或直线的插补方式从当前位置按照设定的增量距离移动。 即可以通过调用函数NRC_RunqueueInsertIMOV(int vel, int acc, int dec, const NRC_Position& deviation, int pl=0)
实现运行队列插入 IMOV 指令,deviation.coord 为 NRC_ACS 时,该指令将使用关节插补方式。deviation.coord 为其他值时,使用直线插补方式。
- 参数 vel 表示 机器人的运行速度,deviation.coord 为 NRC_ACS 时,为机器人最大速度的百分比,参数范围:0 < vel <= 100,deviation.coord 不为 NRC_ACS 时,为机器人末端位置点绝对运行速度,单位为 毫米每秒(mm/s),参数范围:vel > 1。
- deviation 机器人运动偏移量,详见 NRC_Position。
- 参数 acc 表示机器人运行加速度,为机器人各关节最大加速度的百分比,参数范围:0 < vel <= 100 target 机器人运动目标位置,详见 NRC_Position。
- 参数 dec 表示机器人运行减速度,为机器人各关节最大减速度的百分比,参数范围:0 < vel <= 100。
- 参数 pl 表示平滑度,将和后面一条移动指令进行平滑过渡,数值越大,越平滑,轨迹偏差也越大,参数范围:0 <= pl <= 5。
运动队列中插入输入输出类指令
当然调用该函数前,请应先调用NRC_CreateNoFlieRunqueue()
创建一个无文件运行队列。为使某数字输出端口输出某种状态,实现相应控制。调用函数NRC_RunqueueInsertDOUT(int port, int value)
实现运行队列插入 DOUT 指令,其中参数 port 表示 要输出的数字输出端口号,参数范围:port > 0。 参数 value 表示 端口输出的状态,返回值 0 表示低电平,返回值 1 表示高电平。
运动队列中插入定时类指令
当然调用该函数前,请应先调用NRC_CreateNoFlieRunqueue()
创建一个无文件运行队列。有时运动队列中程序执行过程需要延时一定时间,则可调用函数NRC_RunqueueInsertTIMER(double timeSec)
实现运行队列插入 TIMER 指令,参数 timeSec 表示要延时的时间,单位为秒,参数范围:timeSec > 0。
运动队列中插入条件控制类指令
插入 WAIT
当然调用该函数前,请应先调用NRC_CreateNoFlieRunqueue()
创建一个无文件运行队列。若要通过检测某数字输入端口的输入状态来决定等待的时间,则可通过调用函数时NRC_RunqueueInsertWAIT( int port, int value, double timeoutSec, bool now=false)
实现运行队列插入 WAIT 指令。
- 参数 port 表示 要检测的数字输入端口号,参数范围:port > 0。
- 参数 value 表示要等待的输入状态,返回值 0 表示低电平,返回值 1 表示高电平。
- 参数 timeoutSec 表示超时时间,单位为秒,参数范围:timeSec >= 0,如果等待 timeoutSec 时间仍未满足要求,将不再继续等待,本条指令执行结束,如果值为 0 时,将无限时间等待,直到条件成立。
插入 UNTIL,ENDUNTIL
当然调用这两个函数前,请应先调用NRC_CreateNoFlieRunqueue()
创建一个无文件运行队列。调用函数NRC_RunqueueInsertUNTIL( int port, int value)
表示运行队列插入 UNTIL 指令,port 表示 要检测的数字输入端口号,参数范围:port > 0,参数 value 表示要等待的输入状态,返回值 0 表示低电平,返回值 1 表示高电平。 需要和 NRC_RunqueueInsertENDUNTIL()
配合使用。
调用函数NRC_RunqueueInsertENDUNTIL()
表示在运行队列插入 ENDUNTIL 指令,该函数需要和NRC_RunqueueInsertUNTIL( int port, int value)
配合使用。
运行队列插入 UNTIL 指令示例:
相应的需要调用的函数如下:
//在UNTIL和ENDUNTIL之间运行时,UNTIL的条件成立,将立刻中断当前运行指令, 并且跳转到ENDUNTIL执行。
NRC_RunqueueInsertUNTIL(5,1);
NRC_RunqueueInsertMOVJ(100,50,50,pos1,0);
NRC_RunqueueInsertMOVL(100,50,50,pos2,0);
NRC_RunqueueInsertDOUT(1,0);
NRC_RunqueueInsertTIMER(0.5);
NRC_RunqueueInsertENDUNTIL();
插入 IF,ELSE,ENDIF
当然调用这三个函数前,请应先调用NRC_CreateNoFlieRunqueue()
创建一个无文件运行队列。调用函数NRC_RunqueueInsertIF( int port, int value)
实现运行队列插入 IF 指令。port 表示要检测的数字输入端口号,参数范围:port > 0,参数 value 表示要等待的输入状态,返回值 0 表示低电平,返回值 1 表示高电平。同样该函数需要和NRC_RunqueueInsertENDIF()
配合使用。
调用函数NRC_RunqueueInsertELSE()
实现运行队列插入 ELSE 指令。该函数需要和NRC_RunqueueInsertIF( int port, int value);NRC_RunqueueInsertENDIF()
配合使用。
调用函数NRC_RunqueueInsertENDIF()
实现运行队列插入 ENDIF 指令,函数需要和NRC_RunqueueInsertIF( int port, int value)
配合使用。
运行队列插入 IF 指令示例:
//如果IF条件成立,执行IF代码块,否则执行ELSE代码块;如果没有ELSE指令,IF条件不成立,则会跳过IF代码块,直接执行ENDIF指令后面的指令。
NRC_RunqueueInsertIF(5,1);
NRC_RunqueueInsertMOVJ(100,50,50,pos1,0);
NRC_RunqueueInsertDOUT(1,0);
NRC_RunqueueInsertELSE();
NRC_RunqueueInsertMOVL(100,50,50,pos2,0);
NRC_RunqueueInsertTIMER(0.5);
NRC_JobfileInsertENDIF();
运动队列中插入指令类数据
通过调用函数NRC_InsertNoFlieRunqueue(std::vector<NRC_InstrDataBase*>& instrVec)
实现一组指令数据插入到运行队列中,参数 instrVec 是 要插入的一组指令数据。
示例 std::vector<NRC_InstrDataBase*> instrVec//可以不创建队列,会自动创建
instrVec.push_back(new NRC_InstrDataMOVJ(50,50,50, pos1, 5));
instrVec.push_back(new NRC_InstrDataMOVL(30,50,50, pos2, 2));
instrVec.push_back(new NRC_InstrDataMOVC(20, 50,50,pos0, 3));
instrVec.push_back(new NRC_InstrDataMOVC(20,50,50, pos1, 3));
NRC_InsertNoFlieRunqueue(instrVec);
//可以分成多组分次插入,后面插入的会接在之前插入的后面
instrVec.clear();
instrVec.push_back(new NRC_InstrDataIMOV(40,50,50, dev1, 0));
instrVec.push_back(new NRC_InstrDataDOUT(5, 1));
instrVec.push_back(new NRC_InstrDataTIMER(3.3));
instrVec.push_back(new NRC_InstrDataWAIT(new NRC_ConditionJudge(NRC_ConditionJudge::INT_, 3, NRC_ConditionJudge::LESS, NRC_ConditionJudge::DOUBLE_, 5), 2.2));
instrVec.push_back(new NRC_InstrDataWAIT(new NRC_ConditionJudge(NRC_ConditionJudge::DIN_, 2, NRC_ConditionJudge::EQUAL_TO, NRC_ConditionJudge::CONST_, 1), 0));
instrVec.push_back(new NRC_InstrDataMOVJ(30,50,50, pos1, 1));
NRC_InsertNoFlieRunqueue(instrVec);
//开始执行队列
NRC_StartRunNoFlieRunqueue();
无文件运动队列相关的 C++demo 程序:
#include <iostream>
#include "nrcAPI.h"
#include<stdio.h>
using namespace std;
int main()
{
SystemStartup();//系统启动,详见3.3节
SetServoMap();//设置伺服映射关系,见3.5节
SettingofRobotRelatedParameters();//机器人相关参数设置,详见3.6节
NRC_SetServoReadyStatus(1);//设置伺服允许,详见3.8节
NRC_SetInterpolationMethod(1);//设置为S形插补方式,详见3.12节
NRC_SetOperationMode(NRC_RUN_);//设置操作模式为运行模式,详见3.11节
NRC_SetAutoRunSpeedPer(80);//设置自动速度为80,详见3.11节
NRC_Delayms(1000);//延时1000ms
//设置四个点(采用新版本定义方式)
double pos1[7] = { 296.71, -66.12, 606.38, 3.06, 0.15, -0.18,0.00 };
double pos2[7] = { 303.3191, 20.0862, 606.3863, 3.1038, 0.1630, -0.4658,0.0000 };
double pos3[7] = { 315.4386, 21.1369, 595.0522, 3.1006, 0.1196, -0.4678,0.0000 };
double pos4[7] = { 315.6836, -16.5291, 595.0751, 3.0866, 0.1140, -0.3479,0.0000 };
NRC_Position inexbot1 = { NRC_MCS,0,0,0,pos1 };
NRC_Position inexbot2 = { NRC_MCS,0,0,0,pos2 };
NRC_Position inexbot3 = { NRC_MCS,0,0,0,pos3 };
NRC_Position inexbot4 = { NRC_MCS,0,0,0,pos4 };
double devPos1[7] = { 10, 20, -10, 10, 0, 0 };
double devPos2 [7]= { -50, 50, 10, 0, 0, 0.1 };
NRC_Position dev1 = { NRC_ACS,0,0,0,devPos1}; //设置dev1的偏差
NRC_Position dev2 = { NRC_MCS,0,0,0,devPos2 }; //设置dev2的偏差
NRC_Position inexbot9;//定义机器人位置结构体对象inexbot6
NRC_GetCurrentPos(NRC_MCS, inexbot9);//将当前机器人的直角坐标系赋值给inexbot6
printf("inexbot9.pos=%f,%f,%f,,%f,%f,%f,%f,\n",inexbot9.pos[0],inexbot9.pos[1],inexbot9.pos[2],inexbot9.pos[3],inexbot9.pos[4],inexbot9.pos[5],inexbot9.pos[6]);//将当前直角坐标位置输出,
//运动队列
NRC_ServoEnable() ;//伺服上电
NRC_CreateNoFlieRunqueue();//创建一个文件运动队列
NRC_RunqueueInsertDOUT(3, 1);//数字输出端口3输出高电平
NRC_RunqueueInsertMOVJ(50,50,50, inexbot1, 4);//以点到点的运动方式运动到inexbot1
NRC_RunqueueInsertMOVC(300,50,50, inexbot2, 5);
NRC_RunqueueInsertMOVC(300,50,50, inexbot3, 5);//以圆弧的运动方式经过inexbot2运动到inexbot3
NRC_RunqueueInsertMOVL(500,50,50, inexbot4, 1);//以直线的运动方式运动到inexbot4
NRC_RunqueueInsertWAIT(3, 1, 3.3);//等待数字输入端口3输入高电平,若3.3秒后仍然未满足条件,本指令结束
NRC_RunqueueInsertTIMER(5.5);//等待5.5秒
NRC_StartRunNoFlieRunqueue();//运行无文件运动队列
while(NRC_GetProgramRunStatus() != 0) //等待运行结束
{
NRC_Delayms(100); //延时100ms
printf("line=%d,time=%d\n",NRC_GetRunqueueCurrentRunLine(),NRC_GetCycleTimeSec());
}
NRC_ServoDisable(); //伺服下电
NRC_Position inexbot5;//定义机器人位置结构体对象inexbot6
NRC_GetCurrentPos(NRC_MCS, inexbot5);//将当前机器人的直角坐标系赋值给inexbot6
printf("inexbot5.pos=%f,%f,%f,,%f,%f,%f,%f,\n",inexbot5.pos[0],inexbot5.pos[1],inexbot5.pos[2],inexbot5.pos[3],inexbot5.pos[4],inexbot5.pos[5],inexbot5.pos[6]);//将当前直角坐标位置输出,
//在UNTIL和ENDUNTIL之间运行时(顺序执行到ENDUNITL),UNTIL的条件成立,将立刻中断当前运行指令,并跳转到ENDUNTIL执行
NRC_ServoEnable() ;//伺服上电
NRC_CreateNoFlieRunqueue();
NRC_RunqueueInsertUNTIL(5, 1);
NRC_RunqueueInsertMOVJ(50,50,50, inexbot1, 4);//以点到点的运动方式运动到inexbot1
NRC_RunqueueInsertMOVC(100,50,50, inexbot2, 0);
NRC_RunqueueInsertMOVC(100,50,50, inexbot3, 0);//以圆弧的运动方式经过inexbot2运动到inexbot3
NRC_RunqueueInsertDOUT(1, 0);//数字输出端口1输出低电平
NRC_RunqueueInsertTIMER(0.5);//等待0.5秒
NRC_RunqueueInsertENDUNTIL();
NRC_StartRunNoFlieRunqueue();//运行文件运行队列
while(NRC_GetProgramRunStatus() != 0) //等待运行结束
{
NRC_Delayms(100); //延时100ms
printf("line=%d,time=%d\n",NRC_GetRunqueueCurrentRunLine(),NRC_GetCycleTimeSec());
}
NRC_ServoDisable(); //伺服下电
NRC_Position inexbot6;//定义机器人位置结构体对象inexbot6
NRC_GetCurrentPos(NRC_MCS, inexbot6);//将当前机器人的直角坐标系赋值给inexbot6
printf("inexbot6.pos=%f,%f,%f,,%f,%f,%f,%f,\n",inexbot6.pos[0],inexbot6.pos[1],inexbot6.pos[2],inexbot6.pos[3],inexbot6.pos[4],inexbot6.pos[5],inexbot6.pos[6]);//将当前直角坐标位置输出,
//如果IF条件成立,执行IF代码块,否则执行ELSE代码块;如果没有ELSE指令,IF条件不成立,则会跳过IF代码块,直接执行ENDIF指令后面的指令
NRC_ServoEnable() ;//伺服上电
NRC_CreateNoFlieRunqueue();//创建无文件运动队列
NRC_RunqueueInsertIF(5, 1);//数字输入端口5输入高电平时,条件成立
NRC_RunqueueInsertMOVJ(100,50,50, inexbot1, 0);//以点到点的运动方式运动到inexbot1
NRC_RunqueueInsertDOUT(1, 0);//数字输出端口1输出低电平
NRC_RunqueueInsertELSE();//条件不成立时执行以下指令
NRC_RunqueueInsertMOVJ(100,50,50, inexbot4, 0);//点到点运动到点inexbot4
NRC_RunqueueInsertTIMER(0.5);//等待0.5秒
NRC_RunqueueInsertENDIF();
NRC_RunqueueInsertIMOV(50,50,50, dev1, 3);//机器人运动偏移量
NRC_RunqueueInsertIMOV(500,50,50, dev2, 0);//机器人运动偏移量
NRC_StartRunNoFlieRunqueue();//开始运行无文件运动队列
while(NRC_GetProgramRunStatus() != 0) //等待运行结束
{
NRC_Delayms(100); //延时100ms
printf("line=%d,time=%d\n",NRC_GetRunqueueCurrentRunLine(),NRC_GetCycleTimeSec());
}
NRC_ServoDisable(); //伺服下电
NRC_Position inexbot7;//定义机器人位置结构体对象inexbot6
NRC_GetCurrentPos(NRC_MCS, inexbot7);//将当前机器人的直角坐标系赋值给inexbot6
printf("inexbot7.pos=%f,%f,%f,,%f,%f,%f,\n", inexbot7.pos[0], inexbot7.pos[1], inexbot7.pos[2], inexbot7.pos[3], inexbot7.pos[4], inexbot7.pos[5]);//将当前直角坐标位置输出
// 实现一组指令数据插入到运行队列中,参数inexbot是 要插入的一组指令数据
NRC_ServoEnable() ;//伺服上电
std::vector<NRC_InstrDataBase*>inexbot;//定义inexbot为vector类
inexbot.push_back(new NRC_InstrDataMOVJ(100,50,50, inexbot1, 5));//点到点运动到inexbot1
inexbot.push_back(new NRC_InstrDataIF(new NRC_ConditionJudge(NRC_ConditionJudge::INT_, 2, NRC_ConditionJudge::EQUAL_TO, NRC_ConditionJudge::CONST_, 5)));
inexbot.push_back(new NRC_InstrDataMOVC(50,50,50,inexbot3, 3));
inexbot.push_back(new NRC_InstrDataMOVC(50,50,50, inexbot4, 3));//以圆弧的运动方式经过inexbot3运动到inexbot4
inexbot.push_back(new NRC_InstrDataELSE());
inexbot.push_back(new NRC_InstrDataMOVL(100,50,50,inexbot2, 2));//直线运动到点inexbot2
inexbot.push_back(new NRC_InstrDataENDIF());
NRC_InsertNoFlieRunqueue(inexbot);//指令数据插入无文件运动队列
NRC_StartRunNoFlieRunqueue();//开始运行无文件运动队列
while(NRC_GetProgramRunStatus() != 0) //等待运行结束
{
NRC_Delayms(100); //延时100ms
}
NRC_Delayms(1000);
NRC_ServoDisable(); //伺服下电
NRC_Position inexbot8;//定义机器人位置结构体对象inexbot8
NRC_GetCurrentPos(NRC_MCS, inexbot8);//将当前机器人的直角坐标系赋值给inexbot8
printf("inexbot8.pos=%f,%f,%f,,%f,%f,%f,%f,\n",inexbot8.pos[0],inexbot8.pos[1],inexbot8.pos[2],inexbot8.pos[3],inexbot8.pos[4],inexbot8.pos[5],inexbot8.pos[6]);//将当前直角坐标位置输出
inexbot.clear();
inexbot.push_back(new NRC_InstrDataDOUT(5, 1));//数字输出端口输出高电平
inexbot.push_back(new NRC_InstrDataWAIT(new NRC_ConditionJudge(NRC_ConditionJudge::DIN_,5,NRC_ConditionJudge::EQUAL_TO,NRC_ConditionJudge::CONST_, 0), 5));
inexbot.push_back(new NRC_InstrDataTIMER(5));
inexbot.push_back(new NRC_InstrDataMOVJ(30,50,50, inexbot1, 1));//点到点运动到inexbot1
NRC_InsertNoFlieRunqueue(inexbot);//指令数据插入无文件运动队列
NRC_StartRunNoFlieRunqueue();//开始运行无文件运动队列
while(NRC_GetProgramRunStatus() != 0) //等待运行结束
{
NRC_Delayms(100); //延时100ms
}
NRC_Delayms(1000);//延时1000ms
NRC_ServoDisable(); //伺服下电
NRC_Position inexbot10;//定义机器人位置结构体对象inexbot10
NRC_GetCurrentPos(NRC_MCS, inexbot10);//将当前机器人的直角坐标系赋值给inexbot9
printf("inexbot10.pos=%f,%f,%f,,%f,%f,%f,%f,\n", inexbot10.pos[0], inexbot10.pos[1], inexbot10.pos[2], inexbot10.pos[3], inexbot10.pos[4], inexbot10.pos[5],inexbot10.pos[6]);//将当前直角坐标位置输出
while(1)//保持程序继续运行
{
NRC_Delayms(1000);
}
}