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

📄 pathdoc.cpp

📁 本程序主要是设计了一个人工势能场机器人运动规划算法。并提出了一个新的斥力场函数。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// PathDoc.cpp : implementation of the CPathDoc class
//

#include "stdafx.h"
#include "Path.h"

#include "PathDoc.h"
#include "math.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CPathDoc

IMPLEMENT_DYNCREATE(CPathDoc, CDocument)

BEGIN_MESSAGE_MAP(CPathDoc, CDocument)
	//{{AFX_MSG_MAP(CPathDoc)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPathDoc construction/destruction

CPathDoc::CPathDoc()
{
	// TODO: add one-time construction code here
	memset(m_cBoard, 0, sizeof(m_cBoard));
	m_uBrushType = 0;
	m_Start.x = m_Start.y = -1;
	m_End.x = m_End.y = -1;

	m_cStart.x = m_cStart.y = -1;
	m_cNow = m_cStart;
	m_cEnd.x = m_cEnd.y = -1;
	m_bDrawRoute = false;

	m_cObsArray.RemoveAll();
	m_cPathArray.RemoveAll();
	m_cEndArray.RemoveAll();

	flagUp=flagDown=flagLeft=flagRight=true;
	flagLeftUp=flagRightDown=flagRightUp=flagLeftDown=true;
	//KillFlag = false;
}

CPathDoc::~CPathDoc()
{
}

BOOL CPathDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)
	memset(m_cBoard, 0, sizeof(m_cBoard));
	m_uBrushType = 0;
	m_cStart.x = m_cStart.y = -1;
	m_cNow = m_cStart;
	m_cEnd.x = m_cEnd.y = -1;
	m_bDrawRoute = false;

	m_cObsArray.RemoveAll();
	m_cPathArray.RemoveAll();
	m_cEndArray.RemoveAll();

	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CPathDoc serialization

void CPathDoc::Serialize(CArchive& ar)
{
	int x = MAP_BOARDX, y = MAP_BOARDY;
	if (ar.IsStoring())
	{
		ar << x;
		ar << y;
		ar << m_Start;
		ar << m_End;
		ar << m_cStart;
		ar << m_cEnd;

		for (int i=0; i<x; i++) {
			for (int j=0; j<y; j++) {
				ar << m_cBoard[i][j];
			}
		}
	}
	else
	{
		ar >> x;
		ar >> y;
		ar >> m_Start;
		ar >> m_End;
		ar >> m_cStart;
		ar >> m_cEnd;

		for (int i=0; i<x; i++) {
			for (int j=0; j<y; j++) {
				ar >> m_cBoard[i][j];
			}
		}
	}
}

/////////////////////////////////////////////////////////////////////////////
// CPathDoc diagnostics

#ifdef _DEBUG
void CPathDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CPathDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CPathDoc commands

//***** APF *****
bool CPathDoc::GetMapInfo()
//获取地图的相应点信息
{
	m_cObsArray.RemoveAll();
	m_cPathArray.RemoveAll();
	m_cEndArray.RemoveAll();
	//获得障碍节点坐标
	int i,j;
	for(i=0;i<MAP_BOARDX;i++)
		for(j=0;j<MAP_BOARDY;j++)
		{
			if(m_cBoard[i][j]==1)
			{
				CPoint pt = CPoint(i*MAP_GRIDSIZE+4,j*MAP_GRIDSIZE+4);
				m_cObsArray.Add(pt);
			}
		}
	//判断起始,终止节点
	if (m_Start.x == -1 || m_End.x == -1) {
		MessageBox("请确定已经设置了起始、终止节点!\n红色表示起点,蓝色表示终点.", "APF", MB_ICONERROR);
		return false;
	}
	//存储开始,目标点
	m_cStart.x=m_Start.x*MAP_GRIDSIZE+4;
	m_cStart.y=m_Start.y*MAP_GRIDSIZE+4;
	m_cNow=m_cStart;
	m_cEnd.x=m_End.x*MAP_GRIDSIZE+4;
	m_cEnd.y=m_End.y*MAP_GRIDSIZE+4;

	//记入相应点数组
	m_cPathArray.Add(m_cNow);
	m_cEndArray.Add(m_cEnd);

	return true;
}

float CPathDoc::ComDistance(CPoint x,CPoint y)
//计算距离
{
	float dx=(float)(y.x - x.x);
	float dy=(float)(y.y - x.y);
	float dis=(float)sqrt(dx*dx+dy*dy);
	return dis;
}

CVector CPathDoc::ComAngle(CPoint now,CPoint end)
//角度方向 now-->end
{
	CVector t;
	if(now.y==end.y && now.x<end.x)
	{
		t.SetX(1);//cos
		t.SetY(0);//sin
		return t;
	}
	if(now.y==end.y && now.x>end.x)
	{
		t.SetX(-1);//
		t.SetY(0);
		return t;
	}
	if(now.x==end.x && now.y>end.y)
	{
		t.SetX(0);//
		t.SetY(-1);
		return t;
	}
	if(now.x==end.x && now.y<end.y)
	{
		t.SetX(0);//
		t.SetY(1);
		return t;
	}
	//第四象限
	if(now.x<end.x && now.y>end.y)
	{
		float dis=ComDistance(now,end);
		float cos=abs(end.x-now.x)/dis;
		float sin=abs(end.y-now.y)/dis;
		t.SetX(cos);//
		t.SetY(-sin);
		return t;
	}
	//第三象限
	if(now.x>end.x && now.y>end.y)
	{
		float dis=ComDistance(now,end);
		float cos=abs(end.x-now.x)/dis;
		float sin=abs(end.y-now.y)/dis;
		t.SetX(-cos);//
		t.SetY(-sin);
		return t;
	}
	//第二象限
	if(now.x>end.x && now.y<end.y)
	{
		float dis=ComDistance(now,end);
		float cos=abs(end.x-now.x)/dis;
		float sin=abs(end.y-now.y)/dis;
		t.SetX(-cos);//
		t.SetY(sin);
		return t;
	}
	//第一象限
	if(now.x<end.x && now.y<end.y)
	{
		float dis=ComDistance(now,end);
		float cos=abs(end.x-now.x)/dis;
		float sin=abs(end.y-now.y)/dis;
		t.SetX(cos);
		t.SetY(sin);
		return t;
	}

	return CVector(0,0);
}

CVector CPathDoc::ComAttract(CPoint robot,CPoint goal, CVector v)
//goal是相对目标节点,robot是当前节点。向量方向 robot->goal
//v向量是力的方向,用来计算返回的向量 t 存储的X,Y轴的相应分力
{
	float dis=ComDistance(robot,goal);
	CVector t;
	t.SetX(K_ATTRACT*dis*v.GetX());//(系数*距离)*cos(X轴分量)
	t.SetY(K_ATTRACT*dis*v.GetY());//(系数*距离)*cos(Y轴分量)

	return t;
}

CVector CPathDoc::ComRepulsion(CPoint now,CPoint obs,CPoint goal,CVector vobs,CVector vgoal)
//now是当前节点,obs 是障碍节点,方向 obs->now
//vobs,vgoal 存储的是 cos,sin 的值,作为方向正余玄用
{	
	CVector t;
	float Rat,rat,Rre,rre;
	Rat=(goal.x-now.x)*(goal.x-now.x)+(goal.y-now.y)*(goal.y-now.y);
	rat=(float)sqrt(Rat);//与目标点距离
	Rre=(obs.x-now.x)*(obs.x-now.x)+(obs.y-now.y)*(obs.y-now.y);
	rre=(float)sqrt(Rre);//与障碍点距离

	CVector _obs,_goal;
	_obs.SetX(K_REPULSION*(1/rre-1/K_DISTANCE)*1/Rre*Rat*vobs.GetX());
	_obs.SetY(K_REPULSION*(1/rre-1/K_DISTANCE)*1/Rre*Rat*vobs.GetY());
	_goal.SetX(K_REPULSION*(1/rre-1/K_DISTANCE)*(1/rre-1/K_DISTANCE)*rat*vgoal.GetX());
	_goal.SetY(K_REPULSION*(1/rre-1/K_DISTANCE)*(1/rre-1/K_DISTANCE)*rat*vgoal.GetY());
	
	t=_obs+_goal;

	return t;
}

void CPathDoc::MoveToNext(CVector v)
//v 里储存当前节点的合力,可以计算出 cos ,sin
{
	CPoint pt=m_cEnd;
	//pt.x=pt.x*MAP_GRIDSIZE+4;
	//pt.y=pt.y*MAP_GRIDSIZE+4;

	if(ComDistance(m_cNow,pt)<=6)
	{
		m_cNow=pt;
		return;
	}
	float x=v.GetX();
	float y=v.GetY();
	float d=(float)sqrt(x*x+y*y);
	m_cNow.x=m_cNow.x+K_MOVE*x/d;//K_MOVE 移动步长
	m_cNow.y=m_cNow.y+K_MOVE*y/d;
}

bool CPathDoc::IsArrivalGoal()
{
	if(abs(m_cNow.x-m_cEnd.x)<3 && abs(m_cNow.y-m_cEnd.y)<3)
		return true;
	else return false;
}
//**********

void CPathDoc::MessageBox(CString title, CString caption, UINT type)
{
	AfxGetMainWnd()->MessageBox(title, caption, type);
}

//***** 设置中间牵引点 ******
void CPathDoc::CalculateLine1(CPoint now,CPoint end)
//水平或垂直的直线不在计算里面
{
	k1 = (float)(now.y - end.y)/(now.x - end.x);
	b1 = now.y - k1*now.x;
}

void CPathDoc::CheckAlongLine1(float k1,float b1,CPoint now,CPoint end,CPoint &middle)
{
	bool flag;
	if(end.x > now.x)
		flag=true;
	else
		flag=false;
	for(int ii=1;ii<20;ii++)
	{
		float px;
		if(flag)
			px = now.x + 6*ii;
		else
			px = now.x - 6*ii;
		float py = k1*px + b1;
		int i=px/MAP_GRIDSIZE;
		int j=py/MAP_GRIDSIZE;
		if(m_cBoard[i][j]==1)
		{
			middle.x = px;
			middle.y = k1*middle.x + b1;
			return;
		}
	}
}

void CPathDoc::CalculateLine2(CPoint middle,float k1)
{
	k2 = -1/k1;
	b2 = middle.y - k2*middle.x;
}

void CPathDoc::MyCalculateLine2(CPoint middle,float k1)
{
	k3 = -1/k1;
	b3 = middle.y - k3*middle.x;
}

void CPathDoc::CheckAlongLine2(float k2,float b2,CPoint middle,CPoint end,CPoint &newend)
{
	CPoint pt1,pt2;
	if(k2>0)
	//右上,左下
	{
		if(flagRightUp && !flagLeftDown)
		//右上无障碍
		{
			for(int ii=1;ii<40;ii++)
			{
				float px = middle.x + 6*ii;
				float py = k2*px + b2;
				int i=px/MAP_GRIDSIZE;
				int j=py/MAP_GRIDSIZE;
				for(int jj=0;jj<4;jj++)
				{
					if(m_cBoard[i][j+jj])
						jj=5;
					if(m_cBoard[i][j-jj])
						jj=5;
					if(m_cBoard[i+jj][j])
						jj=5;
					if(m_cBoard[i-jj][j])
						jj=5;
				}
				if(jj==4)
				{
					px=px+6;
					py=k2*px+b2;
					pt1 = CPoint(px,py);
					//pt1 = CPoint(px+6,k2*(px+6)+b2);
					ii = 40;
				}
			}
			newend = pt1;
			return;
		}
		if(!flagRightUp && flagLeftDown)
		//左下无障碍
		{
			for(int ii=1;ii<40;ii++)
			{
				float px = middle.x - 6*ii;
				float py = k2*px + b2;
				int i=px/MAP_GRIDSIZE;
				int j=py/MAP_GRIDSIZE;
				for(int jj=0;jj<4;jj++)
				{
					if(m_cBoard[i][j+jj])
						jj=5;
					if(m_cBoard[i][j-jj])
						jj=5;
					if(m_cBoard[i+jj][j])
						jj=5;
					if(m_cBoard[i-jj][j])
						jj=5;
				}
				if(jj==4)
				{
					px=px+6;
					py=k2*px+b2;
					newend = CPoint(px,py);
					ii = 40;
				}
			}
			return;
		}
		if(flagRightUp && flagLeftDown)
		//都无障碍
		{
			for(int ii=1;ii<40;ii++)
			{
				float px = middle.x + 6*ii;
				float py = k2*px + b2;
				int i=px/MAP_GRIDSIZE;
				int j=py/MAP_GRIDSIZE;
				for(int jj=0;jj<4;jj++)
				{
					if(m_cBoard[i][j+jj])
						jj=5;
					if(m_cBoard[i][j-jj])
						jj=5;
					if(m_cBoard[i+jj][j])
						jj=5;
					if(m_cBoard[i-jj][j])
						jj=5;
				}
				if(jj==4)
				{
					px=px+6;
					py=k2*px+b2;
					pt1 = CPoint(px,py);
					//pt1 = CPoint(px+6,k2*(px+6)+b2);
					ii = 40;
				}
			}

			for(ii=1;ii<40;ii++)
			{
				float px = middle.x - 6*ii;
				float py = k2*px + b2;
				int i=px/MAP_GRIDSIZE;
				int j=py/MAP_GRIDSIZE;
				for(int jj=0;jj<4;jj++)
				{
					if(m_cBoard[i][j+jj])
						jj=5;
					if(m_cBoard[i][j-jj])
						jj=5;
					if(m_cBoard[i+jj][j])
						jj=5;
					if(m_cBoard[i-jj][j])
						jj=5;
				}
				if(jj==4)
				{
					px=px;
					py=k2*px+b2;
					pt2 = CPoint(px,py);
					//pt2 = CPoint(px-6,k2*(px+6)+b2);
					ii = 40;
				}
			}

			//计算两个点与中间点的距离,取小的
			float ds1=ComDistance(pt1,middle);
			float ds2=ComDistance(pt2,middle);
			if(ds1<=ds2)
			{
				newend=pt1;
				return;
			}
			else
			{
				newend=pt2;
				return;
			}
		}
		if(!flagRightUp && !flagLeftDown)
		//都有障碍
		{
			CPoint pt1,pt2;
			for(int ii=0;ii<40;ii++)
			{
				float px = middle.x + 6*ii;
				float py = k2*px + b2;
				int i=px/MAP_GRIDSIZE;
				int j=py/MAP_GRIDSIZE;
				if(m_cBoard[i][j])
				{
					pt1 = CPoint(px,py);
					ii = 40;
				}
			}
			///
			for(ii=1;ii<40;ii++)
			{
				float px = middle.x + 6*ii;
				float py = k2*px + b2;
				int i=px/MAP_GRIDSIZE;
				int j=py/MAP_GRIDSIZE;
				for(int jj=1;jj<4;jj++)
				{
					if(m_cBoard[i][j+jj])
						jj=5;
					if(m_cBoard[i][j-jj])
						jj=5;
					if(m_cBoard[i+jj][j])
						jj=5;
					if(m_cBoard[i-jj][j])
						jj=5;
				}
				if(jj==4)
				{
					pt1 = CPoint(px,py);
					ii = 40;
				}
			}
			////////////////////

			for(ii=0;ii<40;ii++)
			{
				float px = middle.x - 6*ii;
				float py = k2*px + b2;
				int i=px/MAP_GRIDSIZE;
				int j=py/MAP_GRIDSIZE;
				if(m_cBoard[i][j])
				{
					pt2 = CPoint(px,py);
					ii = 40;
				}
			}
			//
			for(ii=1;ii<40;ii++)
			{
				float px = middle.x - 6*ii;
				float py = k2*px + b2;
				int i=px/MAP_GRIDSIZE;
				int j=py/MAP_GRIDSIZE;
				for(int jj=1;jj<4;jj++)
				{
					if(m_cBoard[i][j+jj])
						jj=5;
					if(m_cBoard[i][j-jj])
						jj=5;
					if(m_cBoard[i+jj][j])
						jj=5;
					if(m_cBoard[i-jj][j])
						jj=5;
				}
				if(jj==4)
				{
					pt2 = CPoint(px,py);
					ii = 40;
				}
			}
			///////////////////

			//计算两个点与中间点的距离,取小的
			float ds1,ds2;
			ds1=ComDistance(pt1,middle);
			ds2=ComDistance(pt2,middle);
			if(ds1<=ds2)
			{
				newend=pt1;			
			}
			else
			{
				newend=pt2;
			}
			return;
		}
	}
	if(k2<0)
	//左上,右下
	{
		if(!flagLeftUp && flagRightDown)
		//右下无障碍
		{
			for(int ii=1;ii<40;ii++)
			{
				float px = middle.x + 6*ii;
				float py = k2*px + b2;
				int i=px/MAP_GRIDSIZE;
				int j=py/MAP_GRIDSIZE;
				for(int jj=0;jj<4;jj++)
				{
					if(m_cBoard[i][j+jj])
						jj=5;
					if(m_cBoard[i][j-jj])
						jj=5;
					if(m_cBoard[i+jj][j])
						jj=5;
					if(m_cBoard[i-jj][j])
						jj=5;
				}
				if(jj==4)
				{
					px=px+6;
					py=k2*px+b2;
					newend = CPoint(px,py);
					ii = 40;
				}
			}
			return;
		}
		if(flagLeftUp && !flagRightDown)
		//左上无障碍
		{
			for(int ii=1;ii<40;ii++)
			{
				float px = middle.x - 6*ii;
				float py = k2*px + b2;
				int i=px/MAP_GRIDSIZE;
				int j=py/MAP_GRIDSIZE;
				for(int jj=0;jj<4;jj++)
				{
					if(m_cBoard[i][j+jj])
						jj=5;
					if(m_cBoard[i][j-jj])
						jj=5;
					if(m_cBoard[i+jj][j])
						jj=5;
					if(m_cBoard[i-jj][j])
						jj=5;
				}
				if(jj==4)
				{
					px=px+6;
					py=k2*px+b2;
					newend = CPoint(px,py);
					ii = 40;
				}
			}
			return;
		}
		if(flagLeftUp && flagRightDown)
		//都无障碍
		{
			for(int ii=1;ii<40;ii++)
			{
				float px = middle.x + 6*ii;
				float py = k2*px + b2;
				int i=px/MAP_GRIDSIZE;
				int j=py/MAP_GRIDSIZE;
				for(int jj=0;jj<4;jj++)
				{
					if(m_cBoard[i][j+jj])
						jj=5;
					if(m_cBoard[i][j-jj])
						jj=5;
					if(m_cBoard[i+jj][j])
						jj=5;
					if(m_cBoard[i-jj][j])
						jj=5;
				}
				if(jj==4)
				{
					px=px+6;
					py=k2*px+b2;
					pt1 = CPoint(px,py);
					//pt1 = CPoint(px+6,k2*(px+6)+b2);
					ii = 40;
				}
			}

			for(ii=1;ii<40;ii++)
			{
				float px = middle.x - 6*ii;
				float py = k2*px + b2;
				int i=px/MAP_GRIDSIZE;
				int j=py/MAP_GRIDSIZE;
				for(int jj=0;jj<4;jj++)
				{
					if(m_cBoard[i][j+jj])
						jj=5;
					if(m_cBoard[i][j-jj])
						jj=5;
					if(m_cBoard[i+jj][j])
						jj=5;
					if(m_cBoard[i-jj][j])
						jj=5;
				}
				if(jj==4)
				{
					px=px;
					py=k2*px+b2;
					pt2 = CPoint(px,py);
					//pt2 = CPoint(px-6,k2*(px+6)+b2);
					ii = 40;
				}
			}

			//计算两个点与中间点的距离,取小的
			float ds1=ComDistance(pt1,middle);
			float ds2=ComDistance(pt2,middle);
			if(ds1<=ds2)
			{
				newend=pt1;
				return;
			}
			else
			{
				newend=pt2;
				return;
			}
		}
		if(!flagLeftUp && !flagRightDown)
		//都有障碍
		{
			CPoint pt1,pt2;
			for(int ii=0;ii<40;ii++)
			{
				float px = middle.x + 6*ii;
				float py = k2*px + b2;
				int i=px/MAP_GRIDSIZE;
				int j=py/MAP_GRIDSIZE;
				if(m_cBoard[i][j])
				{
					pt1 = CPoint(px,py);
					ii = 40;
				}
			}
			///
			for(ii=1;ii<40;ii++)
			{
				float px = middle.x + 6*ii;
				float py = k2*px + b2;
				int i=px/MAP_GRIDSIZE;
				int j=py/MAP_GRIDSIZE;
				for(int jj=1;jj<4;jj++)
				{
					if(m_cBoard[i][j+jj])
						jj=5;
					if(m_cBoard[i][j-jj])
						jj=5;
					if(m_cBoard[i+jj][j])
						jj=5;
					if(m_cBoard[i-jj][j])
						jj=5;
				}
				if(jj==4)
				{
					pt1 = CPoint(px,py);
					ii = 40;
				}
			}
			////////////////////

			for(ii=0;ii<40;ii++)
			{
				float px = middle.x - 6*ii;
				float py = k2*px + b2;
				int i=px/MAP_GRIDSIZE;
				int j=py/MAP_GRIDSIZE;
				if(m_cBoard[i][j])
				{
					pt2 = CPoint(px,py);
					ii = 40;
				}
			}
			//
			for(ii=1;ii<40;ii++)
			{
				float px = middle.x - 6*ii;
				float py = k2*px + b2;
				int i=px/MAP_GRIDSIZE;
				int j=py/MAP_GRIDSIZE;
				for(int jj=1;jj<4;jj++)
				{
					if(m_cBoard[i][j+jj])
						jj=5;
					if(m_cBoard[i][j-jj])
						jj=5;
					if(m_cBoard[i+jj][j])

⌨️ 快捷键说明

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