radioview.cpp

来自「VC&Matlab混合编程实现无线电导航指示器」· C++ 代码 · 共 1,001 行 · 第 1/2 页

CPP
1,001
字号
/*
This project was created using the Top Studio AppWizard
Radio Navigation Simulator
Project: RADIO
Author : GPS Center
Date : 星期二, 三月 21, 2006
*/

// RADIOView.cpp : implementation of the CRADIOView class
//

#include "stdafx.h"
#include "RADIO.h"

#include "RADIODoc.h"
#include "RADIOView.h"
#include "TrajFileAccess.h"
#include "air.h"

#include "MainFrm.h"
#include "APPStatic.h"

#include "DialogAxisLimit.h"
#include "BeaconManage.h"


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

/////////////////////////////////////////////////////////////////////////////
// CRADIOView

IMPLEMENT_DYNCREATE(CRADIOView, CScrollView)

BEGIN_MESSAGE_MAP(CRADIOView, CScrollView)
	//{{AFX_MSG_MAP(CRADIOView)
	ON_WM_CREATE()
	ON_WM_TIMER()
	ON_COMMAND(ID_START, OnStart)
	ON_UPDATE_COMMAND_UI(ID_START, OnUpdateStart)
	ON_COMMAND(ID_STOP, OnStop)
	ON_UPDATE_COMMAND_UI(ID_STOP, OnUpdateStop)
	ON_COMMAND(ID_CHOOSECOLOR, OnChoosecolor)
	ON_WM_DRAWITEM()
	ON_WM_DESTROY()
	ON_UPDATE_COMMAND_UI(ID_ROTATE3D, OnUpdateRotate3d)
	ON_COMMAND(ID_ZOOM, OnZoom)
	ON_UPDATE_COMMAND_UI(ID_ZOOM, OnUpdateZoom)
	ON_COMMAND(ID_ROTATE2D, OnRotate2d)
	ON_UPDATE_COMMAND_UI(ID_ROTATE2D, OnUpdateRotate2d)
	ON_COMMAND(ID_AXISCOLOR, OnAxiscolor)
	ON_UPDATE_COMMAND_UI(ID_AXISCOLOR, OnUpdateAxiscolor)
	ON_UPDATE_COMMAND_UI(ID_AXISTYPE, OnUpdateAxistype)
	ON_COMMAND(ID_AXISAUTO, OnAxisauto)
	ON_COMMAND(ID_AXISEQUAL, OnAxisequal)
	ON_COMMAND(ID_AXISMANUAL, OnAxismanual)
	ON_COMMAND(ID_AXISNORMAL, OnAxisnormal)
	ON_COMMAND(ID_AXISON, OnAxison)
	ON_COMMAND(ID_AXISSQUARE, OnAxissquare)
	ON_COMMAND(ID_AXISTIGHT, OnAxistight)
	ON_COMMAND(ID_BOXON, OnBoxon)
	ON_COMMAND(ID_FIGURECOLOR, OnFigurecolor)
	ON_COMMAND(ID_XYZCOLOR, OnXyzcolor)
	ON_COMMAND(ID_AXISBACKCOLOR, OnAxisbackcolor)
	ON_COMMAND(ID_TRAJLINECOLOR, OnTrajlinecolor)
	ON_COMMAND(ID_GRID, OnGrid)
	ON_COMMAND(ID_AXISLIMIT, OnAxislimit)
	ON_COMMAND(ID_VIEW3D, OnView3d)
	ON_UPDATE_COMMAND_UI(ID_VIEW3D, OnUpdateView3d)
	ON_COMMAND(ID_TRACEPLANE, OnTraceplane)
	ON_UPDATE_COMMAND_UI(ID_TRACEPLANE, OnUpdateTraceplane)
	ON_COMMAND(ID_SETBEACON, OnSetbeacon)
	ON_COMMAND(ID_INITSTATE, OnInitstate)
	ON_UPDATE_COMMAND_UI(ID_INITSTATE, OnUpdateInitstate)
	ON_COMMAND(ID_ROTATE3D, OnRotate3d)
	ON_UPDATE_COMMAND_UI(ID_FILESETTING, OnUpdateFilesetting)
	ON_UPDATE_COMMAND_UI(ID_SETBEACON, OnUpdateSetbeacon)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRADIOView construction/destruction

CRADIOView::CRADIOView()
{
	m_nCurSheet=APPStatic::nFirstSheet;
	m_rectSheetOffset=CRect(2,8,2,2);//left,top,right,bottom
	m_bSimuStarted=FALSE;
	m_bIsRotating3D=FALSE;
	m_bIsZooming=FALSE;
	m_bIsMatlabFigureShowing=APPStatic::nFirstSheet==1?TRUE:FALSE;
	m_colorLineTrajColor=RGB(0,0,255);
	m_bTracePlane=TRUE;
	m_bInitState=FALSE;
	m_mwhBeacon=empty();

}

CRADIOView::~CRADIOView()
{
delete(m_pBeaconSimu);
}

BOOL CRADIOView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
	static LPCSTR className = NULL;
	
	if (className==NULL) {
		if (!CScrollView::PreCreateWindow(cs))
			return FALSE;
		
		WNDCLASS wndcls;
		::GetClassInfo(AfxGetInstanceHandle(), cs.lpszClass, &wndcls);
		wndcls.lpszClassName = MY_CLASSNAME;
		wndcls.hbrBackground = (HBRUSH) (COLOR_BTNFACE+1);
		VERIFY(AfxRegisterClass(&wndcls));
		className=MY_CLASSNAME;
	}
	cs.lpszClass = className;
	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CRADIOView drawing

void CRADIOView::OnDraw(CDC* pDC)
{
	CRADIODoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here

}

/////////////////////////////////////////////////////////////////////////////
// CRADIOView printing

BOOL CRADIOView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CRADIOView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CRADIOView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CRADIOView diagnostics

#ifdef _DEBUG
void CRADIOView::AssertValid() const
{
	CScrollView::AssertValid();
}

void CRADIOView::Dump(CDumpContext& dc) const
{
	CScrollView::Dump(dc);
}

CRADIODoc* CRADIOView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CRADIODoc)));
	return (CRADIODoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CRADIOView message handlers

int CRADIOView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CScrollView::OnCreate(lpCreateStruct) == -1)
		return -1;
    //TABSHEET的ImageList
	m_imageListTabSheets.Create(124,20,ILC_COLOR16,2,1);
	CBitmap bitmap1;bitmap1.LoadBitmap(IDB_BITMAPSHEET1);
	CBitmap bitmap2;bitmap2.LoadBitmap(IDB_BITMAPSHEET2);
	m_imageListTabSheets.Add(&bitmap1,RGB(0,0,0));
    m_imageListTabSheets.Add(&bitmap2,RGB(0,0,0));
    //创建TABSHEET
	m_tabSheet.Create(WS_CHILD|WS_VISIBLE|TCS_OWNERDRAWFIXED|TCS_FIXEDWIDTH|TCS_FOCUSNEVER ,CRect(0,0,0,0),this,IDS_SHEET);//TCS_OWNERDRAWFIXED指示Tab由父窗口画,WM_DRAWITEM
	m_tabSheet.SetItemSize(CSize(130,24));
	m_tabSheet.AddPage("",&m_dlgSheet1,IDD_SHEET1);
	m_tabSheet.AddPage("",&m_dlgSheet2,IDD_SHEET2);
	SetCurSheetRect(m_nCurSheet);
	m_tabSheet.MoveWindow(&m_rectCurSheet,TRUE);
	m_tabSheet.Show();	
	m_tabSheet.SetCurSel(m_nCurSheet);	
	//取得几个表盘
	m_pAirAttitude=(CAir*)m_dlgSheet1.GetDlgItem(IDC_AIRATTITUDE);
	m_pAirAlt=(CAir*)m_dlgSheet1.GetDlgItem(IDC_AIRALT);
	m_pAirSpeed=(CAir*)m_dlgSheet1.GetDlgItem(IDC_AIRSPEED);
	m_pAirRms=(CAir*)m_dlgSheet1.GetDlgItem(IDC_AIRRMS);
	//初始化matlab窗口,这时千万不能让其可见,用了定时器让它可见。
	GenAxis();
	CWnd * pWndMatlabFrame=m_dlgSheet2.GetDlgItem(IDC_MATLABFRAME);
	DockMatlabFigure(m_mwhFigure,pWndMatlabFrame);
	mlfHGWaitForFiguresToDie();
	//生成Plane
	mwArray ver=transpose(vertcat(horzcat(-.6,.4,-.5,-.6,-.6,.4),
								  horzcat(0,0,0,0,0,0),
								  horzcat(0,0,.1,.25,0,.03)));
	mwArray p1,p2,p3;
	p1=patch("visible","off","vertices",ver,"faces",horzcat(1,2,6,3,4,5),"edgecolor",horzcat(.3,0,1),
		"facecolor",horzcat(1,1,0),"linewidth",2,"parent",m_mwhAxis);
	
	mwArray x2=horzcat(-.2,-.1,0,-.1,-.2,-.2)+mwArray(.1);
	mwArray y2=horzcat(-.5,-.5,0,.5,.5,-.5);
	mwArray z2=horzcat(-.005,-.005,-.005,-.005,-.005,-.005);
	p2=patch("visible","off","xdata",x2,"ydata",y2,"zdata",z2,"parent",m_mwhAxis,"linewidth",1,"edgecolor",
		horzcat(.3,0,1),"facecolor",horzcat(1,.1,.1));
	p3=patch("visible","off","xdata",(x2-1.1)/2,"ydata",y2/2,"parent",m_mwhAxis,"linewidth",1,"edgecolor",horzcat(0.3,0,1),"facecolor",horzcat(1,0,0));
	m_traj3dShow.m_plane.SetParent(m_mwhAxis);
	m_traj3dShow.m_plane.AddPatchElement(p1);
	m_traj3dShow.m_plane.AddPatchElement(p2);
    m_traj3dShow.m_plane.AddPatchElement(p3);

  	//预读beacon.cfg
    CString strName=_T("beacon.cfg");
	CFileException fileExcep;
	CFile fileBeaconConfig;
	fileBeaconConfig.Open(strName, CFile::modeRead,&fileExcep );
	if(fileExcep.m_cause!=CFileException::none)	
	{  //fileExcep.ReportError();
	    return 1;
	}
	TRY{
	CArchive ar( &fileBeaconConfig, CArchive::load);
	m_beaconManage.Serialize(ar);
	}
	CATCH(CException,e){
		//e->ReportError();
		return 1;
	}
 	END_CATCH
	//-------------------------
	return 0;
}


void CRADIOView::OnInitialUpdate() 
{
	CScrollView::OnInitialUpdate();	
	
	CSize &size=GetDocument()->arraySheetSizes[m_nCurSheet];
    //设置滚动范围
	SetScrollSizes(MM_TEXT, size);
		//初始化信标仿真对象
	m_pBeaconSimu=new CBeaconSimu(&m_beaconManage);
    //搞掉GMS的弹出对话框
	//放在构造或precreatewindow里都不行,窗口还没创建,GMS还没出现怎么搞呢。	
	SetTimer(ID_TIMER_KILLGMS,5,NULL);


}

void CRADIOView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
{
	// TODO: Add your specialized code here and/or call the base class
}

CRect CRADIOView::Size2Rect(const CSize& size)
{
	return CRect(0,0,size.cx,size.cy);
}


void CRADIOView::OnTimer(UINT nIDEvent) 
{
	//ID_TIMER_RADIOFILE的变量
	BYTE byteCheck;
	//----------------------------
	switch(nIDEvent){
	case ID_TIMER_KILLGMS://搞掉GMS注册窗口
		HWND hwndGMS;
		hwndGMS=::FindWindow(TEXT("#32770"),TEXT("About Aircraft Instruments Control"));
		if (hwndGMS){				
			::SendMessage(hwndGMS,WM_COMMAND,1,0);//相当于按了OK
			KillTimer(ID_TIMER_KILLGMS);
			GetDocument()->UpdateAllViews(NULL);
		}
		//使matlab窗口可见;
		MakeMatlabFiguresVisible();

        break;
	case ID_TIMER_SIMU://仿真定时
       	APPStatic::app_dSimuTime+=APPStatic::app_lTimeEllapse/1000.0;
		if(m_fileAccess.RefreshCurrentPackageByTime(APPStatic::app_dSimuTime)==FALSE){
			OnStop();
			return;
		}
		RefreshMeters();
		((CMainFrame*)(AfxGetApp()->m_pMainWnd))->m_wndTimeToolBar.SetPaintInfo(APPStatic::Time2String(APPStatic::app_dSimuTime));
        ((CMainFrame*)(AfxGetApp()->m_pMainWnd))->m_wndTimeToolBar.Paint();
		m_traj3dShow.RefreshTraj();
		break;
	case ID_TIMER_DIS://Radio量测定时
        m_pBeaconSimu->RefreshMeasure();
		m_beaconManage.DrawBeacon(m_mwhAxis);
		break;
	case ID_TIMER_RADIOFILE:
		m_dRadioFileTime+=1.0/(GetDocument()->m_dRadioFreq);//?
		if(m_beaconManage.IsBeaconAvailable()){
			byteCheck=1;
			(*m_pBeaconSimu->m_pArRadio)<<APPStatic::app_dSimuTime<<byteCheck<<m_beaconManage.m_iAvailableBCIndex<<
				m_pBeaconSimu->m_dDisMeasure<<m_pBeaconSimu->m_dAzMeasure;
		}
		else{
            byteCheck=0;
			(*m_pBeaconSimu->m_pArRadio)<<m_dRadioFileTime<<byteCheck;
		}
		
	default:;
	}
	CScrollView::OnTimer(nIDEvent);
}


void CRADIOView::RefreshCurSheet(int nSheet)

{	m_nCurSheet=nSheet;
	
	SetCurSheetRect(nSheet);
	m_tabSheet.MoveWindow(&m_rectCurSheet,TRUE);
	m_tabSheet.RefreshShow();//不调用则子窗口不能被刷新。
	RefreshScroll(nSheet);
}

void CRADIOView::SetCurSheetRect(int nSheet)
{CSize size=GetDocument()->arraySheetSizes[nSheet];
CRect rect=Size2Rect(size);
m_rectCurSheet=CRect(rect.left+m_rectSheetOffset.left,rect.top+m_rectSheetOffset.top,rect.right-m_rectSheetOffset.right,rect.bottom-m_rectSheetOffset.bottom);

}

void CRADIOView::RefreshScroll(int nSheet)
{CSize size=GetDocument()->arraySheetSizes[nSheet];
SetScrollSizes(MM_TEXT,size);
}

void CRADIOView::OnStart() 
{
	m_bSimuStarted=TRUE;
	if(!m_bInitState) OnInitstate();
	APPStatic::app_dSimuTime=0.0;//仿真时间,就是航迹的真实时间
	m_dRadioFileTime=0.0;
	if(m_fileAccess.InitializeFileAccess(GetDocument()->m_strTrajFileName.GetBuffer(0))==FALSE)
	{OnStop();
	return;}		
	RefreshMeters();
	m_traj3dShow.Init3DShow(m_fileAccess.GetCurrentPackageData().lon,m_fileAccess.GetCurrentPackageData().lat,m_fileAccess.GetCurrentPackageData().heg);
    SetTimer(ID_TIMER_SIMU,APPStatic::app_lTimeEllapse,NULL);
    ((CMainFrame*)(AfxGetApp()->m_pMainWnd))->m_wndStateToolBar.SetPaintInfo(APPStatic::strOnSimu);
    ((CMainFrame*)(AfxGetApp()->m_pMainWnd))->m_wndStateToolBar.Paint();
	//运行时不能zoom
	OnZoom();
	//量测定时
	SetTimer(ID_TIMER_DIS,(UINT)(1000.0/m_beaconManage.m_dFreq),NULL);
	//文件采样定时
	SetTimer(ID_TIMER_RADIOFILE ,(UINT)(1000.0/(GetDocument()->m_dRadioFreq)),NULL);
	//
	//打开RAdio.dat读
	CString strName=GetDocument()->m_strRadioFilePath+_T("\\")+GetDocument()->m_strRadioFileNameWithoutPath;
	CFileException fileExcep;
	m_pBeaconSimu->m_pFileRadio=new CFile();
	m_pBeaconSimu->m_pFileRadio->Open(strName, CFile::modeCreate|CFile::modeWrite,&fileExcep );
	if(fileExcep.m_cause!=CFileException::none)	
	{  fileExcep.ReportError();
	    return ;
 	}
	TRY{
		m_pBeaconSimu->m_pArRadio=new CArchive(m_pBeaconSimu->m_pFileRadio,CArchive::store);
	}
	CATCH(CException,e){
		e->ReportError();
		return ;
	}
 	END_CATCH
	


}

void CRADIOView::OnUpdateStart(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if(m_bSimuStarted){
		pCmdUI->Enable(FALSE);}
	else{
        pCmdUI->Enable();
	}	
}

void CRADIOView::OnStop() 
{  

	m_bSimuStarted=FALSE;
    KillTimer(ID_TIMER_SIMU);	
	KillTimer(ID_TIMER_DIS);
	KillTimer(ID_TIMER_RADIOFILE); 
    m_fileAccess.EndFileAccess();
	((CMainFrame*)(AfxGetApp()->m_pMainWnd))->m_wndStateToolBar.SetPaintInfo(APPStatic::strStopSimu);
    ((CMainFrame*)(AfxGetApp()->m_pMainWnd))->m_wndStateToolBar.Paint();
	m_beaconManage.m_bIsBeaconAvailable=FALSE;
	m_dlgSheet1.UpdateData(FALSE);
	m_dlgSheet2.UpdateData(FALSE);
	if(m_pBeaconSimu->m_pArRadio){
		m_pBeaconSimu->m_pArRadio->Close();
		delete(m_pBeaconSimu->m_pArRadio);
	}
	if(m_pBeaconSimu->m_pFileRadio){
		m_pBeaconSimu->m_pFileRadio->Close();	
		delete(m_pBeaconSimu->m_pFileRadio);
	}

	m_pBeaconSimu->m_dDisMeasure=0.0;
	m_pBeaconSimu->m_dAzMeasure=0.0;

}

void CRADIOView::OnUpdateStop(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if(m_bSimuStarted){
		pCmdUI->Enable();}
	else{
        pCmdUI->Enable(FALSE);
	}	
}

void CRADIOView::RefreshAirPointer()
{//表盘ActiveX控制对象指针是变化的,所以要Refresh!
	m_pAirAttitude=(CAir*)m_dlgSheet1.GetDlgItem(IDC_AIRATTITUDE);
	m_pAirAlt=(CAir*)m_dlgSheet1.GetDlgItem(IDC_AIRALT);
	m_pAirSpeed=(CAir*)m_dlgSheet1.GetDlgItem(IDC_AIRSPEED);
	m_pAirRms=(CAir*)m_dlgSheet1.GetDlgItem(IDC_AIRRMS);
}

void CRADIOView::RefreshMeters()
{
	//指针抖动,看起来更真实一点
	mwArray mwRnd;
    double dRnd;
	mwRnd=randn(1);
	dRnd=mwRnd.ExtractScalar(1);
	double dAltDither=3;
	double dSpeedDither=2;
	double dAttitudeDither=.2;
    //下面开始刷新表盘
	RefreshAirPointer();
	TRAJ traj=m_fileAccess.GetCurrentPackageData();	
	//Altitude
	m_pAirAlt->SetAltitude(traj.heg+dAltDither*dRnd);
	//GroundSpeed
	double dSpeed=sqrt(traj.vene*traj.vene+traj.venu*traj.venu+traj.venn*traj.venn);
	m_pAirSpeed->SetAirspeed(dSpeed+dSpeedDither*dRnd);
    //Pitch
	m_pAirAttitude->SetAHPitch(traj.pitch+dAttitudeDither*dRnd);
	//Roll
    m_pAirAttitude->SetAHRoll(-traj.roll+dAttitudeDither*dRnd);
	//Yaw(Real North Heading)
	m_pAirAttitude->SetAHHeading(traj.yaw+dAttitudeDither*dRnd);
	//Magnetic North Heading
	m_pAirRms->SetRMICompass(traj.yaw-APPStatic::app_dMagneticErrorAngle+dAttitudeDither*dRnd);
	//Beacon to Plane Bearing
    m_pAirRms->SetRMIBearing1(m_pBeaconSimu->m_dAzMeasure+1*dRnd);
    //下面开始刷新Sheet1的Static控件
	CString str;
	str.Format("%6.3lf",traj.heg);
	m_dlgSheet1.m_strAlt=str;
	str.Format("%6.3lf",traj.pitch);
	m_dlgSheet1.m_strPitch=str;
	str.Format("%6.3lf",traj.roll);
	m_dlgSheet1.m_strRoll=str;
	str.Format("%6.3lf",traj.yaw);
	m_dlgSheet1.m_strYaw=str;
	str.Format("%6.3lf",dSpeed);
	m_dlgSheet1.m_strSpeed=str;
	str.Format("%6.3lf",traj.yaw-APPStatic::app_dMagneticErrorAngle);
	m_dlgSheet1.m_strMagNorth=str;
	m_dlgSheet1.UpdateData(FALSE);
}


void CRADIOView::OnChoosecolor() 

⌨️ 快捷键说明

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