AUV.h
// AUV.h: interface for the AUV class. //
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_AUV_H__A94C101D_1411_414B_B132_C46D65228BAB__INCLUDED_) #define AFX_AUV_H__A94C101D_1411_414B_B132_C46D65228BAB__INCLUDED_
#include "morectangle.h" // Added by ClassView #if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class AUV {
//private internal variables
double m_lastDx, m_lastDy, m_lastDth;
bool m_computeShapeWhenMove, m_computeSSSshapeWhenMove; //always trues
public:
//pubblic internal variables CMoPoint m_center; double m_orientation; CMoPolygon m_shape, m_SSSshape; double m_scale;
bool m_visible, m_SSSvisible;
//pubblic parameters from DataBase double m_length, m_width;
double m_SSSfrequency, m_SSSband, m_SSSlength, m_SSSlobes; double m_SSSrange, m_SSSswath;
double m_navigationPrecision; double m_autonomy;
//pubblic member functions AUV();
double Get_dY(); double Get_dR();
double GetMaxVelocity(); void Rotate(double dth);
void Traslate(double dx, double dy); void ComputeShape();
void ComputeSSSshape(); CMoRectangle GetExtent(); virtual ~AUV();
private:
//private member functions
void ComputeSSSshape(double dx, double dy); void ComputeSSSshape(double dth);
};
Lawnmower.h
// LawnMower.h: interface for the LawnMower class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_LAWNMOWER_H__0332EFB0_13F1_487F_88AC_4436DA9134CE__INCLUDED_) #define AFX_LAWNMOWER_H__0332EFB0_13F1_487F_88AC_4436DA9134CE__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class LawnMower {
enum Direction {NORTH, SOUTH, EAST, WEST}; Direction currentDirection;
Direction lineCross, lineForward, lineBackward; bool scanIsOn;
bool onMySide; int linesToDo;
double areaWidth, areaLength; double residualDistance, outOfSwath; double rg, sw, maxStep;
enum State {BEGIN, LINEFORWARD, LINEBACKWARD, LINECROSS, GOSTRAIGHT}; State currentState, nextState;
void GoStraight(double distanceToDo, Direction directionToFollow, double& xStep, double& yStep);
public:
LawnMower();
LawnMower(double initialX, double initialY, double centralX, double centralY); //LawnMower(double initialX, double initialY, double centralX, double centralY, // double range, double swath, double precision, double maxStepSize);
void SetVehicleParam(double range, double swath, double precision, double maxStepSize); bool Step(double& xStep, double& yStep, bool& scanning, bool& missionAccomplished); virtual ~LawnMower();
};
WaypointsPath.h
// WaypointsPath.h: interface for the WaypointsPath class. // ////////////////////////////////////////////////////////////////////// #include "AUV.h" #if !defined(AFX_WAYPOINTSPATH_H__E91BA542_CAB2_4DE5_A446_70FEB502A398__INCLUDED_) #define AFX_WAYPOINTSPATH_H__E91BA542_CAB2_4DE5_A446_70FEB502A398__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class WaypointsPath {
enum {ROTATION, TRASLATION} m_state; CMoPoint m_nextWaypoint;
VARIANT m_vaIndex; public:
WaypointsPath();
void ComputeStep(AUV* pAUV, double maxTraslStep, double maxRotStep, double& xOffset, double& yOffset);
void SetPath(CMoLine* pPath); CMoLine* m_pPath; CMoPoints* m_pWaypoints; bool m_finish; virtual ~WaypointsPath(); private: void ComputeNextWaypoint(); }; #endif // !defined(AFX_WAYPOINTSPATH_H__E91BA542_CAB2_4DE5_A446_70FEB502A398__INCLUDED_)
VeicoliView.h
// VeicoliView.h : interface of the CVeicoliView class //
///////////////////////////////////////////////////////////////////////////// //{{AFX_INCLUDES()
#include "WaypointsPath.h" // Added by ClassView #include "AUV.h" // Added by ClassView
#include "morecordset.h" // Added by ClassView #include "map.h"
#include "MLO.h" // Added by ClassView //}}AFX_INCLUDES #if !defined(AFX_VEICOLIVIEW_H__904EDACF_10CC_11D9_A0D9_8C3888B4DF43__INCLUDED_) #define AFX_VEICOLIVIEW_H__904EDACF_10CC_11D9_A0D9_8C3888B4DF43__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CVeicoliSet;
class CMoPolyArray : public CTypedPtrArray<CPtrArray, CMoPolygon*> {}; //defined in <afxtempl.h>
class CVeicoliView : public CRecordView {
protected: // create from serialization only CVeicoliView();
DECLARE_DYNCREATE(CVeicoliView)
public:
//{{AFX_DATA(CVeicoliView) enum { IDD = IDD_FINSETT_FORM }; CButton m_mcs_startbutton; CListBox m_ctlTracesList; CButton m_checkAUV; CButton m_checkSSSTrace; CButton m_checkCumulative; CButton m_checkTrace; CListBox m_ctlObjectList; CVeicoliSet* m_pSet; CMap1 m_map; double m_tempo_trascorso; double m_spazio_percorso; double m_auvZ; double m_auvY; double m_auvX; double m_mcs_samples; double m_mcs_confidence; double m_mcs_accuracy; double m_mcs_meanDP; //}}AFX_DATA //double m_velocita; CString m_msgfine; int m_simulationScale; COggettiSet* m_pSetOgg; CNavigazioneSet* m_pSetNav; CMisuraSet* m_pSetMis; CMaterialiSet* m_pSetMat; CImpreseSet* m_pSetImp; CEnergiaSet* m_pSetEne; // Attributes public: CFinSettDoc* GetDocument(); // Operations public: // Overrides
// ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CVeicoliView)
public:
virtual CRecordset* OnGetRecordset();
virtual BOOL PreCreateWindow(CREATESTRUCT& cs); virtual BOOL DestroyWindow();
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support virtual void OnInitialUpdate(); // called first time after construct virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo); virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo); //}}AFX_VIRTUAL
// Implementation public:
virtual ~CVeicoliView(); #ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const; #endif
protected:
// Generated message map functions protected:
//{{AFX_MSG(CVeicoliView) afx_msg void OnVeicoliprev(); afx_msg void OnImpresaprev(); afx_msg void OnEnergiaprev(); afx_msg void OnOggettiprev(); afx_msg void OnNavigazprev(); afx_msg void OnControlloprev(); afx_msg void OnComunicprev(); afx_msg void OnMisuraprev(); afx_msg void OnMaterialiprev(); afx_msg void OnVeicolinext(); afx_msg void OnImpresanext(); afx_msg void OnEnergianext(); afx_msg void OnOggettinext(); afx_msg void OnNevigaznext(); afx_msg void OnControllonext(); afx_msg void OnComunicnext(); afx_msg void OnMisuranext(); afx_msg void OnMaterialinext();
afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg void OnMapTool(UINT nID);
afx_msg void OnUpdateMapTool(CCmdUI* pCmdUI);
afx_msg void OnMouseDownMap1(short Button, short Shift, long X, long Y); afx_msg void OnMapFullextent();
afx_msg void OnMouseMoveMap1(short Button, short Shift, long X, long Y); afx_msg void OnSimulationTool(UINT nID);
afx_msg void OnUpdateSimulationTool(CCmdUI* pCmdUI); afx_msg void OnObjdeleteall();
afx_msg void OnChecktrace(); afx_msg void OnCheckcumulative();
afx_msg void OnAfterTrackingLayerDrawMap1(long hDC); afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnKillfocusEditconfidence(); afx_msg void OnKillfocusEditaccuracy(); afx_msg void OnButtonStartMCS(); afx_msg void OnCheckssstrace(); afx_msg void OnCheckauv();
afx_msg void OnSelchangeListtraces(); DECLARE_EVENTSINK_MAP()
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
void SetObjectFeatures(const int objID, double& radius, double& PDobj); void VerifyPolys(int index, CMoPolygon* pNewArea, VARIANT vaFullExtent); CMoPolygon* Rect2Poly(CMoRectangle* pRect);
void UpdateTraceEdits(); void TrackingLayerRefresh(); //void SetSeaColor();
void ReleaseTracePolys(); void DeletePrevMission();
double GetSeaDepth(double x, double y, bool& collision);
void ComputeTracePolys(CMoPolygon* pNewArea, int index, VARIANT vaFullExtent); void ComputeEnlightedObjects(int nOgg, double dR, double dY, VARIANT vaFullExtent);
UINT m_curSimulTool; UINT m_curTool; CString bathymetry_filename; CString landarea_filename; BOOL m_readyToStart; BOOL m_simulationInProgress; BOOL m_cumulativeMissions; BOOL m_showTrace; AUV* m_pAUV; MLO* m_pMLOs; CMoGeoEvent m_mission_area; LawnMower* m_pLawnMoverPath; WaypointsPath* m_pWaypointsPath; List m_objList; CMoPoints m_objects_collection; CMoPoints m_objects_discovered; CMoPoints m_objects_missed;
CMoPolyArray m_trace_polys; // Polygons in the SSS trace int m_trace_polysIndex;
// costanti
const long moDrawSmooth; const int m_timerTick;
const long m_auv_symbolIndex; const long m_object_symbolIndex; const long m_mission_area_symbolIndex; const long m_waypointsPath_symbolIndex; const long m_waypoints_symbolIndex; const long m_trace_symbolIndex; const long m_nSymbol;
const short m_object_symbolDefault; const short m_object_symbolDiscovered; const short m_object_symbolMissed; };
#ifndef _DEBUG // debug version in VeicoliView.cpp inline CFinSettDoc* CVeicoliView::GetDocument() { return (CFinSettDoc*)m_pDocument; }
#endif
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
AUV.cpp
// AUV.cpp: implementation of the AUV class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "FinSett.h" #include "AUV.h" #ifdef _DEBUG #undef THIS_FILE
static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW
#endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// AUV::AUV() {
//NOTA: talune funzioni membro si possono chiamare anche su oggetti con dispatch NULL (es. GetX(): riporta
//il valore 0.0, ma emette un warning), altre invece NO (es. SetX(): il campo X NON viene settato );
//per sicurezza io inizializzo sempre con un CreateDispatch; se dopo ci fosse un assegnamento di un nuovo
//dispatch questa operazione sarebbe superflua.
m_lastDx = m_lastDy = m_lastDth = 0;
m_center.CreateDispatch("MapObjects2.Point"); m_orientation = 0;
m_shape.CreateDispatch("MapObjects2.Polygon"); m_SSSshape.CreateDispatch("MapObjects2.Polygon");
m_scale = 10;
m_visible = m_SSSvisible = false;
m_computeShapeWhenMove = m_computeSSSshapeWhenMove = true;
m_length = 10; m_width = 5; m_SSSfrequency = 455; m_SSSband = 455; m_SSSlength = 120; m_SSSlobes = 4; m_SSSrange = 100; m_SSSswath = 300; m_navigationPrecision = 0; m_autonomy = 100; } double AUV::GetMaxVelocity() {
double lamda = 1.500 / m_SSSfrequency ;
double dTheta = lamda / (m_SSSlength/100); //convert length from cm to m return 1500 / 4 * dTheta * m_SSSlobes;
} double AUV::Get_dR() { return 1.500 / 2 / m_SSSband; } double AUV::Get_dY() {
double lamda = 1.500 / m_SSSfrequency ;
return m_SSSrange * dTheta; }
void AUV::Traslate(double dx, double dy) { m_center.SetX( m_center.GetX() + dx ); m_center.SetY( m_center.GetY() + dy ); m_lastDx = dx; m_lastDy = dy; m_lastDth = 0; if (m_computeShapeWhenMove) ComputeShape(); if (m_computeSSSshapeWhenMove) ComputeSSSshape(dx, dy); }
void AUV::Rotate(double dth) {
m_orientation += dth;
m_orientation = atan2( sin(m_orientation), cos(m_orientation) ); // equivalent to 'm_orientation % 6.28' m_lastDx = m_lastDy = 0; m_lastDth = dth; if (m_computeShapeWhenMove) ComputeShape(); if (m_computeSSSshapeWhenMove) ComputeSSSshape(dth); } void AUV::ComputeSSSshape() { if (m_lastDx != 0 || m_lastDy != 0) ComputeSSSshape(m_lastDx, m_lastDy); else ComputeSSSshape(m_lastDth); }
//NB: con la funzione ComputeExtent NON FUNZIONA!! Perché non posso mantenere un rectangle (o un dispatch puntatore di
//un rectangle) in due blocchi diversi del programma: si genera violazione della condivisione!! // se invece creo un rectangle provvisorio e poi lo passo al programma chiamante mediante un detachdispatch (ovvero
//mediante un passaggio per valore, che implicitamente equivale ad un detachdispatch, come avevamo già visto)
//il rectangle NON E' MAI CONTEMPORANEAMENTE PUNTATO DA DISPATCH CONTENUTI SOTTO BLOCCHI CON VISIBILITA' DIVERSA
//ed il tutto funziona senza access violation! Ho creato quindi la seguente GetExtent() CMoRectangle AUV::GetExtent()
{
CMoRectangle rExtent( m_SSSshape.GetExtent() );
double minExt = (m_length > m_width) ? m_length : m_width; minExt *= m_scale;
rExtent.SetRight ( rExtent.GetRight() + minExt ); rExtent.SetTop ( rExtent.GetTop() + minExt ); rExtent.SetLeft ( rExtent.GetLeft() - minExt ); rExtent.SetBottom( rExtent.GetBottom() - minExt );
return rExtent; } AUV::~AUV() { m_center.ReleaseDispatch(); m_shape.ReleaseDispatch(); m_SSSshape.ReleaseDispatch(); } void AUV::ComputeShape() {
//delete old shape (polygon) and create a new one
if (LPDISPATCH(m_shape)) m_shape.ReleaseDispatch(); m_shape.CreateDispatch("MapObjects2.Polygon");
// temporary variables
CMoPoints pts;// = CMoPoints(); //Equivalent: Creates a NULL dispatch CMoPoint pt; //= CMoPoint();
pts.CreateDispatch("MapObjects2.Points");//necessario per poterci seguire poi sopra dellle chiamate a funzioni membro
pt.CreateDispatch("MapObjects2.Point");
//geometry settings
double cl = cos(m_orientation) * m_length * m_scale; double sl = sin(m_orientation) * m_length * m_scale; double cw = cos(m_orientation) * m_width * m_scale; double sw = sin(m_orientation) * m_width * m_scale; double X = m_center.GetX(); double Y = m_center.GetY(); // point 1 pt.SetX( 0.4*cl + 0.5*sw + X ); pt.SetY( 0.4*sl - 0.5*cw + Y ); pts.Add( pt.m_lpDispatch ); // point 2 pt.SetX( 0.5*cl + X ); pt.SetY( 0.5*sl + Y ); pts.Add( pt.m_lpDispatch ); // point 3 pt.SetX( 0.4*cl - 0.5*sw + X ); pt.SetY( 0.4*sl + 0.5*cw + Y ); pts.Add( pt.m_lpDispatch ); // point 4 pt.SetX( -0.3*cl - 0.5*sw + X ); pt.SetY( -0.3*sl + 0.5*cw + Y ); pts.Add( pt.m_lpDispatch ); // point 5 pt.SetX( -0.4*cl - 0.25*sw + X ); pt.SetY( -0.4*sl + 0.25*cw + Y ); pts.Add( pt.m_lpDispatch ); // point 6 pt.SetX( -0.5*cl - 0.5*sw + X ); pt.SetY( -0.5*sl + 0.5*cw + Y ); pts.Add( pt.m_lpDispatch ); // point 7 pt.SetX( -0.5*cl + 0.5*sw + X ); pt.SetY( -0.5*sl - 0.5*cw + Y ); pts.Add( pt.m_lpDispatch ); // point 8 pt.SetX( -0.4*cl + 0.25*sw + X ); pt.SetY( -0.4*sl - 0.25*cw + Y ); pts.Add( pt.m_lpDispatch ); // point 9 pt.SetX( -0.3*cl + 0.5*sw + X ); pt.SetY( -0.3*sl - 0.5*cw + Y ); pts.Add( pt.m_lpDispatch );
// set new shape
m_shape.GetParts().Add( pts.m_lpDispatch );
}
void AUV::ComputeSSSshape(double dx, double dy) {
//delete old shape (polygon) and create a new one if (LPDISPATCH(m_SSSshape)) m_SSSshape.ReleaseDispatch(); m_SSSshape.CreateDispatch("MapObjects2.Polygon"); // temporary variables CMoPoints pts; pts.CreateDispatch("MapObjects2.Points"); CMoPoint pt; pt.CreateDispatch("MapObjects2.Point"); //geometry settings
double sr = sin(m_orientation) * m_SSSrange;
double crs = cos(m_orientation) * (m_SSSrange + m_SSSswath); double srs = sin(m_orientation) * (m_SSSrange + m_SSSswath); double X = m_center.GetX(); double Y = m_center.GetY(); // point 1 pt.SetX( -srs + X ); pt.SetY( crs + Y ); pts.Add( pt.m_lpDispatch ); // point 2 pt.SetX( -sr + X ); pt.SetY( cr + Y ); pts.Add( pt.m_lpDispatch ); // point 3 pt.SetX( -sr - dx + X ); pt.SetY( cr - dy + Y ); pts.Add( pt.m_lpDispatch ); // point 4 pt.SetX( -srs - dx + X ); pt.SetY( crs - dy + Y ); pts.Add( pt.m_lpDispatch );
// set new shape (part 1)
m_SSSshape.GetParts().Add( pts.m_lpDispatch );
// clear temporary variables pts.ReleaseDispatch(); pts.CreateDispatch("MapObjects2.Points"); // point 5 pt.SetX( sr + X ); pt.SetY( -cr + Y ); pts.Add( pt.m_lpDispatch ); // point 6 pt.SetX( srs + X ); pt.SetY( -crs + Y ); pts.Add( pt.m_lpDispatch ); // point 7 pt.SetX( srs - dx + X ); pt.SetY( -crs - dy + Y ); pts.Add( pt.m_lpDispatch ); // point 8 pt.SetX( sr - dx + X ); pt.SetY( -cr - dy + Y ); pts.Add( pt.m_lpDispatch );
// set new shape (part 2)
m_SSSshape.GetParts().Add( pts.m_lpDispatch );
}
void AUV::ComputeSSSshape(double dth) {
//delete old shape (polygon) and create a new one if (LPDISPATCH(m_SSSshape)) m_SSSshape.ReleaseDispatch(); m_SSSshape.CreateDispatch("MapObjects2.Polygon"); // temporary variables CMoPoints pts; pts.CreateDispatch("MapObjects2.Points"); CMoPoint pt; pt.CreateDispatch("MapObjects2.Point"); //geometry settings double c = cos(m_orientation); double s = sin(m_orientation); double ch = cos(m_orientation - dth); double sh = sin(m_orientation - dth);
double r = m_SSSrange;
double rs = m_SSSrange + m_SSSswath; double X = m_center.GetX(); double Y = m_center.GetY(); // point 1 pt.SetX( -s*rs + X ); pt.SetY( c*rs + Y ); pts.Add( pt.m_lpDispatch ); // point 2 pt.SetX( -s*r + X ); pt.SetY( c*r + Y ); pts.Add( pt.m_lpDispatch ); // point 3 pt.SetX( -sh*r + X ); pt.SetY( ch*r + Y ); pts.Add( pt.m_lpDispatch ); // point 4 pt.SetX( -sh*rs + X ); pt.SetY( ch*rs + Y ); pts.Add( pt.m_lpDispatch );
// set new shape (part 1)
m_SSSshape.GetParts().Add( pts.m_lpDispatch ); //m_SSSshape.GetArea();
// clear temporary variables pts.ReleaseDispatch(); pts.CreateDispatch("MapObjects2.Points"); // point 5 pt.SetX( s*r + X ); pt.SetY( -c*r + Y ); pts.Add( pt.m_lpDispatch ); // point 6 pt.SetX( s*rs + X ); pt.SetY( -c*rs + Y ); pts.Add( pt.m_lpDispatch ); // point 7 pt.SetX( sh*rs + X ); pt.SetY( -ch*rs + Y ); pts.Add( pt.m_lpDispatch ); // point 8 pt.SetX( sh*r + X ); pt.SetY( -ch*r + Y ); pts.Add( pt.m_lpDispatch );
// set new shape (part 2)
m_SSSshape.GetParts().Add( pts.m_lpDispatch ); m_SSSshape.GetArea();
Lawnmower.cpp
// LawnMower.cpp: implementation of the LawnMower class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "FinSett.h" #include "LawnMower.h" #ifdef _DEBUG #undef THIS_FILE
static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW
#endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// LawnMower::LawnMower() { }
LawnMower:: LawnMower(double initialX, double initialY, double centralX, double centralY) {
const double epsilon = 0.5;
currentState = BEGIN; onMySide = true; scanIsOn = false;
if ( initialX <= centralX ) {
if ( initialY <= centralY ) { // primo quadrante areaWidth = 2*(centralX - initialX); areaLength = 2*(centralY - initialY); lineCross = NORTH;
lineForward = EAST; lineBackward = WEST;
}
else { // quarto quadrante
areaLength = 2*(centralX - initialX); areaWidth = 2*(initialY - centralY); lineCross = EAST; lineForward = SOUTH; lineBackward = NORTH; } } else {
if ( initialY <= centralY ) { // secondo quadrante areaLength = 2*(initialX - centralX); areaWidth = 2*(centralY - initialY); lineCross = WEST;
lineForward = NORTH; lineBackward = SOUTH;
}
else { // terzo quadrante
areaWidth = 2*(initialX - centralX); areaLength = 2*(initialY - centralY); lineCross = SOUTH;
lineForward = WEST; lineBackward = EAST;
}
}
if ( areaWidth < 100*epsilon ) areaWidth = 100*epsilon; if ( areaLength < 100*epsilon ) areaLength = 100*epsilon;
//per completare l'inizializzazione servono i dati del veicolo, quindi per il momento: maxStep = -1;
}
void LawnMower::SetVehicleParam(double range, double swath, double precision, double maxStepSize) {
const double epsilon = 0.1;
// aggiusto lo swath ed il range tenendo conto dell'area sicuramente coperta dal SSS // sapendo che c'è un'incertezza di navigazione di valore 'precision'
// gestisco anche possibili errori assegnando un valore minimo ai vari campi sulla // base della costante epsilon
rg = (range + precision >= 0.0)? range+precision : 0.0;
sw = (swath - 2*precision >= 10*epsilon)? swath-2*precision : 10*epsilon; maxStep = (maxStepSize > epsilon)? maxStepSize : epsilon ;
int numLinesPerSector = (int)ceil(2*rg/sw) + 1; double remainder = fmod(2*rg, sw);
double sector = 2*sw*numLinesPerSector - sw + remainder;
linesToDo = (int)floor(areaLength/sector) * numLinesPerSector;
remainder = fmod(areaLength, sector);
if ( ceil(remainder/sw) < numLinesPerSector) linesToDo += (int)ceil(remainder/sw); else linesToDo += numLinesPerSector; } LawnMower::~LawnMower() { }
bool LawnMower::Step(double& xStep, double& yStep, bool& scanning, bool& missionAccomplished) {
if (maxStep == -1) return 0; //inizializzazione non ancora completata, mancano i parametri del veicolo
const double neglectable = 1; missionAccomplished = false; switch(currentState) { case BEGIN: scanIsOn = false; if (onMySide) nextState = LINEFORWARD; else nextState = LINEBACKWARD; GoStraight(rg+sw, lineCross, xStep, yStep);
outOfSwath = 2*rg + sw; break;
case LINEFORWARD: scanIsOn = true; nextState = LINECROSS;
GoStraight(areaWidth, lineForward, xStep, yStep);
linesToDo--; onMySide = false; break; case LINEBACKWARD: scanIsOn = true; nextState = LINECROSS;
GoStraight(areaWidth, lineBackward, xStep, yStep);
linesToDo--; onMySide = true; break; case LINECROSS: scanIsOn = false; if (linesToDo <= 0) missionAccomplished = true; else { outOfSwath -= sw; if ( outOfSwath <= neglectable ) { nextState = BEGIN;
} else { if (onMySide) nextState = LINEFORWARD; else nextState = LINEBACKWARD;
GoStraight(sw, lineCross, xStep, yStep); }
}
break;
case GOSTRAIGHT:
GoStraight(residualDistance, currentDirection, xStep, yStep); break;
}
scanning = scanIsOn; return 1;
}
void LawnMower::GoStraight(double distanceToDo, Direction directionToFollow, double& xStep, double& yStep)
{
double trueStep;
if ( distanceToDo > maxStep ) {
trueStep = maxStep;
residualDistance = distanceToDo - maxStep; currentState = GOSTRAIGHT; } else { trueStep = distanceToDo; currentState = nextState; } currentDirection = directionToFollow; switch( directionToFollow ) { case NORTH: xStep = 0; yStep = trueStep; break; case SOUTH: xStep = 0; yStep = -trueStep; break; case EAST: xStep = trueStep; yStep = 0; break; case WEST: xStep = -trueStep; yStep = 0; break; } }
WaypointsPath.cpp
// WaypointsPath.cpp: implementation of the WaypointsPath class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "FinSett.h" #include "WaypointsPath.h" #ifdef _DEBUG #undef THIS_FILE
static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW
#endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// WaypointsPath::WaypointsPath() { m_state = TRASLATION; //m_nextWaypoint.CreateDispatch("MapObjects2.Point"); VariantInit(&m_vaIndex); m_vaIndex.vt = VT_I4; m_pPath = NULL; m_pWaypoints = NULL; m_finish = true; } WaypointsPath::~WaypointsPath() { //if(m_pPath) delete m_pPath; //if(m_pWaypoints) delete m_pWaypoints; CMoPolygon p = NULL; delete p;
//dovrebbe essere sufficiente il delete fatto come sopra. Le istruzioni sotto dovrebbero essere
//ridondanti (stesso discorso su m_Path) /*if(m_pWaypoints) { if(m_pWaypoints->m_lpDispatch) m_pWaypoints->ReleaseDispatch(); delete m_pWaypoints; }*/ }
void WaypointsPath::SetPath(CMoLine* pPath) {
//security checks and set Path (Line)
if (!pPath) { throw CString("Empty Line"); } m_pPath = pPath;
//get part 0 (that it would be a points object) m_vaIndex.lVal = 0;
LPDISPATCH disp;
disp = m_pPath->GetParts().Item(m_vaIndex);
if (!disp) { throw CString("No waypoints found"); }
//security checks and set Waypoints (Points)
//NB: anziché creare un oggetto point con dispatch NULL lo inizializzo subito con disp m_pWaypoints = new CMoPoints( disp );
if (m_pWaypoints->GetShapeType() != moShapeTypeMultipoint) { throw CString("Error: Type mismatch"); }
//set Next Point
if (m_pWaypoints->GetCount() == 1) {
m_nextWaypoint = m_pWaypoints->Item( m_vaIndex ); m_finish = true;
} else {
m_vaIndex.lVal = 1;
m_nextWaypoint = m_pWaypoints->Item( m_vaIndex ); m_finish = false;
}
//throw CString("OK!"); }
void WaypointsPath::ComputeStep(AUV *pAUV, double maxTraslStep, double maxRotStep, double& xOffset, double& yOffset)
{ if (m_finish) return; switch(m_state) { case TRASLATION: {
double dx = m_nextWaypoint.GetX() - pAUV->m_center.GetX(); double dy = m_nextWaypoint.GetY() - pAUV->m_center.GetY();
double d = sqrt(dy*dy + dx*dx); if (d <= maxTraslStep)
{
//set next state m_state = ROTATION; ComputeNextWaypoint();
}
else {
double th = atan2(dy, dx); //it would be: pAUV->m_orientation == th dx = maxTraslStep * cos(th);
dy = maxTraslStep * sin(th); //set next state m_state = TRASLATION; } pAUV->Traslate(dx, dy); xOffset = dx; yOffset = dy; break; } case ROTATION: {
double dx = m_nextWaypoint.GetX() - pAUV->m_center.GetX(); double dy = m_nextWaypoint.GetY() - pAUV->m_center.GetY(); double th = atan2(dy, dx);
double dth = th - pAUV->m_orientation; dth = atan2(sin(dth), cos(dth)); if (fabs(dth) <= maxRotStep) {
//set next state m_state = TRASLATION;
}
else {
dth = dth/fabs(dth) * maxRotStep; //set next state
m_state = ROTATION; } pAUV->Rotate(dth); xOffset = 0; yOffset = 0; break; } } }
void WaypointsPath::ComputeNextWaypoint() { m_vaIndex.lVal++; if (m_pWaypoints->GetCount() == m_vaIndex.lVal) { m_finish = true; return; }
m_nextWaypoint = m_pWaypoints->Item( m_vaIndex ); }
VeicoliView.cpp
// VeicoliView.cpp : implementation of the CVeicoliView class // #include "stdafx.h" #include "FinSett.h" #include "VeicoliSet.h" #include "OggettiSet.h" #include "NavigazioneSet.h" #include "MisuraSet.h" #include "MaterialiSet.h" #include "ImpreseSet.h" #include "EnergiaSet.h" #include "FinSettDoc.h" #include "VeicoliView.h" #include "VeicoliView_OnTimer.cpp" #ifdef _DEBUG
#define new DEBUG_NEW #undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CVeicoliView IMPLEMENT_DYNCREATE(CVeicoliView, CRecordView) BEGIN_MESSAGE_MAP(CVeicoliView, CRecordView) //{{AFX_MSG_MAP(CVeicoliView) ON_BN_CLICKED(IDC_VEICOLIPREV, OnVeicoliprev) ON_BN_CLICKED(IDC_IMPRESAPREV, OnImpresaprev) ON_BN_CLICKED(IDC_ENERGIAPREV, OnEnergiaprev) ON_BN_CLICKED(IDC_OGGETTIPREV, OnOggettiprev) ON_BN_CLICKED(IDC_NAVIGAZPREV, OnNavigazprev) ON_BN_CLICKED(IDC_CONTROLLOPREV, OnControlloprev) ON_BN_CLICKED(IDC_COMUNICPREV, OnComunicprev) ON_BN_CLICKED(IDC_MISURAPREV, OnMisuraprev) ON_BN_CLICKED(IDC_MATERIALIPREV, OnMaterialiprev) ON_BN_CLICKED(IDC_VEICOLINEXT, OnVeicolinext) ON_BN_CLICKED(IDC_IMPRESANEXT, OnImpresanext) ON_BN_CLICKED(IDC_ENERGIANEXT, OnEnergianext) ON_BN_CLICKED(IDC_OGGETTINEXT, OnOggettinext) ON_BN_CLICKED(IDC_NEVIGAZNEXT, OnNevigaznext) ON_BN_CLICKED(IDC_CONTROLLONEXT, OnControllonext) ON_BN_CLICKED(IDC_COMUNICNEXT, OnComunicnext) ON_BN_CLICKED(IDC_MISURANEXT, OnMisuranext) ON_BN_CLICKED(IDC_MATERIALINEXT, OnMaterialinext) ON_WM_SIZE()
ON_COMMAND_RANGE(ID_MP_SETMISSIONAREA, ID_MAP_PAN, OnMapTool)
ON_UPDATE_COMMAND_UI_RANGE(ID_MP_SETMISSIONAREA, ID_MAP_PAN, OnUpdateMapTool) ON_COMMAND(ID_MAP_FULLEXTENT, OnMapFullextent)
ON_COMMAND_RANGE(ID_SIMULATION_START, ID_SIMULATION_STOP, OnSimulationTool)
ON_UPDATE_COMMAND_UI_RANGE(ID_SIMULATION_START, ID_SIMULATION_STOP, OnUpdateSimulationTool) ON_COMMAND(ID_OBJDELETEALL, OnObjdeleteall) ON_BN_CLICKED(IDC_CHECKTRACE, OnChecktrace) ON_BN_CLICKED(IDC_CHECKCUMULATIVE, OnCheckcumulative) ON_EN_KILLFOCUS(IDC_EDITCONFIDENCE, OnKillfocusEditconfidence) ON_EN_KILLFOCUS(IDC_EDITACCURACY, OnKillfocusEditaccuracy) ON_BN_CLICKED(IDC_BUTTONSTARTMCS, OnButtonStartMCS) ON_BN_CLICKED(IDC_CHECKSSSTRACE, OnCheckssstrace) ON_BN_CLICKED(IDC_CHECKAUV, OnCheckauv) ON_LBN_SELCHANGE(IDC_LISTTRACES, OnSelchangeListtraces) //}}AFX_MSG_MAP
ON_WM_TIMER() END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CVeicoliView construction/destruction CVeicoliView::CVeicoliView() : CRecordView(CVeicoliView::IDD), moDrawSmooth(TRUE),
m_timerTick(0), //posso impostarlo anche a zero, funziona!!
m_object_symbolIndex(0), m_auv_symbolIndex(1), m_mission_area_symbolIndex(2), m_waypointsPath_symbolIndex(3), m_waypoints_symbolIndex(4), m_trace_symbolIndex(5), m_nSymbol(6), m_object_symbolDefault(167), m_object_symbolDiscovered(254), m_object_symbolMissed(253) { //{{AFX_DATA_INIT(CVeicoliView) m_pSet = NULL; m_tempo_trascorso = 0.0; m_spazio_percorso = 0.0; m_auvZ = 0.0; m_auvY = 0.0; m_auvX = 0.0; m_mcs_samples = 0.0; m_mcs_confidence = 72.0; m_mcs_accuracy = 100.0; m_mcs_meanDP = 0.0; //}}AFX_DATA_INIT
// TODO: add construction code here m_msgfine = ""; m_simulationScale = 100; m_pSetOgg = NULL; m_pSetNav = NULL; m_pSetMis = NULL; m_pSetMat = NULL; m_pSetImp = NULL; m_pSetEne = NULL; m_curTool = ID_MAP_ZOOMIN; m_curSimulTool = ID_SIMULATION_STOP; m_pAUV = NULL; m_pMLOs = NULL; m_pLawnMoverPath = NULL;
m_pWaypointsPath = NULL; // pensare se è il caso di riunire le inizializzazioni sotto OnInitialUpdate... m_readyToStart = FALSE; m_simulationInProgress = FALSE; m_cumulativeMissions = FALSE; m_showTrace = TRUE; m_trace_polysIndex = 0; } CVeicoliView::~CVeicoliView() { delete m_pAUV; delete m_pMLOs; delete m_pLawnMoverPath; delete m_pWaypointsPath; ReleaseTracePolys(); } void CVeicoliView::DoDataExchange(CDataExchange* pDX) {
CRecordView::DoDataExchange(pDX); //{{AFX_DATA_MAP(CVeicoliView)
DDX_Control(pDX, IDC_BUTTONSTARTMCS, m_mcs_startbutton); DDX_Control(pDX, IDC_LISTTRACES, m_ctlTracesList); DDX_Control(pDX, IDC_CHECKAUV, m_checkAUV);
DDX_Control(pDX, IDC_CHECKSSSTRACE, m_checkSSSTrace); DDX_Control(pDX, IDC_CHECKCUMULATIVE, m_checkCumulative); DDX_Control(pDX, IDC_CHECKTRACE, m_checkTrace);
DDX_Control(pDX, IDC_LIST1, m_ctlObjectList); DDX_Control(pDX, IDC_MAP1, m_map);
DDX_Text(pDX, IDC_EDITTEMPO, m_tempo_trascorso); DDX_Text(pDX, IDC_EDITSPAZIO, m_spazio_percorso); DDX_Text(pDX, IDC_EDITZ, m_auvZ);
DDX_Text(pDX, IDC_EDITY, m_auvY); DDX_Text(pDX, IDC_EDITX, m_auvX);
DDX_Text(pDX, IDC_EDITSAMPLES, m_mcs_samples); DDX_Text(pDX, IDC_EDITCONFIDENCE, m_mcs_confidence); DDX_Text(pDX, IDC_EDITACCURACY, m_mcs_accuracy); DDX_Text(pDX, IDC_EDITMEANDP, m_mcs_meanDP);
DDX_FieldText(pDX, IDC_EDITVEICOLI, m_pSet->m_ID_VEICOLO, m_pSet); DDX_FieldText(pDX, IDC_EDITNOMEVEICOLO, m_pSet->m_Nome_veicolo, m_pSet); //}}AFX_DATA_MAP
DDX_FieldText(pDX, IDC_EDITPRECISIONE, m_pSetNav->m_Precisione, m_pSetNav); DDX_FieldText(pDX, IDC_EDITTIPONAVIGAZ, m_pSetNav->m_Tipo_navigazione, m_pSetNav);
DDX_FieldText(pDX, IDC_EDITMISURAPRODUTTORE, m_pSetMis->m_Produttore, m_pSetMis);
DDX_FieldText(pDX, IDC_EDITMISURAMODELLO, m_pSetMis->m_Modello, m_pSetMis); DDX_FieldText(pDX, IDC_EDITMISURAFREQUENZA, m_pSetMis->m_Frequenza,
m_pSetMis);
DDX_FieldText(pDX, IDC_EDITMISURABANDA, m_pSetMis->m_Banda, m_pSetMis);
DDX_FieldText(pDX, IDC_EDITMISURALARGHEZZA, m_pSetMis->m_Larghezza_cortina, m_pSetMis);
DDX_FieldText(pDX, IDC_EDITMISURALOBI, m_pSetMis->m_Lobi_preformati, m_pSetMis);
DDX_FieldText(pDX, IDC_EDITMISURARANGE, m_pSetMis->m_Range, m_pSetMis);
DDX_FieldText(pDX, IDC_EDITMISURASWATH, m_pSetMis->m_Swath, m_pSetMis);
DDX_FieldText(pDX, IDC_EDITTIPOENERGIA, m_pSetEne->m_Tipo_energia, m_pSetEne); DDX_FieldText(pDX, IDC_EDITAUTONOMIA, m_pSetEne->m_Autonomia, m_pSetEne);
} BOOL CVeicoliView::PreCreateWindow(CREATESTRUCT& cs) { return CRecordView::PreCreateWindow(cs); } void CVeicoliView::OnInitialUpdate() { CFinSettDoc* pDoc; try { pDoc = GetDocument(); m_pSet = &GetDocument()->m_veicoliSet; } catch(...){
::MessageBox(this->GetSafeHwnd(), _T("Impossibile caricare VeicoliSet"), _T("EasyMap"), MB_ICONEXCLAMATION); } try{ m_pSetOgg = &pDoc->m_oggettiSet; m_pSetNav = &pDoc->m_navigazioneSet; m_pSetMis = &pDoc->m_misuraSet; m_pSetMat = &pDoc->m_materialiSet; m_pSetImp = &pDoc->m_impreseSet; m_pSetEne = &pDoc->m_energiaSet; if(!pDoc->m_oggettiSet.Open()) return; if(!pDoc->m_navigazioneSet.Open()) return; if(!pDoc->m_misuraSet.Open()) return; if(!pDoc->m_materialiSet.Open()) return; if(!pDoc->m_impreseSet.Open()) return;
if(!pDoc->m_energiaSet.Open()) return; }
catch(...){
::MessageBox(this->GetSafeHwnd(), _T("Impossibile caricare parte del DataSet"), _T("EasyMap"), MB_ICONEXCLAMATION);
}
try{
// Se MapObjects 2.2 non è installato la seguente istruzione causa ERRORE! CRecordView::OnInitialUpdate();
// l'errore sembra essere dovuto alla impossibilità di gestire il meccanismo di // DataExchange fra la 'ID_MAP1' e la variabile 'm_map' di tipo 'CMap1'
GetParentFrame()->RecalcLayout(); ResizeParentToFit();
}
catch(...){
::MessageBox(this->GetSafeHwnd(), _T("Impossibile Inizializzare il programma"), _T("EasyMap"), MB_ICONEXCLAMATION);
}
try {
AddLayer(m_map, TEXT(".\\Dati Battimetria La Spezia2\\Projected\\batimetryprojected2.shp"), moBlue);
bathymetry_filename = "batimetryprojected2";
AddLayer(m_map, TEXT(".\\Dati Battimetria La Spezia2\\Projected\\landareaprojected2.shp"), moOlive);
landarea_filename = "landareaprojected2";
}
catch (...) {
::MessageBox(this->GetSafeHwnd(), _T("Default shape files not found."), _T("EasyMap"), MB_ICONEXCLAMATION);
}
try {
CMoTrackingLayer tLayer(m_map.GetTrackingLayer());
m_map.SetTrackingLayerDrawing(moDrawSmooth); //per risolvere il problema del Pan tLayer.SetSymbolCount(m_nSymbol);
CMoSymbol sym; CMoFont fnt;
fnt.InitializeFont(); // similar to CreateDispatch // now define the font face
fnt.SetName(TEXT("Wingdings")); //NB: se non lo trova non lancia eccezione //ma usa simbolo default [bisognerebbe correggere!]
sym = tLayer.GetSymbol(m_object_symbolIndex); sym.SetSymbolType(moPointSymbol); //facoltativo sym.SetColor(moBlue);
// sym.SetStyle(moCircleMarker); //così uso simboli di mapobject anziché truetype, ma ho lo svantaggio di non opter usare i simboli di discovered e missed
sym.SetStyle(moTrueTypeMarker); sym.SetFont(fnt.GetFontDispatch()); sym.SetSize(18); sym = tLayer.GetSymbol(m_auv_symbolIndex); sym.SetSymbolType(moFillSymbol); sym.SetStyle(moSolidFill); sym.SetColor(moRed); sym.SetOutline(TRUE); sym.SetOutlineColor(moBlack); sym = tLayer.GetSymbol(m_mission_area_symbolIndex); sym.SetSymbolType(moFillSymbol); sym.SetStyle(moTransparentFill); sym.SetOutline(TRUE); sym.SetOutlineColor(moRed); sym = tLayer.GetSymbol(m_waypointsPath_symbolIndex); sym.SetSymbolType(moLineSymbol); sym.SetStyle(moSolidLine); sym.SetSize(1); sym.SetColor(moRed); sym = tLayer.GetSymbol(m_waypoints_symbolIndex);
sym.SetSymbolType(moPointSymbol); sym.SetStyle(moCircleMarker); sym.SetSize(5); sym.SetColor(moRed); sym = tLayer.GetSymbol(m_trace_symbolIndex); sym.SetSymbolType(moFillSymbol); sym.SetStyle(moGrayFill); sym.SetColor(moMagenta); sym.SetOutline(FALSE); //sym.SetOutlineColor(moBlack); fnt.ReleaseFont(); m_objects_collection.CreateDispatch("MapObjects2.Points"); m_objects_discovered.CreateDispatch("MapObjects2.Points"); m_objects_missed.CreateDispatch("MapObjects2.Points"); m_checkTrace.SetCheck(TRUE); m_checkSSSTrace.SetCheck(TRUE); m_checkAUV.SetCheck(TRUE); } catch(...) {
::MessageBox(this->GetSafeHwnd(), _T("Font Wingdings non trovato o altro errore"
"nell'inizializzazione dei simboli"), _T("EasyMap"), MB_ICONEXCLAMATION);
}
//inizializzo generatore di numeri casuali in base all'ora corrente srand( (unsigned)time( NULL ) );
OnKillfocusEditaccuracy(); }
///////////////////////////////////////////////////////////////////////////// // CVeicoliView printing
BOOL CVeicoliView::OnPreparePrinting(CPrintInfo* pInfo) {
// default preparation
return DoPreparePrinting(pInfo); }
void CVeicoliView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) {
// TODO: add extra initialization before printing }
void CVeicoliView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) {
// TODO: add cleanup after printing }
///////////////////////////////////////////////////////////////////////////// // CVeicoliView diagnostics
#ifdef _DEBUG
void CVeicoliView::AssertValid() const {
CRecordView::AssertValid(); }
void CVeicoliView::Dump(CDumpContext& dc) const {
CRecordView::Dump(dc); }
CFinSettDoc* CVeicoliView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CFinSettDoc))); return (CFinSettDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CVeicoliView database support
CRecordset* CVeicoliView::OnGetRecordset() {
return m_pSet; }
///////////////////////////////////////////////////////////////////////////// // CVeicoliView message handlers
void CVeicoliView::OnVeicoliprev() {
// TODO: Add your control notification handler code here if (!m_pSet->IsBOF()){ m_pSet->MovePrev(); if (m_pSet->IsBOF()) m_pSet->MoveNext(); } UpdateData(FALSE); } void CVeicoliView::OnImpresaprev() { } void CVeicoliView::OnEnergiaprev() {
// TODO: Add your control notification handler code here if (!m_pSetEne->IsBOF()){ m_pSetEne->MovePrev(); if (m_pSetEne->IsBOF()) m_pSetEne->MoveNext(); } UpdateData(FALSE); } void CVeicoliView::OnOggettiprev() {
// TODO: Add your control notification handler code here if (!m_pSetOgg->IsBOF()){ m_pSetOgg->MovePrev(); if (m_pSetOgg->IsBOF()) m_pSetOgg->MoveNext(); } UpdateData(FALSE); } void CVeicoliView::OnNavigazprev() {
// TODO: Add your control notification handler code here if (!m_pSetNav->IsBOF()){ m_pSetNav->MovePrev(); if (m_pSetNav->IsBOF()) m_pSetNav->MoveNext(); } UpdateData(FALSE); } void CVeicoliView::OnControlloprev() { } void CVeicoliView::OnComunicprev() { } void CVeicoliView::OnMisuraprev() {
// TODO: Add your control notification handler code here if (!m_pSetMis->IsBOF()){ m_pSetMis->MovePrev(); if (m_pSetMis->IsBOF()) m_pSetMis->MoveNext(); } UpdateData(FALSE); } void CVeicoliView::OnMaterialiprev()
{ }
void CVeicoliView::OnVeicolinext() {
// TODO: Add your control notification handler code here if (!m_pSet->IsEOF()){ m_pSet->MoveNext(); if (m_pSet->IsEOF()) m_pSet->MovePrev(); } UpdateData(FALSE); } void CVeicoliView::OnImpresanext() { } void CVeicoliView::OnEnergianext() {
// TODO: Add your control notification handler code here if (!m_pSetEne->IsEOF()){ m_pSetEne->MoveNext(); if (m_pSetEne->IsEOF()) m_pSetEne->MovePrev(); } UpdateData(FALSE); } void CVeicoliView::OnOggettinext() {
// TODO: Add your control notification handler code here if (!m_pSetOgg->IsEOF()){ m_pSetOgg->MoveNext(); if (m_pSetOgg->IsEOF()) m_pSetOgg->MovePrev(); } UpdateData(FALSE); } void CVeicoliView::OnNevigaznext() {
// TODO: Add your control notification handler code here if (!m_pSetNav->IsEOF()){ m_pSetNav->MoveNext(); if (m_pSetNav->IsEOF()) m_pSetNav->MovePrev(); } UpdateData(FALSE); } void CVeicoliView::OnControllonext() { } void CVeicoliView::OnComunicnext() { } void CVeicoliView::OnMisuranext() {
// TODO: Add your control notification handler code here if (!m_pSetMis->IsEOF()){ m_pSetMis->MoveNext(); if (m_pSetMis->IsEOF()) m_pSetMis->MovePrev(); } UpdateData(FALSE); } void CVeicoliView::OnMaterialinext() {
}
void CVeicoliView::OnSize(UINT nType, int cx, int cy) {
CRecordView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here if(m_map.m_hWnd)
m_map.SetWindowPos(NULL, 250, 140, cx-250, cy-140, SWP_NOZORDER);
}
void CVeicoliView::OnMapTool(UINT nID) { switch(nID) { case ID_MP_SETMISSIONAREA: case ID_MP_SETWAYPOINTS: case ID_MAP_OBJADD1: case ID_MAP_OBJADD10: case ID_MAP_OBJADD100: if (!m_simulationInProgress) m_curTool = nID; break; default: m_curTool = nID; } }
void CVeicoliView::OnUpdateMapTool(CCmdUI* pCmdUI) {
pCmdUI->SetCheck(pCmdUI->m_nID == m_curTool); }
BEGIN_EVENTSINK_MAP(CVeicoliView, CRecordView) //{{AFX_EVENTSINK_MAP(CVeicoliView)
ON_EVENT(CVeicoliView, IDC_MAP1, -605 /* MouseDown */, OnMouseDownMap1, VTS_I2 VTS_I2 VTS_I4 VTS_I4)
ON_EVENT(CVeicoliView, IDC_MAP1, -606 /* MouseMove */, OnMouseMoveMap1, VTS_I2 VTS_I2 VTS_I4 VTS_I4)
ON_EVENT(CVeicoliView, IDC_MAP1, 4 /* AfterTrackingLayerDraw */, OnAfterTrackingLayerDrawMap1, VTS_I4)
//}}AFX_EVENTSINK_MAP END_EVENTSINK_MAP()
void CVeicoliView::OnMouseDownMap1(short Button, short Shift, long X, long Y) {
// TODO: Add your control notification handler code here CMoPoint mapPt(m_map.ToMapPoint(float(X),float(Y)));
m_auvX = mapPt.GetX(); m_auvY = mapPt.GetY();
CMoLayers layers(m_map.GetLayers());
CMoMapLayer depthLayer( layers.Item((COleVariant(bathymetry_filename))) ); CMoPoint mousePoint( m_map.ToMapPoint((float)X, (float)Y) );
CMoRecordset polySet( depthLayer.SearchShape(mousePoint, moEdgeTouchOrAreaIntersect,
TEXT("")) );
if ( LPDISPATCH(polySet) != 0 && polySet.GetEof() == FALSE ) {
//seleziono i campi contenuti nel recordset (tutti i campi) CMoFields fields(polySet.GetFields());
//seleziono il campo 'depth' (attributo di ogni poligono) e ne estraggo il valore //che è un double (è obbligato il passaggio attraverso un variant)
CMoField depthField(fields.Item(COleVariant(DEPTH_FIELDNAME))); VARIANT vaDepth = depthField.GetValue();
m_auvZ = vaDepth.dblVal; //visualizzo il valore di profondità nel punto cliccato
/* //Nota: Selezionare queste opzioni per veder blinkare i poligoni cliccati //seleziono il campo 'shape' che conterrà un polygon; faccio blinkare il polygon CMoField shapeField(fields.Item(COleVariant(TEXT("Shape"))));
CMoPolygon shape;
shape.AttachDispatch(shapeField.GetValue().pdispVal);
m_map.FlashShape(shape, 3); //faccio lampeggiare il polygono toccato col mouse
polySet.MoveNext(); while (!polySet.GetEof()) {
// MessageBox("One more shape found!"); polySet.MoveNext(); } } else { m_auvZ = 0.0; } //SetSeaColor(); UpdateData(FALSE);
/* //NOTE: Attivare queste istruzioni per far inserire i punti cliccati //dal mouse sulla mappa
static List m_objList; int niente;
if ( m_objList.IsNewElem(m_auvX, m_auvY, niente) ){ static int objCount = 0;
objCount++; CString stringa = " "; char carat[9]; stringa += " X = "; gcvt(m_auvX, 8, carat); stringa += carat; stringa += " Y = "; gcvt(m_auvY, 8, carat); stringa += carat; m_ctlObjectList.AddString(stringa); } else MessageBox("non inserito"); //*/
if (Button == 1) //left click { CMoTrackingLayer tLayer(m_map.GetTrackingLayer()); switch (m_curTool) { case ID_MP_SETMISSIONAREA: { if (m_simulationInProgress) return; DeletePrevMission();
// creo il nuovo percorso
CMoPoint pI(m_map.ToMapPoint(float(X),float(Y))); CMoRectangle rTmp(m_map.TrackRectangle());
m_mission_area = tLayer.AddEvent(rTmp, m_mission_area_symbolIndex);
CMoPoint pC = rTmp.GetCenter();
m_pLawnMoverPath = new LawnMower(pI.GetX(), pI.GetY(), pC.GetX(), pC.GetY() );
// Create AUV Object m_pAUV = new AUV(); m_pAUV->m_center = pI;
if ( pI.GetX() <= pC.GetX() )
if ( pI.GetY() <= pC.GetY() ) // primo quadrante m_pAUV->m_orientation = 3.1416*0.5;
else
// quarto quadrante
m_pAUV->m_orientation = 0.0; else
if ( pI.GetY() <= pC.GetY() ) // secondo quadrante m_pAUV->m_orientation = 3.1416; else // terzo quadrante m_pAUV->m_orientation = 3.1416*1.5; m_readyToStart = TRUE; break; }
case ID_MP_SETWAYPOINTS: {
if (m_simulationInProgress) return;
DeletePrevMission();
//create WaypointsPath Object
m_pWaypointsPath = new WaypointsPath();
CMoLine* pLine = new CMoLine(m_map.TrackLine()); if (!pLine) { MessageBox("Empty Line!"); return;}
try {
m_pWaypointsPath->SetPath( pLine ); } catch(CString err) { MessageBox(err); return;}
VARIANT vlong;
VariantInit(&vlong);
vlong.vt = VT_I4;
vlong.lVal = 0;
// Create AUV Object m_pAUV = new AUV(); m_pAUV->m_center.GetX(); m_pAUV->m_center.SetX( 45.0 ); m_pAUV->m_center = m_pWaypointsPath->m_pWaypoints->Item( vlong ); if (m_pWaypointsPath->m_pWaypoints->GetCount() <= 1) m_pAUV->m_orientation = 0.0; else { vlong.lVal++;
CMoPoint pNext = m_pWaypointsPath->m_pWaypoints->Item( vlong );
double deltaX = pNext.GetX() - m_pAUV->m_center.GetX();
double deltaY = pNext.GetY() - m_pAUV->m_center.GetY();
m_pAUV->m_orientation = atan2( deltaY, deltaX ); } TrackingLayerRefresh(); m_readyToStart = true; break; } case ID_MAP_OBJADD1: { if (m_simulationInProgress) return; CMoPoint mapPt(m_map.ToMapPoint(float(X),float(Y))); m_objects_collection.Add(mapPt); TrackingLayerRefresh(); break; } case ID_MAP_OBJADD10: { if (m_simulationInProgress) return; CMoRectangle rTmp(m_map.TrackRectangle()); CMoPoint mapPt(m_map.ToMapPoint(float(X),float(Y))); double x,y;
for ( int i = 0; i < 10; i++ ) { x = rTmp.GetLeft() + ((double)rand() / (double)RAND_MAX) * rTmp.GetWidth(); y = rTmp.GetBottom() + ((double)rand() / (double)RAND_MAX) * rTmp.GetHeight(); mapPt.SetX(x); mapPt.SetY(y);
m_objects_collection.Add( mapPt ); } TrackingLayerRefresh(); break; } case ID_MAP_OBJADD100: { if (m_simulationInProgress) return; CMoRectangle rTmp(m_map.TrackRectangle()); CMoPoint mapPt(m_map.ToMapPoint(float(X),float(Y))); double x,y;
for ( int i = 0; i < 100; i++ ) { x = rTmp.GetLeft() + ((double)rand() / (double)RAND_MAX) * rTmp.GetWidth(); y = rTmp.GetBottom() + ((double)rand() / (double)RAND_MAX) * rTmp.GetHeight(); mapPt.SetX(x); mapPt.SetY(y); m_objects_collection.Add( mapPt ); } TrackingLayerRefresh(); break; } case ID_MAP_ZOOMIN: { CMoRectangle r(m_map.TrackRectangle()); if (LPDISPATCH(r)) m_map.SetExtent(r); break; } case ID_MAP_ZOOMOUT: {
// zoom out around the current point
CMoPoint pt( m_map.ToMapPoint((float)X, (float)Y) ); m_map.CenterAt(pt.GetX(),pt.GetY()); CMoRectangle r(m_map.GetExtent()); r.ScaleRectangle(1.5); m_map.SetExtent(r); break; } case ID_MAP_PAN: m_map.Pan(); break; }//end switch }
else if(Button == 2) // right click: always zoom out {
// zoom out around the current point
CMoPoint pt( m_map.ToMapPoint((float)X, (float)Y) ); m_map.CenterAt(pt.GetX(),pt.GetY());
CMoRectangle r(m_map.GetExtent()); r.ScaleRectangle(1.5);
m_map.SetExtent(r); }
else if(Button == 4) // Tasto centrale: always pan { m_map.Pan(); } } void CVeicoliView::DeletePrevMission() { if (m_pAUV)
{ delete m_pAUV; m_pAUV = NULL; } if (m_pMLOs) { delete m_pMLOs; m_pMLOs = NULL; }
// cancello il percorso precedente se esiste if(m_pLawnMoverPath) { delete m_pLawnMoverPath; m_pLawnMoverPath = NULL; } if (m_pWaypointsPath) { delete m_pWaypointsPath; m_pWaypointsPath = NULL; } CMoTrackingLayer tLayer(m_map.GetTrackingLayer()); if (LPDISPATCH(m_mission_area)) { tLayer.RemoveEvent( m_mission_area.GetIndex() ); m_mission_area.ReleaseDispatch(); //Importante, da non dimenticare mai!!! (Quantomeno per i GEOEVENTS)
// Il ReleaseDispatch fa si che risulti LPDISPATCH(m_mission_area) = NULL.
// Altrimenti avrei solo rimosso l'oggetto, ma il 'puntatore' (dispatch) sarebbe
// rimasto pendente (con rischio di errori a run time)
}
// cancello gli oggetti trovati nella precedente missione
// (a meno che non si vogliano fare missioni cumulative) if (!m_cumulativeMissions) { long c; int i; c = m_objects_discovered.GetCount(); for (i = 0; i < c; i++ ) m_objects_discovered.Remove(0); c = m_objects_missed.GetCount(); for (i = 0; i < c; i++ ) m_objects_missed.Remove(0);
// rimuovo oggetti trovati dalla lista m_objList.Reset(); m_ctlObjectList.ResetContent(); m_mcs_meanDP = 0.0; } ReleaseTracePolys(); m_ctlTracesList.ResetContent(); m_trace_polysIndex = 0; UpdateTraceEdits(); m_tempo_trascorso = 0.0; m_spazio_percorso = 0.0; UpdateData(FALSE); TrackingLayerRefresh(); } void CVeicoliView::ReleaseTracePolys() {
for (int i = 0; i < m_trace_polys.GetSize(); i++) {
m_trace_polys[i]->ReleaseDispatch(); delete m_trace_polys[i];
}
} void CVeicoliView::OnMapFullextent() { CMoRectangle r(m_map.GetFullExtent()); m_map.SetExtent(r); }
void CVeicoliView::OnMouseMoveMap1(short Button, short Shift, long X, long Y) {
// TODO: Add your control notification handler code here switch (m_curTool) { case ID_MAP_ZOOMIN: m_map.SetMousePointer(moZoomIn); break; case ID_MAP_ZOOMOUT: m_map.SetMousePointer(moZoomOut); break; case ID_MAP_PAN: m_map.SetMousePointer(moPan); break; case ID_MP_SETMISSIONAREA: case ID_MP_SETWAYPOINTS: m_map.SetMousePointer(moCross); break; case ID_MAP_OBJADD1: case ID_MAP_OBJADD10: case ID_MAP_OBJADD100: m_map.SetMousePointer(moHotLink); break; } } BOOL CVeicoliView::DestroyWindow() { KillTimer(1); return CRecordView::DestroyWindow(); }
void CVeicoliView::OnSimulationTool(UINT nID) { switch(nID) { case ID_SIMULATION_START: if (m_readyToStart) { m_curSimulTool = nID; m_readyToStart = FALSE;
VERIFY(SetTimer(1, m_timerTick, 0)); // timer in millesimi di secondo m_simulationInProgress = TRUE; m_msgfine = ""; switch(m_curTool) { case ID_MP_SETMISSIONAREA: case ID_MP_SETWAYPOINTS: case ID_MAP_OBJADD1: case ID_MAP_OBJADD10: case ID_MAP_OBJADD100: OnMapTool(ID_MAP_ZOOMIN); } } break; case ID_SIMULATION_PAUSE: if (m_simulationInProgress) { m_curSimulTool = nID; KillTimer(1);
m_readyToStart = TRUE; } break; case ID_SIMULATION_STOP: if (m_simulationInProgress) { if (m_msgfine == "") {
// MessageBox("simulazione interrotta");//NB: sostituirci question "sei Sicuro?"
m_msgfine = "Missione interrotta dall'utente. \n\n"; } m_curSimulTool = nID; KillTimer(1); m_simulationInProgress = FALSE; m_readyToStart = FALSE; char temp[10];
m_msgfine += "Tempo trascorso: "; gcvt(m_tempo_trascorso,8,temp); m_msgfine += temp;
m_msgfine += " minuti. \n Spazio percorso: "; gcvt(m_spazio_percorso,8,temp);
m_msgfine += temp;
m_msgfine += " metri. \n Velocità: ";
gcvt(m_pAUV->GetMaxVelocity(),4,temp); m_msgfine += temp;
m_msgfine += " metri al secondo."; MessageBox(m_msgfine);
}
break; }
}
void CVeicoliView::OnUpdateSimulationTool(CCmdUI* pCmdUI) { pCmdUI->SetCheck(pCmdUI->m_nID == m_curSimulTool); } void CVeicoliView::OnObjdeleteall() { if (m_simulationInProgress) return; long c = m_objects_collection.GetCount(); int i; for (i = 0; i < c; i++ ) m_objects_collection.Remove(0); c = m_objects_discovered.GetCount(); for (i = 0; i < c; i++ ) m_objects_discovered.Remove(0); c = m_objects_missed.GetCount(); for (i = 0; i < c; i++ ) m_objects_missed.Remove(0); TrackingLayerRefresh(); } void CVeicoliView::OnChecktrace() { m_showTrace = (m_checkTrace.GetCheck() == 1) ? 1 : 0; UpdateTraceEdits(); TrackingLayerRefresh(); } void CVeicoliView::OnCheckssstrace() { if(m_pAUV) { m_pAUV->m_SSSvisible = (m_checkSSSTrace.GetCheck() == 1) ? 1 : 0;
UpdateTraceEdits(); TrackingLayerRefresh(); } } void CVeicoliView::OnCheckauv() { if(m_pAUV) { m_pAUV->m_visible = (m_checkAUV.GetCheck() == 1) ? 1 : 0; TrackingLayerRefresh(); } } void CVeicoliView::OnCheckcumulative() { m_cumulativeMissions = (m_checkCumulative.GetCheck() == 1)? 1 : 0; } void CVeicoliView::OnSelchangeListtraces() { m_trace_polysIndex = m_ctlTracesList.GetCurSel(); UpdateTraceEdits(); TrackingLayerRefresh(); } void CVeicoliView::TrackingLayerRefresh() { CMoRectangle rFullExtent(m_map.GetFullExtent()); VARIANT vaFullExtent; VariantInit(&vaFullExtent); vaFullExtent.vt = VT_DISPATCH; vaFullExtent.pdispVal = rFullExtent.m_lpDispatch; CMoTrackingLayer tLayer(m_map.GetTrackingLayer()); tLayer.Refresh(true, vaFullExtent); } void CVeicoliView::OnAfterTrackingLayerDrawMap1(long hDC) {
//Note: se tento di usare 'm_map.DrawShape(..)' al di fuori di questa routine //mi viene visualizzato il msg:
//"Drawing is only permitted in response to BeforeLayerDraw, AfterLayerDraw //BeforeTrackingLayerDraw and AfterTrackingLayerDraw events."
CMoTrackingLayer tLayer(m_map.GetTrackingLayer()); CMoSymbol sym;
// first of all: draw SSSshape and trace
if (m_pAUV && m_pAUV->m_SSSvisible)// /*&& m_showTrace) {
sym = tLayer.GetSymbol(m_trace_symbolIndex); m_map.DrawShape( m_pAUV->m_SSSshape , sym); } if (m_showTrace) { sym = tLayer.GetSymbol(m_trace_symbolIndex); if (m_trace_polysIndex < m_trace_polys.GetSize()) m_map.DrawShape(*m_trace_polys[m_trace_polysIndex], sym); }
// second: draw objects
if (m_objects_collection.GetCount() != 0) { sym = tLayer.GetSymbol(m_object_symbolIndex); sym.SetColor(moYellow); sym.SetCharacterIndex(m_object_symbolDefault); m_map.DrawShape(m_objects_collection, sym); } if (m_objects_discovered.GetCount() != 0) { sym = tLayer.GetSymbol(m_object_symbolIndex); sym.SetColor(moGreen); sym.SetCharacterIndex(m_object_symbolDiscovered); m_map.DrawShape(m_objects_discovered, sym);
} if (m_objects_missed.GetCount() != 0) { sym = tLayer.GetSymbol(m_object_symbolIndex); sym.SetColor(moRed); sym.SetCharacterIndex(m_object_symbolMissed); m_map.DrawShape(m_objects_missed, sym); }
// third: draw waypointsPath and waypoints if (m_pWaypointsPath)
{
sym = tLayer.GetSymbol(m_waypointsPath_symbolIndex); m_map.DrawShape( *(m_pWaypointsPath->m_pPath), sym);
if (m_pWaypointsPath->m_pWaypoints != NULL && m_pWaypointsPath->m_pWaypoints->GetCount() != 0)
{
sym = tLayer.GetSymbol(m_waypoints_symbolIndex); m_map.DrawShape( *(m_pWaypointsPath->m_pWaypoints) , sym);
}
}
// fourth: above all draw AUV shape if (m_pAUV && m_pAUV->m_visible) {
sym = tLayer.GetSymbol(m_auv_symbolIndex); m_map.DrawShape( m_pAUV->m_shape , sym); }
}
void CVeicoliView::OnKillfocusEditconfidence() {
if(!UpdateData()) return;//retrive data from dialog box
if(m_mcs_confidence < CONFIDENCEMIN) m_mcs_confidence = CONFIDENCEMIN; if(m_mcs_confidence > CONFIDENCEMAX) m_mcs_confidence = CONFIDENCEMAX;
double eps2 = m_mcs_accuracy/100 * m_mcs_accuracy/100; double arg = (1 - m_mcs_confidence/100) / 2;
m_mcs_samples = ceil( -1/(2*eps2) * log(arg) );
if(m_mcs_samples < 1) m_mcs_samples = 1;
UpdateData(FALSE);//send data to dialog box }
void CVeicoliView::OnKillfocusEditaccuracy() {
if(!UpdateData()) return; //retrive data from dialog box
if(m_mcs_accuracy < ACCURACYMIN) m_mcs_accuracy = ACCURACYMIN; if(m_mcs_accuracy > ACCURACYMAX) m_mcs_accuracy = ACCURACYMAX;
double eps2 = m_mcs_accuracy/100 * m_mcs_accuracy/100; double arg = (1 - m_mcs_confidence/100) / 2;
m_mcs_samples = ceil( -1/(2*eps2) * log(arg) );
if(m_mcs_samples < 1) m_mcs_samples = 1;
UpdateData(FALSE); //send data to dialog box }
void CVeicoliView::OnButtonStartMCS() {
if (m_trace_polys.GetSize() == 0 || m_trace_polys[0]->GetArea() == 0.0) {
MessageBox("To execute a Monte Carlo Simulation:\n\n"
"\t 1) First execute a standard, graphical, simulation; \n"
"\t 2) Than set Monte Carlo Simulation parameters ('Accuracy' and 'Confidence') \n"
"\t and press the 'Start Simulation' button."); return;
//delete all objects OnObjdeleteall(); m_objList.Reset();
m_ctlObjectList.ResetContent(); m_mcs_startbutton.SetState(true);
//set trace extension
CMoRectangle rExtent = m_trace_polys[0]->GetExtent(); VARIANT vaExtent; VariantInit(&vaExtent); vaExtent.vt = VT_DISPATCH; vaExtent.pdispVal = rExtent.m_lpDispatch; CMoTrackingLayer tLayer(m_map.GetTrackingLayer()); //create variables CMoPoint* pMapPt;
int nTrace = m_trace_polys.GetSize(); double dR = m_pAUV->Get_dR();
double dY = m_pAUV->Get_dY(); m_mcs_meanDP = 0;
CMoPoint* pTmp = new CMoPoint(m_pAUV->m_center.m_lpDispatch); m_objects_missed.Add( *pTmp );
m_objects_missed.Add( *pTmp ); m_objects_discovered.Add( *pTmp ); double nDetect = 0;
// main loop
for ( int i = 0; i < m_mcs_samples; i++ ) {
pMapPt = new CMoPoint();
pMapPt->CreateDispatch("MapObjects2.Point");
double objX = rExtent.GetLeft() + ((double)rand()/(double)RAND_MAX) * rExtent.GetWidth();
double objY = rExtent.GetBottom() + ((double)rand()/(double)RAND_MAX) * rExtent.GetHeight();
pMapPt->SetX(objX); pMapPt->SetY(objY);
if ( !m_trace_polys[0]->IsPointIn( *pMapPt ) )
{
i--; // loop again, try a new point
//m_objects_collection.Add( pMapPt->DetachDispatch() ); //tLayer.Refresh(true, vaExtent); //MessageBox("mancato"); continue; } else {
bool detected = false;
for (int j = 0; j < nTrace && m_trace_polys[j]->IsPointIn( *pMapPt ); j++) {
try {
bool d = TryToDetect(*pMapPt, m_pMLOs->m_nObjects, dR, dY, vaExtent); detected = detected || d; //m_trace_polysIndex = j; //tLayer.Refresh(true, vaExtent); //MessageBox("pausa"); } catch(...) { //MessageBox("eccolo!"); } } if (detected) nDetect++; m_mcs_meanDP = nDetect / (i+1) * 100; UpdateData(FALSE);
}
//if (i%100 == 0) tLayer.Refresh(true, vaExtent); }
//MessageBox("REMOVE");
//m_objects_collection.Remove( 0 ); m_objects_missed.Remove( 0 ); m_objects_missed.Remove( 0 );
m_objects_discovered.Remove( 0 );
m_mcs_startbutton.SetState(false); TrackingLayerRefresh();
}
bool CVeicoliView::TryToDetect(CMoPoint mapPt, int nObj, double dR, double dY, VARIANT vaExtent) {
bool detected;
//pesco a caso per vedere che oggetto ho trovato
//fra quelli presenti nel DB; se l'oggetto è nuovo manterrò questa //impostazione, sennò IsNewElem mi fornirà l'impostazione giusta int oggID = (int)ceil( (double)rand()/(double)RAND_MAX * nObj ); // verifico se è un nuovo oggetto
BOOL isNewObj = m_objList.IsNewElem( mapPt.GetX(), mapPt.GetY(), oggID );
//recupero le caratteristiche dell'oggetto m_pSetOgg->MoveFirst();
for (int j = 1; j < oggID; j++) m_pSetOgg->MoveNext();
double raggio = 0.01 * m_pSetOgg->m_Raggio; //lo uso per dY e dR double probDimensioni = 1 * sqrt( (raggio/dR*0.01)*(raggio/dR*0.01) + (raggio/dY)*(raggio/dY) ); //NB 0.01 * dR !!!!!
double probIntrinseca = 0.01 * m_pSetOgg->m_Prob_Detect; //prob. aggiuntiva (le compongo)
double probDetection = probDimensioni * probIntrinseca; probDetection = (probDetection > 1.0) ? 1.0 : probDetection;
// preparo la frase da stampare a video CString stringa = " ";
char carat[15];
stringa += " X = "; gcvt(mapPt.GetX(), 8, carat); stringa += carat; stringa += " Y = "; gcvt(mapPt.GetY(), 8, carat); stringa += carat; stringa += " R = "; gcvt(raggio*100, 6, carat); stringa += carat; stringa += " M: "; stringa += m_pSetOgg->m_Materiale;
stringa += " A: "; stringa += (m_pSetOgg->m_Artificiale?"Si":"No"); stringa += " L: "; stringa += m_pSetOgg->m_Locazione;
stringa += " PD = "; gcvt(probDetection*100, 3, carat); stringa += carat;
// tiro un dado per vedere se l'ho visto
detected = ( (double)rand()/(double)RAND_MAX <= probDetection )? 1 : 0;
return detected; }
VeicoliView_OnTimer.cpp
// VeicoliView_OnTimer.cpp
#include "defines.h"
void CVeicoliView::OnTimer(UINT nIDEvent) {
if(nIDEvent == 1) {
KillTimer(1); //stoppo il timer per poter provvedere alla simulazione
/*--- INIZIALIZZAZIONI PER L'AVVIO DELLA SIMULAZIONE---*/ //Le seguenti righe di codice hanno effetti solo al primo passo della simulazione static double maxStepSize; // static affinché non risentano di spippolamenti sul //static double dY;// dataset a simulazione in corso (vengono aggiornati
//static double dR;// solo ad inizio simulazione) //static bool firstscan;
if (m_tempo_trascorso == 0.0)
{
//inizializzo i parametri del veicolo prescelto
m_pAUV->m_autonomy = atof(m_pSetEne->m_Autonomia); m_pAUV->m_navigationPrecision = 0; m_pAUV->m_SSSfrequency = m_pSetMis->m_Frequenza; m_pAUV->m_SSSband = m_pSetMis->m_Banda; m_pAUV->m_SSSlength = m_pSetMis->m_Larghezza_cortina; m_pAUV->m_SSSlobes = m_pSetMis->m_Lobi_preformati; m_pAUV->m_SSSrange = m_pSetMis->m_Range; m_pAUV->m_SSSswath = m_pSetMis->m_Swath;
maxStepSize = m_pAUV->Get_dY() * m_simulationScale;
if (m_pLawnMoverPath) m_pLawnMoverPath->SetVehicleParam(m_pAUV->m_SSSrange , m_pAUV->m_SSSswath , m_pAUV->m_navigationPrecision, maxStepSize); m_pAUV->m_visible = true; //m_pAUV->m_SSSvisible = true;
//inizializzo i parametri degli oggetti del DataBase m_pMLOs = new MLO();
int nObjects = 0; m_pSetOgg->MoveFirst(); while(!m_pSetOgg->IsEOF()) { nObjects++; m_pSetOgg->MoveNext(); } m_pMLOs->m_nObjects = nObjects; } CMoTrackingLayer tLayer(m_map.GetTrackingLayer()); CMoRectangle rFullExtent(m_map.GetFullExtent());
VARIANT vaFullExtent; //NB: importante differenza:
VariantInit(&vaFullExtent); // -) se faccio extent.DetachDispatch() DISTACCO il puntatore da
vaFullExtent.vt = VT_DISPATCH; // l'identificatore extent, che non sarà più utilizzabile!
vaFullExtent.pdispVal = rFullExtent.m_lpDispatch;// -) con extent.m_lpDispatch ne faccio invece solo una copia;
/*--- CALCOLO DEL PASSO DI SIMULAZIONE ---*/ //Nelle seguenti righe di codice viene effettuato il calcolo del successivo passo //di simulazione. In realtà, in fase di inizializzazione si è provveduto a
//modificare la lunghezza di maxStepSize al fine di velocizzare la simulazione, //in modo da compiere un unico passo gigante, di lunghezza pari a
//'m_simulationScale' passi (ogni passo è calcolato in base al 'dY' del SONAR; //così facendo si fa un unico passo di lunghezza 'm_simulationScale'*'dY').
double xOffset = 0; double yOffset = 0;
bool finish = false; bool scanning = true;
if (m_pLawnMoverPath)
m_pLawnMoverPath->Step(xOffset, yOffset, scanning, finish);
if (m_pWaypointsPath)
m_pWaypointsPath->ComputeStep(m_pAUV, maxStepSize, 3.1416/4, xOffset, yOffset);
/*--- MOVIMENTO DEL VEICOLO ---*/ if (m_pLawnMoverPath && !finish)
{
//calcolo l'orientazione del veicolo
if ( xOffset > 0 ) m_pAUV->m_orientation = 0.0; else if ( xOffset < 0 ) m_pAUV->m_orientation = 3.1416; else if ( yOffset > 0 ) m_pAUV->m_orientation = 3.1416*0.5; else /* ( yOffset < 0 )*/ m_pAUV->m_orientation = 3.1416*1.5;
// Muovo il veicolo m_pAUV->Traslate(xOffset, yOffset); } bool collision; m_auvX = m_pAUV->m_center.GetX(); m_auvY = m_pAUV->m_center.GetY();
m_auvZ = GetSeaDepth(m_auvX, m_auvY, collision);
//verifica di non collisione if (collision) {
m_msgfine = "Incontrato Ostacolo, simulazione terminata \n\n "; OnSimulationTool(ID_SIMULATION_STOP);
return;
}
/*--- ANALISI DELL'AREA ILLUMINATA DAL SONAR ---*/
// Se lo scan è attivo traccio l'area scandagliata dal SSS con due rettangoli if (!scanning)
m_pAUV->m_SSSvisible = false;
else
{
//se il relativo check button è attivo disegno l'area del SSS
if (m_checkSSSTrace.GetCheck() == 1) m_pAUV->m_SSSvisible = true;
// to avoid a numeric problem on SSSshape:
//il problema era sulle unità di misura dell'area.... veniva 0.0 anche quandi area != 0.
// con l'union mi viene un valore di area corretto //m_pAUV->m_SSSshape.GetArea();
LPDISPATCH disp = m_pAUV->m_SSSshape.Union( m_pAUV->m_SSSshape, vaFullExtent); if (disp) { m_pAUV->m_SSSshape.ReleaseDispatch(); m_pAUV->m_SSSshape.AttachDispatch(disp); //m_pAUV->m_SSSshape.GetArea(); try{
// Calcolo la forma della traccia lasciata dal SSS
ComputeTracePolys( &(m_pAUV->m_SSSshape), 0, vaFullExtent); } catch(...) { };//MessageBox("Bug");}//MessageBox("ERR in compute trace polys "); }
// ricerco i punti illuminati dal SSS tramite i due lobi del SSS
ComputeEnlightedObjects(m_pMLOs->m_nObjects , m_pAUV->Get_dR(), m_pAUV->Get_dY(), vaFullExtent);
}
else { };//MessageBox("Bug"); }//MessageBox("ERR nell'union dell'SSSshape"); }
} // end if (scanning) ;
// Refresh
TrackingLayerRefresh();
/*--- AGGIORNAMENTO DELLE STATISTICHE E RIAVVIO DEL TIMER ---*/
m_spazio_percorso += sqrt(xOffset*xOffset + yOffset*yOffset);
m_tempo_trascorso += sqrt(xOffset*xOffset + yOffset*yOffset) / m_pAUV->GetMaxVelocity() / 60 ;
double tot = m_objects_missed.GetCount() + m_objects_discovered.GetCount(); double detect = m_objects_discovered.GetCount();
if(!tot) m_mcs_meanDP = 0;
else m_mcs_meanDP = detect / tot * 100;
if (m_tempo_trascorso >= m_pAUV->m_autonomy) {
m_msgfine = "Autonomia Esaurita, Missione Interrotta \n\n "; OnSimulationTool(ID_SIMULATION_STOP);
return;
}
if (m_pLawnMoverPath) if (finish) {
m_msgfine = "Missione Completata \n\n "; OnSimulationTool(ID_SIMULATION_STOP); return;
}
if (m_pWaypointsPath)
if (m_pWaypointsPath->m_finish) {
m_msgfine = "Missione Completata \n\n "; OnSimulationTool(ID_SIMULATION_STOP); return;
}
//Aggiorno gli editor ausiliari sulla traccia UpdateTraceEdits();
//UpdateData(FALSE); //lo fa già UpdateTraceEdits();
#ifdef STEPBYSTEP OnSimulationTool(ID_SIMULATION_PAUSE); #else // riavvio il timer VERIFY(SetTimer(1, m_timerTick, 0)); #endif //STEPBYSTEP
/*--- FINE DELLA ROUTINE DI SIMULAZIONE---*/
}// end if (nIDEvent == 1)
CRecordView::OnTimer(nIDEvent);
//TODO: eventualmente si può provare a spostare il riavvio del timer qui } /**************************************************************************************/ //////////////////////////////////////////////////////////////////////////////////////// ///////////////// OTHER FUNCTIONS //////////////////////////// //////////////////////////////////////////////////////////////////////////////////////// /**************************************************************************************/ void CVeicoliView::UpdateTraceEdits() {
//Aggiorno List Box che contiene Trace Index
if (m_ctlTracesList.GetCount() < m_trace_polys.GetSize())
{
m_ctlTracesList.ResetContent(); char str[5];
for (int k=0; k<m_trace_polys.GetSize(); k++) {
itoa(k+1,str,10);
m_ctlTracesList.AddString(str); }