EgtMachKernel :

- aggiunta gestione archi su piani diversi da XY
- disposizione rimette sempre anche i sottopezzi al loro posto
- aggiunti attacchi e uscite a fresature
- aggiunta prima versione calcolo collegamenti tra lavorazioni evitando collisioni
- modifiche a simulazione per tavole mobili con sottopezzi e pezzi.
This commit is contained in:
Dario Sassi
2016-05-30 08:55:15 +00:00
parent a53dfcd676
commit 3cd21182d3
16 changed files with 1189 additions and 289 deletions
+96 -256
View File
@@ -24,6 +24,7 @@
#include "/EgtDev/Include/EgkIntersCurves.h"
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
#include "/EgtDev/Include/EGkGeomDB.h"
#include "/EgtDev/Include/EXeConst.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ;
@@ -608,9 +609,7 @@ Operation::CalculateClPathAxesValues( int nClPathId, int nLinAxes, int nRotAxes,
vAxVal.emplace_back( dAng) ;
// verifico i limiti di corsa degli assi
int nStat ;
double dAngA = ( vAng1.size() >= 1 ? vAng1[0] : 0) ;
double dAngB = ( vAng1.size() >= 2 ? vAng1[1] : 0) ;
bool bOsOk = m_pMchMgr->VerifyOutstroke( dX, dY, dZ, dAngA, dAngB, nStat) ;
bool bOsOk = m_pMchMgr->VerifyOutstroke( dX, dY, dZ, vAng1, nStat) ;
if ( ! bOsOk || nStat != 0) {
bOk = false ;
pCamData->SetAxes( CamData::AS_OUTSTROKE, vAxVal) ;
@@ -631,8 +630,9 @@ Operation::CalculateClPathAxesValues( int nClPathId, int nLinAxes, int nRotAxes,
// ricavo punto medio
Point3d ptCen = pCamData->GetCenter() ;
double dAngCen = pCamData->GetAngCen() ;
Vector3d vtN = pCamData->GetNormDir() ;
Point3d ptMid = ptP ;
ptMid.Rotate( ptCen, Z_AX, - dAngCen / 2) ;
ptMid.Rotate( ptCen, vtN, - dAngCen / 2) ;
// determino i valori degli assi al punto medio
DBLVECTOR vAngMid( vAng1.size()) ;
for ( size_t i = 0 ; i < vAng1.size() ; ++ i)
@@ -655,6 +655,7 @@ Operation::CalculateClPathAxesValues( int nClPathId, int nLinAxes, int nRotAxes,
pCamData->SetAxesCen( ptP2M) ;
pCamData->SetAxesRad( 0) ;
pCamData->SetAxesAngCen( 0) ;
pCamData->SetAxesNormDir( V_NULL) ;
// il movimento diventa lineare
pCamData->SetMoveType( 1) ;
// non è necessario verificare i limiti di corsa degli assi
@@ -668,28 +669,30 @@ Operation::CalculateClPathAxesValues( int nClPathId, int nLinAxes, int nRotAxes,
continue ;
}
// verifico il piano
if ( pArc->GetNormVersor().z < 0)
if ( pArc->GetNormVersor() * pCamData->GetToolDir() < 0)
pArc->InvertN() ;
// assegno il centro e il raggio di questo arco ai dati cam
pCamData->SetAxesCen( pArc->GetCenter()) ;
pCamData->SetAxesRad( pArc->GetRadius()) ;
pCamData->SetAxesAngCen( pArc->GetAngCenter()) ;
pCamData->SetAxesNormDir( pArc->GetNormVersor()) ;
// aggiorno il tipo di arco
pCamData->SetMoveType( pArc->GetAngCenter() > 0 ? 3 : 2) ;
// verifico i limiti di corsa dei punti lungo l'arco
const int NUM_VERIF_STEP = 16 ;
Point3d ptCen = pCamData->GetAxesCen() ;
double dAngCenStep = pCamData->GetAxesAngCen() / NUM_VERIF_STEP ;
Vector3d vtN = pCamData->GetAxisNormDir() ;
Vector3d vtCurr = Point3d( dXprec, dYprec, dZprec) - ptCen ;
for ( int i = 1 ; i < NUM_VERIF_STEP ; ++ i) {
vtCurr.Rotate( Z_AX, dAngCenStep) ;
vtCurr.Rotate( vtN, dAngCenStep) ;
Point3d ptCurr = ptCen + vtCurr ;
double dCoeff = i / NUM_VERIF_STEP ;
DBLVECTOR vAng( vAng1.size()) ;
for ( size_t i = 0 ; i < vAng1.size() ; ++ i)
vAng[i] = vAxRotPrec[i] * ( 1 - dCoeff) + vAng1[i] * dCoeff ;
int nStat ;
bool bOsOk = m_pMchMgr->VerifyOutstroke( ptCurr.x, ptCurr.y, ptCurr.z, vAng[0], vAng[1], nStat) ;
bool bOsOk = m_pMchMgr->VerifyOutstroke( ptCurr.x, ptCurr.y, ptCurr.z, vAng, nStat) ;
if ( ! bOsOk || nStat != 0) {
bOk = false ;
pCamData->SetAxes( CamData::AS_OUTSTROKE, vAxVal) ;
@@ -761,6 +764,11 @@ Operation::AdjustStartEndMovements(void)
DBLVECTOR vAxIni ;
if ( ! pPrevOp->GetFinalAxesValues( vAxVal) || ! GetInitialAxesValues( vAxIni))
return false ;
// verifico se la testa interferisce con i pezzi o i bloccaggi sulla tavola
if ( ! TestCollisionAvoid( vAxVal, vAxIni)) {
if ( ! pPrevOp->AddRise( vAxVal))
return false ;
}
// determino delta Z rispetto a posizione finale
if ( vAxVal.size() >= 4 && vAxIni.size() >= 4) {
double dDelta = 0 ;
@@ -902,7 +910,7 @@ Operation::AddRise( DBLVECTOR& vAxVal, double dDelta)
int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLastPxClId, Release( pGP)) ;
if ( nId == GDB_ID_NULL)
return false ;
m_pGeomDB->SetName( nId, MCH_RISE) ;
m_pGeomDB->SetName( nId, MCH_CL_RISE) ;
// creo oggetto dati Cam
PtrOwner<CamData> pCam( pCamData->Clone()) ;
if ( IsNull( pCam))
@@ -958,16 +966,16 @@ Operation::RemoveRise( void)
// recupero l'ultimo percorso CL
int nClPathId = m_pGeomDB->GetLastGroupInGroup( nClId) ;
// elimino tutte le entità RISE alla fine del percorso
int nId = m_pGeomDB->GetFirstNameInGroup( nClPathId, MCH_RISE) ;
int nId = m_pGeomDB->GetFirstNameInGroup( nClPathId, MCH_CL_RISE) ;
while ( nId != GDB_ID_NULL) {
m_pGeomDB->Erase( nId) ;
nId = m_pGeomDB->GetFirstNameInGroup( nClPathId, MCH_RISE) ;
nId = m_pGeomDB->GetFirstNameInGroup( nClPathId, MCH_CL_RISE) ;
}
// elimino a maggior ragione le entità HOME
nId = m_pGeomDB->GetFirstNameInGroup( nClPathId, MCH_HOME) ;
nId = m_pGeomDB->GetFirstNameInGroup( nClPathId, MCH_CL_HOME) ;
while ( nId != GDB_ID_NULL) {
m_pGeomDB->Erase( nId) ;
nId = m_pGeomDB->GetFirstNameInGroup( nClPathId, MCH_HOME) ;
nId = m_pGeomDB->GetFirstNameInGroup( nClPathId, MCH_CL_HOME) ;
}
return true ;
@@ -986,7 +994,7 @@ Operation::AddHome( void)
// recupero l'ultimo percorso
int nLastPxClId = m_pGeomDB->GetLastGroupInGroup( nClId) ;
// recupero l'ultima entità del percorso di nome RISE
int nEntId = m_pGeomDB->GetLastNameInGroup( nLastPxClId, MCH_RISE) ;
int nEntId = m_pGeomDB->GetLastNameInGroup( nLastPxClId, MCH_CL_RISE) ;
if ( nEntId == GDB_ID_NULL)
return false ;
// ne recupero i dati Cam
@@ -1003,7 +1011,7 @@ Operation::AddHome( void)
int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLastPxClId, Release( pGP)) ;
if ( nId == GDB_ID_NULL)
return false ;
m_pGeomDB->SetName( nId, MCH_HOME) ;
m_pGeomDB->SetName( nId, MCH_CL_HOME) ;
// creo oggetto dati Cam
PtrOwner<CamData> pCam( pCamData->Clone()) ;
if ( IsNull( pCam))
@@ -1037,10 +1045,10 @@ Operation::RemoveHome( void)
// recupero l'ultimo percorso CL
int nClPathId = m_pGeomDB->GetLastGroupInGroup( nClId) ;
// elimino tutte le entità HOME alla fine del percorso
int nId = m_pGeomDB->GetFirstNameInGroup( nClPathId, MCH_HOME) ;
int nId = m_pGeomDB->GetFirstNameInGroup( nClPathId, MCH_CL_HOME) ;
while ( nId != GDB_ID_NULL) {
m_pGeomDB->Erase( nId) ;
nId = m_pGeomDB->GetFirstNameInGroup( nClPathId, MCH_HOME) ;
nId = m_pGeomDB->GetFirstNameInGroup( nClPathId, MCH_CL_HOME) ;
}
return true ;
@@ -1092,250 +1100,82 @@ Operation::CalcDeltaZForHeadRotation( const DBLVECTOR& vAxStart, const DBLVECTOR
return true ;
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
bool
Operation::SetPathId( int nPathId)
Operation::TestCollisionAvoid( const DBLVECTOR& vAxStart, const DBLVECTOR& vAxEnd)
{
m_nPathId = nPathId ;
return true ;
}
//----------------------------------------------------------------------------
bool
Operation::SetToolDir( const Vector3d& vtDir)
{
m_vtTool = vtDir ;
return ( m_vtTool.Normalize()) ;
}
//----------------------------------------------------------------------------
bool
Operation::SetCorrDir( const Vector3d& vtDir)
{
m_vtCorr = vtDir ;
return ( ! m_vtCorr.IsSmall()) ;
}
//----------------------------------------------------------------------------
bool
Operation::SetAuxDir( const Vector3d& vtDir)
{
m_vtAux = vtDir ;
return true ;
}
//----------------------------------------------------------------------------
bool
Operation::SetCorrAuxDir( const Vector3d& vtDir)
{
m_vtCorr = vtDir ;
m_vtAux = vtDir ;
return ( ! m_vtCorr.IsSmall()) ;
}
//----------------------------------------------------------------------------
bool
Operation::SetFeed( double dFeed)
{
m_dFeed = dFeed ;
return true ;
}
//----------------------------------------------------------------------------
bool
Operation::SetFlag( int nFlag)
{
m_nFlag = nFlag ;
return true ;
}
//----------------------------------------------------------------------------
int
Operation::AddRapidStart( const Point3d& ptP)
{
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return GDB_ID_NULL ;
// verifico di essere in uno stato valido per inizio
if ( m_vtTool.IsSmall())
return GDB_ID_NULL ;
// creo oggetto punto per DB geometrico
PtrOwner<IGeoPoint3d> pGP( CreateGeoPoint3d()) ;
if ( IsNull( pGP))
return GDB_ID_NULL ;
// assegno le coordinate del punto
pGP->Set( ptP) ;
// inserisco l'oggetto nel DB geometrico
int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, m_nPathId, Release( pGP)) ;
if ( nId == GDB_ID_NULL)
return GDB_ID_NULL ;
// creo oggetto dati Cam
PtrOwner<CamData> pCam( new( nothrow) CamData) ;
if ( IsNull( pCam))
return GDB_ID_NULL ;
// assegno valori
pCam->SetMoveType( 0) ;
pCam->SetToolDir( m_vtTool) ;
pCam->SetCorrDir( m_vtCorr) ;
pCam->SetAuxDir( m_vtAux) ;
pCam->SetEndPoint( ptP) ;
pCam->SetFeed( 0) ;
pCam->SetFlag( m_nFlag) ;
// associo questo oggetto a quello geometrico
m_pGeomDB->SetUserObj( nId, Release( pCam)) ;
// salvo la posizione corrente
m_bCurr = true ;
m_ptCurr = ptP ;
return nId ;
}
//----------------------------------------------------------------------------
int
Operation::AddRapidMove( const Point3d& ptP)
{
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return GDB_ID_NULL ;
// verifico di essere in uno stato valido per un movimento in rapido
if ( ! m_bCurr || m_vtTool.IsSmall())
return GDB_ID_NULL ;
// creo oggetto linea per DB geometrico
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
if ( IsNull( pLine))
return GDB_ID_NULL ;
// assegno le coordinate degli estremi
if ( ! pLine->Set( m_ptCurr, ptP))
return GDB_ID_NULL ;
// inserisco l'oggetto nel DB geometrico
int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, m_nPathId, Release( pLine)) ;
if ( nId == GDB_ID_NULL)
return GDB_ID_NULL ;
// creo oggetto dati Cam
PtrOwner<CamData> pCam( new( nothrow) CamData) ;
if ( IsNull( pCam))
return GDB_ID_NULL ;
// assegno valori
pCam->SetMoveType( 0) ;
pCam->SetToolDir( m_vtTool) ;
pCam->SetCorrDir( m_vtCorr) ;
pCam->SetAuxDir( m_vtAux) ;
pCam->SetEndPoint( ptP) ;
pCam->SetFeed( 0) ;
pCam->SetFlag( m_nFlag) ;
// associo questo oggetto a quello geometrico
m_pGeomDB->SetUserObj( nId, Release( pCam)) ;
// salvo la posizione corrente
m_ptCurr = ptP ;
return nId ;
}
//----------------------------------------------------------------------------
int
Operation::AddLinearMove( const Point3d& ptP)
{
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return GDB_ID_NULL ;
// verifico di essere in uno stato valido per un movimento lineare
if ( ! m_bCurr || m_vtTool.IsSmall()) {
LOG_INFO( GetEMkLogger(), "Error on LinearMove : Curr or ToolDir")
return GDB_ID_NULL ;
// Recupero macchina corrente
Machine* pMch = ( m_pMchMgr != nullptr ? m_pMchMgr->GetCurrMachine() : nullptr) ;
if ( pMch == nullptr)
return false ;
// Recupero tavola corrente
string sTable ;
if ( ! pMch->GetCurrTable( sTable))
return false ;
// Recupero assi correnti
STRVECTOR vAxName ;
pMch->GetAllCurrAxesName( vAxName) ;
// il numero di assi deve essere costante
if ( vAxName.size() != vAxStart.size() || vAxName.size() != vAxEnd.size())
return false ;
// Porto la macchina in home
pMch->ResetAllAxesPos() ;
// Elenco grezzi attivi
INTVECTOR vRawId ;
int nRawId = m_pMchMgr->GetFirstRawPart() ;
while ( nRawId != GDB_ID_NULL) {
if ( m_pMchMgr->VerifyRawPartPhase( nRawId, m_nPhase))
vRawId.emplace_back( nRawId) ;
nRawId = m_pMchMgr->GetNextRawPart( nRawId) ;
}
// se feed nulla, assegno il minimo e lo segnalo
if ( m_dFeed < FEED_MIN) {
m_dFeed = FEED_MIN ;
LOG_INFO( GetEMkLogger(), "Error on LinearMove : Min Feed")
// Aggancio pezzi attivi alla tavola corrente
for ( const auto nRawId : vRawId)
pMch->LinkRawPartToGroup( nRawId, sTable) ;
// Elenco bloccaggi attivi
INTVECTOR vFxtId ;
int nFxtId = m_pMchMgr->GetFirstFixture() ;
while ( nFxtId != GDB_ID_NULL) {
vFxtId.emplace_back( nFxtId) ;
nFxtId = m_pMchMgr->GetNextFixture( nFxtId) ;
}
// creo oggetto linea per DB geometrico
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
if ( IsNull( pLine))
return GDB_ID_NULL ;
// assegno le coordinate degli estremi
if ( ! pLine->Set( m_ptCurr, ptP))
return GDB_ID_NULL ;
// inserisco l'oggetto nel DB geometrico
int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, m_nPathId, Release( pLine)) ;
if ( nId == GDB_ID_NULL)
return GDB_ID_NULL ;
// creo oggetto dati Cam
PtrOwner<CamData> pCam( new( nothrow) CamData) ;
if ( IsNull( pCam))
return GDB_ID_NULL ;
// assegno valori
pCam->SetMoveType( 1) ;
pCam->SetToolDir( m_vtTool) ;
pCam->SetCorrDir( m_vtCorr) ;
pCam->SetAuxDir( m_vtAux) ;
pCam->SetEndPoint( ptP) ;
pCam->SetFeed( m_dFeed) ;
pCam->SetFlag( m_nFlag) ;
// associo questo oggetto a quello geometrico
m_pGeomDB->SetUserObj( nId, Release( pCam)) ;
// salvo la posizione corrente
m_ptCurr = ptP ;
return nId ;
}
// Aggancio bloccaggi alla tavola corrente
for ( const auto nFxtId : vFxtId)
pMch->LinkFixtureToGroup( nFxtId, sTable) ;
// Vado nelle posizioni da controllare
bool bCollide = false ;
for ( int i = 1 ; i <= 3 && ! bCollide ; ++ i) {
double dCoeff = double( i) / 4 ;
for ( size_t j = 0 ; j < vAxStart.size() ; ++ j) {
double dPos = ( 1 - dCoeff) * vAxStart[j] + dCoeff * vAxEnd[j] ;
pMch->SetAxisPos( vAxName[j], dPos) ;
}
// Eseguo controllo
BBox3d b3Head ;
m_pGeomDB->GetGlobalBBox( pMch->GetCurrHead(), b3Head) ;
for ( const auto nRawId : vRawId) {
BBox3d b3Raw ;
int nRawSolidId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ;
if ( m_pGeomDB->GetGlobalBBox( nRawSolidId, b3Raw) && b3Head.Overlaps( b3Raw)) {
bCollide = true ;
break ;
}
}
for ( const auto nFxtId : vFxtId) {
BBox3d b3Fxt ;
if ( m_pGeomDB->GetGlobalBBox( nFxtId, b3Fxt) && b3Head.Overlaps( b3Fxt)) {
bCollide = true ;
break ;
}
}
//int nRes = 1 ;
//while ( nRes != 0)
// nRes = ExeProcessEvents( 0, 5) ;
}
// Riporto la macchina in home
pMch->ResetAllAxesPos() ;
// Sgancio grezzi e sottopezzi dalla tavola corrente
pMch->UnlinkAllRawPartsFromGroups() ;
pMch->UnlinkAllFixturesFromGroups() ;
//----------------------------------------------------------------------------
int
Operation::AddArcMove( const Point3d& ptP, const Point3d& ptCen, double dAngCen, double dDeltaZ)
{
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return GDB_ID_NULL ;
// verifico di essere in uno stato valido per un movimento arco
if ( ! m_bCurr || m_vtTool.IsSmall()) {
LOG_INFO( GetEMkLogger(), "Error on ArcMove : Curr or ToolDir")
return GDB_ID_NULL ;
}
// se feed nulla, assegno il minimo e lo segnalo
if ( m_dFeed < FEED_MIN) {
m_dFeed = FEED_MIN ;
LOG_INFO( GetEMkLogger(), "Error on ArcMove : Min Feed")
}
// creo oggetto arco per DB geometrico
PtrOwner<ICurveArc> pArc( CreateCurveArc()) ;
if ( IsNull( pArc))
return GDB_ID_NULL ;
// assegno i dati dell'arco
if ( ! pArc->SetCPA( ptCen, m_ptCurr, dAngCen, dDeltaZ))
return GDB_ID_NULL ;
Point3d ptFin ;
if ( ! pArc->GetEndPoint( ptFin) || ! AreSamePointApprox( ptFin, ptP))
return GDB_ID_NULL ;
int nMove = ( dAngCen > 0 ? 3 : 2) ;
// inserisco l'oggetto nel DB geometrico
int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, m_nPathId, Release( pArc)) ;
if ( nId == GDB_ID_NULL)
return GDB_ID_NULL ;
// creo oggetto dati Cam
PtrOwner<CamData> pCam( new( nothrow) CamData) ;
if ( IsNull( pCam))
return GDB_ID_NULL ;
// assegno valori
pCam->SetMoveType( nMove) ;
pCam->SetToolDir( m_vtTool) ;
pCam->SetCorrDir( m_vtCorr) ;
pCam->SetAuxDir( m_vtAux) ;
pCam->SetEndPoint( ptP) ;
pCam->SetCenter( ptCen) ;
pCam->SetAngCen( dAngCen) ;
pCam->SetFeed( m_dFeed) ;
pCam->SetFlag( m_nFlag) ;
// associo questo oggetto a quello geometrico
m_pGeomDB->SetUserObj( nId, Release( pCam)) ;
// salvo la posizione corrente
m_ptCurr = ptP ;
return nId ;
}
//----------------------------------------------------------------------------
bool
Operation::ResetMoveData( void)
{
m_bCurr = false ;
m_ptCurr = ORIG ;
m_vtTool = V_NULL ;
m_vtCorr = V_NULL ;
m_vtAux = V_NULL ;
m_dFeed = 0 ;
m_nFlag = 0 ;
return true ;
return ( ! bCollide) ;
}