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

📄 followlinedlg.cpp

📁 智能小车导航
💻 CPP
字号:
// FollowLineDlg.cpp : implementation file
//

#include "stdafx.h"
#include "FollowLine.h"
#include "FollowLineDlg.h"
#include "robotapi.h"

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

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFollowLineDlg dialog

CFollowLineDlg::CFollowLineDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CFollowLineDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CFollowLineDlg)
	m_Ultra_Left = 0.0f;
	m_Ultra_Left45 = 0.0f;
	m_Ultra_LeftBack = 0.0f;
	m_Ultra_LeftFront = 0.0f;
	m_Ultra_Right = 0.0f;
	m_Ultra_Right45 = 0.0f;
	m_Ultra_RightBack = 0.0f;
	m_Ultra_RightFront = 0.0f;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CFollowLineDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CFollowLineDlg)
	DDX_Text(pDX, IDC_EDIT_LEFT, m_Ultra_Left);
	DDX_Text(pDX, IDC_EDIT_LEFT_45, m_Ultra_Left45);
	DDX_Text(pDX, IDC_EDIT_LEFT_BACK, m_Ultra_LeftBack);
	DDX_Text(pDX, IDC_EDIT_LEFT_FRONT, m_Ultra_LeftFront);
	DDX_Text(pDX, IDC_EDIT_RIGHT, m_Ultra_Right);
	DDX_Text(pDX, IDC_EDIT_RIGHT_45, m_Ultra_Right45);
	DDX_Text(pDX, IDC_EDIT_RIGHT_BACK, m_Ultra_RightBack);
	DDX_Text(pDX, IDC_EDIT_RIGHT_FRONT, m_Ultra_RightFront);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CFollowLineDlg, CDialog)
	//{{AFX_MSG_MAP(CFollowLineDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_TIMER()
	ON_BN_CLICKED(ID_START, OnStart)
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFollowLineDlg message handlers

BOOL CFollowLineDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	m_Infra_FrontLeft=false;
	m_Infra_FrontMid=false;
	m_Infra_FrontRight=false;
	m_Infra_Left45=false;
	m_Infra_Right45=false;
	m_Infra_LeftFront=false;
	m_Infra_LeftBack=false;
	m_Infra_RightFront=false;
	m_Infra_RightBack=false;	
	m_Infra_BackLeft=false;
	m_Infra_BackMid=false;
	m_Infra_BackRight=false;	
	m_Infra_FrontLong=false;
	m_Infra_BackLong=false;
	m_Infra_RightLong=false;
	m_Infra_LeftLong=false;
	m_Infra_Left45Long=false;
	m_Infra_Right45Long=false;

	m_bExecuting=false;
//added
	m_pResImage=NULL;
//
	SetControlPos();		
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CFollowLineDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CFollowLineDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CFollowLineDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CFollowLineDlg::SetControlPos()
{	
	CRect rc;
	GetClientRect(&rc);
	
	CStatic *pST;
	CButton *pBut;
	CEdit *pEdit;
	
	pST=(CStatic *)GetDlgItem(IDC_STATIC_IMAGE);
	pST->SetWindowPos(NULL,rc.Width()/2-165,rc.Height()/2-155,330,250,SWP_SHOWWINDOW);
	m_rcOrignImage.SetRect(rc.Width()/2-160,rc.Height()/2-150,rc.Width()/2+160,rc.Height()/2+100);
	pEdit=(CEdit *)GetDlgItem(IDC_EDIT_LEFT_FRONT);
	pEdit->SetWindowPos(NULL,rc.Width()/2-100,rc.Height()/2-180,60,20,SWP_SHOWWINDOW);
	pEdit=(CEdit *)GetDlgItem(IDC_EDIT_RIGHT_FRONT);
	pEdit->SetWindowPos(NULL,rc.Width()/2+40,rc.Height()/2-180,60,20,SWP_SHOWWINDOW);
	pEdit=(CEdit *)GetDlgItem(IDC_EDIT_LEFT_45);
	pEdit->SetWindowPos(NULL,rc.Width()/2-230,rc.Height()/2-150,60,20,SWP_SHOWWINDOW);
	pEdit=(CEdit *)GetDlgItem(IDC_EDIT_RIGHT_45);
	pEdit->SetWindowPos(NULL,rc.Width()/2+170,rc.Height()/2-150,60,20,SWP_SHOWWINDOW);
	pEdit=(CEdit *)GetDlgItem(IDC_EDIT_LEFT);
	pEdit->SetWindowPos(NULL,rc.Width()/2-230,rc.Height()/2-50,60,20,SWP_SHOWWINDOW);
	pEdit=(CEdit *)GetDlgItem(IDC_EDIT_RIGHT);
	pEdit->SetWindowPos(NULL,rc.Width()/2+170,rc.Height()/2-50,60,20,SWP_SHOWWINDOW);
	pEdit=(CEdit *)GetDlgItem(IDC_EDIT_LEFT_BACK);
	pEdit->SetWindowPos(NULL,rc.Width()/2-100,rc.Height()/2+100,60,20,SWP_SHOWWINDOW);
	pEdit=(CEdit *)GetDlgItem(IDC_EDIT_RIGHT_BACK);
	pEdit->SetWindowPos(NULL,rc.Width()/2+40,rc.Height()/2+100,60,20,SWP_SHOWWINDOW);
	pBut=(CButton *)GetDlgItem(ID_START);
	pBut->SetWindowPos(NULL,rc.left+90,rc.bottom-50,140,25,SWP_SHOWWINDOW);
	pBut=(CButton *)GetDlgItem(IDOK);
	pBut->SetWindowPos(NULL,rc.right-230,rc.bottom-50,140,25,SWP_SHOWWINDOW);

}

void CFollowLineDlg::OnTimer(UINT nIDEvent) 
{	
	CDialog::OnTimer(nIDEvent);

	UpdateData(FALSE);

	float minFront=500.00;

	if((m_Ultra_RightFront!=0)&&(minFront>m_Ultra_RightFront))
		minFront=m_Ultra_RightFront;
	if((m_Ultra_LeftFront!=0)&&(minFront>m_Ultra_LeftFront))
		minFront=m_Ultra_LeftFront;

	if(minFront<80)
	{
		pid.ClearHistory();
		if((m_Ultra_Left>0)&&(m_Ultra_Right>0)&&(m_Ultra_Right<m_Ultra_Left))//左转
			Drive_Rotate_Position(-10,20);
		else if((m_Ultra_Left>0)&&(m_Ultra_Right>0)&&(m_Ultra_Right>=m_Ultra_Left))//右转
			Drive_Rotate_Position(10,20);
		else if((m_Ultra_Left>0)&&(m_Ultra_Right==0))//右转
			Drive_Rotate_Position(10,20);
		else if((m_Ultra_Left==0)&&(m_Ultra_Right>0))//左转
			Drive_Rotate_Position(-10,20);
		else
			Drive_Rotate_Position(-10,20);		
	}
	else
	{
		CDC *pDC;
		pDC=GetDC();
		m_ImageManager.SnapOneToMem(1);

//{{ modified
		m_ImageManager.RobertOperator(m_pOrignImage,m_pResImage,320,240);
		m_ImageManager.Binary(m_pResImage,80,320,240);
		m_ImageManager.FindLine(m_pResImage,320,240);
		
		CString strTemp;
		strTemp.Format("角度:%d,速度:%.2f",m_ImageManager.g_phei,m_ImageManager.g_v);
		pDC->TextOut(0,0,strTemp);
// P控制
//		Drive_Velocity(m_ImageManager.g_phei,m_ImageManager.g_v);
		
// PID控制
		
		Drive_Velocity((short)pid.pid_calc(m_ImageManager.g_phei), m_ImageManager.g_v);
		
		m_ImageManager.ShowImage(pDC->m_hDC,m_rcOrignImage,320,240,m_pResImage);
		ReleaseDC(pDC);	
// modified}}
		
	}
	
}

//传感器信息采集线程
DWORD WINAPI SensorQueryThread(LPVOID pParam)  // 控制函数定义线程。输入此函数后线程开始,此函数退出时线程终止。
                                              // 此函数的原型应为:UINT MyControllingFunction( LPVOID pParam );

{	
	CFollowLineDlg *pView;
	pView=(CFollowLineDlg *)pParam;
	ROBOT_SENSOR_INFO *pSensorInfo;		
	
	while(pView->m_bExecuting)
	{
		pSensorInfo=QueryAllSensorData();
		if(pSensorInfo!=NULL)
		{		
			pView->m_Ultra_LeftFront=pSensorInfo->m_UltrasonicData.m_approach4;
			pView->m_Ultra_RightFront=pSensorInfo->m_UltrasonicData.m_approach5;
			pView->m_Ultra_Left45=pSensorInfo->m_UltrasonicData.m_approach3;
			pView->m_Ultra_Right45=pSensorInfo->m_UltrasonicData.m_approach6;
			pView->m_Ultra_Left=pSensorInfo->m_UltrasonicData.m_approach2;
			pView->m_Ultra_Right=pSensorInfo->m_UltrasonicData.m_approach7;
			pView->m_Ultra_LeftBack=pSensorInfo->m_UltrasonicData.m_approach1;
			pView->m_Ultra_RightBack=pSensorInfo->m_UltrasonicData.m_approach8;			
		}
		Sleep(60);
	}
	

	return 1;
}

void CFollowLineDlg::OnStart() 
{
	if(RobotInitial(2,3)!=ROBOT_NO_ERROR)
	{		
		AfxMessageBox("机器人初始化失败!");
		return;
	}

	m_ImageManager.InitCardsProperty();	
	if(m_ImageManager.OpenCard(1)==TRUE)
	{	
		m_ImageManager.SetInputViewSize(1,768,576);
		m_ImageManager.SetOutImageSize(320,240,320,240,320,240,320,240);		
		m_ImageManager.UpdateCardAttribute(1,ATTR_ALL);
		m_ImageManager.BeginCapture(1);
		m_ImageManager.SetOutImageMem(1);
		m_pOrignImage=m_ImageManager.m_CardMemState.m_pucOutputImage_Card1;

		//added
		if(m_pResImage==NULL)
		{
			m_hResImage=GlobalAlloc(GMEM_FIXED,320*240*3);
			m_pResImage=(BYTE *)GlobalLock(m_hResImage);
		}
		//
		
	}
	else
	{		
		AfxMessageBox("图像采集初始化失败!");
		return;
	}
//	m_imManager.g_phei=0;
//	m_imManager.g_v=0;
	m_bExecuting=true;

// MFC 应用程序中的所有线程都由 CWinThread 对象表示。大多数情况下,甚至不必显式创建这些对象,
// 而只需调用框架 Helper 函数 AfxBeginThread,该函数将为您创建 CWinThread 对象。
//  启动辅助线程
//	AfxBeginThread 有两个重载版本:一个用于用户界面线程,一个用于辅助线程。
//  若要开始执行辅助线程,请调用 AfxBeginThread 提供下列信息: 
//        控制函数的地址。 
//        要传递到控制函数的参数。 
//       (可选)所需的线程优先级。默认值为正常优先级。有关可用的优先级级别的更多信息,请参见 Platform SDK 中的 SetThreadPriority。

//对于辅助线程,正常线程终止很简单:退出控制函数并返回表示终止原因的值。
//可以使用 AfxEndThread 函数或 return 语句。一般情况下,0 表示成功完成,但这取决于您自己。
//过早终止线程几乎一样简单:从线程内调用 AfxEndThread。将所需的退出代码作为唯一参数传递。
//这将停止执行线程、解除对线程堆栈的分配、分离附加到线程的所有 DLL 并从内存中删除线程对象。
//必须从要终止的线程内调用 AfxEndThread。如果要从其他线程终止线程,必须设置两个线程间的通信方法。
	
	m_pSensorThread=AfxBeginThread((AFX_THREADPROC)SensorQueryThread,this,THREAD_PRIORITY_NORMAL);	

//设置pid参数	
	pid.pid_tune();

	SetTimer(1,30,NULL);
}

void CFollowLineDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	
	KillTimer(1);

	//added
	if(m_pResImage!=NULL)
	{
		GlobalUnlock(m_hResImage);
		GlobalFree(m_hResImage);
		
	}
	//
	
	if(m_bExecuting)
	{
		m_bExecuting=false;
		m_ImageManager.StopCapture(1);
		m_ImageManager.FreeOutImageMem(1);	
		m_ImageManager.CloseCard(1);
	}	
}












































⌨️ 快捷键说明

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