From ab392fb4e254a8dca07c9c21f7fe05e15b2c9247 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Wed, 4 Jan 2017 18:50:51 +0000 Subject: [PATCH] EgtMachKernel : - razionalizzazione simulatore - in caricamento macchina, generazione e simulazione non viene impostata modifica progetto. --- Disposition.cpp | 2 +- Machine.h | 2 +- MachineCalc.cpp | 10 +- MachineLua.cpp | 20 +- Machining.cpp | 2 +- Operation.cpp | 2 +- Simulator.cpp | 625 ++++++++++++++++++++++++------------------------ Simulator.h | 7 +- 8 files changed, 344 insertions(+), 326 deletions(-) diff --git a/Disposition.cpp b/Disposition.cpp index 7a7effa..80f613a 100644 --- a/Disposition.cpp +++ b/Disposition.cpp @@ -1048,7 +1048,7 @@ Disposition::SpecialApply( bool bRecalc) bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + EVAR_TABNAME, m_sTabName) ; bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + EVAR_DISPID, m_nOwnerId) ; // eseguo - bOk = bOk && pMch->LuaCallFunction( ON_SPECIAL_APPLY) ; + bOk = bOk && pMch->LuaCallFunction( ON_SPECIAL_APPLY, false) ; // recupero valori parametri obbligatori bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_ERROR, nErr) ; bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_HEAD, m_sHead) ; diff --git a/Machine.h b/Machine.h index 6b1ed08..47949fc 100644 --- a/Machine.h +++ b/Machine.h @@ -119,7 +119,7 @@ class Machine bool UnlinkFixtureFromGroup( int nFxtId) ; bool UnlinkAllFixturesFromGroups( void) ; bool LuaExistsFunction( const std::string& sFun) ; - bool LuaCallFunction( const std::string& sFun) ; + bool LuaCallFunction( const std::string& sFun, bool bSetModifiedOff = true) ; bool LuaCreateGlobTable( const std::string& sName) ; bool LuaResetGlobVar( const std::string& sName) ; template diff --git a/MachineCalc.cpp b/MachineCalc.cpp index 11fb8c3..2d12ed8 100644 --- a/MachineCalc.cpp +++ b/MachineCalc.cpp @@ -20,8 +20,8 @@ #include "Axis.h" #include "Head.h" #include "Exit.h" -#include "/EgtDev/Include/EGkGeoVector3d.h" #include "/EgtDev/Include/EMkToolConst.h" +#include "/EgtDev/Include/EGkGeoVector3d.h" #include "/EgtDev/Include/EGnStringUtils.h" #include "/EgtDev/Include/EGnFileUtils.h" @@ -54,10 +54,14 @@ Machine::SetCurrTable( const string& sTable) } // lancio eventuale funzione lua di personalizzazione if ( LuaExistsFunction( ON_SET_TABLE)) { + // definisco variabili bool bOk = LuaCreateGlobTable( EMC_VAR) ; bOk = bOk && LuaSetGlobVar( EMC_VAR + EVAR_TABNAME, sTable) ; + // chiamo funzione bOk = bOk && LuaCallFunction( ON_SET_TABLE) ; + // reset variabili bOk = bOk && LuaResetGlobVar( EMC_VAR) ; + // restituisco risultato return bOk ; } else @@ -216,14 +220,18 @@ Machine::SetCurrTool( const string& sTool, const string& sHead, int nExit) m_dCalcTOvRad = dTOvDiam / 2 ; // lancio eventuale funzione lua di personalizzazione if ( LuaExistsFunction( ON_SET_HEAD)) { + // definisco variabili bool bOk = LuaCreateGlobTable( EMC_VAR) ; bOk = bOk && LuaSetGlobVar( EMC_VAR + EVAR_HEAD, sHead) ; bOk = bOk && LuaSetGlobVar( EMC_VAR + EVAR_EXIT, nExit) ; bOk = bOk && LuaSetGlobVar( EMC_VAR + EVAR_TOOL, sTool) ; bOk = bOk && LuaSetGlobVar( EMC_VAR + EVAR_TOTDIAM, dTOvDiam) ; bOk = bOk && LuaSetGlobVar( EMC_VAR + EVAR_TOTLEN, dTOvLen) ; + // chiamo funzione bOk = bOk && LuaCallFunction( ON_SET_HEAD) ; + // reset variabili bOk = bOk && LuaResetGlobVar( EMC_VAR) ; + // in caso di errore esco if ( ! bOk) return false ; } diff --git a/MachineLua.cpp b/MachineLua.cpp index cfbf1f7..c72b2e0 100644 --- a/MachineLua.cpp +++ b/MachineLua.cpp @@ -16,6 +16,7 @@ #include "MachMgr.h" #include "DllMain.h" #include "/EgtDev/Include/EXeExecutor.h" +#include "/EgtDev/Include/EXeSetModifiedOff.h" #include "/EgtDev/Include/EGkGeomDB.h" #include "/EgtDev/Include/EGkLuaAux.h" #include "/EgtDev/Include/EGnStringUtils.h" @@ -138,21 +139,30 @@ Machine::LuaExistsFunction( const string& sFun) //---------------------------------------------------------------------------- bool -Machine::LuaCallFunction( const string& sFun) +Machine::LuaCallFunction( const string& sFun, bool bSetModifiedOff) { // imposto contesto corretto int nOldCtx = ExeGetCurrentContext() ; if ( nOldCtx != m_pMchMgr->GetContextId()) ExeSetCurrentContext( m_pMchMgr->GetContextId()) ; + // se richiesto, disabilito gestione segnalazione modifiche progetto + bool bOldMod = false ; + if ( bSetModifiedOff) { + bOldMod = ExeGetEnableModified() ; + ExeDisableModified() ; + } // imposto l'oggetto corrente per Lua m_pMchLua = this ; // eseguo la funzione bool bOk = m_LuaMgr.CallFunction( sFun, 0) ; + // reset dell'oggetto corrente per Lua + m_pMchLua = nullptr ; + // ripristino gestione segnalazione modifiche progetto + if ( bSetModifiedOff && bOldMod) + ExeEnableModified() ; // ripristino contesto originale if ( nOldCtx != m_pMchMgr->GetContextId()) ExeSetCurrentContext( nOldCtx) ; - // reset dell'oggetto corrente per Lua - m_pMchLua = nullptr ; return bOk ; } @@ -207,10 +217,14 @@ Machine::LuaLoadMachine( const string& sFile) int nOldCtx = ExeGetCurrentContext() ; if ( nOldCtx != m_pMchMgr->GetContextId()) ExeSetCurrentContext( m_pMchMgr->GetContextId()) ; + // disabilito gestione segnalazione modifiche progetto + SetModifiedOff modOff ; // imposto l'oggetto corrente per Lua m_pMchLua = this ; // carico la macchina bool bOk = m_LuaMgr.ExecFile( sFile) ; + // ripristino gestione segnalazione modifiche progetto + modOff.Reset() ; // ripristino contesto originale if ( nOldCtx != m_pMchMgr->GetContextId()) ExeSetCurrentContext( nOldCtx) ; diff --git a/Machining.cpp b/Machining.cpp index bf6064c..1ad43e9 100644 --- a/Machining.cpp +++ b/Machining.cpp @@ -95,7 +95,7 @@ Machining::PostApply( void) bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + EVAR_PHASE, m_nPhase) ; bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + EVAR_MCHID, m_nOwnerId) ; // eseguo - bOk = bOk && pMch->LuaCallFunction( ON_POST_APPLY) ; + bOk = bOk && pMch->LuaCallFunction( ON_POST_APPLY, false) ; // recupero valori parametri obbligatori bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_ERROR, nErr) ; // recupero valori parametri opzionali diff --git a/Operation.cpp b/Operation.cpp index f7181d8..4ada86a 100644 --- a/Operation.cpp +++ b/Operation.cpp @@ -1526,7 +1526,7 @@ Operation::SpecialMoveZup( Vector3d& vtTool, DBLVECTOR& vAx, bool& bModif) bOk = bOk && pMch->LuaResetGlobVar( GetGlobVarAxisValue( i, EMC_VAR)) ; } // eseguo - bOk = bOk && pMch->LuaCallFunction( ON_SPECIAL_MOVEZUP) ; + bOk = bOk && pMch->LuaCallFunction( ON_SPECIAL_MOVEZUP, false) ; // recupero valori parametri obbligatori bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_ERROR, nErr) ; bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_MODIF, bModif) ; diff --git a/Simulator.cpp b/Simulator.cpp index 0d68608..e354674 100644 --- a/Simulator.cpp +++ b/Simulator.cpp @@ -1,13 +1,14 @@ //---------------------------------------------------------------------------- // EgalTech 2015-2016 //---------------------------------------------------------------------------- -// File : Simulator.cpp Data : 26.02.16 Versione : 1.6n8 +// File : Simulator.cpp Data : 04.01.17 Versione : 1.6x5 // Contenuto : Implementazione della classe Simulator. // // // // Modifiche : 19.10.15 DS Creazione modulo. // 26.02.16 DS Aggiunta gestione archi. +// 04.01.17 DS Riorganizzazione codice. // //---------------------------------------------------------------------------- @@ -68,84 +69,30 @@ Simulator::Init( MachMgr* pMchMgr) bool Simulator::Start( void) { - // verifico ci sia una macchinata corrente - if ( m_pMchMgr == nullptr) + // Verifico ci sia una macchinata corrente + if ( m_pMchMgr == nullptr || m_pMchMgr->GetCurrMachGroup() == GDB_ID_NULL) return false ; - int nMachGrp = m_pMchMgr->GetCurrMachGroup() ; - if ( nMachGrp == GDB_ID_NULL) - return false ; - // reset utensile e assi correnti + + // Reset utensile e assi correnti m_sTool.clear() ; - m_AxesName.clear() ; - m_AxesToken.clear() ; - m_AxesLinear.clear() ; + ResetAxes() ; + ResetAuxAxes() ; // porto la macchina in home if ( ! GoHome()) return false ; - // imposto fase iniziale - m_pMchMgr->SetCurrPhase( 1) ; - // verifico la disposizione iniziale della macchinata + + // Verifico la disposizione iniziale della macchinata m_nOpId = m_pMchMgr->GetFirstActiveOperation() ; m_nOpInd = 1 ; if ( m_pMchMgr->GetOperationType( m_nOpId) != OPER_DISP) return false ; - // definisco tavola variabili globali + + // Definisco tabella variabili globali bool bOk = m_pMachine->LuaCreateGlobTable( GLOB_VAR) ; - // recupero dati tavola macchina - Disposition* pDisp = GetDisposition( m_pGeomDB->GetUserObj( m_nOpId)) ; - string sTable ; - pDisp->GetTable( sTable) ; - Point3d ptOri1 ; - pDisp->GetTableRef1( ptOri1) ; - // richiamo gestione evento inizio e fine disposizione - if ( ! OnDispositionStart( m_nOpId, m_nOpInd, 1, sTable, ptOri1, true) || - ! OnDispositionEnd()) - return false ; - // cerco la prima lavorazione valida - m_nOpId = m_pMchMgr->GetNextActiveOperation( m_nOpId) ; - Machining* pMch = GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) ; - while ( m_nOpId != GDB_ID_NULL) { - if ( IsValidMachiningType( m_pMchMgr->GetOperationType( m_nOpId)) && - pMch != nullptr && ! pMch->IsEmpty()) - break ; - m_nOpId = m_pMchMgr->GetNextActiveOperation( m_nOpId) ; - pMch = GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) ; - } - if ( m_nOpId == GDB_ID_NULL) - return false ; - // aggiornamenti legati al cambio di lavorazione (utensile e assi conseguenti) - if ( ! UpdateTool()) - return false ; - - // richiamo gestione evento inizio lavorazione - ++ m_nOpInd ; - if ( ! OnMachiningStart( m_nOpId, m_nOpInd)) - return false ; - - // determino il primo percorso di lavoro - int nClId = m_pGeomDB->GetFirstNameInGroup( m_nOpId, MCH_CL) ; - m_nCLPathId = m_pGeomDB->GetFirstGroupInGroup( nClId) ; - m_nCLPathInd = 0 ; - m_nEntId = m_pGeomDB->GetFirstInGroup( m_nCLPathId) ; - m_nEntInd = 0 ; - m_dCoeff = 0 ; - // recupero punto di inizio del percorso - Point3d ptStart ; - m_pGeomDB->GetInfo( m_nCLPathId, KEY_START, ptStart) ; - // recupero versore estrusione associato al percorso (normale al piano di interpolazione) - Vector3d vtExtr ; - m_pGeomDB->GetInfo( m_nCLPathId, KEY_EXTR, vtExtr) ; - // recupero punti di minimo e massimo ingombro - Point3d ptMin, ptMax ; - m_pGeomDB->GetInfo( m_nCLPathId, KEY_PMIN, ptMin) ; - m_pGeomDB->GetInfo( m_nCLPathId, KEY_PMAX, ptMax) ; - // richiamo gestione evento inizio percorso di lavoro - ++ m_nCLPathInd ; - if ( ! OnPathStart( m_nCLPathId, m_nCLPathInd, ptStart, vtExtr, ptMin, ptMax)) - return false ; - - return true ; + // Arrivo alla preparazione per la prima lavorazione + int nStatus ; + return FindAndManageOperationStart( true, nStatus) ; } //---------------------------------------------------------------------------- @@ -153,266 +100,48 @@ bool Simulator::Move( int& nStatus) { // Verifiche - if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr || m_pMachine == nullptr) { + if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr || m_pMachine == nullptr) { nStatus = MCH_SIM_ERR ; return false ; } + // Se arrivato alla fine dell'interpolazione if ( m_dCoeff > 0.999) { // recupero una nuova entità m_nEntId = m_pGeomDB->GetNext( m_nEntId) ; m_dCoeff = 0 ; } + // Se arrivato alla fine di un percorso di lavoro if ( m_nEntId == GDB_ID_NULL) { - // richiamo gestione evento fine percorso di lavoro - if ( ! OnPathEnd()) { - nStatus = MCH_SIM_ERR ; + // gestione fine percorso di lavoro + if ( ! ManagePathEnd( nStatus)) + return false ; + // ricerca e gestione inizio percorso di lavoro + if ( ! FindAndManagePathStart( nStatus)) return false ; - } - // recupero un nuovo CLpath - while ( m_nEntId == GDB_ID_NULL) { - m_nCLPathId = m_pGeomDB->GetNextGroup( m_nCLPathId) ; - // se non ce ne sono altri, devo passare a una nuova lavorazione - if ( m_nCLPathId == GDB_ID_NULL) - break ; - m_nEntId = m_pGeomDB->GetFirstInGroup( m_nCLPathId) ; - m_dCoeff = 0 ; - } - // se trovato nuovo CLpath - if ( m_nEntId != GDB_ID_NULL) { - // recupero punto di inizio del percorso - Point3d ptStart ; - m_pGeomDB->GetInfo( m_nCLPathId, KEY_START, ptStart) ; - // recupero versore estrusione associato al percorso (normale al piano di interpolazione) - Vector3d vtExtr ; - m_pGeomDB->GetInfo( m_nCLPathId, KEY_EXTR, vtExtr) ; - // recupero punti di minimo e massimo ingombro - Point3d ptMin, ptMax ; - m_pGeomDB->GetInfo( m_nCLPathId, KEY_PMIN, ptMin) ; - m_pGeomDB->GetInfo( m_nCLPathId, KEY_PMAX, ptMax) ; - // richiamo gestione evento inizio percorso di lavoro - ++ m_nCLPathInd ; - if ( ! OnPathStart( m_nCLPathId, m_nCLPathInd, ptStart, vtExtr, ptMin, ptMax)) { - nStatus = MCH_SIM_ERR ; - return false ; - } - m_nEntInd = 0 ; - } } + // Se arrivato alla fine di una operazione if ( m_nCLPathId == GDB_ID_NULL) { - // richiamo gestione evento fine operazione - if ( ! OnOperationEnd()) { - nStatus = MCH_SIM_ERR ; + // gestione fine operazione + if ( ! ManageOperationEnd( nStatus)) + return false ; + // ricerca e gestione nuova operazione + if ( ! FindAndManageOperationStart( false, nStatus)) + return false ; + // se non ce ne sono altre, sono alla fine + if ( m_nOpId == GDB_ID_NULL) { + nStatus = MCH_SIM_END ; return false ; } - // recupero la successiva valida - while ( m_nCLPathId == GDB_ID_NULL) { - m_nOpId = m_pMchMgr->GetNextActiveOperation( m_nOpId) ; - while ( m_nOpId != GDB_ID_NULL) { - // se lavorazione valida - Machining* pMch = GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) ; - if ( pMch != nullptr && ! pMch->IsEmpty()) { - // aggiorno utensile e assi conseguenti - if ( ! UpdateTool()) { - nStatus = MCH_SIM_ERR ; - return false ; - } - ++ m_nOpInd ; - // richiamo gestione evento inizio lavorazione - if ( ! OnMachiningStart( m_nOpId, m_nOpInd)) { - nStatus = MCH_SIM_ERR ; - return false ; - } - break ; - } - // se disposizione con cambio di fase - Disposition* pDisp = GetDisposition( m_pGeomDB->GetUserObj( m_nOpId)) ; - if ( pDisp != nullptr) { - // in alcuni casi la disposizione non è inizializzata - pDisp->Init( m_pMchMgr) ; - // recupero dati tavola - string sTable ; - pDisp->GetTable( sTable) ; - Point3d ptOri1 ; - pDisp->GetTableRef1( ptOri1) ; - // se con movimenti autonomi - if ( ! pDisp->IsEmpty()) { - // richiamo gestione evento appena prima di inizio disposizione - if ( ! OnDispositionStarting( m_nOpId, m_nOpInd, pDisp->GetPhase(), sTable, ptOri1, false)) { - nStatus = MCH_SIM_ERR ; - return false ; - } - // cambio fase - m_pMchMgr->SetCurrPhase( pDisp->GetPhase()) ; - // aggiorno utensile e assi conseguenti - if ( ! UpdateTool()) { - nStatus = MCH_SIM_ERR ; - return false ; - } - ++ m_nOpInd ; - // richiamo gestione evento inizio disposizione - if ( ! OnDispositionStart( m_nOpId, m_nOpInd, pDisp->GetPhase(), sTable, ptOri1, false)) { - nStatus = MCH_SIM_ERR ; - return false ; - } - break ; - } - // altrimenti disposizione passiva - else { - // cambio fase - m_pMchMgr->SetCurrPhase( pDisp->GetPhase()) ; - ++ m_nOpInd ; - // richiamo gestione evento inizio e fine disposizione - if ( ! OnDispositionStart( m_nOpId, m_nOpInd, pDisp->GetPhase(), sTable, ptOri1, true) || - ! OnDispositionEnd()) { - nStatus = MCH_SIM_ERR ; - return false ; - } - // aggiorno visualizzazione e breve pausa (200 ms) - ExeDraw() ; - Sleep( 200) ; - } - } - // passo alla operazione successiva - m_nOpId = m_pMchMgr->GetNextActiveOperation( m_nOpId) ; - } - // se non ce ne sono altre, sono alla fine - if ( m_nOpId == GDB_ID_NULL) { - nStatus = MCH_SIM_END ; - return false ; - } - // aggiorno gli altri dati - int nClId = m_pGeomDB->GetFirstNameInGroup( m_nOpId, MCH_CL) ; - m_nCLPathId = m_pGeomDB->GetFirstGroupInGroup( nClId) ; - m_nCLPathInd = 0 ; - m_nEntId = m_pGeomDB->GetFirstInGroup( m_nCLPathId) ; - m_nEntInd = 0 ; - m_dCoeff = 0 ; - // richiamo gestione evento inizio percorso di lavoro - if ( m_nEntId != GDB_ID_NULL) { - // recupero punto di inizio del percorso - Point3d ptStart ; - m_pGeomDB->GetInfo( m_nCLPathId, KEY_START, ptStart) ; - // recupero versore estrusione associato al percorso (normale al piano di interpolazione) - Vector3d vtExtr ; - m_pGeomDB->GetInfo( m_nCLPathId, KEY_EXTR, vtExtr) ; - // recupero punti di minimo e massimo ingombro - Point3d ptMin, ptMax ; - m_pGeomDB->GetInfo( m_nCLPathId, KEY_PMIN, ptMin) ; - m_pGeomDB->GetInfo( m_nCLPathId, KEY_PMAX, ptMax) ; - // richiamo gestione evento inizio percorso di lavoro - ++ m_nCLPathInd ; - if ( ! OnPathStart( m_nCLPathId, m_nCLPathInd, ptStart, vtExtr, ptMin, ptMax)) { - nStatus = MCH_SIM_ERR ; - return false ; - } - } - } - } - - // Se inizio di nuova entità - bool bNewEnt = ( m_nEntId != GDB_ID_NULL && m_dCoeff < EPS_ZERO) ; - - // Recupero posizione finale - const CamData* pCamData = GetCamData( m_pGeomDB->GetUserObj( m_nEntId)) ; - if ( pCamData == nullptr) { - nStatus = MCH_SIM_ERR ; - return false ; - } - switch ( pCamData->GetAxesStatus()) { - case CamData::AS_OK : - break ; - case CamData::AS_OUTSTROKE : { - DBLVECTOR OutAxes = pCamData->GetAxesVal() ; - for ( size_t i = OutAxes.size() ; i < 5 ; ++ i) - OutAxes.emplace_back( 0) ; - DBLVECTOR vAng( OutAxes.begin() + 3, OutAxes.end()) ; - int nStat ; - m_pMachine->VerifyOutstroke( OutAxes[0], OutAxes[1], OutAxes[2], vAng, nStat) ; - nStatus = MCH_SIM_OUTSTROKE ; - return false ; } - case CamData::AS_DIR_ERR : - nStatus = MCH_SIM_DIR_ERR ; - return false ; - default : - nStatus = MCH_SIM_ERR ; - return false ; - } - const DBLVECTOR& AxesEnd = pCamData->GetAxesVal() ; - // Tipo di movimento - int nMoveType = pCamData->GetMoveType() ; - - // Eventuale gestione evento inizio entità - if ( bNewEnt) { - ++ m_nEntInd ; - if ( ! OnMoveStart( pCamData)) { - nStatus = MCH_SIM_ERR ; + // ricerca e gestione inizio percorso di lavoro + if ( ! FindAndManagePathStart( nStatus)) return false ; - } - bNewEnt = false ; } - // Calcolo distanza di movimento - double dSqDist = 0 ; - for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) { - // coefficiente moltiplicativo per differenziare assi lineari (primi3) e rotanti (altri) - double dSqCoeff = (( i >= 3) ? 100 : 1) ; - dSqDist += dSqCoeff * ( AxesEnd[i] - m_AxesVal[i]) * ( AxesEnd[i] - m_AxesVal[i]) ; - } - double dDist = sqrt( dSqDist) ; - m_dCoeff += ( nMoveType == 0 ? 4 : 1) * m_dStep / dDist ; - if ( m_dCoeff > 1) - m_dCoeff = 1 ; - - // Eseguo movimento rapido o lineare - if ( nMoveType != 2 && nMoveType != 3) { - for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) { - double dVal = m_AxesVal[i] * ( 1 - m_dCoeff) + AxesEnd[i] * m_dCoeff ; - m_pMachine->SetAxisPos( m_AxesName[i], dVal) ; - } - } - // Eseguo movimento su arco - else { - // primi due assi lineari - Point3d ptCen = pCamData->GetAxesCen() ; - double dAngCen = pCamData->GetAxesAngCen() ; - Vector3d vtN = pCamData->GetAxesNormDir() ; - Vector3d vtRot = Point3d( m_AxesVal[0], m_AxesVal[1], m_AxesVal[2]) - ptCen ; - vtRot.Rotate( vtN, m_dCoeff * dAngCen) ; - double dDeltaN = ( Point3d( AxesEnd[0], AxesEnd[1], AxesEnd[2]) - ptCen) * vtN ; - m_pMachine->SetAxisPos( m_AxesName[0], ptCen.x + vtRot.x + m_dCoeff * dDeltaN * vtN.x) ; - m_pMachine->SetAxisPos( m_AxesName[1], ptCen.y + vtRot.y + m_dCoeff * dDeltaN * vtN.y) ; - m_pMachine->SetAxisPos( m_AxesName[2], ptCen.z + vtRot.z + m_dCoeff * dDeltaN * vtN.z) ; - // altri assi - for ( size_t i = 3 ; i < m_AxesName.size() ; ++ i) { - double dVal = m_AxesVal[i] * ( 1 - m_dCoeff) + AxesEnd[i] * m_dCoeff ; - m_pMachine->SetAxisPos( m_AxesName[i], dVal) ; - } - } - - // Muovo eventuali assi ausiliari - for ( size_t i = 0 ; i < m_AuxAxesName.size() ; ++ i) { - double dVal = m_AuxAxesVal[i] * ( 1 - m_dCoeff) + m_AuxAxesEnd[i] * m_dCoeff ; - m_pMachine->SetAxisPos( m_AuxAxesName[i], dVal) ; - } - - // Se arrivato a fine interpolazione movimento, salvo posizioni e segnalo - if ( m_dCoeff > 0.999) { - for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) - m_AxesVal[i] = AxesEnd[i] ; - nStatus = MCH_SIM_END_STEP ; - // richiamo gestione evento fine entità - if ( ! OnMoveEnd()) { - nStatus = MCH_SIM_ERR ; - return false ; - } - } - // Altrimenti sto muovendomi all'interno dello step - else - nStatus = MCH_SIM_OK ; - return true ; + // Gestione movimento assi + return ManageMove( nStatus) ; } //---------------------------------------------------------------------------- @@ -657,6 +386,17 @@ Simulator::UpdateAxesPos( void) return true ; } +//---------------------------------------------------------------------------- +bool +Simulator::ResetAxes( void) +{ + // pulisco dati assi + m_AxesName.clear() ; + m_AxesToken.clear() ; + m_AxesLinear.clear() ; + return true ; +} + //---------------------------------------------------------------------------- bool Simulator::ResetAuxAxes( void) @@ -673,22 +413,272 @@ Simulator::ResetAuxAxes( void) //---------------------------------------------------------------------------- bool -Simulator::OnOperationEnd( void) +Simulator::FindAndManageOperationStart( bool bFirst, int& nStatus) { + // recupero la nuova operazione + if ( bFirst) { + m_nOpId = m_pMchMgr->GetFirstActiveOperation() ; + m_nOpInd = 0 ; + } + else + m_nOpId = m_pMchMgr->GetNextActiveOperation( m_nOpId) ; + // ciclo sulle successive operazioni + while ( m_nOpId != GDB_ID_NULL) { + // se lavorazione valida + Machining* pMch = GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) ; + if ( pMch != nullptr && ! pMch->IsEmpty()) { + // aggiorno utensile e assi conseguenti + if ( ! UpdateTool()) { + nStatus = MCH_SIM_ERR ; + return false ; + } + ++ m_nOpInd ; + // richiamo gestione evento inizio lavorazione + if ( ! OnMachiningStart( m_nOpId, m_nOpInd)) { + nStatus = MCH_SIM_ERR ; + return false ; + } + break ; + } + // se disposizione con cambio di fase + Disposition* pDisp = GetDisposition( m_pGeomDB->GetUserObj( m_nOpId)) ; + if ( pDisp != nullptr) { + // in alcuni casi la disposizione non è inizializzata + pDisp->Init( m_pMchMgr) ; + // recupero dati tavola + string sTable ; + pDisp->GetTable( sTable) ; + Point3d ptOri1 ; + pDisp->GetTableRef1( ptOri1) ; + // se con movimenti autonomi + if ( ! pDisp->IsEmpty()) { + // richiamo gestione evento appena prima di inizio disposizione + if ( ! OnDispositionStarting( m_nOpId, m_nOpInd, pDisp->GetPhase(), sTable, ptOri1, false)) { + nStatus = MCH_SIM_ERR ; + return false ; + } + // cambio fase + m_pMchMgr->SetCurrPhase( pDisp->GetPhase()) ; + // aggiorno utensile e assi conseguenti + if ( ! UpdateTool()) { + nStatus = MCH_SIM_ERR ; + return false ; + } + ++ m_nOpInd ; + // richiamo gestione evento inizio disposizione + if ( ! OnDispositionStart( m_nOpId, m_nOpInd, pDisp->GetPhase(), sTable, ptOri1, false)) { + nStatus = MCH_SIM_ERR ; + return false ; + } + break ; + } + // altrimenti disposizione passiva + else { + // cambio fase + m_pMchMgr->SetCurrPhase( pDisp->GetPhase()) ; + ++ m_nOpInd ; + // richiamo gestione evento inizio e fine disposizione + if ( ! OnDispositionStart( m_nOpId, m_nOpInd, pDisp->GetPhase(), sTable, ptOri1, true) || + ! OnDispositionEnd()) { + nStatus = MCH_SIM_ERR ; + return false ; + } + // aggiorno visualizzazione e breve pausa (200 ms) + ExeDraw() ; + Sleep( 200) ; + } + } + // passo alla operazione successiva + m_nOpId = m_pMchMgr->GetNextActiveOperation( m_nOpId) ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +Simulator::ManageOperationEnd( int& nStatus) +{ + bool bOk = false ; // se è una lavorazione - Machining* pMch = GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) ; - if ( pMch != nullptr) { + if ( GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) != nullptr) { // richiamo gestione evento fine lavorazione - return OnMachiningEnd() ; + bOk = OnMachiningEnd() ; } // se è una disposizione - Disposition* pDisp = GetDisposition( m_pGeomDB->GetUserObj( m_nOpId)) ; - if ( pDisp != nullptr) { + if ( GetDisposition( m_pGeomDB->GetUserObj( m_nOpId)) != nullptr) { // richiamo gestione evento fine disposizione - return OnDispositionEnd() ; + bOk = OnDispositionEnd() ; } - // errore - return false ; + // gestione stato + if ( ! bOk) + nStatus = MCH_SIM_ERR ; + return bOk ; +} + +//---------------------------------------------------------------------------- +bool +Simulator::FindAndManagePathStart( int& nStatus) +{ + // se devo cercare il primo nella nuova operazione + if ( m_nCLPathId == GDB_ID_NULL) { + // aggiorno gli altri dati + int nClId = m_pGeomDB->GetFirstNameInGroup( m_nOpId, MCH_CL) ; + m_nCLPathId = m_pGeomDB->GetFirstGroupInGroup( nClId) ; + m_nCLPathInd = 0 ; + m_nEntId = m_pGeomDB->GetFirstInGroup( m_nCLPathId) ; + m_nEntInd = 0 ; + m_dCoeff = 0 ; + } + // altrimenti cerco il successivo nella stessa operazione + else { + // recupero un nuovo CLpath + while ( m_nEntId == GDB_ID_NULL) { + m_nCLPathId = m_pGeomDB->GetNextGroup( m_nCLPathId) ; + // se non ce ne sono altri, devo passare a una nuova lavorazione + if ( m_nCLPathId == GDB_ID_NULL) + break ; + m_nEntId = m_pGeomDB->GetFirstInGroup( m_nCLPathId) ; + m_nEntInd = 0 ; + m_dCoeff = 0 ; + } + } + // se trovato nuovo CLpath, gestisco inizio percorso di lavoro + if ( m_nEntId != GDB_ID_NULL) { + ++ m_nCLPathInd ; + // recupero punto di inizio del percorso + Point3d ptStart ; + m_pGeomDB->GetInfo( m_nCLPathId, KEY_START, ptStart) ; + // recupero versore estrusione associato al percorso (normale al piano di interpolazione) + Vector3d vtExtr ; + m_pGeomDB->GetInfo( m_nCLPathId, KEY_EXTR, vtExtr) ; + // recupero punti di minimo e massimo ingombro + Point3d ptMin, ptMax ; + m_pGeomDB->GetInfo( m_nCLPathId, KEY_PMIN, ptMin) ; + m_pGeomDB->GetInfo( m_nCLPathId, KEY_PMAX, ptMax) ; + // richiamo gestione evento inizio percorso di lavoro + if ( ! OnPathStart( m_nCLPathId, m_nCLPathInd, ptStart, vtExtr, ptMin, ptMax)) { + nStatus = MCH_SIM_ERR ; + return false ; + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Simulator::ManagePathEnd( int& nStatus) +{ + // richiamo gestione evento fine percorso di lavoro + if ( ! OnPathEnd()) { + nStatus = MCH_SIM_ERR ; + return false ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +Simulator::ManageMove( int& nStatus) +{ + + // Recupero posizione finale + const CamData* pCamData = GetCamData( m_pGeomDB->GetUserObj( m_nEntId)) ; + if ( pCamData == nullptr) { + nStatus = MCH_SIM_ERR ; + return false ; + } + switch ( pCamData->GetAxesStatus()) { + case CamData::AS_OK : + break ; + case CamData::AS_OUTSTROKE : { + DBLVECTOR OutAxes = pCamData->GetAxesVal() ; + for ( size_t i = OutAxes.size() ; i < 5 ; ++ i) + OutAxes.emplace_back( 0) ; + DBLVECTOR vAng( OutAxes.begin() + 3, OutAxes.end()) ; + int nStat ; + m_pMachine->VerifyOutstroke( OutAxes[0], OutAxes[1], OutAxes[2], vAng, nStat) ; + nStatus = MCH_SIM_OUTSTROKE ; + return false ; } + case CamData::AS_DIR_ERR : + nStatus = MCH_SIM_DIR_ERR ; + return false ; + default : + nStatus = MCH_SIM_ERR ; + return false ; + } + const DBLVECTOR& AxesEnd = pCamData->GetAxesVal() ; + // Tipo di movimento + int nMoveType = pCamData->GetMoveType() ; + + // Se inizio di nuova entità + if ( m_nEntId != GDB_ID_NULL && m_dCoeff < EPS_ZERO) { + ++ m_nEntInd ; + if ( ! OnMoveStart( pCamData)) { + nStatus = MCH_SIM_ERR ; + return false ; + } + } + + // Calcolo distanza di movimento + double dSqDist = 0 ; + for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) { + // coefficiente moltiplicativo per differenziare assi lineari (primi3) e rotanti (altri) + double dSqCoeff = (( i >= 3) ? 100 : 1) ; + dSqDist += dSqCoeff * ( AxesEnd[i] - m_AxesVal[i]) * ( AxesEnd[i] - m_AxesVal[i]) ; + } + double dDist = sqrt( dSqDist) ; + m_dCoeff += ( nMoveType == 0 ? 4 : 1) * m_dStep / dDist ; + if ( m_dCoeff > 1) + m_dCoeff = 1 ; + + // Eseguo movimento rapido o lineare + if ( nMoveType != 2 && nMoveType != 3) { + for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) { + double dVal = m_AxesVal[i] * ( 1 - m_dCoeff) + AxesEnd[i] * m_dCoeff ; + m_pMachine->SetAxisPos( m_AxesName[i], dVal) ; + } + } + // Eseguo movimento su arco + else { + // primi due assi lineari + Point3d ptCen = pCamData->GetAxesCen() ; + double dAngCen = pCamData->GetAxesAngCen() ; + Vector3d vtN = pCamData->GetAxesNormDir() ; + Vector3d vtRot = Point3d( m_AxesVal[0], m_AxesVal[1], m_AxesVal[2]) - ptCen ; + vtRot.Rotate( vtN, m_dCoeff * dAngCen) ; + double dDeltaN = ( Point3d( AxesEnd[0], AxesEnd[1], AxesEnd[2]) - ptCen) * vtN ; + m_pMachine->SetAxisPos( m_AxesName[0], ptCen.x + vtRot.x + m_dCoeff * dDeltaN * vtN.x) ; + m_pMachine->SetAxisPos( m_AxesName[1], ptCen.y + vtRot.y + m_dCoeff * dDeltaN * vtN.y) ; + m_pMachine->SetAxisPos( m_AxesName[2], ptCen.z + vtRot.z + m_dCoeff * dDeltaN * vtN.z) ; + // altri assi + for ( size_t i = 3 ; i < m_AxesName.size() ; ++ i) { + double dVal = m_AxesVal[i] * ( 1 - m_dCoeff) + AxesEnd[i] * m_dCoeff ; + m_pMachine->SetAxisPos( m_AxesName[i], dVal) ; + } + } + + // Muovo eventuali assi ausiliari + for ( size_t i = 0 ; i < m_AuxAxesName.size() ; ++ i) { + double dVal = m_AuxAxesVal[i] * ( 1 - m_dCoeff) + m_AuxAxesEnd[i] * m_dCoeff ; + m_pMachine->SetAxisPos( m_AuxAxesName[i], dVal) ; + } + + // Se arrivato a fine interpolazione movimento, salvo posizioni e segnalo + if ( m_dCoeff > 0.999) { + for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) + m_AxesVal[i] = AxesEnd[i] ; + nStatus = MCH_SIM_END_STEP ; + // richiamo gestione evento fine entità + if ( ! OnMoveEnd()) { + nStatus = MCH_SIM_ERR ; + return false ; + } + } + // Altrimenti sto muovendomi all'interno dello step + else + nStatus = MCH_SIM_OK ; + return true ; } //---------------------------------------------------------------------------- @@ -911,6 +901,7 @@ Simulator::OnMoveStart( const CamData* pCamData) } // chiamo la funzione bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_MOVE_START) ; + // con errore, esco if ( ! bOk) { ResetAuxAxes() ; return false ; diff --git a/Simulator.h b/Simulator.h index 9a37755..cde5523 100644 --- a/Simulator.h +++ b/Simulator.h @@ -40,10 +40,15 @@ class Simulator bool UpdateTool( bool bForced = false) ; bool UpdateAxes( void) ; bool UpdateAxesPos( void) ; + bool ResetAxes( void) ; bool ResetAuxAxes( void) ; private : - bool OnOperationEnd( void) ; + bool FindAndManageOperationStart( bool bFirst, int& nStatus) ; + bool ManageOperationEnd( int& nStatus) ; + bool FindAndManagePathStart( int& nStatus) ; + bool ManagePathEnd( int& nStatus) ; + bool ManageMove( int& nStatus) ; bool OnDispositionStarting( int nOpId, int nOpInd, int nPhase, const std::string& sTable, const Point3d& ptOri1, bool bEmpty) ; bool OnDispositionStart( int nOpId, int nOpInd, int nPhase,