⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 robot.h

📁 吸尘机器人全覆盖算法仿真源码,希望对大家有用
💻 H
字号:
#ifndef ROBOT_H
#define ROBOT_H
#include<iostream>
#include<vector>
#include"ABCRobotDefine.h"
#include"helper.h"
#include"GraphicEngine.h"
using namespace std;
typedef int DIRECTION;
class Robot{
	
	
	int visited;
	int SeeObstacleBefore;
	int SeeMagnet;
public:int CurrentDirection;
	int CurrentDirectionInEM;
	struct point{
		int x;
		int y;
	}StartPointInEM,CurrentPointInEM;
	public:	vector<point> idealpath;
//
	int NextDirection(int i){
        int dTemp=CurrentDirection+i;
        if(dTemp>4){
//			std::cout<<"attention:"<<dTemp<<","<<dTemp%4;
			dTemp=dTemp%4;
//			std::cout<<","<<dTemp<<std::endl;
		}
		return dTemp;
	}
	int NextDirectionInEM(int i){
        int dTemp=CurrentDirectionInEM+i;
        if(dTemp>4){dTemp=dTemp%4;}
		return dTemp;
	}
//
	int RDToVD(int realdirection){
		//convert real direction to virtual direction
		int dTemp=realdirection-DifferenceOfRDandVD;
		if(dTemp<=0) dTemp+=4;
		return dTemp;
	}
	int VDToRD(int virtualdirection){
		//convert virtual direction to real direction
		int dTemp=virtualdirection+DifferenceOfRDandVD;
		if(dTemp>4) dTemp-=4;
		return dTemp;
	}
//
	int CrossingIP(){
		//Inersecting with idealpath.
		for(int i=0;i<idealpath.size();i++){
	        if((idealpath[i].x==CurrentPointInEM.x)&&
				(idealpath[i].y==CurrentPointInEM.y)){
				if(i==0) return i;
				else if((map[idealpath[i-1].x][idealpath[i-1].y]==1))
					return i;}		
		}
		return -1;//
	}
	int TurnToD2(){
		//turn to direction 2(a direction in EM.)
		switch(CurrentDirectionInEM){
		case 1:
			ClockwiseTurn();return 1;
		case 2:
			return 1;
		case 3:
			AnticlockwiseTurn();return 1;
		case 4:
			AnticlockwiseTurn();
			AnticlockwiseTurn();return 1;
		default:
			return 0;}
	}
	int TurnToD4(){
		//turn to direction 4(a direction In EM.)
		switch(CurrentDirectionInEM){
		case 1:
			AnticlockwiseTurn();return 1;
		case 2:
			AnticlockwiseTurn();
			AnticlockwiseTurn();return 1;
		case 3:
			ClockwiseTurn();return 1;
		case 4:
			return 1;
		default:
			return 0;
		}
	}
	int TurnToD1(){
		//turn to direction 1(a direction in EM.)
		switch(CurrentDirectionInEM){
		case 1:
			return 1;
		case 2:
			AnticlockwiseTurn();return 1;
		case 3:
			AnticlockwiseTurn();
			AnticlockwiseTurn();return 1;
		case 4:
			ClockwiseTurn();return 1;
		default:
			return 0;}
	}
	int TurnToD3(){
		//turn to direction 4(a direction in EM.)
		switch(CurrentDirectionInEM){
		case 1:
			ClockwiseTurn();
			ClockwiseTurn();return 1;
		case 2:
			ClockwiseTurn();return 1;
		case 3:
			return 1;
		case 4:
			AnticlockwiseTurn();return 1;
		default:
			return 0;}
	}
	int MarkMap();
	int Evaluate();
//Find out ideal path between (xstart,ystart) and (xend,yend),
//stuff the idealpath vector with that ideal path.
public:	int FindIdealpath(int xstart,int ystart,int xend,int yend);
public:int map[40][40];//EM
	   point CurrentPoint;
	   int *realmap;//delete later
	   MAP _realmap;//real map
       Robot(int x,int y,int pixelx,int pixely,LPDIRECTDRAWSURFACE src,int direction=1);
/******************************************************
The following three (RealMove(),RotateAC(),RotateC(),Detect())
is designed to simulate the real action of robot,and 
will be replaced by fuctions which will actually drive 
the robot moving or rotating.
******************************************************/
	
	int PhyMove(int MaxMovedStep);
	//Move according to current direction.
	//return pixels have moved.
	
	bool SideMove();	
    //nSideMoveFlag_To and nSideMoveFlag_Fro is flags that
	//SideMove() used to communicate with main function.
	
	bool TurnToDirection(int direction);
	//Turn to direction indicated by argument.
	//this function will be called inside SideMove()
	
	bool TurnToOppositeDirectionOf(int direction);
	//Turn to opposite direction indicated by argument.
	//this function will be called inside SideMove() either.
	
	bool RotateC();
	//Rotate clockwise.
	
	bool RotateAC();
	//Rotate anticlockwise.

    //Detect "direction",return 1 if there exists obstacles,otherwise return 0
	//if "direction" is invalid ,return 2
	int Detect(int direction);	
private:	
	//Detect2() will be called inside Detect()
	bool Detect2(int direction);
    //DetectX will detect one robot unit far in the "direction"
	//and return how many robot units the robot can move forward.
	// 1 robot unit=1/5 width of the robot= 1/5 height of the robot=4 pixels 
	int DetectX(int direction);
	bool PreMove();
public:
/**********************************************************
Fuctions below(including Move(),AnticlockwiseTurn(),ClockwiseTurn()
,MoveOutside()etc.) are independent of robot's physical action.
***********************************************************/
int Move();
int MoveA();
//MarkMap() must be executed once before MoveTo is to be called.
int MoveTo(int x,int y);//Move to {x,y}
int MoveTo2(int x,int y);//MoveTo2() will be called inside MoveTo()
int AnticlockwiseTurn();
int ClockwiseTurn();
int MoveOutside();
int MoveRectangularly();
int ToAndFroA();//map dependent.
bool VMove(int* x,int* y,int direction);
int VDetect(int *x,int *y,int direction);//map dependent
int ClearPath();
/**/
bool MoveOutsideSucceed();
int DetectA(int direction){
	//detecting in EM
	//if there are obstacle or the area in the direction 
	//indicated by direction argument has been cleaned 
	//return true,otherwise return false
	switch(direction){
	case 1:
		if((map[CurrentPointInEM.x][CurrentPointInEM.y+1]==1)||
           (map[CurrentPointInEM.x][CurrentPointInEM.y+1]==2))
		   return 1;
		else return 0;
	case 2:
		if((map[CurrentPointInEM.x+1][CurrentPointInEM.y]==1)||
           (map[CurrentPointInEM.x+1][CurrentPointInEM.y]==2))
		   return 1;
		else return 0;
	case 3:
		if((map[CurrentPointInEM.x][CurrentPointInEM.y-1]==1)||
           (map[CurrentPointInEM.x][CurrentPointInEM.y-1]==2))
		   return 1;
		else return 0;
	case 4:
		if((map[CurrentPointInEM.x-1][CurrentPointInEM.y]==1)||
           (map[CurrentPointInEM.x-1][CurrentPointInEM.y]==2))
		   return 1;
		else return 0;
	default:
		return 2;
	}
}
int DetectA2(int nextpoint){
	//detecting in EM
	//if there are obstacle  on the next point 
	//in the ideal path  
	//return true,otherwise return false
	if(nextpoint==idealpath.size()) return 0;
	if(map[idealpath[nextpoint].x][idealpath[nextpoint].y]==1) return 1;
	else if((map[idealpath[nextpoint].x-1][idealpath[nextpoint].y]==1)&&
		    (map[idealpath[nextpoint].x][idealpath[nextpoint].y-1]==1)) return 1;
	else return 0;
}
int DetectA3(int direction){
	//detecting in EM
	//if there are obstacle  in the direction 
	//indicated by direction argument 
	//return true,otherwise return false
	switch(direction){
	case 1:
		if((map[CurrentPointInEM.x][CurrentPointInEM.y+1]==1))
		   return 1;
		else return 0;
	case 2:
		if((map[CurrentPointInEM.x+1][CurrentPointInEM.y]==1))
		   return 1;
		else return 0;
	case 3:
		if((map[CurrentPointInEM.x][CurrentPointInEM.y-1]==1))
		   return 1;
		else return 0;
	case 4:
		if((map[CurrentPointInEM.x-1][CurrentPointInEM.y]==1))
		   return 1;
		else return 0;
	default:
		return 2;
	}
}
/*
Manipulating EM.
*/
bool SetMap(DIRECTION direction,int x){
	if(x<0||x>4) return false;
	switch(direction){
	case 1:
		map[CurrentPointInEM.x][CurrentPointInEM.y+1]=x;
		break;
	case 2:
		map[CurrentPointInEM.x+1][CurrentPointInEM.y]=x;
		break;
	case 3:
		map[CurrentPointInEM.x][CurrentPointInEM.y-1]=x;
		break;
	case 4:
		map[CurrentPointInEM.x-1][CurrentPointInEM.y]=x;
		break;
	default:return false;
	}
	return true;
}
bool AdjustMap();
void ClearMap();
/*
Display Robot
*/
bool LoadRobotImage(cGraphicEngine &cg);
bool DisplayRobot();
bool RotatingAnimation(LPDIRECTDRAWSURFACE surface,bool clockwise);

bool SetActualPosition(int pixelx,int pixely){
	ActualPosition.x=pixelx;ActualPosition.y=pixely;
}
bool SetSurface(LPDIRECTDRAWSURFACE src){
	surface=src;
	return true;
}
int *GetMapPtr(){return (int *)&map;}
bool LoadRealMap(const char*filename);

private:
	bool Flag_reserved;
	int DifferenceOfRDandVD;
	int runflag;
    cBaseSprite robot_sprite;
	cBaseSprite rotating_sprite;
	cBaseSprite clean_floor;
	cTimer robot_timer;
    LPDIRECTDRAWSURFACE surface;

	int nLastXMovedTime;
//	int nLastXRotatedTime;
	int nSpeed;
public:	bool bPaused;
//	int nRotateFlag_phase;
private:	bool bMoveFlag_NewStart;
	int nMoveFlag_HasMoved20pixels;
	int nMoveFlag_HasMoved4pixels;
	bool bMoveFlag_Move20PixelsFinished;
	bool bMoveFlag_Move4PixelsFinished;
	bool bMoveFlag_NeedDetectEnvi;
	bool bMoveOutsideFlag_MoveFinished;
//	bool bMoveFlag_NeedDetectSide;
	POINT ActualPosition;//position on the surface
	int nSideMoveFlag_To;
	int nSideMoveFlag_Fro;
	int nSideMoveFlag_DirectionBackup;
	int nSideMoveFlag_bflag;
	int nSideMoveFlag_Direction;
//	bool bNeedSideMoving;
//	bool bSideMoving;
//	int nSideMovedNum;

	bool bMoveTo2Flag_start;
	int nMoveTo2Flag_phase;
    int nMoveTo2Flag_scheme;

	bool bMoveToFlag_start;
	int nMoveToFlag_curr;
	bool bMoveToFlag_seeObstacle;
	bool bMoveToFlag_temp;
	bool bMoveToFlag_temp1;
	bool bMoveToFlag_rotating;
	int nMoveToFlag_flag;
	bool bMoveToFlag_evaluated;

	bool bTFAFlag_to;
	bool bTFAFlag_fro;
	int nTFAFlag_phase;
	int nTFAFlag_j;
};
#endif
#define cb2(x) #x
#define cb(x) cb2(x)
#define cMsg(direct) message(__FILE__"("cb(__LINE__)"):"#direct)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -