c++/qt/opencv实现魔方复原【机器人应用】

  • Post author:
  • Post category:其他


[]@

TOC




前言

本文主要实现使用Qt做软甲界面,opencv做魔方识别,本软件主要是配合机械手进行通信完成魔方的识别

机器人:ABB双臂机器人




效果视频

本软件效果如下:

c++/opencv实现魔方还原



工程目录如下:

在这里插入图片描述

  • CtuLib:此工程包含了多个算法,包括软件加密,opencv图像处理算法,魔方还原算法等



一、算法库的构建:CtuLib.dll

本文收集了大量资料并且根据根据个人经验,实现了一个基于C++写的算法库,并且本算法库是多个命名空间,实现多个算法

CtuLib.h内容如下:

在这里插入图片描述



1.基于opencv实现的算法

namespace CtuLibLink
{
	CTULIB_API bool read_image(cv::Mat* img, std::string fileName,bool nchannels=false);
	CTULIB_API bool write_image(cv::Mat* img,std::string SavePath);
	CTULIB_API bool ConnectedCamera(int Type=0,int Num=0);
	CTULIB_API bool DisConnectedCamera();
	CTULIB_API bool CameraIsConnected();
	CTULIB_API bool GetOnceImage(cv::Mat* img);
	CTULIB_API bool DrawModelROI(cv::Mat* img, cv::Mat* model,cv::Rect* rect,int min_width=500);
	CTULIB_API bool DrawPoint(cv::Mat* img,cv::Rect rect,cv::Point* point,int min_width=500);
	CTULIB_API bool DrawSearchROI(cv::Mat* img, cv::Mat* searchROI,cv::Rect* rect,int min_width=500);
	CTULIB_API bool FindModel1(cv::Mat img,cv::Mat model,cv::Mat* dst,cv::Point* p);
	CTULIB_API bool SetCalib(double ImageX[3],double Image_Y[3],double Robot_X[3],double Robot_Y[3]);
	CTULIB_API bool GetP(double ImageX,double Image_Y,double* Robot_X,double* Robot_Y);
	CTULIB_API void Rotate_Angle(cv::Mat &src,cv::Mat &dst,float angle);
}



2.魔方还原算法

namespace MagicCubeLink
{
	CTULIB_API std::vector<std::string> GetCubeFunc(int data[6][9],int countNum=100000);
	CTULIB_API std::vector<std::string> GetCubeFlipFunc(std::vector<std::string> data);
	CTULIB_API std::vector<std::string> GetCubeData(int data[6][9]);
	CTULIB_API cv::Scalar getAvgBGR(cv::Mat img);
	CTULIB_API std::string isDigitStr(std::string src);
}
namespace MagicCubeFastLink
{
	CTULIB_API std::vector<std::string> GetCubeFunc(int data[6][9]);
}



3.软加密方式

namespace PermissionLink
{
	CTULIB_API bool GetData(char* uuid,int check);
	CTULIB_API bool AddUser(char* recv,char* Project,char* ID);
	CTULIB_API bool CheckUser(char* recv,char* Project,char* ID);
	CTULIB_API bool DeleteUser(char* recv,char* Project,char* ID);
	CTULIB_API bool FindAllUser(char* recv,char* Project);
	CTULIB_API bool GetMinWen(char* mingwen,char* miwen);
	CTULIB_API bool Registration(char* writemes,char* fileName);
	CTULIB_API bool CheckRegistration(char* fileName);
}



4.软件狗加密方式:ET99

namespace MircoDogLink
{
	CTULIB_API void SoftWareCheck(std::string KeyData_ID,int length,Fun pCallback);
	CTULIB_API void SoftWareCheck_Once(std::string KeyData_ID,int length,bool* res);
	CTULIB_API int WriteDog(std::string KeyData_ID,std::string miwen,bool* res);
	CTULIB_API void GetDogID(DWORD* data1,DWORD* data2,bool* res);
}

namespace ET99DLLLink
{
	CTULIB_API bool SoftWareCheck(Fun pCallback);
	CTULIB_API void SoftWareCheck_Once(bool* res);
}



二、魔方还原

界面主要看视频即可



1.工程目录如下:

在这里插入图片描述



2.重要代码



1.2D

//刷新平面2D界面图
void MagicCube::Auto_Ref_2D()
{
	for(int i=0;i<6;i++)
	{
		for(int j=0;j<9;j++)
		{
			ShowLab[i][j]->setStyleSheet(SetCircleMes(Magic_Data.Magic_Data[i][j]));
			ShowLab[i][j]->setText(QString::number(Magic_Data.Magic_Data[i][j]));
		}
	}
}

如图:

在这里插入图片描述



2.3D

3D效果图主要是用opengl方式进行绘制,对27个方格进行绘制

void Model_3D_Cube::upDataColor(int data[6][9])
{
	//0->前   1->后   2->下   3->上     4->右    5->左
	//1
	cubeWidget->rotatecube[0]->color[0]=getColor(data[FORWARD_COLOR][6]);
	cubeWidget->rotatecube[0]->color[1]=getColor(0);
	cubeWidget->rotatecube[0]->color[2]=getColor(data[DOWN_COLOR][0]);
	cubeWidget->rotatecube[0]->color[3]=getColor(0);
	cubeWidget->rotatecube[0]->color[4]=getColor(0);
	cubeWidget->rotatecube[0]->color[5]=getColor(data[LEFT_COLOR][8]);
	//2
	cubeWidget->rotatecube[1]->color[0]=getColor(data[FORWARD_COLOR][7]);
	cubeWidget->rotatecube[1]->color[1]=getColor(0);
	cubeWidget->rotatecube[1]->color[2]=getColor(data[DOWN_COLOR][1]);
	cubeWidget->rotatecube[1]->color[3]=getColor(0);
	cubeWidget->rotatecube[1]->color[4]=getColor(0);
	cubeWidget->rotatecube[1]->color[5]=getColor(0);
	//3
	cubeWidget->rotatecube[2]->color[0]=getColor(data[FORWARD_COLOR][8]);
	cubeWidget->rotatecube[2]->color[1]=getColor(0);
	cubeWidget->rotatecube[2]->color[2]=getColor(data[DOWN_COLOR][2]);
	cubeWidget->rotatecube[2]->color[3]=getColor(0);
	cubeWidget->rotatecube[2]->color[4]=getColor(data[RIGHT_COLOR][6]);
	cubeWidget->rotatecube[2]->color[5]=getColor(0);
	//4
	cubeWidget->rotatecube[3]->color[0]=getColor(data[FORWARD_COLOR][3]);
	cubeWidget->rotatecube[3]->color[1]=getColor(0);
	cubeWidget->rotatecube[3]->color[2]=getColor(0);
	cubeWidget->rotatecube[3]->color[3]=getColor(0);
	cubeWidget->rotatecube[3]->color[4]=getColor(0);
	cubeWidget->rotatecube[3]->color[5]=getColor(data[LEFT_COLOR][5]);
	//5
	cubeWidget->rotatecube[4]->color[0]=getColor(data[FORWARD_COLOR][4]);
	cubeWidget->rotatecube[4]->color[1]=getColor(0);
	cubeWidget->rotatecube[4]->color[2]=getColor(0);
	cubeWidget->rotatecube[4]->color[3]=getColor(0);
	cubeWidget->rotatecube[4]->color[4]=getColor(0);
	cubeWidget->rotatecube[4]->color[5]=getColor(0);
	//6
	cubeWidget->rotatecube[5]->color[0]=getColor(data[FORWARD_COLOR][5]);
	cubeWidget->rotatecube[5]->color[1]=getColor(0);
	cubeWidget->rotatecube[5]->color[2]=getColor(0);
	cubeWidget->rotatecube[5]->color[3]=getColor(0);
	cubeWidget->rotatecube[5]->color[4]=getColor(data[RIGHT_COLOR][3]);
	cubeWidget->rotatecube[5]->color[5]=getColor(0);
	//7
	cubeWidget->rotatecube[6]->color[0]=getColor(data[FORWARD_COLOR][0]);
	cubeWidget->rotatecube[6]->color[1]=getColor(0);
	cubeWidget->rotatecube[6]->color[2]=getColor(0);
	cubeWidget->rotatecube[6]->color[3]=getColor(data[UP_COLOR][6]);
	cubeWidget->rotatecube[6]->color[4]=getColor(0);
	cubeWidget->rotatecube[6]->color[5]=getColor(data[LEFT_COLOR][2]);
	//8
	cubeWidget->rotatecube[7]->color[0]=getColor(data[FORWARD_COLOR][1]);
	cubeWidget->rotatecube[7]->color[1]=getColor(0);
	cubeWidget->rotatecube[7]->color[2]=getColor(0);
	cubeWidget->rotatecube[7]->color[3]=getColor(data[UP_COLOR][7]);
	cubeWidget->rotatecube[7]->color[4]=getColor(0);
	cubeWidget->rotatecube[7]->color[5]=getColor(0);
	//9
	cubeWidget->rotatecube[8]->color[0]=getColor(data[FORWARD_COLOR][2]);
	cubeWidget->rotatecube[8]->color[1]=getColor(0);
	cubeWidget->rotatecube[8]->color[2]=getColor(0);
	cubeWidget->rotatecube[8]->color[3]=getColor(data[UP_COLOR][8]);
	cubeWidget->rotatecube[8]->color[4]=getColor(data[RIGHT_COLOR][0]);
	cubeWidget->rotatecube[8]->color[5]=getColor(0);

	//10
	cubeWidget->othercube[0]->color[0]=getColor(0);
	cubeWidget->othercube[0]->color[1]=getColor(0);
	cubeWidget->othercube[0]->color[2]=getColor(data[DOWN_COLOR][3]);
	cubeWidget->othercube[0]->color[3]=getColor(0);
	cubeWidget->othercube[0]->color[4]=getColor(0);
	cubeWidget->othercube[0]->color[5]=getColor(data[LEFT_COLOR][7]);

	//11
	cubeWidget->othercube[1]->color[0]=getColor(0);
	cubeWidget->othercube[1]->color[1]=getColor(0);
	cubeWidget->othercube[1]->color[2]=getColor(data[DOWN_COLOR][4]);
	cubeWidget->othercube[1]->color[3]=getColor(0);
	cubeWidget->othercube[1]->color[4]=getColor(0);
	cubeWidget->othercube[1]->color[5]=getColor(0);

	//12
	cubeWidget->othercube[2]->color[0]=getColor(0);
	cubeWidget->othercube[2]->color[1]=getColor(0);
	cubeWidget->othercube[2]->color[2]=getColor(data[DOWN_COLOR][5]);
	cubeWidget->othercube[2]->color[3]=getColor(0);
	cubeWidget->othercube[2]->color[4]=getColor(data[RIGHT_COLOR][7]);
	cubeWidget->othercube[2]->color[5]=getColor(0);

	//13
	cubeWidget->othercube[3]->color[0]=getColor(0);
	cubeWidget->othercube[3]->color[1]=getColor(0);
	cubeWidget->othercube[3]->color[2]=getColor(0);
	cubeWidget->othercube[3]->color[3]=getColor(0);
	cubeWidget->othercube[3]->color[4]=getColor(0);
	cubeWidget->othercube[3]->color[5]=getColor(data[LEFT_COLOR][4]);

	//14
	cubeWidget->othercube[4]->color[0]=getColor(0);
	cubeWidget->othercube[4]->color[1]=getColor(0);
	cubeWidget->othercube[4]->color[2]=getColor(0);
	cubeWidget->othercube[4]->color[3]=getColor(0);
	cubeWidget->othercube[4]->color[4]=getColor(0);
	cubeWidget->othercube[4]->color[5]=getColor(0);

	//15
	cubeWidget->othercube[5]->color[0]=getColor(0);
	cubeWidget->othercube[5]->color[1]=getColor(0);
	cubeWidget->othercube[5]->color[2]=getColor(0);
	cubeWidget->othercube[5]->color[3]=getColor(0);
	cubeWidget->othercube[5]->color[4]=getColor(data[RIGHT_COLOR][4]);
	cubeWidget->othercube[5]->color[5]=getColor(0);

	//16
	cubeWidget->othercube[6]->color[0]=getColor(0);
	cubeWidget->othercube[6]->color[1]=getColor(0);
	cubeWidget->othercube[6]->color[2]=getColor(0);
	cubeWidget->othercube[6]->color[3]=getColor(data[UP_COLOR][3]);
	cubeWidget->othercube[6]->color[4]=getColor(0);
	cubeWidget->othercube[6]->color[5]=getColor(data[LEFT_COLOR][1]);

	//17
	cubeWidget->othercube[7]->color[0]=getColor(0);
	cubeWidget->othercube[7]->color[1]=getColor(0);
	cubeWidget->othercube[7]->color[2]=getColor(0);
	cubeWidget->othercube[7]->color[3]=getColor(data[UP_COLOR][4]);
	cubeWidget->othercube[7]->color[4]=getColor(0);
	cubeWidget->othercube[7]->color[5]=getColor(0);
	
	//18
	cubeWidget->othercube[8]->color[0]=getColor(0);
	cubeWidget->othercube[8]->color[1]=getColor(0);
	cubeWidget->othercube[8]->color[2]=getColor(0);
	cubeWidget->othercube[8]->color[3]=getColor(data[UP_COLOR][5]);
	cubeWidget->othercube[8]->color[4]=getColor(data[RIGHT_COLOR][1]);
	cubeWidget->othercube[8]->color[5]=getColor(0);
	
	//19
	cubeWidget->othercube[9]->color[0]=getColor(0);
	cubeWidget->othercube[9]->color[1]=getColor(data[BACK_COLOR][8]);
	cubeWidget->othercube[9]->color[2]=getColor(data[DOWN_COLOR][6]);
	cubeWidget->othercube[9]->color[3]=getColor(0);
	cubeWidget->othercube[9]->color[4]=getColor(0);
	cubeWidget->othercube[9]->color[5]=getColor(data[LEFT_COLOR][6]);
	
	//20
	cubeWidget->othercube[10]->color[0]=getColor(0);
	cubeWidget->othercube[10]->color[1]=getColor(data[BACK_COLOR][7]);
	cubeWidget->othercube[10]->color[2]=getColor(data[DOWN_COLOR][7]);
	cubeWidget->othercube[10]->color[3]=getColor(0);
	cubeWidget->othercube[10]->color[4]=getColor(0);
	cubeWidget->othercube[10]->color[5]=getColor(0);

	//21
	cubeWidget->othercube[11]->color[0]=getColor(0);
	cubeWidget->othercube[11]->color[1]=getColor(data[BACK_COLOR][6]);
	cubeWidget->othercube[11]->color[2]=getColor(data[DOWN_COLOR][8]);
	cubeWidget->othercube[11]->color[3]=getColor(0);
	cubeWidget->othercube[11]->color[4]=getColor(data[RIGHT_COLOR][8]);
	cubeWidget->othercube[11]->color[5]=getColor(0);
	
	//22
	cubeWidget->othercube[12]->color[0]=getColor(0);
	cubeWidget->othercube[12]->color[1]=getColor(data[BACK_COLOR][5]);
	cubeWidget->othercube[12]->color[2]=getColor(0);
	cubeWidget->othercube[12]->color[3]=getColor(0);
	cubeWidget->othercube[12]->color[4]=getColor(0);
	cubeWidget->othercube[12]->color[5]=getColor(data[LEFT_COLOR][3]);
	
	//23
	cubeWidget->othercube[13]->color[0]=getColor(0);
	cubeWidget->othercube[13]->color[1]=getColor(data[BACK_COLOR][4]);
	cubeWidget->othercube[13]->color[2]=getColor(0);
	cubeWidget->othercube[13]->color[3]=getColor(0);
	cubeWidget->othercube[13]->color[4]=getColor(0);
	cubeWidget->othercube[13]->color[5]=getColor(0);

	//24
	cubeWidget->othercube[14]->color[0]=getColor(0);
	cubeWidget->othercube[14]->color[1]=getColor(data[BACK_COLOR][3]);
	cubeWidget->othercube[14]->color[2]=getColor(0);
	cubeWidget->othercube[14]->color[3]=getColor(0);
	cubeWidget->othercube[14]->color[4]=getColor(data[RIGHT_COLOR][5]);
	cubeWidget->othercube[14]->color[5]=getColor(0);

	
	//25
	cubeWidget->othercube[15]->color[0]=getColor(0);
	cubeWidget->othercube[15]->color[1]=getColor(data[BACK_COLOR][2]);
	cubeWidget->othercube[15]->color[2]=getColor(0);
	cubeWidget->othercube[15]->color[3]=getColor(data[UP_COLOR][0]);
	cubeWidget->othercube[15]->color[4]=getColor(0);
	cubeWidget->othercube[15]->color[5]=getColor(data[LEFT_COLOR][0]);
	
	//26
	cubeWidget->othercube[16]->color[0]=getColor(0);
	cubeWidget->othercube[16]->color[1]=getColor(data[BACK_COLOR][1]);
	cubeWidget->othercube[16]->color[2]=getColor(0);
	cubeWidget->othercube[16]->color[3]=getColor(data[UP_COLOR][1]);
	cubeWidget->othercube[16]->color[4]=getColor(0);
	cubeWidget->othercube[16]->color[5]=getColor(0);

	//27
	cubeWidget->othercube[17]->color[0]=getColor(0);
	cubeWidget->othercube[17]->color[1]=getColor(data[BACK_COLOR][0]);
	cubeWidget->othercube[17]->color[2]=getColor(0);
	cubeWidget->othercube[17]->color[3]=getColor(data[UP_COLOR][2]);
	cubeWidget->othercube[17]->color[4]=getColor(data[RIGHT_COLOR][2]);
	cubeWidget->othercube[17]->color[5]=getColor(0);
}

如图:

在这里插入图片描述



3.生成队列

void MagicCube::on_pushButton_CreateData_clicked()
{
	ui.TabWidget_ODNGMes->clear();
	ui.TabWidget_ODNGMes->setRowCount(0);
	QStringList header;
	header<<QStringLiteral("ID")<<QStringLiteral("Data");
	ui.TabWidget_ODNGMes->setHorizontalHeaderLabels(header);
	for (int i=0;i<ui.TabWidget_ODNGMes->columnCount();i++)
		ui.TabWidget_ODNGMes->setColumnWidth(i,15);

	for(int i=0;i<6;i++)
	{
		if(Magic_Data.Magic_Flag[i]==false)
		{
			ShowMessageToLog(QStringLiteral("识别颜色不全"));
			return;
		}
	}
	int temp_Num[6]={0,0,0,0,0,0};
	for(int i=0;i<6;i++)
	{
		for(int j=0;j<9;j++)
		{
			temp_Num[Magic_Data.Magic_Data[i][j]-1]++;
		}
	}
	for(int i=0;i<6;i++)
	{
		if(temp_Num[i]!=9)
		{
			ShowMessageToLog(QStringLiteral("颜色数据错误"));
			return;
		}
	}
	Magic_Queue.clear();
	if(Function_Fast == 1)
		Magic_Queue = MagicCubeFastLink::GetCubeFunc(Magic_Data.Magic_Data);
	else
		Magic_Queue = MagicCubeLink::GetCubeFunc(Magic_Data.Magic_Data);

	if(DataModel == "1")
		Magic_Queue = MagicCubeLink::GetCubeFlipFunc(Magic_Queue);
	
	if(Magic_Queue.size()>0)
	{
		ShowMessageToLog(QStringLiteral("队列形成!"));

		for(int i=0;i<Magic_Queue.size();i++)
		{
			try{
				int Num = ui.TabWidget_ODNGMes->rowCount();
				ui.TabWidget_ODNGMes->insertRow(Num);
				ui.TabWidget_ODNGMes->setItem(Num,0,new QTableWidgetItem(QString::number(Num+1)));
				ui.TabWidget_ODNGMes->setItem(Num,1,new QTableWidgetItem(QString::fromStdString(Magic_Queue.at(Num))));
				QCoreApplication::processEvents(QEventLoop::AllEvents, 5);
			}catch(...){}
		}
	}
	else
	{
		ShowMessageToLog(QStringLiteral("队列形成失败!"));
	}
}

在这里插入图片描述




三、机器人协议

DefaultSetting.ini 
IP配置文件
视觉(计算机)IP:192.168.0.200,255.255.255.0;
机器人IP:192.168.0.10,255.255.255.0
Angle=180

1、双击“MagiCube.exe”,点击相机,点击连接相机,ID为0,代表外部相机(###建议:重启软件时自动连接上次所选相机)
2、点击相机,开始预览
3、颜色设置,绘制搜索区域,(###建议:搜索区域重启软件应保留上次设置)
4、参数设置,点击区域划分,修改,修改颜色区域范围,保存(参数文件:color.dat)
5、测试颜色,执行识别
6、点击运行(###建议:新增功能,点击运行后,窗口按钮不可再操作)

7、颜色识别(机器人触发,颜色识别程序)(###建议:机器人与视觉通讯链接已建立,机器人发:Hello Vision,视觉发:Hello Robot)
8、点击操作,数据生成(提示队列形成)(###建议:机器人发:GetData,视觉发:DataOK(队列形成),DataNG(队列形成失败)
9、点击操作,点击运行(视觉发:S,Start       返回:R,Start,OK)(###建议:机器人发:Run,视觉发:Run  OK )

机器人连接成功:
视觉发:S,00

机器人清空数据队列:
机器人发:R,Clear,F         返回:S,Clear,F,OK
机器人发:R,Clear,B         返回:S,Clear,B,OK
机器人发:R,Clear,L         返回:S,Clear,L,OK
机器人发:R,Clear,R         返回:S,Clear,R,OK
机器人发:R,Clear,U         返回:S,Clear,U,OK
机器人发:R,Clear,D         返回:S,Clear,D,OK
机器人发:R,Clear,A         返回:S,Clear,A,OK

颜色识别程序:
机器人发:R,F      返回:S,F,OK (S,F,NG)  (前) 21		r21Move_RF_L
机器人发:R,B      返回:S,B,OK (S,B,NG) (后) 22		r22Move_RB_L
机器人发:R,L      返回:S,L,OK (S,L,NG)   (左)23		r23Move_RL_L
机器人发:R,R      返回:S,R,OK (S,R,NG) (右)24		r24Move_RR_L
机器人发:R,U      返回:S,U,OK(S,U,NG) (上)25		r25Move_RU_L
机器人发:R,D      返回:S,D,OK(S,D,NG) (下)26		r26Move_RD_L

颜色识别完,机器人要求生成队列
机器人发:R,Cali     返回:S,Cali,OK (S,Cali,NG)

机器人要求开始转魔方:
机器人发:R,Start    视觉返回:S,Start,OK(S,Start,NG)      机器人返回:R,Start,OK

程序运行:(###建议:视觉发两步指令:第1步;第2步(第2步;第3步);S,F1,1;S,F1,1;最后1步后跟S,End0)每组数据6个字符,以“;”分隔

前面F(左手)###	
视觉发:S,F1,1       机器人旋转完:R,F1,1,OK(顺时针90)      31	      r31S_F1_1_L
视觉发:S,F1,0       机器人旋转完:R,F1,0,OK(逆时针90)      32	      r32S_F1_0_L
视觉发:S,F2,1       机器人旋转完:R,F2,1,OK(顺时针180)     33	      r33S_F2_1_L

后面B(右手)	
视觉发:S,B1,1       机器人旋转完:R,B1,1,OK(顺时针90)      41	r41S_B1_1_R
视觉发:S,B1,0       机器人旋转完:R,B1,0,OK(逆时针90)      42	r42S_B1_0_R
视觉发:S,B2,1       机器人旋转完:R,B2,1,OK(顺时针180)    43	r43S_B2_1_R

左面L(左手)###
视觉发:S,L1,1       机器人旋转完:R,L1,1,OK(顺时针90)      51	r51S_L1_1_L
视觉发:S,L1,0       机器人旋转完:R,L1,0,OK(逆时针90)      52	r52S_L1_0_L
视觉发:S,L2,1       机器人旋转完:R,L2,1,OK(顺时针180)    53	r53S_L2_1_L

右面R(右手)
视觉发:S,R1,1       机器人旋转完:R,R1,1,OK(顺时针90)     61	r61S_R1_1_R
视觉发:S,R1,0       机器人旋转完:R,R1,0,OK(逆时针90)    62	r62S_R1_0_R
视觉发:S,R2,1       机器人旋转完:R,R2,1,OK(顺时针180)  63	r63S_R2_1_R

上面U(左手)###
视觉发:S,U1,1       机器人旋转完:R,U1,1,OK(顺时针90)   71	r71S_U1_1_L
视觉发:S,U1,0       机器人旋转完:R,U1,0,OK(逆时针90)   72	r72S_U1_0_L
视觉发:S,U2,1       机器人旋转完:R,U2,1,OK(顺时针180) 73	r73S_U2_1_L

下面D(右手)
视觉发:S,D1,1       机器人旋转完:R,D1,1,OK(顺时针90)   81	r81S_D1_1_R
视觉发:S,D1,0       机器人旋转完:R,D1,0,OK(逆时针90)   82	r82S_D1_0_R
视觉发:S,D2,1       机器人旋转完:R,D2,1,OK(顺时针180) 83	r83S_D2_1_R

动作完成(代表无指令):

视觉发:S,End       返回:R,End,OK




总结

感兴趣及对代码感兴趣可私聊



版权声明:本文为ctu_sue原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。