EgtNumKernel :
- in Machining Optimization aggiunta gestione OpenBounds.
This commit is contained in:
+217
-139
@@ -60,6 +60,7 @@ MachOptimization::MachOptimization( void)
|
||||
m_dFeedA = 1. ;
|
||||
m_bAllMandatory = false ;
|
||||
m_bOptInGroup = false ;
|
||||
m_vOpenBounds.clear() ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -242,6 +243,44 @@ MachOptimization::SetOptimizationForGroups( bool bOptForGroups)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool
|
||||
MachOptimization::SetOpenBound( bool bStartVsEnd, int nFlag, double dX, double dY, double dZ)
|
||||
{
|
||||
// Se parametro Start o End già impostato, lo sovrascrivo
|
||||
for ( int i = 0 ; i < int( m_vOpenBounds.size()) ; ++ i) {
|
||||
if ( m_vOpenBounds[i].bStartVsEnd == bStartVsEnd) {
|
||||
m_vOpenBounds[i].nFlag = nFlag ;
|
||||
m_vOpenBounds[i].dX = dX ;
|
||||
m_vOpenBounds[i].dY = dY ;
|
||||
m_vOpenBounds[i].dZ = dZ ;
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
// altrimenti lo inserisco
|
||||
m_vOpenBounds.emplace_back( -1, bStartVsEnd, nFlag, dX, dY, dZ) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
MachOptimization::SetOpenBoundForGroups( int nGroup, bool bStartVsEnd, int nFlag, double dX, double dY, double dZ)
|
||||
{
|
||||
// Se parametro Start o End del Gruppo scelto già impostato, lo sovrascrivo
|
||||
for ( int i = 0 ; i < int( m_vOpenBounds.size()) ; ++ i) {
|
||||
if ( m_vOpenBounds[i].nGroup == nGroup && m_vOpenBounds[i].bStartVsEnd == bStartVsEnd) {
|
||||
m_vOpenBounds[i].nFlag = nFlag ;
|
||||
m_vOpenBounds[i].dX = dX ;
|
||||
m_vOpenBounds[i].dY = dY ;
|
||||
m_vOpenBounds[i].dZ = dZ ;
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
// altrimenti lo inserisco
|
||||
m_vOpenBounds.emplace_back( nGroup, bStartVsEnd, nFlag, dX, dY, dZ) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/* Funzione che assegna le dipendenze suggerite in base ai Gruppi */
|
||||
bool
|
||||
@@ -290,7 +329,8 @@ MachOptimization::SetGroupDependences( void)
|
||||
//----------------------------------------------------------------------------
|
||||
/* Funzione per il controllo delle dipendenze inserite : se già presenti o se in conflitto */
|
||||
bool
|
||||
MachOptimization::CheckDependences( int nIdPrev, int nIdNext, const INTINTVECTOR& vDep, bool bBlockMessages, bool& bExist, bool& bConflict)
|
||||
MachOptimization::CheckDependences( int nIdPrev, int nIdNext, const INTINTVECTOR& vDep,
|
||||
bool bBlockMessages, bool& bExist, bool& bConflict) const
|
||||
{
|
||||
bExist = false ;
|
||||
bConflict = false ;
|
||||
@@ -334,7 +374,7 @@ MachOptimization::CheckDependences( int nIdPrev, int nIdNext, const INTINTVECTOR
|
||||
/* Funzione per il calcolo della distanza euclidea tra assi Lineari o Angolari di due lavorazioni
|
||||
Considerando lo stesso utensile */
|
||||
double
|
||||
MachOptimization::CalcTimeLavLav( const MachOptm& Lav1, const MachOptm& Lav2, bool bLin)
|
||||
MachOptimization::CalcTimeLavLav( const MachOptm& Lav1, const MachOptm& Lav2, bool bLin) const
|
||||
{
|
||||
double dDist = 0. ;
|
||||
double dFeed = EPS_SMALL ;
|
||||
@@ -361,7 +401,7 @@ MachOptimization::CalcTimeLavLav( const MachOptm& Lav1, const MachOptm& Lav2, bo
|
||||
bool
|
||||
MachOptimization::CalcTimeLavLavTC( const MachOptm& Lav1, const MachOptm& Lav2, bool bLin,
|
||||
double& dTimeLav1TC1, double& dTimeTC1TC2, double& dTimeTC2Lav2,
|
||||
double& dTUnload1, double& dTLoad2)
|
||||
double& dTUnload1, double& dTLoad2) const
|
||||
{
|
||||
/*
|
||||
dTimeLav1TC1 : Tempo tra EndPoint di Lav1 e Posizione di TC per Utensile di Lav1
|
||||
@@ -466,7 +506,7 @@ MachOptimization::CalcTimeLavLavTC( const MachOptm& Lav1, const MachOptm& Lav2,
|
||||
/* Funzione per calcolare il tempo nel passare dalla lavorazione nInd1-esima alla lavorazione
|
||||
nInd2-esima */
|
||||
bool
|
||||
MachOptimization::CalcMachTime( int nInd1, int nInd2, int& nTime)
|
||||
MachOptimization::CalcMachTime( int nInd1, int nInd2, int& nTime) const
|
||||
{
|
||||
// Se Indice fuori dal range, errore
|
||||
nTime = 0 ;
|
||||
@@ -475,8 +515,8 @@ MachOptimization::CalcMachTime( int nInd1, int nInd2, int& nTime)
|
||||
return false ;
|
||||
|
||||
// Recupero riferimento delle due lavorazioni
|
||||
MachOptm& Lav1 = m_vMachOptm[nInd1] ;
|
||||
MachOptm& Lav2 = m_vMachOptm[nInd2] ;
|
||||
const MachOptm& Lav1 = m_vMachOptm[nInd1] ;
|
||||
const MachOptm& Lav2 = m_vMachOptm[nInd2] ;
|
||||
|
||||
return ( CalcMachTime( Lav1, Lav2, nTime)) ;
|
||||
}
|
||||
@@ -484,7 +524,7 @@ MachOptimization::CalcMachTime( int nInd1, int nInd2, int& nTime)
|
||||
//----------------------------------------------------------------------------
|
||||
/* Funzione per calcolare il tempo nel passare da una lavorazione all'altra */
|
||||
bool
|
||||
MachOptimization::CalcMachTime( const MachOptm& Lav1, const MachOptm& Lav2, int& nTime)
|
||||
MachOptimization::CalcMachTime( const MachOptm& Lav1, const MachOptm& Lav2, int& nTime) const
|
||||
{
|
||||
// Se l'utensile è lo stesso
|
||||
if ( Lav1.nIdTool == Lav2.nIdTool)
|
||||
@@ -508,7 +548,7 @@ MachOptimization::CalcMachTime( const MachOptm& Lav1, const MachOptm& Lav2, int&
|
||||
//----------------------------------------------------------------------------
|
||||
/* Funzione per il calcolo della Matrice dei tempi (NxN), dove N = #Lavorazioni */
|
||||
bool
|
||||
MachOptimization::ComputeTimeMatrix( INTMATRIX& mTimes)
|
||||
MachOptimization::ComputeTimeMatrix( INTMATRIX& mTimes) const
|
||||
{
|
||||
// Creo una copia dei vettori delle dipendenze ( le cancello di volta in volta che le assegno)
|
||||
const int N = int( m_vMachOptm.size()) ;
|
||||
@@ -578,7 +618,7 @@ MachOptimization::ComputeTimeMatrix( INTMATRIX& mTimes)
|
||||
//----------------------------------------------------------------------------
|
||||
/* Funzione che restituisce la posizione della lavorazione di Id pari a nId nel vettore delle lavorazioni */
|
||||
int
|
||||
MachOptimization::GetIndById( int nId)
|
||||
MachOptimization::GetIndById( int nId) const
|
||||
{
|
||||
// Scorro le lavorazioni
|
||||
for ( int i = 0 ; i < int( m_vMachOptm.size()) ; ++ i) {
|
||||
@@ -654,135 +694,114 @@ MachOptimization::SplitMachOptsInGroups( MACHOPTMMATRIX& matMachOpt, vector<INTI
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
MachOptimization::GetResult( INTVECTOR& vIds)
|
||||
MachOptimization::GetGlobalResult( INTVECTOR& vIds)
|
||||
{
|
||||
// Se non ho lavorazioni, allora non faccio nulla
|
||||
vIds.clear() ;
|
||||
if ( m_vMachOptm.empty())
|
||||
return true ;
|
||||
// Se ho una sola lavorazione allora ritorno se stessa
|
||||
if ( int( m_vMachOptm.size()) == 1) {
|
||||
vIds.push_back( m_vMachOptm[0].nId) ;
|
||||
return true ;
|
||||
// Inserisco le lavorazioni per ordine di inserimento
|
||||
for ( const MachOptm& myLav : m_vMachOptm)
|
||||
vIds.push_back( myLav.nId) ;
|
||||
// Inizializzo le dipendenze suggerite dai gruppi di lavorazione
|
||||
if ( ! SetGroupDependences()) {
|
||||
LOG_ERROR( GetENkLogger(), "Error in defining Group depedences") ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
// --- Se richiesta ottimizzazione solo interna per i gruppi
|
||||
if ( m_bOptInGroup) {
|
||||
// Recupero tutti i gruppi e le dipendenze separatamente ed ordinate per priorità di gruppo
|
||||
MACHOPTMMATRIX matMachOpt ;
|
||||
vector<INTINTVECTOR> matDep, matSuggDep ;
|
||||
if ( ! SplitMachOptsInGroups( matMachOpt, matDep, matSuggDep))
|
||||
return false ;
|
||||
// Per ognuna di esse eseguo l'algoritmo di ShortestPath
|
||||
MachOptm LastMach ;
|
||||
for ( int i = 0 ; i < int( matMachOpt.size()) ; ++ i) {
|
||||
m_vMachOptm.clear() ;
|
||||
m_vDependences.clear() ;
|
||||
m_vSuggDependences.clear() ;
|
||||
if ( matMachOpt.empty())
|
||||
continue ;
|
||||
m_vMachOptm = matMachOpt[i] ;
|
||||
m_vDependences = matDep[i] ;
|
||||
m_vSuggDependences = matSuggDep[i] ;
|
||||
// Calcolo la matrice dei tempi
|
||||
INTMATRIX mTimes ;
|
||||
if ( ! ComputeTimeMatrix( mTimes)) {
|
||||
LOG_ERROR( GetENkLogger(), "Error in Computing Time Matrix") ;
|
||||
return false ;
|
||||
}
|
||||
// Istanzio il Problema ShortesPath con vincoli
|
||||
PtrOwner<IShortestPath> mySP( CreateShortestPath()) ;
|
||||
if ( IsNull( mySP))
|
||||
return false ;
|
||||
// Per ogni lavorazione inserisco gli estremi
|
||||
for ( const MachOptm& Lav : m_vMachOptm) {
|
||||
if ( ! mySP->AddPoint( Lav.dX_Start, Lav.dY_Start, Lav.dZ_End, 0., 0.,
|
||||
Lav.dX_End, Lav.dY_End, Lav.dZ_End, 0., 0.)) {
|
||||
LOG_ERROR( GetENkLogger(), "Error adding Machining Bounds") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// Assegno la matrice delle distanze calcolata in precedenza
|
||||
if ( ! mySP->SetDistMatrix( mTimes)) {
|
||||
LOG_ERROR( GetENkLogger(), "Error setting distances matrix") ;
|
||||
return false ;
|
||||
}
|
||||
// Se ho una lavorazione impostata in precedenza
|
||||
if ( LastMach.nId != -1) {
|
||||
// Cerco le lavorazioni che non presentano precedenze
|
||||
MACHOPTMVECTOR vLav ; vLav.reserve( m_vMachOptm.size()) ;
|
||||
if ( m_vDependences.empty())
|
||||
vLav = m_vMachOptm ;
|
||||
else {
|
||||
INTSET setSecondDep ;
|
||||
for ( const INTINT& Dep : m_vDependences)
|
||||
setSecondDep.insert( Dep.second) ;
|
||||
for ( int i = 0 ; i < int( m_vMachOptm.size()) ; ++ i) {
|
||||
if ( setSecondDep.find( m_vMachOptm[i].nId) == setSecondDep.end())
|
||||
vLav.emplace_back( m_vMachOptm[i]) ;
|
||||
}
|
||||
}
|
||||
// Tra quelle valide cerco la migliore da cui partire
|
||||
int nBestLavId = 0 ;
|
||||
int nBestTime = MAXTIME ;
|
||||
for ( int i = 0 ; i < int( vLav.size()) ; ++ i) {
|
||||
int nCurrTime = MAXTIME ;
|
||||
CalcMachTime( LastMach, vLav[i], nCurrTime) ;
|
||||
if ( nCurrTime < nBestTime) {
|
||||
nBestTime = nCurrTime ;
|
||||
nBestLavId = vLav[i].nId ;
|
||||
}
|
||||
}
|
||||
// Imposto la prima lavorazione
|
||||
if ( ! SetFirstMachining( nBestLavId))
|
||||
return false ;
|
||||
}
|
||||
// Per ogni dipendeza obbligatoria assegno un vincolo
|
||||
for ( const INTINT& nnDep : m_vDependences) {
|
||||
if ( ! mySP->SetConstraintOrder( GetIndById( nnDep.first), GetIndById( nnDep.second))) {
|
||||
LOG_ERROR( GetENkLogger(), "Error in adding Constraints") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// Aggiungo le dipendenza suggerite
|
||||
for ( const INTINT& nnSuggDep : m_vSuggDependences) {
|
||||
if ( ! mySP->SetSuggestedOrder( GetIndById( nnSuggDep.first), GetIndById( nnSuggDep.second))) {
|
||||
LOG_ERROR( GetENkLogger(), "Error in adding Suggested Dependence") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// Calcolo la soluzione
|
||||
#if _TIME_DEBUG
|
||||
PerformanceCounter PC ; PC.Start() ;
|
||||
#endif
|
||||
if ( ! mySP->Calculate( IShortestPath::SP_OPEN)) {
|
||||
LOG_ERROR( GetENkLogger(), "Error in computing solution") ;
|
||||
return false ;
|
||||
}
|
||||
// Recupero l'ordine
|
||||
INTVECTOR U ;
|
||||
if ( ! mySP->GetOrder( U)) {
|
||||
LOG_ERROR( GetENkLogger(), "Error in ordering") ;
|
||||
return false ;
|
||||
}
|
||||
// Restituisco gli Id ordinati
|
||||
for ( int nInd = 0 ; nInd < int( U.size()) ; ++ nInd)
|
||||
vIds.emplace_back( m_vMachOptm[U[nInd]].nId) ;
|
||||
// Memorizzo l'ultima lavorazione per il gruppo successivo
|
||||
LastMach = ( U.empty() ? MachOptm() : m_vMachOptm[U.back()]) ;
|
||||
}
|
||||
// Calcolo la matrice dei tempi
|
||||
INTMATRIX mTimes ;
|
||||
if ( ! ComputeTimeMatrix( mTimes)) {
|
||||
LOG_ERROR( GetENkLogger(), "Error in Computing Time Matrix") ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
//--- Se invece ottimizzazione globale
|
||||
else {
|
||||
// Inserisco le lavorazioni per ordine di inserimento
|
||||
for ( const MachOptm& myLav : m_vMachOptm)
|
||||
vIds.push_back( myLav.nId) ;
|
||||
// Inizializzo le dipendenze suggerite dai gruppi di lavorazione
|
||||
if ( ! SetGroupDependences()) {
|
||||
LOG_ERROR( GetENkLogger(), "Error in defining Group depedences") ;
|
||||
// Istanzio il Problema ShortesPath con vincoli
|
||||
PtrOwner<IShortestPath> mySP( CreateShortestPath()) ;
|
||||
if ( IsNull( mySP))
|
||||
return false ;
|
||||
// Per ogni lavorazione inserisco gli estremi
|
||||
for ( const MachOptm& Lav : m_vMachOptm) {
|
||||
if ( ! mySP->AddPoint( Lav.dX_Start, Lav.dY_Start, Lav.dZ_End, 0., 0.,
|
||||
Lav.dX_End, Lav.dY_End, Lav.dZ_End, 0., 0.)) {
|
||||
LOG_ERROR( GetENkLogger(), "Error adding Machining Bounds") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// Assegno la matrice delle distanze calcolata in precedenza
|
||||
if ( ! mySP->SetDistMatrix( mTimes)) {
|
||||
LOG_ERROR( GetENkLogger(), "Error setting distances matrix") ;
|
||||
return false ;
|
||||
}
|
||||
// Per ogni dipendeza obbligatoria assegno un vincolo
|
||||
for ( const INTINT& nnDep : m_vDependences) {
|
||||
if ( ! mySP->SetConstraintOrder( GetIndById( nnDep.first), GetIndById( nnDep.second))) {
|
||||
LOG_ERROR( GetENkLogger(), "Error in adding Constraints") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// Aggiungo le dipendenza suggerite
|
||||
for ( const INTINT& nnSuggDep : m_vSuggDependences) {
|
||||
if ( ! mySP->SetSuggestedOrder( GetIndById( nnSuggDep.first), GetIndById( nnSuggDep.second))) {
|
||||
LOG_ERROR( GetENkLogger(), "Error in adding Suggested Dependence") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// Se presenti dei incoli di OpenBound, li assegno
|
||||
if ( ! m_vOpenBounds.empty()) {
|
||||
for ( const OpenBoundOptm& OB : m_vOpenBounds) {
|
||||
if ( OB.nGroup == -1) {
|
||||
if ( ! mySP->SetOpenBound( OB.bStartVsEnd, OB.nFlag, OB.dX, OB.dY, OB.dZ, 0., 0.)) {
|
||||
LOG_ERROR( GetENkLogger(), "Error in adding OpenBound") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Calcolo la soluzione
|
||||
#if _TIME_DEBUG
|
||||
PerformanceCounter PC ; PC.Start() ;
|
||||
#endif
|
||||
if ( ! mySP->Calculate( IShortestPath::SP_OPEN)) {
|
||||
LOG_ERROR( GetENkLogger(), "Error in computing solution") ;
|
||||
return false ;
|
||||
}
|
||||
#if _TIME_DEBUG
|
||||
string sTime = string( to_string( m_vDependences.size()) + string( "Time : ") + ToString( PC.Stop())) ;
|
||||
LOG_INFO( GetENkLogger(), sTime.c_str()) ;
|
||||
#endif
|
||||
// Recupero l'ordine
|
||||
INTVECTOR U ;
|
||||
if ( ! mySP->GetOrder( U)) {
|
||||
LOG_ERROR( GetENkLogger(), "Error in ordering") ;
|
||||
return false ;
|
||||
}
|
||||
// Restituisco gli Id ordinati
|
||||
vIds.resize( m_vMachOptm.size()) ;
|
||||
for ( int nInd = 0 ; nInd < int( U.size()) ; ++ nInd)
|
||||
vIds[nInd] = m_vMachOptm[U[nInd]].nId ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
MachOptimization::GetGroupResult( INTVECTOR& vIds)
|
||||
{
|
||||
// Se Flag ottimizzazione di gruppo non attivo, errore
|
||||
if ( ! m_bOptInGroup)
|
||||
return false ;
|
||||
|
||||
// Recupero tutti i gruppi e le dipendenze separatamente ed ordinate per priorità di gruppo
|
||||
MACHOPTMMATRIX matMachOpt ;
|
||||
vector<INTINTVECTOR> matDep, matSuggDep ;
|
||||
if ( ! SplitMachOptsInGroups( matMachOpt, matDep, matSuggDep))
|
||||
return false ;
|
||||
// Per ognuna di esse eseguo l'algoritmo di ShortestPath
|
||||
MachOptm LastMach ;
|
||||
for ( int i = 0 ; i < int( matMachOpt.size()) ; ++ i) {
|
||||
m_vMachOptm.clear() ;
|
||||
m_vDependences.clear() ;
|
||||
m_vSuggDependences.clear() ;
|
||||
if ( matMachOpt.empty())
|
||||
continue ;
|
||||
m_vMachOptm = matMachOpt[i] ;
|
||||
m_vDependences = matDep[i] ;
|
||||
m_vSuggDependences = matSuggDep[i] ;
|
||||
// Calcolo la matrice dei tempi
|
||||
INTMATRIX mTimes ;
|
||||
if ( ! ComputeTimeMatrix( mTimes)) {
|
||||
@@ -806,6 +825,47 @@ MachOptimization::GetResult( INTVECTOR& vIds)
|
||||
LOG_ERROR( GetENkLogger(), "Error setting distances matrix") ;
|
||||
return false ;
|
||||
}
|
||||
// Se presente un vincolo OpenBound lo assegno
|
||||
bool bForStart = false ;
|
||||
for ( const OpenBoundOptm& OB : m_vOpenBounds) {
|
||||
if ( OB.nGroup == m_vMachOptm[0].nGroup) {
|
||||
bForStart = ( bForStart || OB.bStartVsEnd) ;
|
||||
if ( ! mySP->SetOpenBound( OB.bStartVsEnd, OB.nFlag, OB.dX, OB.dY, OB.dZ, 0., 0.)) {
|
||||
LOG_ERROR( GetENkLogger(), "Error in adding OpenBound") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Se ho una lavorazione impostata in precedenza e nessun vincolo OpenBound
|
||||
if ( ! bForStart && LastMach.nId != -1) {
|
||||
// Cerco le lavorazioni che non presentano precedenze
|
||||
MACHOPTMVECTOR vLav ; vLav.reserve( m_vMachOptm.size()) ;
|
||||
if ( m_vDependences.empty())
|
||||
vLav = m_vMachOptm ;
|
||||
else {
|
||||
INTSET setSecondDep ;
|
||||
for ( const INTINT& Dep : m_vDependences)
|
||||
setSecondDep.insert( Dep.second) ;
|
||||
for ( int i = 0 ; i < int( m_vMachOptm.size()) ; ++ i) {
|
||||
if ( setSecondDep.find( m_vMachOptm[i].nId) == setSecondDep.end())
|
||||
vLav.emplace_back( m_vMachOptm[i]) ;
|
||||
}
|
||||
}
|
||||
// Tra quelle valide cerco la migliore da cui partire
|
||||
int nBestLavId = 0 ;
|
||||
int nBestTime = MAXTIME ;
|
||||
for ( int i = 0 ; i < int( vLav.size()) ; ++ i) {
|
||||
int nCurrTime = MAXTIME ;
|
||||
CalcMachTime( LastMach, vLav[i], nCurrTime) ;
|
||||
if ( nCurrTime < nBestTime) {
|
||||
nBestTime = nCurrTime ;
|
||||
nBestLavId = vLav[i].nId ;
|
||||
}
|
||||
}
|
||||
// Imposto la prima lavorazione
|
||||
if ( ! SetFirstMachining( nBestLavId))
|
||||
return false ;
|
||||
}
|
||||
// Per ogni dipendeza obbligatoria assegno un vincolo
|
||||
for ( const INTINT& nnDep : m_vDependences) {
|
||||
if ( ! mySP->SetConstraintOrder( GetIndById( nnDep.first), GetIndById( nnDep.second))) {
|
||||
@@ -828,10 +888,6 @@ MachOptimization::GetResult( INTVECTOR& vIds)
|
||||
LOG_ERROR( GetENkLogger(), "Error in computing solution") ;
|
||||
return false ;
|
||||
}
|
||||
#if _TIME_DEBUG
|
||||
string sTime = string( to_string( m_vDependences.size()) + string( "Time : ") + ToString( PC.Stop())) ;
|
||||
LOG_INFO( GetENkLogger(), sTime.c_str()) ;
|
||||
#endif
|
||||
// Recupero l'ordine
|
||||
INTVECTOR U ;
|
||||
if ( ! mySP->GetOrder( U)) {
|
||||
@@ -839,10 +895,32 @@ MachOptimization::GetResult( INTVECTOR& vIds)
|
||||
return false ;
|
||||
}
|
||||
// Restituisco gli Id ordinati
|
||||
vIds.resize( m_vMachOptm.size()) ;
|
||||
for ( int nInd = 0 ; nInd < int( U.size()) ; ++ nInd)
|
||||
vIds[nInd] = m_vMachOptm[U[nInd]].nId ;
|
||||
vIds.emplace_back( m_vMachOptm[U[nInd]].nId) ;
|
||||
// Memorizzo l'ultima lavorazione per il gruppo successivo
|
||||
LastMach = ( U.empty() ? MachOptm() : m_vMachOptm[U.back()]) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
MachOptimization::GetResult( INTVECTOR& vIds)
|
||||
{
|
||||
// Se non ho lavorazioni, allora non faccio nulla
|
||||
vIds.clear() ;
|
||||
if ( m_vMachOptm.empty())
|
||||
return true ;
|
||||
// Se ho una sola lavorazione allora ritorno se stessa
|
||||
if ( int( m_vMachOptm.size()) == 1) {
|
||||
vIds.push_back( m_vMachOptm[0].nId) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
// --- Se richiesta ottimizzazione solo interna per i gruppi
|
||||
if ( m_bOptInGroup)
|
||||
return ( GetGroupResult( vIds)) ;
|
||||
// --- Se invece ottimizzazione globale
|
||||
return ( GetGlobalResult( vIds)) ;
|
||||
}
|
||||
|
||||
+22
-15
@@ -39,6 +39,8 @@ class MachOptimization : public IMachOptimization
|
||||
bool SetFeeds( double dFeedL, double dFeedA) override ;
|
||||
bool SetAllGroupsAsMandatory( bool bAllMandatory) override ;
|
||||
bool SetOptimizationForGroups( bool bOptForGroups) override ;
|
||||
bool SetOpenBound( bool bStartVsEnd, int nFlag, double dX, double dY, double dZ) override ;
|
||||
bool SetOpenBoundForGroups( int nGroup, bool bStartVsEnd, int nFlag, double dX, double dY, double dZ) override ;
|
||||
|
||||
// Risultati
|
||||
bool GetResult( INTVECTOR& vIds) override ;
|
||||
@@ -48,33 +50,38 @@ class MachOptimization : public IMachOptimization
|
||||
|
||||
private :
|
||||
// Calcolo dei tempi tra le lavorazioni
|
||||
double CalcTimeLavLav( const MachOptm& Lav1, const MachOptm& Lav2, bool bLin) ;
|
||||
double CalcTimeLavLav( const MachOptm& Lav1, const MachOptm& Lav2, bool bLin) const ;
|
||||
bool CalcTimeLavLavTC( const MachOptm& Lav1, const MachOptm& Lav2, bool bLin,
|
||||
double& dTimeLav1TC1, double& dTimeTC1TC2, double& dTimeTC2Lav2,
|
||||
double& dTUnload1, double& dTLoad2) ;
|
||||
bool CalcMachTime( int nInd1, int nInd2, int& nTime) ;
|
||||
bool CalcMachTime( const MachOptm& Lav1, const MachOptm& Lav2, int& nTime) ;
|
||||
double& dTUnload1, double& dTLoad2) const ;
|
||||
bool CalcMachTime( int nInd1, int nInd2, int& nTime) const ;
|
||||
bool CalcMachTime( const MachOptm& Lav1, const MachOptm& Lav2, int& nTime) const ;
|
||||
|
||||
// Controllo Conflitti tra dipendenze e Gestione Dipendenze
|
||||
bool CheckDependences( int nIdPrev, int nIdNext, const INTINTVECTOR& vDep,
|
||||
bool bBlockMessages, bool& bExist, bool& bConflict) ;
|
||||
bool bBlockMessages, bool& bExist, bool& bConflict) const ;
|
||||
bool SetGroupDependences( void) ;
|
||||
|
||||
// Calcolo della Matrice dei tempi, Del fattore perso dipendenze suggerite e della soluzione ottimale
|
||||
bool ComputeTimeMatrix( INTMATRIX& mTimes) ;
|
||||
bool ComputeTimeMatrix( INTMATRIX& mTimes) const ;
|
||||
|
||||
// Calcolo dei risultati a seconda della modalità
|
||||
bool GetGlobalResult( INTVECTOR& vIds) ;
|
||||
bool GetGroupResult( INTVECTOR& vIds) ;
|
||||
|
||||
// Utility
|
||||
int GetIndById( int nId) ;
|
||||
int GetIndById( int nId) const ;
|
||||
bool SplitMachOptsInGroups( MACHOPTMMATRIX& matMachOpt, vector<INTINTVECTOR>& matDep,
|
||||
vector<INTINTVECTOR>& matSuggDep) ;
|
||||
|
||||
private :
|
||||
MACHOPTMVECTOR m_vMachOptm ; // Vettore delle lavorazioni
|
||||
TOOLOPTMVECTOR m_vToolOptm ; // Vettore degli utensili
|
||||
INTINTVECTOR m_vDependences ; // Vettore di dipendenze ( IdPrev, IdSucc) -> deve essere rispettato
|
||||
INTINTVECTOR m_vSuggDependences ; // Vettore delle dipendenze suggerite ( IdPrev, IdSucc) -> si cerca di rispettarle
|
||||
double m_dFeedL ; // Feed Lineare
|
||||
double m_dFeedA ; // Feed Angolare
|
||||
bool m_bAllMandatory ; // Flag per impostare ogni dipendenza da Gruppo come vincolo
|
||||
bool m_bOptInGroup ; // Flag per ottimizzazione solo interna ai gruppi
|
||||
MACHOPTMVECTOR m_vMachOptm ; // Vettore delle lavorazioni
|
||||
TOOLOPTMVECTOR m_vToolOptm ; // Vettore degli utensili
|
||||
INTINTVECTOR m_vDependences ; // Vettore di dipendenze ( IdPrev, IdSucc) -> deve essere rispettato
|
||||
INTINTVECTOR m_vSuggDependences ; // Vettore delle dipendenze suggerite ( IdPrev, IdSucc) -> si cerca di rispettarle
|
||||
double m_dFeedL ; // Feed Lineare
|
||||
double m_dFeedA ; // Feed Angolare
|
||||
bool m_bAllMandatory ; // Flag per impostare ogni dipendenza da Gruppo come vincolo
|
||||
bool m_bOptInGroup ; // Flag per ottimizzazione solo interna ai gruppi
|
||||
MACHOPTOPENBOUNDVECTOR m_vOpenBounds ; // Vettore dei punti OpenBound
|
||||
} ;
|
||||
|
||||
Reference in New Issue
Block a user