EgtMachKernel :
- razionalizzazione simulatore - in caricamento macchina, generazione e simulazione non viene impostata modifica progetto.
This commit is contained in:
+308
-317
@@ -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 ;
|
||||
|
||||
Reference in New Issue
Block a user