Files
EgtMachKernel/Simulator.cpp
T
Dario Sassi 329136f5ca EgtMachKernel :
- aggiunta gestione Invert su asse (per ora solo in simulazione)
- possibilità di invertire lavorazione fori passanti
- in simulazione e generazione aggiunti punti estremi di box lavorazione.
2016-12-12 09:18:50 +00:00

970 lines
36 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2015-2016
//----------------------------------------------------------------------------
// File : Simulator.cpp Data : 26.02.16 Versione : 1.6n8
// Contenuto : Implementazione della classe Simulator.
//
//
//
// Modifiche : 19.10.15 DS Creazione modulo.
// 26.02.16 DS Aggiunta gestione archi.
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "Simulator.h"
#include "MachMgr.h"
#include "Disposition.h"
#include "Machining.h"
#include "MachiningConst.h"
#include "OutputConst.h"
#include "/EgtDev/Include/EMkToolConst.h"
#include "/EgtDev/Include/EMkOperationConst.h"
using namespace std ;
//----------------------------------------------------------------------------
Simulator::Simulator( void)
{
m_pMchMgr = nullptr ;
m_pGeomDB = nullptr ;
m_pMachine = nullptr ;
m_dStep = 5.0 ;
m_nOpId = GDB_ID_NULL ;
m_nOpInd = 0 ;
m_nCLPathId = GDB_ID_NULL ;
m_nCLPathInd = 0 ;
m_nEntId = GDB_ID_NULL ;
m_nEntInd = 0 ;
m_dCoeff = 0 ;
m_AxesName.reserve( 8) ;
m_AxesToken.reserve( 8) ;
m_AxesLinear.reserve( 8) ;
m_AxesVal.reserve( 8) ;
}
//----------------------------------------------------------------------------
Simulator::~Simulator( void)
{
Stop() ;
}
//----------------------------------------------------------------------------
bool
Simulator::Init( MachMgr* pMchMgr)
{
// verifico ambiente
if ( pMchMgr == nullptr || pMchMgr->GetContextId() == 0 ||
pMchMgr->GetGeomDB() == nullptr || pMchMgr->GetCurrMachine() == nullptr)
return false ;
m_pMchMgr = pMchMgr ;
m_pGeomDB = m_pMchMgr->GetGeomDB() ;
m_pMachine = m_pMchMgr->GetCurrMachine() ;
return true ;
}
//----------------------------------------------------------------------------
bool
Simulator::Start( void)
{
// verifico ci sia una macchinata corrente
if ( m_pMchMgr == nullptr)
return false ;
int nMachGrp = m_pMchMgr->GetCurrMachGroup() ;
if ( nMachGrp == GDB_ID_NULL)
return false ;
// reset utensile e assi correnti
m_sTool.clear() ;
m_AxesName.clear() ;
m_AxesToken.clear() ;
m_AxesLinear.clear() ;
// porto la macchina in home
if ( ! GoHome())
return false ;
// imposto fase iniziale
m_pMchMgr->SetCurrPhase( 1) ;
// 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
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 ;
}
//----------------------------------------------------------------------------
bool
Simulator::Move( int& nStatus)
{
// Verifiche
if ( m_pMchMgr == nullptr || m_pGeomDB == 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 ;
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 ;
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 ;
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 ;
}
//----------------------------------------------------------------------------
bool
Simulator::GetAxisInfoPos( int nI, string& sToken, bool& bLinear, double& dVal) const
{
// Verifiche
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return false ;
// numero assi di calcolo e ausiliari
int nAxisCount = int( m_AxesName.size()) ;
int nAuxAxisCount = int( m_AuxAxesName.size()) ;
// recupero i dati dell'asse
if ( nI < 0 || nI >= nAxisCount + nAuxAxisCount)
return false ;
string sName ;
if ( nI < nAxisCount) {
sName = m_AxesName[nI] ;
sToken = m_AxesToken[nI] ;
bLinear = m_AxesLinear[nI] ;
}
else {
sName = m_AuxAxesName[ nI - nAxisCount] ;
sToken = m_AuxAxesToken[ nI - nAxisCount] ;
bLinear = m_AuxAxesLinear[ nI - nAxisCount] ;
}
// recupero la posizione
if ( ! m_pMchMgr->GetAxisPos( sName, dVal))
return false ;
// verifico se da invertire
if ( nI < nAxisCount) {
if ( m_AxesInvert[nI])
dVal = - dVal ;
}
else {
if ( m_AuxAxesInvert[nI - nAxisCount])
dVal = - dVal ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
Simulator::GetToolInfo( string& sName, double& dSpeed) const
{
// Verifiche
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return false ;
// Assegno il nome dell'utensile
sName = m_sTool ;
if ( sName.empty()) {
dSpeed = 0 ;
return true ;
}
// Recupero speed
Machining* pMch = GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) ;
return ( pMch != nullptr && pMch->GetParam( MPA_SPEED, dSpeed)) ;
}
//----------------------------------------------------------------------------
bool
Simulator::GetMoveInfo( int& nGmove, double& dFeed) const
{
// Verifiche
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return false ;
// Recupero il movimento corrente
CamData* pCamData = GetCamData( m_pGeomDB->GetUserObj( m_nEntId)) ;
if ( pCamData == nullptr)
return false ;
// Assegno feed
dFeed = pCamData->GetFeed() ;
// Assegno tipo di movimento
if ( dFeed < EPS_SMALL)
nGmove = 0 ;
else
nGmove = 1 ;
return true ;
}
//----------------------------------------------------------------------------
bool
Simulator::SetStep( double dStep)
{
const double MIN_STEP = 0.1 ;
const double MAX_STEP = 100.0 ;
if ( dStep < MIN_STEP)
m_dStep = MIN_STEP ;
else if ( dStep > MAX_STEP)
m_dStep = MAX_STEP ;
else
m_dStep = dStep ;
return true ;
}
//----------------------------------------------------------------------------
bool
Simulator::GoHome( void)
{
// controllo validità stato
if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr || m_pMachine == nullptr)
return false ;
// porto la macchina in home
m_pMchMgr->ResetAllAxesPos() ;
// reset stato macchina
OnResetMachine() ;
// assegno valori home degli assi macchina attivi
return m_pMchMgr->GetAllCalcAxesHomePos( m_AxesVal) ;
}
//----------------------------------------------------------------------------
bool
Simulator::Stop( void)
{
// controllo validità stato
if ( m_pGeomDB == nullptr || m_pMchMgr == nullptr || m_pMachine == nullptr)
return false ;
// porto la macchina in home
m_pMchMgr->ResetAllAxesPos() ;
// reset stato macchina
OnResetMachine() ;
// rimuovo tavola variabili globali
m_pMachine->LuaResetGlobVar( GLOB_VAR) ;
// reset dello stato
m_nOpId = GDB_ID_NULL ;
m_nCLPathId = GDB_ID_NULL ;
m_nEntId = GDB_ID_NULL ;
m_dCoeff = 0 ;
return true ;
}
//----------------------------------------------------------------------------
bool
Simulator::UpdateTool( bool bForced)
{
// Recupero l'utensile della lavorazione corrente
Machining* pMch = GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) ;
if ( pMch != nullptr) {
// recupero nome e dati nuovo utensile
string sTuuid, sTool ;
if ( ! pMch->GetParam( MPA_TUUID, sTuuid) ||
! m_pMchMgr->TdbGetToolFromUUID( sTuuid, sTool))
return false ;
if ( ! m_pMchMgr->TdbSetCurrTool( sTool))
return false ;
string sHead ; m_pMchMgr->TdbGetCurrToolParam( TPA_HEAD, sHead) ;
int nExit ; m_pMchMgr->TdbGetCurrToolParam( TPA_EXIT, nExit) ;
string sTcPos ; m_pMchMgr->TdbGetCurrToolParam( TPA_TCPOS, sTcPos) ;
// se cambierà e non forzato (inizio), scarico l'utensile corrente
if ( sTool != m_sTool && ! bForced) {
// eventuale lancio script per scarico utensile
if ( ! OnToolDeselect( sHead, nExit, sTcPos))
return false ;
}
// se cambiato oppure forzato, attivo l'utensile della lavorazione
if ( sTool != m_sTool || bForced) {
// se forzato, pulisco la testa
if ( bForced)
m_pMchMgr->ResetHeadSet( sHead) ;
// carico l'utensile
if ( ! m_pMchMgr->SetCalcTool( sTool, sHead, nExit))
return false ;
m_sTool = sTool ;
// aggiorno gli assi macchina
if ( ! UpdateAxes())
return false ;
// eventuale lancio script
if ( ! OnToolSelect( m_sTool, sHead, nExit, sTcPos))
return false ;
}
return true ;
}
// Provo con una disposizione
Disposition* pDisp = GetDisposition( m_pGeomDB->GetUserObj( m_nOpId)) ;
if ( pDisp != nullptr) {
// recupero i dati
string sTool ; string sHead ; int nExit ; string sTcPos ;
pDisp->GetToolData( sTool, sHead, nExit, sTcPos) ;
// eventuale lancio script per scarico utensile
if ( ! OnToolDeselect( sHead, nExit, sTcPos))
return false ;
// carico l'utensile
if ( ! m_pMchMgr->SetCalcTool( sTool, sHead, nExit))
return false ;
m_sTool = sTool ;
// aggiorno gli assi macchina
if ( ! UpdateAxes())
return false ;
// eventuale lancio script
if ( ! OnToolSelect( m_sTool, sHead, nExit, sTcPos))
return false ;
return true ;
}
return false ;
}
//----------------------------------------------------------------------------
bool
Simulator::UpdateAxes( void)
{
// Macchina corrente
Machine* pMachine = m_pMchMgr->GetCurrMachine() ;
if ( pMachine == nullptr)
return false ;
// Carico i nomi e i token degli assi macchina attivi
if ( ! pMachine->GetAllCurrAxesName( m_AxesName) ||
! pMachine->GetAllCurrAxesToken( m_AxesToken))
return false ;
// Aggiorno flag invertito, il tipo e la posizione corrente degli assi macchina attivi
m_AxesInvert.clear() ;
m_AxesLinear.clear() ;
m_AxesVal.clear() ;
for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) {
bool bInvert ;
m_pMachine->GetAxisInvert( m_AxesName[i], bInvert) ;
m_AxesInvert.push_back( bInvert) ;
bool bLinear ;
m_pMachine->GetAxisType( m_AxesName[i], bLinear) ;
m_AxesLinear.push_back( bLinear) ;
double dVal ;
m_pMachine->GetAxisPos( m_AxesName[i], dVal) ;
m_AxesVal.emplace_back( dVal) ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
Simulator::UpdateAxesPos( void)
{
// Macchina corrente
Machine* pMachine = m_pMchMgr->GetCurrMachine() ;
if ( pMachine == nullptr)
return false ;
// Aggiorno la posizione corrente degli assi macchina attivi
m_AxesVal.clear() ;
for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) {
double dVal ;
m_pMachine->GetAxisPos( m_AxesName[i], dVal) ;
m_AxesVal.emplace_back( dVal) ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
Simulator::OnOperationEnd( void)
{
// se è una lavorazione
Machining* pMch = GetMachining( m_pGeomDB->GetUserObj( m_nOpId)) ;
if ( pMch != nullptr) {
// richiamo gestione evento fine lavorazione
return OnMachiningEnd() ;
}
// se è una disposizione
Disposition* pDisp = GetDisposition( m_pGeomDB->GetUserObj( m_nOpId)) ;
if ( pDisp != nullptr) {
// richiamo gestione evento fine disposizione
return OnDispositionEnd() ;
}
// errore
return false ;
}
//----------------------------------------------------------------------------
bool
Simulator::OnDispositionStarting( int nOpId, int nOpInd, int nPhase,
const string& sTable, const Point3d& ptOri1, bool bEmpty)
{
// assegno identificativo e indice disposizione
bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_DISPID, nOpId) ;
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_DISPIND, nOpInd) ;
// assegno nuovo indice di fase
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PHASE, nPhase) ;
// assegno nome e valore riferimento della tavola corrente
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TABNAME, sTable) ;
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TABORI1, ptOri1) ;
// assegno flag disposizione passiva
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_EMPTY, bEmpty) ;
// verifico esistenza funzione
if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_DISPOSITION_STARTING))
return true ;
// chiamo la funzione di inizio disposizione
bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_DISPOSITION_STARTING) ;
// forzo aggiornamento posizione assi (possono essere stati mossi nello script)
UpdateAxesPos() ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
Simulator::OnDispositionStart( int nOpId, int nOpInd, int nPhase,
const string& sTable, const Point3d& ptOri1, bool bEmpty)
{
// assegno identificativo e indice disposizione
bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_DISPID, nOpId) ;
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_DISPIND, nOpInd) ;
// assegno nuovo indice di fase
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PHASE, nPhase) ;
// assegno nome e valore riferimento della tavola corrente
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TABNAME, sTable) ;
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TABORI1, ptOri1) ;
// assegno flag disposizione passiva
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_EMPTY, bEmpty) ;
// verifico esistenza funzione
if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_DISPOSITION_START))
return true ;
// chiamo la funzione di inizio disposizione
bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_DISPOSITION_START) ;
// forzo aggiornamento posizione assi (possono essere stati mossi nello script)
UpdateAxesPos() ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
Simulator::OnDispositionEnd( void)
{
// verifico esistenza funzione
if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_DISPOSITION_END))
return true ;
// chiamo la funzione di fine disposizione
bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_DISPOSITION_END) ;
// forzo aggiornamento posizione assi (possono essere stati mossi nello script)
UpdateAxesPos() ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
Simulator::OnToolSelect( const string& sTool, const string& sHead, int nExit, const string& sTcPos)
{
// assegno il nome dell'utensile, la testa e l'uscita
if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_TOOL, sTool) ||
! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_HEAD, sHead) ||
! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_EXIT, nExit))
return false ;
// assegno il token e il nome degli assi
int nNumAxes = int( m_AxesName.size()) ;
for ( int i = 1 ; i <= MAX_AXES ; ++ i) {
if ( i <= nNumAxes) {
if ( ! m_pMachine->LuaSetGlobVar( GetGlobVarAxisToken(i), m_AxesToken[i-1]) ||
! m_pMachine->LuaSetGlobVar( GetGlobVarAxisName(i), m_AxesName[i-1]))
return false ;
}
else {
if ( ! m_pMachine->LuaResetGlobVar( GetGlobVarAxisToken(i)) ||
! m_pMachine->LuaResetGlobVar( GetGlobVarAxisName(i)))
return false ;
}
}
// verifico esistenza funzione
if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_TOOL_SELECT))
return true ;
// chiamo la funzione di selezione utensile
bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_TOOL_SELECT) ;
// forzo aggiornamento posizione assi (possono essere stati mossi nello script)
UpdateAxesPos() ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
Simulator::OnToolDeselect( const string& sNextHead, int nNextExit, const string& sNextTcPos)
{
// assegno la prossima testa
bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_NEXTHEAD, sNextHead) ;
// assegno la prossima uscita
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_NEXTEXIT, nNextExit) ;
// assegno l'eventuale prossima posizione nel TC
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_NEXTTCPOS, sNextTcPos) ;
// verifico esistenza funzione
if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_TOOL_DESELECT))
return bOk ;
// chiamo la funzione di deselezione utensile
bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_TOOL_DESELECT) ;
// forzo aggiornamento posizione assi (possono essere stati mossi nello script)
UpdateAxesPos() ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
Simulator::OnMachiningStart( int nOpId, int nOpInd)
{
// assegno identificativo e indice lavorazione
if ( ! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MCHID, nOpId) ||
! m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MCHIND, nOpInd))
return false ;
// verifico esistenza funzione
if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_MACHINING_START))
return true ;
// chiamo la funzione di inizio disposizione
bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_MACHINING_START) ;
// forzo aggiornamento posizione assi (possono essere stati mossi nello script)
UpdateAxesPos() ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
Simulator::OnMachiningEnd( void)
{
// verifico esistenza funzione
if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_MACHINING_END))
return true ;
// chiamo la funzione di fine lavorazione
bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_MACHINING_END) ;
// forzo aggiornamento posizione assi (possono essere stati mossi nello script)
UpdateAxesPos() ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
Simulator::OnPathStart( int nClPathId, int nClPathInd, const Point3d& ptStart, const Vector3d& vtExtr,
const Point3d& ptMin, const Point3d& ptMax)
{
// assegno identificativo e indice percorso di lavorazione
bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PATHID, nClPathId) ;
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PATHIND, nClPathInd) ;
// assegno punto iniziale e versore estrusione
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_START, ptStart) ;
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_EXTR, vtExtr) ;
// assegno punti estremi dell'ingombro del percorso di lavorazione
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PMIN, ptMin) ;
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_PMAX, ptMax) ;
// verifico esistenza funzione
if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_PATH_START))
return bOk ;
// chiamo la funzione di inizio percorso di lavorazione
bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_PATH_START) ;
// forzo aggiornamento posizione assi (possono essere stati mossi nello script)
UpdateAxesPos() ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
Simulator::OnPathEnd( void)
{
// verifico esistenza funzione
if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_PATH_END))
return true ;
// chiamo la funzione di fine percorso di lavorazione
bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_PATH_END) ;
// forzo aggiornamento posizione assi (possono essere stati mossi nello script)
UpdateAxesPos() ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
Simulator::OnMoveStart( const CamData* pCamData)
{
// pulisco dati assi ausiliari
m_AuxAxesName.clear() ;
m_AuxAxesToken.clear() ;
m_AuxAxesInvert.clear() ;
m_AuxAxesLinear.clear() ;
m_AuxAxesVal.clear() ;
m_AuxAxesEnd.clear() ;
// recupero e assegno i dati
// dati generali
bool bOk = m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MOVEID, m_nEntId) ;
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MOVEIND, m_nEntInd) ;
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_MOVE, pCamData->GetMoveType()) ;
bOk = bOk && m_pMachine->LuaSetGlobVar( GLOB_VAR + GVAR_FLAG, pCamData->GetFlag()) ;
// valore degli assi all'inizio e alla fine del movimento
int nNumAxes = int( m_AxesName.size()) ;
const DBLVECTOR& AxesEnd = pCamData->GetAxesVal() ;
for ( int i = 1 ; i <= MAX_AXES ; ++ i) {
if ( i <= nNumAxes) {
bOk = bOk && m_pMachine->LuaSetGlobVar( GetGlobVarAxisPrev( i), m_AxesVal[i-1]) ;
bOk = bOk && m_pMachine->LuaSetGlobVar( GetGlobVarAxisValue( i), AxesEnd[i-1]) ;
}
else {
bOk = bOk && m_pMachine->LuaResetGlobVar( GetGlobVarAxisPrev( i)) ;
bOk = bOk && m_pMachine->LuaResetGlobVar( GetGlobVarAxisValue( i)) ;
}
}
// reset numero assi ausiliari
bOk = bOk && m_pMachine->LuaResetGlobVar( GLOB_VAR + GVAR_AUXAXES) ;
// verifico esistenza funzione
if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_MOVE_START))
return bOk ;
// chiamo la funzione
bOk = bOk && m_pMachine->LuaCallFunction( ON_SIMUL_MOVE_START) ;
if ( ! bOk)
return false ;
// forzo aggiornamento posizione assi (possono essere stati mossi nello script)
UpdateAxesPos() ;
// recupero i dati di ritorno
int nNumAuxAxes = 0 ;
if ( ! m_pMachine->LuaGetGlobVar( GLOB_VAR + GVAR_AUXAXES, nNumAuxAxes) || nNumAuxAxes == 0)
return true ;
m_AuxAxesName.reserve( nNumAuxAxes) ;
m_AuxAxesToken.reserve( nNumAuxAxes) ;
m_AuxAxesInvert.reserve( nNumAuxAxes) ;
m_AuxAxesLinear.reserve( nNumAuxAxes) ;
m_AuxAxesVal.reserve( nNumAuxAxes) ;
m_AuxAxesEnd.reserve( nNumAuxAxes) ;
for ( int i = 1 ; i <= nNumAuxAxes && bOk ; ++ i) {
string sName ; string sToken ; bool bInvert ; bool bLinear ; double dVal ; double dEnd ;
string sAuxAxVal = GLOB_VAR + GVAR_AN ; ReplaceString( sAuxAxVal, "N", ToString( i)) ;
string sAuxAxName = GLOB_VAR + GVAR_ANN ; ReplaceString( sAuxAxName, "N", ToString( i)) ;
if ( m_pMachine->LuaGetGlobVar( sAuxAxName, sName) &&
m_pMachine->GetAxisToken( sName, sToken) &&
m_pMachine->GetAxisInvert( sName, bInvert) &&
m_pMachine->GetAxisType( sName, bLinear) &&
m_pMachine->GetAxisPos( sName, dVal) &&
m_pMachine->LuaGetGlobVar( sAuxAxVal, dEnd)) {
m_AuxAxesName.emplace_back( sName) ;
m_AuxAxesToken.emplace_back( sToken) ;
m_AuxAxesInvert.push_back( bInvert) ;
m_AuxAxesLinear.push_back( bLinear) ;
m_AuxAxesVal.emplace_back( dVal) ;
m_AuxAxesEnd.emplace_back( dEnd) ;
}
else
bOk = false ;
}
return bOk ;
}
//----------------------------------------------------------------------------
bool
Simulator::OnMoveEnd( void)
{
// verifico esistenza funzione
if ( ! m_pMachine->LuaExistsFunction( ON_SIMUL_MOVE_END))
return true ;
// chiamo la funzione
bool bOk = m_pMachine->LuaCallFunction( ON_SIMUL_MOVE_END) ;
// forzo aggiornamento posizione assi (possono essere stati mossi nello script)
UpdateAxesPos() ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
Simulator::OnResetMachine( void)
{
// verifico esistenza funzione
if ( ! m_pMachine->LuaExistsFunction( ON_RESET_MACHINE))
return true ;
// eseguo reset macchina
return m_pMachine->LuaCallFunction( ON_RESET_MACHINE) ;
}