//---------------------------------------------------------------------------- // EgalTech 2015-2015 //---------------------------------------------------------------------------- // File : Drilling.cpp Data : 21.05.15 Versione : 1.6e7 // Contenuto : Implementazione gestione forature. // // Note : Questa lavorazione è sempre espressa nel riferimento globale. // // Modifiche : 21.05.15 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "MachMgr.h" #include "DllMain.h" #include "Drilling.h" #include "MachiningConst.h" #include "/EgtDev/Include/EGkGeoPoint3d.h" #include "/EgtDev/Include/EGkCurveLine.h" #include "/EgtDev/Include/EGkCurveArc.h" #include "/EgtDev/Include/EGkUserObjFactory.h" #include "/EgtDev/Include/EGnStringKeyVal.h" #include "/EgtDev/Include/EgtPointerOwner.h" using namespace std ; //---------------------------------------------------------------------------- struct Hole { int nOriId ; // identificativo della geometria di origine Point3d ptIni ; // punto iniziale Vector3d vtDir ; // direzione di riferimento (dal fondo verso l'inizio) double dDiam ; // diametro double dLen ; // lunghezza dell'asse bool bBlind ; // flag per cieco/passante // eventuale tipo ( standard, ribassato, svasato) Hole( void) : nOriId( GDB_ID_NULL), ptIni(), vtDir(), dDiam( 0), dLen( 0), bBlind( true) {} }; //---------------------------------------------------------------------------- USEROBJ_REGISTER( "EMkDrilling", Drilling) ; //---------------------------------------------------------------------------- const string& Drilling::GetClassName( void) const { return USEROBJ_GETNAME( Drilling) ; } //---------------------------------------------------------------------------- Drilling* Drilling::Clone( void) const { // alloco oggetto Drilling* pDri = new(nothrow) Drilling ; // eseguo copia dei dati if ( pDri != nullptr) { try { pDri->m_nOwnerId = GDB_ID_NULL ; pDri->m_pGeomDB = nullptr ; pDri->m_Params = m_Params ; pDri->m_TParams = m_TParams ; } catch( ...) { delete pDri ; return nullptr ; } } // ritorno l'oggetto return pDri ; } //---------------------------------------------------------------------------- bool Drilling::Dump( string& sOut, bool bMM, const char* szNewLine) const { sOut += GetClassName() + "[mm]" + szNewLine ; sOut += KEY_IDS + EQUAL + ToString( m_vId) + szNewLine ; for ( int i = 0 ; i < m_Params.GetSize() ; ++ i) sOut += m_Params.ToString( i) + szNewLine ; for ( int i = 0 ; i < m_TParams.GetSize() ; ++ i) sOut += m_TParams.ToString( i) + szNewLine ; return true ; } //---------------------------------------------------------------------------- bool Drilling::Save( STRVECTOR& vString) const { try { int nSize = 1 + m_Params.GetSize() + m_TParams.GetSize() ; vString.insert( vString.begin(), nSize, "") ; int k = - 1 ; if ( ! SetVal( KEY_IDS, m_vId, vString[++k])) return false ; for ( int i = 0 ; i < m_Params.GetSize() ; ++ i) vString[++k] = m_Params.ToString( i) ; for ( int i = 0 ; i < m_TParams.GetSize() ; ++ i) vString[++k] = m_TParams.ToString( i) ; } catch( ...) { return false ; } return true ; } //---------------------------------------------------------------------------- bool Drilling::Load( const STRVECTOR& vString) { int nSize = 1 + m_Params.GetSize() + m_TParams.GetSize() ; if ( int( vString.size()) < nSize) return false ; int k = - 1 ; if ( ! GetVal( vString[++k], KEY_IDS, m_vId)) return false ; for ( int i = 0 ; i < m_Params.GetSize() ; ++ i) { int nKey ; if ( ! m_Params.FromString( vString[++k], nKey) || nKey != i) return false ; } for ( int i = 0 ; i < m_TParams.GetSize() ; ++ i) { int nKey ; if ( ! m_TParams.FromString( vString[++k], nKey) || nKey != i) return false ; } return true ; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- Drilling::Drilling( void) { m_nOwnerId = GDB_ID_NULL ; m_pGeomDB = nullptr ; m_Params.m_sName = "*" ; m_Params.m_sToolName = "*" ; m_TParams.m_sName = "*" ; m_TParams.m_sHead = "*" ; } //---------------------------------------------------------------------------- bool Drilling::Prepare( const string& sDriName) { // verifico il gestore lavorazioni if ( m_pMchMgr == nullptr) return false ; // recupero il gestore DB utensili della macchina corrente ToolsMgr* pTMgr = m_pMchMgr->GetCurrToolsMgr() ; if ( pTMgr == nullptr) return false ; // recupero il gestore DB lavorazioni della macchina corrente MachiningsMgr* pMMgr = m_pMchMgr->GetCurrMachiningsMgr() ; if ( pMMgr == nullptr) return false ; // ricerca della lavorazione di libreria con il nome indicato const DrillingData* pDdata = GetDrillingData( pMMgr->GetMachining( sDriName)) ; if ( pDdata == nullptr) return false ; m_Params = *pDdata ; // ricerca dell'utensile usato dalla lavorazione const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; if ( pTdata == nullptr) return false ; m_TParams = *pTdata ; m_Params.m_sToolName = m_TParams.m_sName ; return true ; } //---------------------------------------------------------------------------- bool Drilling::SetParam( int nType, bool bVal) { switch ( nType) { case MPA_INVERT : m_Params.m_bInvert = bVal ; break ; default : return false ; } return true ; } //---------------------------------------------------------------------------- bool Drilling::SetParam( int nType, int nVal) { return false ; } //---------------------------------------------------------------------------- bool Drilling::SetParam( int nType, double dVal) { switch ( nType) { case MPA_TOOLSPEED : if ( ! m_TParams.VerifySpeed( dVal)) return false ; m_TParams.m_dSpeed = dVal ; break ; case MPA_TOOLFEED : m_TParams.m_dFeed = dVal ; break ; case MPA_TOOLSTARTFEED : m_TParams.m_dStartFeed = dVal ; break ; case MPA_TOOLENDFEED : m_TParams.m_dEndFeed = dVal ; break ; case MPA_STARTPOS : m_Params.m_dStartPos = dVal ; break ; case MPA_STARTSLOWLEN : m_Params.m_dStartSlowLen = dVal ; break ; case MPA_ENDSLOWLEN : m_Params.m_dEndSlowLen = dVal ; break ; case MPA_THROUADDLEN : m_Params.m_dThroughAddLen = dVal ; break ; case MPA_STEP : m_Params.m_dStep = dVal ; break ; case MPA_RETURNPOS : m_Params.m_dReturnPos = dVal ; break ; default : return false ; } return true ; } //---------------------------------------------------------------------------- bool Drilling::SetParam( int nType, const string& sVal) { switch ( nType) { case MPA_TOOL : { const ToolData* pTdata ; if ( ! m_Params.VerifyTool( m_pMchMgr->GetCurrToolsMgr(), sVal, pTdata)) return false ; m_Params.m_sToolName = sVal ; m_Params.m_ToolUuid = pTdata->m_Uuid ; m_TParams = *pTdata ; } break ; default : return false ; } return true ; } //---------------------------------------------------------------------------- bool Drilling::SetGeometry( const SELVECTOR& vIds) { // verifico validità gestore DB geometrico if ( m_pGeomDB == nullptr) return false ; // reset della geometria corrente m_vId.clear() ; // verifico che gli identificativi rappresentino dei fori con il corretto diametro for ( int i = 0 ; i < int( vIds.size()) ; ++ i) { // recupero i dati del foro Hole hole ; if ( ! GetHoleData( vIds[i], hole) || fabs( hole.dDiam - m_TParams.m_dDiam) > EPS_SMALL) { string sOut = "Entity " + ToString( vIds[i].nId) + " skipped by Drilling" ; LOG_INFO( GetEMkLogger(), sOut.c_str()) ; continue ; } // posso aggiungere alla lista m_vId.push_back( vIds[i]) ; } return ( ! m_vId.empty()) ; } //---------------------------------------------------------------------------- bool Drilling::Apply( void) { // verifico validità gestore DB geometrico e Id del gruppo if ( m_pGeomDB == nullptr || ! m_pGeomDB->ExistsObj( m_nOwnerId)) return false ; // recupero gruppo per geometria di lavorazione (Cutter Location) int nClId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_CL) ; // se non c'è, lo aggiungo if ( nClId == GDB_ID_NULL) { nClId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ; if ( nClId == GDB_ID_NULL) return false ; m_pGeomDB->SetName( nClId, MCH_CL) ; } // altrimenti lo svuoto else m_pGeomDB->EmptyGroup( nClId) ; // elaboro i singoli fori int i = 0 ; for ( const auto& vId : m_vId) { // creo gruppo per geometria di lavorazione del foro int nPathId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ; if ( nPathId == GDB_ID_NULL) return false ; m_pGeomDB->SetName( nPathId, MCH_PATH + ToString( ++i)) ; m_pGeomDB->SetInfo( nPathId, KEY_IDS, ToString( vId)) ; m_pGeomDB->SetMaterial( nPathId, GREEN) ; // recupero i dati del foro Hole hole ; if ( ! GetHoleData( vId, hole) || fabs( hole.dDiam - m_TParams.m_dDiam) > EPS_SMALL) { m_pGeomDB->Erase( nPathId) ; string sOut = "Entity " + ToString( vId) + " skipped by Drilling" ; LOG_INFO( GetEMkLogger(), sOut.c_str()) ; continue ; } // limito lunghezza foro a massima lavorazione della punta if ( hole.dLen > m_TParams.m_dMaxMat + EPS_SMALL) { hole.dLen = m_TParams.m_dMaxMat ; string sOut = "Drill bit too short for Hole " + ToString( vId) ; LOG_INFO( GetEMkLogger(), sOut.c_str()) ; } // foro normale if ( m_Params.m_dStep < EPS_SMALL || m_Params.m_dStep > hole.dLen - EPS_SMALL) { if ( ! DoStandardDrilling( hole, vId, nPathId)) { m_pGeomDB->Erase( nPathId) ; string sOut = "Hole " + ToString( vId) + " skipped by Standard Drilling" ; LOG_INFO( GetEMkLogger(), sOut.c_str()) ; } } else { if ( ! DoPeckDrilling( hole, vId, nPathId)) { m_pGeomDB->Erase( nPathId) ; string sOut = "Hole " + ToString( vId) + " skipped by Peck Drilling" ; LOG_INFO( GetEMkLogger(), sOut.c_str()) ; } } } // calcolo gli assi macchina return CalculateAxesValues() ; } //---------------------------------------------------------------------------- bool Drilling::GetParam( int nType, bool& bVal) const { switch ( nType) { case MPA_INVERT : bVal = m_Params.m_bInvert ; return true ; } return false ; } //---------------------------------------------------------------------------- bool Drilling::GetParam( int nType, int& nVal) const { return false ; } //---------------------------------------------------------------------------- bool Drilling::GetParam( int nType, double& dVal) const { switch ( nType) { case MPA_TOOLSPEED : dVal = m_TParams.m_dSpeed ; return true ; case MPA_TOOLFEED : dVal = m_TParams.m_dFeed ; return true ; case MPA_TOOLSTARTFEED : dVal = m_TParams.m_dStartFeed ; return true ; case MPA_TOOLENDFEED : dVal = m_TParams.m_dEndFeed ; return true ; case MPA_STARTPOS : dVal = m_Params.m_dStartPos ; return true ; case MPA_STARTSLOWLEN : dVal = m_Params.m_dStartSlowLen ; return true ; case MPA_ENDSLOWLEN : dVal = m_Params.m_dEndSlowLen ; return true ; case MPA_THROUADDLEN : dVal = m_Params.m_dThroughAddLen ; return true ; case MPA_STEP : dVal = m_Params.m_dStep ; return true ; case MPA_RETURNPOS : dVal = m_Params.m_dReturnPos ; return true ; } return false ; } //---------------------------------------------------------------------------- bool Drilling::GetParam( int nType, string& sVal) const { switch ( nType) { case MPA_NAME : sVal = m_Params.m_sName ; return true ; case MPA_TOOL : sVal = m_Params.m_sToolName ; return true ; case MPA_TUUID : sVal = ToString( m_Params.m_ToolUuid) ; return true ; case MPA_UUID : sVal = ToString( m_Params.m_Uuid) ; return true ; } return false ; } //---------------------------------------------------------------------------- const ToolData& Drilling::GetToolData( void) const { return m_TParams ; } //---------------------------------------------------------------------------- bool Drilling::GetHoleData( SelData Id, Hole& hole) { // deve essere un arco (ignoro il sotto identificativo) const ICurveArc* pArc = GetCurveArc( m_pGeomDB->GetGeoObj( Id.nId)) ; if ( pArc == nullptr) return false ; // deve avere estrusione e spessore double dThick ; Vector3d vtExtr ; if ( ! pArc->GetThickness( dThick) || ! pArc->GetExtrusion( vtExtr) || ( dThick * vtExtr).IsSmall ()) return false ; // ne recupero il riferimento globale Frame3d frGlob ; if ( ! m_pGeomDB->GetGlobFrame( Id.nId, frGlob)) return false ; // assegno Id hole.nOriId = Id.nId ; // ne recupero il diametro hole.dDiam = 2 * pArc->GetRadius() ; // ne recupero il centro hole.ptIni = pArc->GetCenter() ; hole.ptIni.ToGlob( frGlob) ; // ne recupero versore direzione e lunghezza hole.vtDir = (( dThick < 0) ? vtExtr : - vtExtr) ; hole.vtDir.ToGlob( frGlob) ; hole.vtDir.Normalize() ; hole.dLen = fabs( dThick) ; // lo dichiaro cieco (andrà calcolato opportunamente) hole.bBlind = true ; return true ; } //---------------------------------------------------------------------------- bool Drilling::DoStandardDrilling( const Hole& hole, SelData Id, int nPathId) { // aggiusto alcuni parametri del ciclo di foratura double dStartSlowLen = fabs( m_Params.m_dStartSlowLen) ; if ( fabs( m_TParams.m_dStartFeed - m_TParams.m_dFeed) < EPS_SMALL) dStartSlowLen = 0 ; double dEndSlowLen = ( hole.bBlind ? 0 : fabs( m_Params.m_dEndSlowLen)) ; if ( fabs( m_TParams.m_dEndFeed - m_TParams.m_dFeed) < EPS_SMALL) dEndSlowLen = 0 ; if ( ( dStartSlowLen + dEndSlowLen) > hole.dLen) { dStartSlowLen = dStartSlowLen / ( dStartSlowLen + dEndSlowLen) * hole.dLen ; dEndSlowLen = hole.dLen - dStartSlowLen ; } double dAddLen = ( hole.bBlind ? 0 : m_Params.m_dThroughAddLen) ; bool bStartSlow = ( dStartSlowLen > EPS_SMALL) ; bool bStd = ( ( hole.dLen - dStartSlowLen - dEndSlowLen) > EPS_SMALL) ; bool bEndSlow = ( dEndSlowLen > EPS_SMALL) ; // determino alcune caratteristiche dell'utensile double dTExtrLen = max( 0.0, m_TParams.m_dTLen - m_TParams.m_dLen) ; // imposto dati comuni SetPathId( nPathId) ; SetToolDir( hole.vtDir) ; // 1 -> punto approccio double dAppr = GetApproachDist() ; Point3d ptP1 = hole.ptIni + hole.vtDir * ( dAppr + dTExtrLen) ; if ( AddStart( ptP1) == GDB_ID_NULL) return false ; // 2 -> punto fuori (se diverso dal precedente) if ( m_Params.m_dStartPos < dAppr) { SetFeed( MAX_FEED) ; SetFlag( 0) ; Point3d ptP2 = hole.ptIni + hole.vtDir * ( m_Params.m_dStartPos + dTExtrLen) ; if ( AddLinearMove( ptP2) == GDB_ID_NULL) return false ; } // 3 -> punto termine velocità ridotta iniziale (se previsto) if ( bStartSlow) { SetFeed( m_TParams.m_dStartFeed) ; if ( ! bStd && ! bEndSlow) SetFlag( 1) ; // fondo del foro Point3d ptP3 = hole.ptIni - hole.vtDir * dStartSlowLen ; if ( ! bStd && ! bEndSlow) ptP3 -= hole.vtDir * dAddLen ; if ( AddLinearMove( ptP3) == GDB_ID_NULL) return false ; } // 4 -> punto termine velocità standard (se risulta) if ( bStd) { SetFeed( m_TParams.m_dFeed) ; if ( ! bEndSlow) SetFlag( 1) ; // fondo del foro Point3d ptP4 = hole.ptIni - hole.vtDir * ( hole.dLen - dEndSlowLen) ; if ( ! bEndSlow) ptP4 -= hole.vtDir * dAddLen ; if ( AddLinearMove( ptP4) == GDB_ID_NULL) return false ; } // 5 -> punto termine velocità finale ridotta (se previsto) if ( bEndSlow) { SetFeed( m_TParams.m_dEndFeed) ; SetFlag( 1) ; // fondo del foro Point3d ptP5 = hole.ptIni - hole.vtDir * ( hole.dLen + dAddLen) ; if ( AddLinearMove( ptP5) == GDB_ID_NULL) return false ; } // 6 -> ritorno all'approccio del foro SetFeed( MAX_FEED) ; SetFlag( 0) ; if ( AddLinearMove( ptP1) == GDB_ID_NULL) return false ; // reset dati di movimento ResetMoveData() ; return true ; } //---------------------------------------------------------------------------- bool Drilling::DoPeckDrilling( const Hole& hole, SelData Id, int nPathId) { // aggiusto alcuni parametri del ciclo di foratura double dStartSlowLen = fabs( m_Params.m_dStartSlowLen) ; if ( fabs( m_TParams.m_dStartFeed - m_TParams.m_dFeed) < EPS_SMALL) dStartSlowLen = 0 ; double dEndSlowLen = ( hole.bBlind ? 0 : fabs( m_Params.m_dEndSlowLen)) ; if ( fabs( m_TParams.m_dEndFeed - m_TParams.m_dFeed) < EPS_SMALL) dEndSlowLen = 0 ; if ( ( dStartSlowLen + dEndSlowLen) > hole.dLen) { dStartSlowLen = dStartSlowLen / ( dStartSlowLen + dEndSlowLen) * hole.dLen ; dEndSlowLen = hole.dLen - dStartSlowLen ; } double dStdLen = hole.dLen - dStartSlowLen - dEndSlowLen ; double dAddLen = ( hole.bBlind ? 0 : m_Params.m_dThroughAddLen) ; double dReturnPos = m_Params.m_dReturnPos ; bool bStartSlow = ( dStartSlowLen > EPS_SMALL) ; bool bStd = ( dStdLen > EPS_SMALL) ; bool bEndSlow = ( dEndSlowLen > EPS_SMALL) ; // determino alcune caratteristiche dell'utensile double dTExtrLen = max( 0.0, m_TParams.m_dTLen - m_TParams.m_dLen) ; // imposto dati comuni SetPathId( nPathId) ; SetToolDir( hole.vtDir) ; // 1 -> punto approccio double dAppr = GetApproachDist() ; Point3d ptP1 = hole.ptIni + hole.vtDir * ( dAppr + dTExtrLen) ; if ( AddStart( ptP1) == GDB_ID_NULL) return false ; // 2 -> punto fuori (se diverso dal precedente) if ( m_Params.m_dStartPos < dAppr) { SetFeed( MAX_FEED) ; SetFlag( 0) ; Point3d ptP2 = hole.ptIni + hole.vtDir * ( m_Params.m_dStartPos + dTExtrLen) ; if ( AddLinearMove( ptP2) == GDB_ID_NULL) return false ; } // ciclo di affondamento a step const double MIN_STEP = 5 ; const double APPR_STEP = 1 ; const double MIN_MOVE = 1 ; double dStep = max( m_Params.m_dStep, MIN_STEP) ; int nStep = int( ceil( hole.dLen / dStep)) ; dStep = hole.dLen / nStep ; if ( dReturnPos < - dStep + APPR_STEP + MIN_MOVE) dReturnPos = - dStep + APPR_STEP + MIN_MOVE ; double dCurrLen = 0 ; for ( int i = 1 ; i <= nStep ; ++ i) { // se non è primo step faccio retrazione e riaffondo if ( i != 1) { // retrazione SetFeed( MAX_FEED) ; SetFlag( 3) ; // punto di scarico truciolo Point3d ptPr = hole.ptIni + hole.vtDir * dReturnPos ; if ( AddLinearMove( ptPr) == GDB_ID_NULL) return false ; // riaffondo SetFeed( MAX_FEED) ; SetFlag( 0) ; Point3d ptPa = hole.ptIni - hole.vtDir * ( dCurrLen - APPR_STEP) ; if ( AddLinearMove( ptPa) == GDB_ID_NULL) return false ; } // lunghezza di fine step double dEndLen = dCurrLen + dStep ; // 3 -> punto termine velocità ridotta iniziale (se previsto) if ( bStartSlow && ( i == 1 || dCurrLen < dStartSlowLen + EPS_SMALL)) { // lunghezza di esecuzione double dLen = min( dStartSlowLen, dEndLen) ; // determino se arrivo in fondo al foro bool bHoleEnd = ( ! bStd && ! bEndSlow && dLen > hole.dLen - EPS_SMALL) ; // determino se arrivo in fondo allo step bool bStepEnd = ( dLen > dEndLen - EPS_SMALL) ; // assegno parametri SetFeed( m_TParams.m_dStartFeed) ; if ( bHoleEnd) SetFlag( 1) ; // fondo del foro else if ( bStepEnd) SetFlag( 2) ; // fondo dello step // movimento Point3d ptP3 = hole.ptIni - hole.vtDir * dLen ; if ( bHoleEnd) ptP3 -= hole.vtDir * dAddLen ; if ( AddLinearMove( ptP3) == GDB_ID_NULL) return false ; // aggiorno posizione e verifico se step completato dCurrLen = dLen ; if ( bHoleEnd || bStepEnd) continue ; } // 4 -> punto termine velocità standard (se risulta) if ( bStd && dCurrLen < dStartSlowLen + dStdLen + EPS_SMALL) { // lunghezza di esecuzione double dLen = min( hole.dLen - dEndSlowLen, dEndLen) ; // determino se arrivo in fondo al foro bool bHoleEnd = ( ! bEndSlow && dLen > hole.dLen - EPS_SMALL) ; // determino se arrivo in fondo allo step bool bStepEnd = ( dLen > dEndLen - EPS_SMALL) ; // assegno parametri SetFeed( m_TParams.m_dFeed) ; if ( bHoleEnd) SetFlag( 1) ; // fondo del foro else if ( bStepEnd) SetFlag( 2) ; // fondo dello step // movimento Point3d ptP4 = hole.ptIni - hole.vtDir * dLen ; if ( bHoleEnd) ptP4 -= hole.vtDir * dAddLen ; if ( AddLinearMove( ptP4) == GDB_ID_NULL) return false ; // aggiorno posizione e verifico se step completato dCurrLen = dLen ; if ( bHoleEnd || bStepEnd) continue ; } // 5 -> punto termine velocità finale ridotta (se previsto) if ( bEndSlow) { // lunghezza di esecuzione double dLen = dEndLen ; // determino se arrivo in fondo al foro bool bHoleEnd = ( dLen > hole.dLen - EPS_SMALL) ; // sono sempre in fondo allo step // assegno parametri SetFeed( m_TParams.m_dEndFeed) ; if ( bHoleEnd) SetFlag( 1) ; // fondo del foro else SetFlag( 2) ; // fondo dello step // movimento Point3d ptP5 = hole.ptIni - hole.vtDir * dLen ; if ( bHoleEnd) ptP5 -= hole.vtDir * dAddLen ; if ( AddLinearMove( ptP5) == GDB_ID_NULL) return false ; // aggiorno posizione dCurrLen = dLen ; } } // 6 -> ritorno all'approccio del foro SetFeed( MAX_FEED) ; SetFlag( 0) ; if ( AddLinearMove( ptP1) == GDB_ID_NULL) return false ; // reset dati di movimento ResetMoveData() ; return true ; } //---------------------------------------------------------------------------- bool Drilling::AdjustPositionForAxesCalc( const CamData* pCamData, Point3d& ptP) { // non devo fare alcunché return true ; }