/******************************************************* * * DESCRIPTION: QBG serial junction class * * AUTHOR: Mariana C. D'Abreu * * EMAIL: mdabreu@dc.uba.ar * ********************************************************/ #include "qbg_sjunc.h" #include "defaults.h" #include "defaults_mapping.h" /******************************************************************* * Function Name: QBGSerialJunction * Description: constructor ********************************************************************/ QBGSerialJunction::QBGSerialJunction( const string &name ) : Atomic( name ) , f1p( addInputPort( "f1p" ) ) , f1n( addInputPort( "f1n" ) ) , e2p( addInputPort( "e2p" ) ) , e3p( addInputPort( "e3p" ) ) , e4p( addInputPort( "e4p" ) ) , e5p( addInputPort( "e5p" ) ) , e6p( addInputPort( "e6p" ) ) , e2n( addInputPort( "e2n" ) ) , e3n( addInputPort( "e3n" ) ) , e4n( addInputPort( "e4n" ) ) , e5n( addInputPort( "e5n" ) ) , e6n( addInputPort( "e6n" ) ) , e1p( addOutputPort( "e1p" ) ) , e1n( addOutputPort( "e1n" ) ) , f2p( addOutputPort( "f2p" ) ) , f3p( addOutputPort( "f3p" ) ) , f4p( addOutputPort( "f4p" ) ) , f5p( addOutputPort( "f5p" ) ) , f6p( addOutputPort( "f6p" ) ) , f2n( addOutputPort( "f2n" ) ) , f3n( addOutputPort( "f3n" ) ) , f4n( addOutputPort( "f4n" ) ) , f5n( addOutputPort( "f5n" ) ) , f6n( addOutputPort( "f6n" ) ) { flow = 0; effortP = 0; effortN = 0; efforts = new RealValue[JUNC_MAX_PORTS]; MASSERT( efforts ); } /******************************************************************* * Function Name: ********************************************************************/ QBGSerialJunction::~QBGSerialJunction() { if( efforts != NULL ) { delete efforts; } } /******************************************************************* * Function Name: initFunction ********************************************************************/ Model &QBGSerialJunction::initFunction() { init = true; flow = 0; effortP = 0; effortN = 0; resetEfforts(); passivate(); return *this ; } /******************************************************************* * Function Name: internalFunction ********************************************************************/ Model &QBGSerialJunction::internalFunction( const InternalMessage &msg ) { passivate(); return *this; } /******************************************************************* * Function Name: externalFunction ********************************************************************/ Model &QBGSerialJunction::externalFunction( const ExternalMessage &msg ) { RealValue value = msg.value(); if ( msg.port() == f1p || msg.port() == f1n ) { // Si recibe nuevo flow, y es distinto al ultimo valor recibido, actualiza los valores if( value != flow || init ) { flow = value; holdIn( active, Time::Zero ); } else { passivate(); } } else { // Si se produjo entrada de effort por alguno de los ports, y es distinto al // ultimo effort recibido para ese port, recalculo el valor if( updateEffort( msg.port().name(), value ) ) { holdIn( active, Time::Zero ); } else { passivate(); } } init = false; return *this; } /******************************************************************* * Function Name: outputFunction ********************************************************************/ Model &QBGSerialJunction::outputFunction( const InternalMessage &msg ) { // Envia el flow por todos los puertos de flujo... sendOutput( msg.time(), f2p, flow ); sendOutput( msg.time(), f3p, flow ); sendOutput( msg.time(), f4p, flow ); sendOutput( msg.time(), f5p, flow ); sendOutput( msg.time(), f6p, flow ); sendOutput( msg.time(), f2n, flow ); sendOutput( msg.time(), f3n, flow ); sendOutput( msg.time(), f4n, flow ); sendOutput( msg.time(), f5n, flow ); sendOutput( msg.time(), f6n, flow ); // ... y el effort por el port de salida de effort sendOutput( msg.time(), e1p, effortP ); sendOutput( msg.time(), e1n, ( effortP * -1 ) ); return *this ; } /******************************************************************* * Function Name: ********************************************************************/ bool QBGSerialJunction::updateEffort( const string &portName, const RealValue &value ) { RealValue val; int signPort; getPortValueAndSign( portName, val, signPort ); if( value == val && !init ) { // no se realiza actualizacion return false; } effortP = effortP + ( val * signPort ); effortP = effortP - ( value * signPort ); setPortValue( portName, value ); return true; } /******************************************************************* * Function Name: ********************************************************************/ void QBGSerialJunction::resetEfforts() { for( int i = 0; i < JUNC_MAX_PORTS - 1; i++ ) efforts[i] = 0; } /******************************************************************* * Function Name: ********************************************************************/ void QBGSerialJunction::getPortInfo( const string &pName, string &pType, int &pNum, string &pSign ) { // Descompongo el nombre del puerto en (e|f) + id + sign int len = strlen( pName.c_str() ); pType = pName.substr( 0, 1 ); pNum = atoi( pName.substr( 1, len - 1).c_str() ); pSign = pName.substr( len - 1 ); } /******************************************************************* * Function Name: ********************************************************************/ void QBGSerialJunction::getPortValueAndSign( const string &pName, RealValue &pVal, int &pSign ) { string type, sign; int num; getPortInfo( pName, type, num, sign ); if ( num < 2 || num > JUNC_MAX_PORTS ) { throw MException( "Invalid port number: " + num ); } num -= 2; // los puertos se numeran desde 2 pVal = efforts[num]; if( sign == POSITIVE_ID ) pSign = 1; else pSign = -1; } /******************************************************************* * Function Name: ********************************************************************/ void QBGSerialJunction::setPortValue( const string &pName, const RealValue &pVal ) { string type, sign; int num; getPortInfo( pName, type, num, sign ); if ( num < 2 || num > JUNC_MAX_PORTS ) { throw MException( "Invalid port number: " + num ); } num -= 2; // los puertos se numeran desde 2 efforts[num] = pVal; }