EgtMachKernel :

- razionalizzazione simulatore
- in caricamento macchina, generazione e simulazione non viene impostata modifica progetto.
This commit is contained in:
Dario Sassi
2017-01-04 18:50:51 +00:00
parent f8c83ea5bc
commit ab392fb4e2
8 changed files with 344 additions and 326 deletions
+1 -1
View File
@@ -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) ;
+1 -1
View File
@@ -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 <typename T>
+9 -1
View File
@@ -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 ;
}
+17 -3
View File
@@ -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) ;
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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) ;
+308 -317
View File
@@ -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 ;
+6 -1
View File
@@ -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,