• Non ci sono risultati.

Sviluppo di modelli e simulazioni per pianificazione e valutazione di veicoli subacquei autonomi

N/A
N/A
Protected

Academic year: 2021

Condividi "Sviluppo di modelli e simulazioni per pianificazione e valutazione di veicoli subacquei autonomi"

Copied!
45
0
0

Testo completo

(1)

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);

};

(2)

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();

};

(3)

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_)

(4)

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

(5)

// 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();

(6)

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.

(7)

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 ;

(8)

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();

(9)

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

(10)

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);

(11)

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();

(12)

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;

(13)

}

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;

(14)

} 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; } }

(15)

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"); }

(16)

//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; } } }

(17)

void WaypointsPath::ComputeNextWaypoint() { m_vaIndex.lVal++; if (m_pWaypoints->GetCount() == m_vaIndex.lVal) { m_finish = true; return; }

m_nextWaypoint = m_pWaypoints->Item( m_vaIndex ); }

(18)

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

(19)

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) {

(20)

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;

(21)

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);

(22)

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

(23)

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()

(24)

{ }

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() {

(25)

}

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

(26)

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; }

(27)

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);

(28)

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)

(29)

{ 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];

}

(30)

} 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);

(31)

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;

(32)

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);

(33)

} 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;

(34)

//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 );

(35)

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; }

(36)

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

(37)

//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"); }

(38)

} // 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); }

Riferimenti

Documenti correlati

Reckoning with the modern spatial discourse, from the symbolic and figurative aspects of the Athens Charter to the theories of Ebenezer Howard’s Garden Cities of Tomorrow and

Inoltre esso ha temperatura inferiore a quella del vapore che sale e in ogni piatto quindi, mescolandosi vapori più caldi e meno ricchi nel componente più volatile con liquidi

In 2019, the European project of Atlas World Heritage was launched to identify the best management strategies to overcome overtourism in Art Cities, with the participation of five

disciplina, quanto nella definizione di “Terzo settore”, richiama proprio questo principio.. E questo, lo si ripete, solo per citarne alcune che sembrano fra quelle

• utilizzi la funzione leggi per caricare da tastiera n righe della matrice memorizzando in un vettore di interi m quanti valori contiene ogni riga della matrice. • utilizzi

La funzione father deve moltiplicare per 2 il valore di n (modificandolo) e visualizzare il messaggio &#34;Padre&#34;, il pid del processo ed il valore attualmente contenuto in n.

[r]

Analytical model for the evolution of soil water characteristic curve with void ratio including hydraulic hysteresis - Journal of Engineering Mechanics - under