Simulation Engine Interface

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 64

DYNSIM Dynamic Simulation Suite

Simulation Engine Interface


Programmers Guide
© 2018 AVEVA Group plc and its subsidiaries. All rights reserved.

No part of this documentation shall be reproduced, stored in a retrieval system, or transmitted by any
means, electronic, mechanical, photocopying, recording, or otherwise, without the prior written
permission of AVEVA. No liability is assumed with respect to the use of the information contained
herein.
Although precaution has been taken in the preparation of this documentation, AVEVA assumes no
responsibility for errors or omissions. The information in this documentation is subject to change
without notice and does not represent a commitment on the part of AVEVA. The software described in
this documentation is furnished under a license agreement. This software may be used or copied only
in accordance with the terms of such license agreement.
ArchestrA, Aquis, Avantis, DYNSIM, eDNA, EYESIM, InBatch, InduSoft, InStep, IntelaTrac, InTouch,
PIPEPHASE, PRiSM, PRO/II, PROVISION, ROMeo, SIM4ME, SimCentral, SimSci, Skelta,
SmartGlance, Spiral Software, Termis, WindowMaker, WindowViewer, and Wonderware are
trademarks of AVEVA and/or its subsidiaries. An extensive listing of AVEVA trademarks can be found
at: https://sw.aveva.com/legal. All other brands may be trademarks of their respective owners.
Publication date: 10/26/2018
Contact Information
AVEVA Group plc
High Cross
Madingley Road
Cambridge
CB3 OHB. UK
https://sw.aveva.com/
For information on how to contact sales, customer training, and technical support, see
https://sw.aveva.com/contact.
Contents
ARCHITECTURE OVERVIEW ................................................................................................................ 1
SIMULATION ENGINE INTERFACE ................................................................................................................ 1
METHODS TO BE IMPLEMENTED BY ALL ENGINES ........................................................................................ 3
SCENARIO BUILDER METHODS.................................................................................................................... 5
SIMEXECUTIVE COMMUNICATION METHODS.............................................................................................. 7
ENGINE SYNCHRONIZATION METHODS ....................................................................................................... 7
SIMPOINT METHODS .................................................................................................................................... 8
Conversion Function Methods................................................................................................................ 9
Limit Checking Methods ....................................................................................................................... 10
Scaling Methods ................................................................................................................................... 10
COMMAND LINE PARAMETERS................................................................................................................... 11
OPTIONAL SIMULATION EVENT METHODS................................................................................................. 13
Method references: ............................................................................................................................... 13
TSU::SIMEVENTLISTENER CLASS REFERENCE .......................................................................................... 13
PUBLIC MEMBER FUNCTIONS ................................................................................................................. 13
DETAILED DESCRIPTION ......................................................................................................................... 14
MEMBER FUNCTION DOCUMENTATION .................................................................................................. 15
DATA HISTORY (TREND) METHODS .......................................................................................................... 16
Required Methods for Trend Implementation ....................................................................................... 16
Additional Methods and Structures for Trend Implementation ............................................................ 19
YGSIM – DEMONSTRATION ENGINE ................................................................................................ 22
YGSIMMAIN.CPP ...................................................................................................................................... 22
YGSIM.H ................................................................................................................................................... 24
YGSIM.CPP ............................................................................................................................................... 31
YGSIMPOINT.H ......................................................................................................................................... 48
YGSIMPOINT.CPP...................................................................................................................................... 54

Simulation Engine Interface Programmers Guide i


Architecture Overview

Architecture Overview
SIM4ME is a modular environment, which allows multiple engines and multiple Graphical User
Interfaces (GUI) to work in a coordinated effort for the development and use of dynamic
simulation applications such as Operator Training Simulators (OTS). The primary reason for
development of SIM4ME is to integrate the capabilities of numerous existing pieces of software
into a single environment, as well as provide capability for splitting OTS tasks between multiple
processors and/or multiple computers.

Any number of instances of the GUI may be attached to the environment at any time. The GUI(s)
and engine(s) will communicate with the Simulation Executive through CORBA interfaces. A
graphical representation of how SIM4ME will work is presented below:

GUI
GUI
GUI
CORBA Simulation
Executive Simulation
CORBA
Engine
Simulation
Engine
Simulation
Engine

Simulation Engine Interface

The Simulation Engine interface (ISimEngine) is the primary interface that must be
implemented by each engine that wishes to work with Simulation Executive. This interface is
called by the Simulation Executive to operate the Simulation Engine. The IMalfunctionable
interface must be implemented if the engine supports malfunctions. The IValueBundle interface
is used to communicate values to the GUI. The ICrossReferenceBundle interface is used to
communicate values between different running engines. These interfaces are all implemented by
the SimEngine Toolkit. This toolkit insulates an engine from any CORBA dependencies and it
provides a great deal of default implementation.

NOTE- All engines make use of the SimEngineToolkit. The toolkit shields the developer
from having to implement all the required interfaces for an engine.

Simulation Engine Interface Programmers Guide 1


Architecture Overview

Some detail
not shown
«interface»
«interface» ISimExecutive
CORBA IDL
ISimEngine

SimExecutiveProxy
GenericEngine

EngineValueBundleImpl

EngineCrossRefManager
1
*

EngineValueBundlePoint
1 1
DigitalXRefPushTarget

*
SimEngineToolkit
Library EngineCrossRefBundle

Insulates AnyEngine from AnalogXRefPushTarget


any CORBA dependency
and provides a great *
deal of default implementation
1 1
of engine features EngineMalfunctionManager

AnalogXRefPushValue

DigitalXRefPushValue

SimEngine «interface» «interface»


ISimMalfunctionable ISimPoint

AnySimMalfunctionable

AnySimPoint
AnyEngine
AnyEngine
Implementation

Simulation Engine Interface Programmers Guide 2


Architecture Overview

Methods to be implemented by all engines

Listed below are the methods that need to be implemented for an engine that uses the
SimEngine Toolkit.

init ( ) // Performs Engine initialization


- This method looks up references to specific points (DELT, etc)
- Must set operation progress to > 100 to let SimExec know that init() is complete

setCommandLineOptions ( )
- This method creates list of Engine specific options.

executeCalculationCycle ( )
- Method can be overridden but is not necessary
- Any Engine Specific calculations are performed here
- Update Engine time with DELT (may not be needed for Full Stimulation)

saveIC ( )
loadIC ( )
saveBacktrack ( )
loadBacktrack ( )
- Determine how IC/Backtrack data will be saved. Call noSnapshotDir() from
the constructor of the engine, if you want the engine to
receive the location of the snapshot data as a file as opposed
to a directory name.
- Save methods dump snapshot to file and Load methods load the snapshot from file
- Acquires main thread key.
- Opens and writes/reads data from/to a binary file
- Close file and Release main thread key.
- Call engineOperationComplete ( )

Helpful Hint #1: Implement saveSnapshot ( ) and call it from saveIC() and saveBacktrack()
Helpful Hint #2: Implement loadSnapshot ( ) and call it from loadIC() and loadBacktrack()

isValidSymbol ( )
- Looks up symbol in the local engine symbol table and returns true if the symbol is
found. (Typically a point, control block, or model object)

getSymbolInfo ( )
- This method gets the symbol information (structure)
- SymbolInfo structure has:
o Name
o Description
o SymbolType (Point, Model Object, Control block, other)
o Point Data Type (double, float, etc.)
o Class Name (may not be supported in every engine. Return an empty string
or “undefined” if not implemented (?))

Simulation Engine Interface Programmers Guide 3


Architecture Overview

o Units (may not be supported in every engine. Return an empty string or


“undefined” if not implemented (?))
- This method throws an exception (symbol not found) if symbol is not found.

getSimPoint ( )
- Returns pointer to a new ISimPoint data type = pointer into engine symbol table to
see a value.
- * Must override to find value in symbol table.
- * If symbol not found, throw “Symbol not found” exception.
- Allows access to the ISimPoint methods for cross reference and direct data access.
See SimPoint methods.
- See units note in SimEngine.h

releaseSimPoint ( )
- Deletes reference and Instance
- Base implementation calls delete point.
- Assumes getSimPoint ( ) allocated with “new” operator. If not, override and do
something else. EG. If “malloc” was used, the you should use “free”.

The following methods will be implemented by some engines with special capabilities or needs.

loadConfiguration ( )
- Full Stimulations will not use this.
- Emulations will probably use this.
- The options are
o FULL_CONFIG_FROM_DATABASE
o INCREMENTAL_CONFIG_FROM_DATABASE
o FULL_CONFIG_FROM_FILES
o STATIC_VALUES_FROM_FILES

getSimMalfunctionable ( )
releaseSimMalfunctionable ( )

- These methods are used in process modeling applications and maybe emulations.

setDefaultUOMSlate ( )
- Process Modeling (Future)?

getDefaultUnitforUOMType ( )
- Process Modeling (Future)?

getSimEquation ( )
- Most engines will use the default implementation of this.
- SYSL may use this to implement the Steam properties calls. (Reuse Ascend Engine
implementation)

releaseSimEquation ( )

Simulation Engine Interface Programmers Guide 4


Architecture Overview

- Most engines will use the default implementation of this.


- SYSL may use this to implement the Steam properties calls. (Reuse Ascend Engine
implementation)
- Assumes allocated with “new” operator and calls “delete”. If “malloc” used then
need to implement “free”.

Scenario Builder Methods

The following methods are needed to support the Scenario builder/player:

performEngineAction ( )
- Engine Action is a structure:
o Name
o Engine Name
o Options

logEngineAction ( )
- Engine Action is a structure:
o Name
o Engine Name
o Options

(1) BktRplyProxy:

An engine can log an action using BktRplyProxy API.

BktRplyProxy provides following methods:

(i) static BktRplyProxy* instance();


Description: returns a singleton instance of BktRplyProxy.

(ii)void logEngineAction(const Tsu::SimEngine::EngineAction& action)


Description: This method logs engine action with simexecutive.

(iii) void startOperatorActionRecord()


Description: This method starts the backtrack replay through simexecutive.

(iv) void stopOperatorActionRecord()


Description: This method stops the backtrack replay through simeexecutive.

(v) double getSimBktRplyValue()


Description: This method returns the SimExecutive::SIMBKTRPLY point value.

Use case:
(a)Engine would log an action using BktRplyProxy::instance()->logEngineAction(action)
(b) Prior to this scenario recording was enabled.
(c) Save scenario (generated script will contain PERFROM command)
(d) Run scenario (this is replaying part)

Simulation Engine Interface Programmers Guide 5


Architecture Overview

When scenario is run, Simexecutive would invoke “performEngineAction” method on the


engine.

(2) ScenarioProxy:

Using ScenarioProxy, an engine can add or remove scenario and playback listeners.
An engine has to implement the sce_ScenarioListener interface and register the implementation
object with ScenarioProxy, if it wishes to receive scenario event callbacks (viz.
scenarioActivated, scenarioStatusChanged, scenarioDeactivated, scenarioSaved,
scenarioDeleted). Similarly, an engine can implement sce_PlaybackListener interface and register
the implementation object with ScenarioProxy to receive playback event callbacks (viz.
recordModeChanged).

Use case for receiving scenarioListener callbacks:


(a)Engine implements Tsu:: sce_ScenarioListener interface. Say sceListener is the pointer to
Tsu:: sce_ScenarioListener interface implementation.
(b)Engine registers its implementation pointer using ScenarioProxy::instance()-
>addScenarioListener(sceListener);
(c)Create and run a scenario to receive event callbacks.

Usecase for receiving playbackListener callbacks:


(a)Engine implements Tsu::sce_PlaybackListener interface. Say playbackListener is the pointer to
Tsu:: sce_PlaybackListener interface implementation.
(b)Engine registers its implementation pointer using ScenarioProxy::instance()-
>addPlaybackListener(playbackListener);
(c)Start and stop recording a scenario to receive event callbacks.

API:

(1)

(2)

(3)

Simulation Engine Interface Programmers Guide 6


Architecture Overview

SimExecutive Communication Methods

The following methods are needed to communicate with the simulation executive.

sendMessage ( )
- SIM_INFO
- SIM_WARNING
- SIM_ERROR
- SIM_SEVERE_ERROR

setOperationProgress ( )
- This is used to provide the progress of the initialization operation during engine
startup

Engine Synchronization Methods

An engine that wishes to use its own synchronization and time step control scheme implements
the following methods.

execute ( )
- Sets up speed control synchronization period
- Executes forever loop waiting for SIM_SHUTDOWN
- Checks mode for shutdown command
- Waits for the SimExecutive to tell it to run
- Loop is executed for # of DELTS in its sync period
- Calls executeCalculationCycle ( )
- Updates Push Targets (Cross Referencing)
- Increments time for the engine
- Calls engineOperationComplete ( ) at the end
- Override this method only if engine wishes to control the operations, otherwise, the
engine should simply implement executeCalculationCycle ( ).

setSimMode ( )
getSimMode ( )
- Implement if engine wants to control mode
- Mode is an enumeration in SimEngine.h
- Dig through “csetup.c”, “runtime.c” (…/dynsuite/Generic/libsrc/modlib) and
“proc_msg.c”(…/dynsuite/Generic/libsrc/modelcom/host) to see if anything needs to
be done when the mode is changed.

Simulation Engine Interface Programmers Guide 7


Architecture Overview

shutdown ( )
- Calls Base shutdown ( )
- Engine specific clean up (clean up Symbol table, deallocate memory (free, delete)

resume ( )
- Check previous mode and take appropriate actions before proceeding
- Calls Base method – release run key
- Not likely to be overridden

If the engine chooses to use the default synchronization and time step control scheme, then the
following methods may be used to internally synchronize with the main execution thread, and
with the simulation executive.

acquireMainThreadKey ( )
- Acquires control of the main thread

releaseMainThreadKey ( )
- Release control of the main thread

engineOperationComplete ( )
- Notifies the SimExecutive that the operation is complete.

SimPoint methods

An engine specific SimPoint class derived from ISimPoint should be implemented. This allows
access to internal engine data from the cross referencing scheme. The following engine methods
are used to access SimPoint:

ISimPoint* Engine::getSimPoint( const string& name, const string& units )


Returns a pointer to a new IsimPoint instance (and to our derived SimPoint). The
pointer is used to access the point methods described below (the external user
supplies a point name as input argument).
bool Engine::isValidSymbol( const string& symbolName)
The engine returns true if the symbol name exists
SimEngine::SymbolInfo Engine::getSymbolInfo( const string& symbolName)
The engine returns a predefined structure containing symbol data including
symbol type. Symbol type can be a point or object.

The following useful virtual SimPoint methods are inherited from ISimPoint. The getSimPoint
engine method enables external access to these methods:
bool SimPoint::isValidPoint()
This method returns true if the point exists.
ISimPoint::PointDataType SimPoint::getDataType()

Simulation Engine Interface Programmers Guide 8


Architecture Overview

Returns an ISimPoint enumeration defining the point type.


bool SimPoint::isValueSettableByUser()
QUERIES THE ACCESS TYPE OF THE SIMPOINT
void SimPoint::setValue( const datatype &val, const std::string &units)
Overloaded method to set SimPoint value of any data type.
float SimPoint::getFloatValue( const std::string &units)
Overloaded function returns the SimPoint value.
Similar methods exist for double, integer and boolean
types.
std::string WXapiPoint::getDescription()
Returns a string with the SimPoint description.

By implementing the engine methods and overriding the ISimPoint methods the engine
implementation exposes its internal data to the rest of the SIM4ME environment.

Conversion Function Methods

The following methods are relevant when using conversion factors. Each of the methods below
has a default implementation in ISimPoint.h. The default implementations should be overridden
in a custom engine if additional functionality is required.

virtual std::string getConvFuncName() const


{
return "";
}

• Obtains the conversion function name associated with the point. Typcially used for
conversions such as raw count counts to another type of conversion (i.e.
FOXSCI_##)
• returns: conversion function name

virtual void setConvFuncName(const std::string &conv_func_name)


{}

• Sets the conversion function name of the point.


• param: conv_func_name IN: name of conversion function
• It is recommended that any class that implements the get and setConvFuncName()
methods add a std::string member variable to represent the conversion function name
and as well as a numerical representation of the conversion factor associated with the
conversion function. Since a std::string defaults to “” (empty string), the default
value should be left as “” so as to keep the overhead as low as possible for points that
do not need to use conversion functions.
• It is recommended that implementations of setConvFuncName() always reset the
actual conversion factor (by a local call to a method analogous to
get/setConversionFactor(conv_func_name)). The alternative would be a run-time
evaluation of the conversion factor based on the conversion function name, which
will, in most cases, be much slower.

Simulation Engine Interface Programmers Guide 9


Architecture Overview

Limit Checking Methods

The following methods are relevant when using high and low limits. Each of the methods below
has a default implementation in ISimPoint.h. The default implementations should be overridden
in a custom engine if additional functionality is required.

Typical limit checking code might look as follows (where m_hiLim is the hi limit value and
m_loLim is the low limit value):

* if( m_hiLim <= m_loLim )


* return;
*
* if( val > m_hiLim )
* {
* val = m_hiLim;
* }
* if( val < m_loLim )
* {
* val = m_loLim;
* }

virtual void setHiLimit(const float hi_lim)


{}

virtual float getHiLimit() const


{
return 99999.0f;
}

• default HiLimit value set to 99999.0 to match cross reference default value.

virtual void setLowLimit(const float lo_lim)


{}

virtual float getLowLimit() const


{
return -9999.9f;
}

• default LoLimit value set to -99999.0 to match cross reference default value.

Scaling Methods

The following methods are relevant when using high and low scales. Each of the methods below
has a default implementation in ISimPoint.h. The default implementations should be overridden
in a custom engine if additional functionality is required.

Simulation Engine Interface Programmers Guide 10


Architecture Overview

Default value set to 99999.0 to match cross reference default value.

In cases where minScale and maxScale are used to set a span (to normalize a value) default
values should likely be set to zero in the engine's specific implementation. The reason for doing
so is that when both minScale and maxScale are zero, they can be ignored with code such as in
the example below which could be used in a setValue routine:

* void checkScale(double &val)


*{
* if( m_maxScale <= m_minScale )
* return;
*
* val = (val-minScale)/(maxScale-m_minScale)*100.0;
*}

Of course, there are other ways to disable scaling. Be aware, however, that if scaling is used for
normalization as above and the default values are left very large and very small (i.e. 99999.0 and
-99999.0), the normalized number will appear to be incorrect unless minScale and maxScale are
properly initialized.

virtual void setMaxScale(const float max_scale)


{}

virtual float getMaxScale() const


{
return 99999.0f;
}

virtual void setMinScale(const float min_scale)


{}

virtual float getMinScale() const


{
return -99999.0f;
}

Command line parameters


The engine uses command line parameters to determine some
information about the simulation and its parameters(such as
Naming Server host, SimExec host etc). The basic command line
parameters used for every engine are:

-ORBInitRef NameService=iioploc://%NSHOST%:%NSPORT%/NameService -
ORBSvcConfDirective "static Server_Strategy_Factory '-
ORBConcurrency thread-per-connection'" -simulationname
%SIMULATION% -UOM
"E:\SIMSCI\{DSSVERSION}\servers\system\UOMdata.txt" -nsversion
{DSSVERSION}

Simulation Engine Interface Programmers Guide 11


Architecture Overview

Note the –UOM parameter. The value of –UOM parameter should be


valid path to the version of DSS the engine is used
Where:
%NSHOST% is the name for the name service host
%NSPORT% is the port number for the name service
{DSSVERSION} – the version of Dynsim, ex, DSS43, DSS44

Additional command line parameters can be defined and used by


overriding the setCommandLineOptions method and using the
CmdLineManager object:

void myEngine::
setCommandLineOptions()
{
// Add the supported command line options for this engine.
CmdLineManager* cmdLineMgr = CmdLineManager::instance();

cmdLineMgr->addOption("-debugLevel",
"none, low, high",
"none");
cmdLineMgr->addOption("-myLogFile",
"debug info log file",
"WXapi.log");
} // end myEngine::setCommandLineOptions()

The user selected options (e.g. –debugLevel low) can be accessed


anywhere in the engine code by using:
CmdLineManager::instance()->getOptionArg("-debugLevel",
&dbgLevelString);

Simulation Engine Interface Programmers Guide 12


Architecture Overview

Optional Simulation Event methods


Simulation event is an event that occurred during the course of simulation lifetime.

Here are the simulation events that are supported:

Event type Description


LOAD_IC_COMPLETE IC Load complete by all the engines
SAVE_IC_COMPLETE IC save complete by all the engines
ENGINE_INIT_COMPLETE Engine Initialization completed by all engines
POST_LOAD_IC_ACTION Step between LOAD_IC_COMPLETE and
loadIC() engine method
SIM_SPEED_CHANGED Simulation speed is changed in GUI
LX_INITIATED LX is pressed in GUI
LF_INITIATED LF is pressed in GUI
LX_COMPLETE LX operation is complete
LF_COMPLETE LF operation is complete

The SimExec will make call back to the listening engines if and when any of the events should occur.

In order to listen to an event, the engine should perform the following:

a) Inherit the engine from class Tsu::SimEventListener


b) Request SimExec to be added as listener for one or more of the
above simulation events by calling method registerEvent()
c) Implement simulationEvent() method.

Method references:

Tsu::SimEventListener Class Reference


#include <SimEventListener.h>

List of all members.

Public Member Functions


virtual long simulationEvent (const std::string &eventType)=0

virtual const char * getEngineName () const

long registerEvent (const std::string &eventType)

long unRegisterEvent (const std::string &eventType)

Simulation Engine Interface Programmers Guide 13


Architecture Overview

Detailed Description
An interface that engine inherits to receive a call back as and when the simulation event
occurs.

Simulation Engine Interface Programmers Guide 14


Architecture Overview

Member Function Documentation

Simulation Engine Interface Programmers Guide 15


Architecture Overview

Data History (Trend) Methods


The TrendProxy class is a wrapper for accessing the methods from trn_TrendCorba.idl. TrendProxy
isolates the user from having to use CORBA directly in the implementation of trending.

Any engine implementing trending must inherit from Tsu::EngineTrendListener as per the example below:

class YGSim : public Tsu::SimEngine,


public virtual Tsu::EngineTrendListener

Any engine that inherits from EngineTrendListener is required to override the two pure virtual methods
noted below. Include EngineTrendListener.h when implementing these methods.

virtual void EngineTrendListener::dataValueAdded(long itemID, Tsu::TrendValue *tv)

This method notifies the engine that a DataPair (time and value) have been added to the trend
historical data queue for the item with the itemID. In order to obtain the itemID from the item
name, use long TrendProxy::getItemIdFromName(const char * itemName

virtual void EngineTrendListener::dataHistoryChanged(long itemID, std::vector<TrendValue *> *v_tv)

This method notifies the engine that the DataPairList (vector of time and value) has changed. This
typcially happens after a snapshot is restored so that the historical data can be displayed. In order
to obtain the itemID from the item name, use long TrendProxy::getItemIdFromName(const char *
itemName);

All historical data is saved and accessed through the SimExecutive. In order to save historical data, the
data point for which data is to be saved must be added to the SimExecutive’s data historian. A point is
added to the SimExecutive’s historian with a call to one of the addDataItem() methods (see detail below).

Once the data item has been added to the historian, a listener must be added in order to update the data item
in the historian at a specified time interval. The data item listener is added with a call to either
addDataItemListener() or addDataItemListenerByName(). Every point in the historian must have a
listener.

Required Methods for Trend Implementation

Include EngineTrendListener.h when implementing the following two methods.

/*
* Method that notifies the engine that a DataPair (time and value) have been added
* to the trend historical data queue for the item with the itemID.
*
* In order to obtain the itemID from the item name, use :
* long TrendProxy::getItemIdFromName(const char * itemName);
*/
virtual void EngineTrendListener::dataValueAdded(long itemID, Tsu::TrendValue *tv)

/*
* Method that notifies the engine that the DataPairList (vector of time and value) has changed.
* This typcially happens after a snapshot is restored so that the historical data can be displayed.

Simulation Engine Interface Programmers Guide 16


Architecture Overview

*
* In order to obtain the itemID from the item name, use :
* long TrendProxy::getItemIdFromName(const char * itemName);
*/
virtual void EngineTrendListener::dataHistoryChanged(long itemID, std::vector<TrendValue *> *v_tv)

The TrendValue class contains two floating point variables: time and value. The class is defined in
EngineTrendListerer.h as:

class SIMENGINETOOLKIT_API TrendValue


{
public:
float time;
float value;
}

Include TrendProxy.h when implementing the classes and methods below.

Definitions for the following classes are in TrendProxy.h. The TP_ prefix indicates that the class is a
TrendProxy wrapper for the class of corresponding name. The TrendProxy wrappers allow these classes to
be implemented without directly using CORBA.
• TP_DHCollectionSet
• TP_DHCollectionSetList
• TP_DHItem
• TP_DHItemList
• TP_TrendItem

/**
* Proxies for IDataCollectionManager::addDataItem(in in TrendItem dataItem)
*/

/**
* This implementation is the most current and is the minimum necessary to
* add a data item for storage in the data historian. More information can
* be passed in via the addDataItem(TP_TrendItem) implementation below.
*
* returns ItemID; when -1 is returned, addDataItem failed.
*
*/
virtual long addDataItem(const char *);

/**
* This implementation replaces createTrend(const char *, long, float). Duration
* and interval (2nd and 3rd arguments) have been marked as deprecated in the IDL
* file which is why the name only constructor above is adequate. Duration and
* interval are now handled by the dataItemListener class
*
* returns ItemID; when -1 is returned, addDataItem failed.
*
*/
virtual long addDataItem(const char *, long, float);

/**
* This implementation allows the most information to be passed when adding

Simulation Engine Interface Programmers Guide 17


Architecture Overview

* a data item for storage in the data historian. All of the information in
* TP_TrendItem (and TrendItem) is not necessary. This method effectively calls
* addDHItem(DHItem) which really onlry requires the name. This method should
* eventually be deprecated and phased out of use. Duration is now stored in the
* collection set and interval is an automatically calculated value.
*
* returns ItemID; when -1 is returned, addDataItem failed.
*
*/
virtual long addDataItem(const TP_TrendItem & tpti);

/**
* Proxy for IDataCollectionManager::removeDataItem(in CORBA::Long id_in).
* This method allows the implementing engine to remove the DataItem from the database
* when trending is finished with the data item. This method might typically be called
* when a data item is expressly deleted from a trend. This method could also be called
* upon engine shutdown, but does not need to be called when the engine shuts
* down. If removeDataItem is not called during engine shut down, the DataItem
* will be in the SimExec database the next time the engine starts up. If this
* is the case, the item ID stored in the engine should be reconciled with the
* itemID stored in the SimExecutive database via long getItemIdFromName(const char *).
* If too many data history items are left in the SimExecutive database, engine performance
* will suffer. Only points for which trends are of active or continuing interest should be left
* in the SimExecutive database.
*/
virtual void removeDataItem(long id_in);

/**
* Proxy for IDataCollectionManager::addDataItemListener()
*
* The listener is not passed in because the listener is available to the
* engine via the GenericEngine::m_EngineTrendListenerRef.
*
* This method adds a listener to a particular data item (specified by id_in)
* and returns the id of the listener. While uom and uomClass can be empty ("")
* cid is required. cid refers to the collection set ID and determines the rate
* at which the data item's value and time stamp are stored in the data historion.
* In the current implementation, 1= "Very Fast", 2 = "Fast", 3 = "Medium", 4 = "Slow".
*
* In order to obtain the itemID from the item name, use:
* long TrendProxy::getItemIdFromName(const char * itemName) or simply call the
* addDataItemListenerByName() method below.
*/
virtual long addDataItemListener(long id_in, long cid, const char* uom, const char* uomClass);

/**
* Proxy for IDataCollectionManager::removeDataItemListener()
*
* Removes the data item listener with the data item ID id_in
* and the listener ID listenerID.
*
* In order to obtain the itemID from the item name, use:
* long TrendProxy::getItemIdFromName(const char * itemName) or simply call the
* removeDataItemListenerByName() method below.
* It is suggested that the implementing engine stores a map that connects item name,
* item ID, and listener ID.

Simulation Engine Interface Programmers Guide 18


Architecture Overview

*/
virtual void removeDataItemListener(long id_in, long listenerID);

/**
* Proxy for IDataCollectionManager::addDataItemListenerByName()
*
* The listener is not passed in because the listener is available to the
* engine via the GenericEngine::m_EngineTrendListenerRef.
*
* This method adds a listener to a particular data item (specified by name_in)
* and returns the id of the listener. While uom and uomClass can be empty ("")
* collectiosetname_in is required. collectionsetname_in refers to the collection set
* name and determines the rate at which the data item's value and time stamp are stored
* in the data historion. In the current implementation, collection set IDs and names are:
* 1= "Very Fast", 2 = "Fast", 3 = "Medium", 4 = "Slow".
* It is suggested that the implementing engine stores a map that connects item name,
* item ID, and listener ID.
*/
virtual long addDataItemListenerByName(
const char* name_in,
const char* collectionsetname_in,
const char* uom,
const char* uomClass);

/**
* Proxy for IDataCollectionManager::removeDataItemListner()
*
* Removes the data item listener with the listener id id_in.
*
* In order to obtain the itemID from the item name, use:
* long TrendProxy::getItemIdFromName(const char * itemName) or simply call the
* removeDataItemListenerByName() method below.
*/
virtual void removeDataItemListenerByName(const char* name, long listenerId_in);

Additional Methods and Structures for Trend Implementation

There are several structures and methods that support the required methods above. For example,
getItemIdFromName(const char * itemName) returns the index of a data item based on its name. This is
required if addDataItemListener() is to be used instead of addDataItemListenerByName(). One reason for
using addDataItemListener() might be that it is already implemented in a legacy application. New
implementations will generally find it simpler to use addDataItemListenerByName().

Include TrendProxy.h when implementing these methods.

/**
* Proxy for IDataCollectionManager::getNextDataCollectionListenerID().
* Returns the next available collection listener ID.
*/
virtual long getNextDataCollectionListenerID();

/**
* Proxy for IDataCollectionManager::getNextDataItemListenerID().
* Returns the next available data item listener ID.
*/

Simulation Engine Interface Programmers Guide 19


Architecture Overview

virtual long getNextDataItemListenerID();

/*
* Proxy for DHItem IDataCollectionManagerImpl::getDHItem(in CORBA::Long item_id)
*
* returns: TP_DHItem
*/

TP_DHItem * getDHItem(long item_id);

/*
* Proxy for DHItemList IDataCollectionManagerImpl::getAllDHItems(
* in string simulation,
* in boolean fromDB)
*
* Gets all the TP_DHItems. Useful for building a table of DH items
* or perhaps reconciling the engine implementations data history database with
* the SimExecutive data history database.
*
* returns: TP_DHItemList
*/
TP_DHItemList * getAllDHItems();

/**
* Proxy for IDataCollectionManager::findDHItem(itemName).
* Returns the item ID associated with the item Name.
*/
virtual long getItemIdFromName(const char * itemName);

/**
* Proxy for IDataCollectionManager::modifyDHItem(long itemID, long option_in).
* option_in sets the DataItem::m_option field. The m_option field sets up
* which collection speeds are to be supported for that data item. The default
* (bitwise notation) is 1110 of 0xe (hex) which allows "Fast", "Medium", and "Slow"
* data collection for the DataItem in question. In order to support "Very Fast"
* data collection, the first bit must be set (1111 or 0xf hex). If a listener is
* set up to collect "Very Fast" but the DataItem is not configured to support it,
* the historian will not collect data at the "Very Fast" rate. In order to set
* item ID 1 up for "Very Fast" data collection, the call would look as follows in the
* implementing engine:
* TrendProxy::instance()->modifyDataItem(1,0xf)
* Similarly, the collection rate could be reduced to "Medium" (1100 or 0xc) or
* "Slow" (1000 or 8) which would cause the data collection to be more efficient
* if faster collection was not required. Different combinations of collection rates
* can be set. For example, to set up "Very Fast" and "Medium" the option would be
* set to 1010 or 0xa in hex.
*/
virtual void modifyDataItem(long itemID, long option_in);

/*
* Proxy for IDataCollectionManager::getCollectionSets()
*
* Returns a list of TrendProxy::TP_DHCollectionSets in the form of
* a TrendProxy::TP_DHCollectionSetList. Each TP_DHCollectionSet
* contains the following information:
* name (i.e. "Very Fast", "Fast", etc...)

Simulation Engine Interface Programmers Guide 20


Architecture Overview

* id (i.e. 1= "Very Fast", 2 = "Fast", etc...)


* duration = length of time over which historical data is stored.
*/
virtual TP_DHCollectionSetList * getCollectionSets();

/**
* Proxy for IDataCollectionManager::configureCollectionSet(DHCollectionSet *)
* Allows parameters of the collection set to be configured explicitly.
* Each collection set consists of the following:
* const char * name;
* long id;
* long duration;
* A call to configure collection set could be used to change any of the variables
* above, but would most commonly be called to change the duration. If the duration
* changes, the sample size will be recalculated as will the interval between collections.
*
* The sample size is determined by dividing the duration of the
* first/fastest collection set ("Very Fast") by the simulation time
* step (delt). If the duration is 60 seconds and delt is 0.25, the
* sample size will be 240. The interval between collections is
* (duration/size)*delt.
*/
virtual void configureCollectionSet(TP_DHCollectionSet *dhcset);

/*
* Proxy for IDataCollectionManager::exportDH().
* Exports collection in formation to a file.
* format: 0 = CSV (comma separated variable), 1 = TSV (tab separated variable)
* collectionSet = "Very Fast", "Fast", "Medium", "Slow"
* filePath = full path with filename
*/
virtual void exportDH(long format, const char * collectionSet, const char * filePath);

/*
* Proxy for IDataCollectionManager::exportDHUOMChecked().
* Exports collection in formation to a file with UOM checked.
* format: 0 = CSV (comma separated variable), 1 = TSV (tab separated variable)
* collectionSet = "Very Fast", "Fast", "Medium", "Slow"
* filePath = full path with filename
*/
virtual void
exportDHUOMChecked(long format, const char * collectionSet, const char * filePath, bool uomCheck);

/*
* Proxy for IDataCollectionManager::getSampleSize().
* Returns the number of samples collected for each data item.
* The sample size is determined by dividing the duration of the
* first/fastest collection set ("Very Fast") by the simulation time
* step (delt). If the duration is 60 and delt is 0.25, the
* sample size will be 240. The interval between collections is
* (duration/size)*delt.
*/
virtual long getSampleSize();

Simulation Engine Interface Programmers Guide 21


Architecture Overview

YGSIM – Demonstration Engine


Listed below is the full listing for an engine that was developed using the SimEngineToolkit.
This engine runs in the SIM4ME environment and it defines a few points that a user can get
access to.

YGSimMain.cpp
//YGSimMain.cpp

/*
* Copyright(c) 2005 by SIMSCI-ESSCOR Inc. All Rights Reserved.
*
* This software is the confidential and proprietary information of SIMSCI-ESSCOR Inc.
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the
* license agreement you entered into with SIMSCI-ESSCOR.
*
* SIMSCI-ESSCOR MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
* NON-INFRINGEMENT. SIMSCI-ESSCOR SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
* LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR
* ITS DERIVATIVES.
*/

/**
*
* Abstract:
*
* This is the main() for the YGSim.
*
*/

#include <stdlib.h>

#include "YGSim.h"
//#include <MessageManagerInterface.h>
#include <windows.h>

using namespace std;


using namespace Tsu;

int main(
int argc,
char* argv[])
{
int ret = EXIT_SUCCESS; // Return value.

//uncomment the MessageBox to buy time for attaching the process to debug!
//MessageBox( NULL,"attach YGSim process to debugger", "YGSimMain::main", MB_OK |
MB_ICONINFORMATION);

YGSim* engine = YGSim::instance();

if (!engine->run(argc, argv))
{
//S4M::MessageManagerInterface::instance()->reportSevereError("Error in running
engine", "Error in running YGsim engine");
MessageBox( NULL,"Unable to run the Engine", "YGSim", MB_OK |
MB_ICONINFORMATION);
ret = EXIT_FAILURE;

Simulation Engine Interface Programmers Guide 22


Architecture Overview

return ret;
}

Simulation Engine Interface Programmers Guide 23


Architecture Overview

YGSim.h
//YGSim.h

/*
* Copyright(c) 2005 by SIMSCI-ESSCOR Inc. All Rights Reserved.
*
* This software is the confidential and proprietary information of SIMSCI-ESSCOR Inc.
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the
* license agreement you entered into with SIMSCI-ESSCOR.
*
* SIMSCI-ESSCOR MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
* NON-INFRINGEMENT. SIMSCI-ESSCOR SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
* LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR
* ITS DERIVATIVES.
*/

/**
* YGSim.h
* 18-Sep-09 Satish Jonnadula
* added scenario listeners
* 02-May-06 A.D. Mills
* New Engine
*
* Abstract:
*
* This class is the interface for an YGSim engine.
*/

#ifndef _YGSim_H
#define _YGSim_H

#include "YGSimPoint.h"
#include "Tsunami/SimEngine.h"
#include <Tsunami/pt_PointRef.h>
#include "CmdLineManager.h"
#include <map>
#ifdef TRN_TREND_IMPLEMENTED
#include <Tsunami/EngineTrendListener.h>
#endif
#include <Tsunami/SimEventListener.h>

#include "Tsunami/sce_ScenarioListener.h"
#include "Tsunami/sce_PlaybackListener.h"
#include <iostream>

using namespace std;

namespace Tsu
{

class YGSIMScenarioListener : public sce_ScenarioListener


{

virtual void scenarioActivated(long scenarioID)


{
cout << "YGSIM: scenarioActivated " << endl;
}

Simulation Engine Interface Programmers Guide 24


Architecture Overview

virtual void
scenarioStatusChanged(
const ActiveScenarioData & activescenData)
{
cout << "YGSIM: scenarioStatusChanged " << endl;
}

virtual void
scenarioDeactivated(
long scenarioID)
{
cout << "YGSIM: scenarioDeactivated " << endl;
}

virtual void
scenarioSaved(
const ScenarioData & scenData)
{
cout << "YGSIM: scenarioSaved " << endl;
}

virtual void
scenarioDeleted(
long scenarioID)
{
cout << "YGSIM: scenarioDeleted " << endl;
}

};

//-------------
class YGSIMPlaybackListener : public sce_PlaybackListener
{
virtual void
recordModeChanged(
const char* recordMode)
{
cout << "YGSIM: recordModeChanged" << endl;
}
};

//-------------

class YGSim : public Tsu::SimEngine


#ifdef SIM_EVENT_IMPLEMENTED
,
public Tsu::SimEventListener
#endif
#ifdef TRN_TREND_IMPLEMENTED
,
public virtual Tsu::EngineTrendListener
#endif
{

protected:

/**
* No protected data.
*/

private:

/** The one and only instance of this class. */


static YGSim* mInstance;

/** flag to mark first pass to init */


bool firstPass;

/** Map of all YGSim points vs. their names */


std::map<std::string,YGSimPoint*>::iterator it_point;

Simulation Engine Interface Programmers Guide 25


Architecture Overview

std::map<std::string,YGSimPoint*> point_map;

/* The command line manager */


S4M::CmdLineManager* cmdLineMgr;

Tsu::pt_PointRef mode;
Tsu::pt_PointRef simTime;
Tsu::pt_PointRef simDelt;
Tsu::pt_PointRef tempRef;

#ifdef TRN_TREND_IMPLEMENTED
typedef std::map<std::string,long> TrendItemMap;
TrendItemMap trendItemListenerMap;
TrendItemMap trendItemIdMap;

typedef std::map<long,std::string> TrendIdMap;


TrendIdMap itemIdToNameMap;
#endif

YGSIMScenarioListener *mSceListener;
YGSIMPlaybackListener *mPlaybackListener;
bool mListenersAdded;

long getSimEvents();
/**
* First pass initialization
*/
void
firstPassInit();

public:

/**
* Unregisters engine from SimExecutive
*
*/
void unregisterEngine();

/**
* Get the singleton instance of this class.
*
* returns: the unique class instance
*/
static YGSim*
instance();

/**
* Specifies the supported command line options for this class.
*/
virtual void
setCommandLineOptions();

/**
* Initializes (or reinitializes) the simulation engine. If the options
* were changed since the last initialize, it will take that into
* account.
*
* This method will be called when the engine is first started (from the
* "startup") method of this class. Since it may also be called subsequently
* after the setOptions method is called, changing the run options, it
* may be necessary for the engine to internally implement a "first pass"
* initialization that only needs to be done once, and a recurring initialization
* that needs to be done anytime the options change. This should all be
* handled specific to the engine within this method.
*
* If the engine encounters any problem with initializing itself, which
* will prevent it from running, then the EngineInitException should be
* thrown. If any problems encountered are simply information or warning
* in nature, but will still allow the engine to run, the those problems

Simulation Engine Interface Programmers Guide 26


Architecture Overview

* should be reported through the SimEngine::instance()->sendMessage


* method, and no exception should be thrown.
*/
virtual void
init()
throw(Tsu::EngineInitException);

/**
* This method will be called from the "execute" method, once for each
* calculation cycle (time step). The period by which this method will
* be called is based on the mTimeStep member variable of this class,
* set and accessed by the getTimeStep and setTimeStep methods.
*
* If the specific engine chooses to implement its own "execute" method
* then the use of this method is optional, and up to the engine
* implementation.
*
* The default implementation of this method does nothing.
*
*/
virtual void
executeCalculationCycle();

/**
* Determines if a symbol exists in the engine configuration. A symbol
* is typically a point (numerical value), but may also be a control
* block (example: PID), process model object (example: valve) or other.
*
* This method should return true if any type of symbol with the given
* name exists in the engine.
*
* param: symbolName IN: name of symbol
*
* returns: true if symbol exists, false if not
*/
virtual bool
isValidSymbol(
const std::string &symbolName);

/**
* Gets information about a specific symbol. A symbol
* is typically a point (numerical value), but may also be a control
* block (example: PID), process model object (example: valve) or other.
*
* This method may be used to obtain information about the nature of
* the symbol of the given name.
*
* param: symbolname IN: name of symbol
*
* returns: information about the symbol
*/
virtual SymbolInfo
getSymbolInfo(
const std::string &symbolName)
throw(Tsu::SymbolNotFoundException);

/**
* Obtains (probably creates) an instance of an ISimPoint as implemented
* by the specific engine. This method is expected to be
* implemented by the derived class, as an interface method to the
* specific engine's symbol table, and point objects.
*
* If the point is not found in the symbol table, or if the symbol
* is not really a point (say a block or model object), then the
* symbol not found exception should be thrown.
*
* If the units string is empty, then the setValue and getValue methods
* on the point will pass values in the internal units of measure. If
* the units string is not empty, then the setValue and getValue methods
* will pass values in the specified units of measure. If the units

Simulation Engine Interface Programmers Guide 27


Architecture Overview

* string is not blank, and not recognized by the engine, then the engine
* specific code should generate a WARNING message, and report it through
* the ISimEngine::instance()->sendMessage method. In such a case, the
* point should then revert to working in internal units of measure.
*
* The default implementation of this method will always throw the
* symbol not found exception, and is not useful. The engine specific
* implementation should always override this method.
*
* param: name IN: name of symbol
* param: units IN: units of measure to pass values in, for example
* if the units type is pressure, then the string
* passed in here would be something like "psia"
* of "kPa", etc.
*
* returns: pointer to an instance of ISimPoint, as implemented by
* the specific engine.
*/
virtual Tsu::ISimPoint*
getSimPoint(
const std::string &name,
const std::string &units = "")
throw(Tsu::SymbolNotFoundException);

/**
* This method will be called when the simulation executive wishes the
* engine to shutdown. The default implementation of exeucte will return
* when this method is called, then the engine can perform any other
* cleanup operations before shutting down.
*
* If the default "execute" method is used, then the default "shutdown"
* method implementation should also be used. If your engine
* implements its own execute method, then it will probably also need
* to implement its own shutdown method.
*/
virtual void
shutdown();

/**
* This method will change the mode of the engine. Note
* that this method does not actually cause the engine to run or freeze,
* since that is actually caused by the calling of the "resume" method.
*
* If the default "execute" method is used, then the default "setSimMode"
* method implementation should also be used. If your engine
* implements its own execute method, then it will probably also need
* to implement its own setSimMode method.
*
* param: mode IN: simulation mode
*/
virtual void
setSimMode(
const SimEngine::SimMode &mode);

/**
* Gets the string name of the units defined by the default slate for
* the specified units type. For example; if the default slate is set
* to SI, and the arguement to this method is "Temp", then the
* return string will be "C".
*
* param: uomType IN: Type of units to get default uom string for
*
* returns: name of default units
*/
virtual std::string
getDefaultUnitsForUOMType(
const std::string &uomType) const;

/**
* Save an initial conditions file.
*/

Simulation Engine Interface Programmers Guide 28


Architecture Overview

virtual void
saveIC(
const std::string &directoryName,
const SnapshotOptions &options);

/**
* Load an initial conditions file.
*/
virtual void
loadIC(
const std::string &directoryName,
const SnapshotOptions &options);

/**
* Delete an initial conditions file.
*/
virtual void
deleteIC(
const std::string &directoryName,
const SnapshotOptions &options);

/**
* Performs the actual save for both ICs and backtracks.
*
* param directoryName IN: directory in which to save a snapshot
*/
void
saveSnapshot(
const std::string& directoryName);

/**
* Performs the actual load for both ICs and backtracks.
*
* param directoryName IN: directory from which to load a snapshot
*/
void
loadSnapshot(
const std::string& directoryName);

/**
* Performs the actual delete for both ICs and backtracks.
*
* param directoryName IN: directory from which to load a snapshot
*/
void
deleteSnapshot(
const std::string& directoryName);

/**
* Save a backtrack file.
*/
virtual void
saveBacktrack(
const std::string &directoryName,
const SnapshotOptions &options);

/**
* Load a backtrack file.
*/
virtual void
loadBacktrack(
const std::string &directoryName,
const SnapshotOptions &options);

/**
* Delete a backtrack file.
*/
virtual void
deleteBacktrack(
const std::string &directoryName,

Simulation Engine Interface Programmers Guide 29


Architecture Overview

const SnapshotOptions &options);

virtual long simulationEvent(const std::string &eventType);

#ifdef TRN_TREND_IMPLEMENTED
virtual void
dataValueAdded(long itemID, Tsu::TrendValue *tv);

virtual void
dataHistoryChanged(long itemID, std::vector<TrendValue *> *v_tv);

virtual void
trend_shutdown();
#endif

/**
* Performs the action specified. More details to be defined in the
* future about how to use this method.
*
* param: action IN: definition of action to perform
*/
virtual void
performEngineAction(
const EngineAction& action);

protected:

/* Find Point method */


//YGSimPoint* find(std::string key);

/**
* Default constructor, made protected to disallow instantiation of this
* class.
*/
YGSim();

/**
* Copy constructor, made protected to disallow copying of this class.
*/
YGSim(
const YGSim&);

/**
* Destructor.
*/
virtual ~YGSim();

/**
* Assignment operator, made protected to disallow assignments on this class.
*/
YGSim&
operator=(
const YGSim&);

/**
* Address-of operators, made protected to disallow getting the address of
* this class.
*/
YGSim*
operator&();
const YGSim*
operator&() const;

#ifdef TRN_TREND_IMPLEMENTED
/*
* Method added to implement testing of trend functionality
*/
void
testTrends();

Simulation Engine Interface Programmers Guide 30


Architecture Overview

#endif

#ifdef CONVFUNC_IMPLEMENTED
/*
* Method added to implement testing of trend functionality
*/
void
testConvFuncs();
#endif

void
testScenarioListeners();

void
addOrRemoveListeners();

void
logEngineAction();

}; // end class YGSim

}; // end namespace Tsu

#endif // end _YGSim_H

YGSim.cpp

/*
* Copyright(c) 2005 by SIMSCI-ESSCOR Inc. All Rights Reserved.
*
* This software is the confidential and proprietary information of SIMSCI-ESSCOR Inc.
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the
* license agreement you entered into with SIMSCI-ESSCOR.
*
* SIMSCI-ESSCOR MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
* NON-INFRINGEMENT. SIMSCI-ESSCOR SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
* LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR
* ITS DERIVATIVES.
*/

/**
* YGSim.cpp
*
*
* Abstract:
*
* This class implements an YGSim engine.
* on loadIC() , scenario listeners will be added or removed.
* on loadIC() engine action will be logged.
*/

#include <iostream>
#include <stdlib.h>
#include "YGSim.h"
#ifdef TRN_TREND_IMPLEMENTED
#include <Tsunami/TrendProxy.h>
#endif

Simulation Engine Interface Programmers Guide 31


Architecture Overview

#include <Tsunami/SimEngine.h>
#include <Tsunami/pt_Point.h>
#include <Tsunami/pt_SymbolTable.h>
#include <setk_MessageManagerInterface.h>
//#include <windows.h> //for GetCurrentDirectory
#include <time.h> //for _strdate
#include <Tsunami/RequiredPointsTable.h>
#include "Tsunami/pt_PointsSnapshotManager.h"
#include <io.h> // _access(), remove()
#include <CmdLineManager.h>
#include <Tsunami/pt_DynamicPoint.h>

#include <fstream> //for file IO


#include <map>

#include "Tsunami/ScenarioProxy.h"
#include <Tsunami/BktRplyProxy.h>

using namespace std;


using namespace Tsu;

static std::string SIM_EVENT_FILE_NAME = "_SimEvents.txt";


//------------------------------------------------------------------------------

// Initialize the static instance members.


YGSim* YGSim::mInstance = 0;

// IO file to write the debug data.

static ofstream ofile;


const string DEBUG_FILENAME = "YGSimDebugLog.txt";

//------------------------------------------------------------------------------

inline string curDateTime()


{
char dateStr [20], timeStr [20];

_strdate( dateStr); _strtime( timeStr );

string retStr(dateStr);
retStr.append(" ");
retStr.append(timeStr);
retStr.append(" ");
return retStr;
}

//------------------------------------------------------------------------------

void trim(std::string& s) {

string org_str = s;
if(s.length() == 0)
return ;
std::size_t beg = s.find_first_not_of(" \a\b\f\n\r\t\v");
if(beg == std::string::npos) // No non-spaces
return ;
string::size_type len = s.length();
s.erase(0,beg);
len = s.length();
std::size_t end = s.find_last_not_of(" \a\b\f\n\r\t\v");
s.erase(end+1,len-(end+1));
}

//------------------------------------------------------------------------------

YGSim::
YGSim()
{
#ifdef _USR_DEBUG

Simulation Engine Interface Programmers Guide 32


Architecture Overview

string fileName = getName() + DEBUG_FILENAME;


ofile.open(fileName.c_str());
if (!ofile.is_open())
cout << "could n't open the debug log file\n";
else
{
char directory[2048];
GetCurrentDirectory(2048,directory);
cout << "opened the debug log file:" << DEBUG_FILENAME << "@ " << directory
<<endl;
}
ofile << curDateTime() << "YGSIM constructor called\n";
ofile.flush();
#endif

firstPass = true;
// Get an instance of the command line manager.
cmdLineMgr = S4M::CmdLineManager::instance();

mListenersAdded = false;

//------------------------------------------------------------------------------

YGSim::
~YGSim()
{
#ifdef _USR_DEBUG
ofile << curDateTime() << "YGSIM destructor called";
ofile.close();
#endif

// Delete the singleton instance of this class.


if (mInstance)
{
delete mInstance;
mInstance = 0;
}
}

//------------------------------------------------------------------------------

YGSim* YGSim::
instance()
{
if (mInstance == 0)
{
mInstance = new YGSim;
}
return mInstance;
}

//------------------------------------------------------------------------------

void YGSim::
setCommandLineOptions()
{
cmdLineMgr->addOption("-h",
"Show this message.");
cmdLineMgr->addOption("-?",
"Show this message.");
cmdLineMgr->addOption("-enginename",
"The name of this Engine ",
"YGSIM");
cmdLineMgr->addOption("-enginehost",
"The name of the machine on which to"
" run this engine.",
"localhost");
cmdLineMgr->addOption("-simexechost",
"The hostname of the simulation executive",

Simulation Engine Interface Programmers Guide 33


Architecture Overview

"localhost");
cmdLineMgr->addOption("-simexecname",
"The name of the simulation executive",
"SimExecutive");
cmdLineMgr->addOption("-simulation",
"The simulation name.",
"");
cmdLineMgr->addOption("-customer",
"The customer name.",
"");
cmdLineMgr->addOption("-debug",
"Turn on Debugging",
"No");
}
//------------------------------------------------------------------------------

void YGSim::
init()
throw(EngineInitException)
{
// perform initialization that should only happen one time
if (firstPass)
{
firstPassInit();
firstPass = false;
}
getSimEvents();

// Set the Load progress


setOperationProgress( 105.0 );
}

//------------------------------------------------------------------------------

void YGSim::
firstPassInit()
{
//local variables
const char POINT_FILENAME[] = "_simPoints.txt";
const int FREEZE_MODE = 1;
double delt = 0.25;

const int NO_OF_ATTRIBS = 7; // no. of attributes for each point line entry
string fileAttributes[NO_OF_ATTRIBS];

// the list of points and their attributes


typedef Tsu::RequiredPointsTable::RequiredPointAttributes attr;
std::vector<attr> points;

std::string buffer;

// Set the Load progress


setOperationProgress( 1.0 );
// Store the engine's sync period.
S4M::CmdLineManager::instance()->getOptionArg("-delt", &delt);

typedef map<string,Tsu::pt_PointInitData::PointDataType> PointDataTypeMap;


PointDataTypeMap pointDataTypeMap ;

pointDataTypeMap["FLOAT"]=Tsu::pt_PointInitData::FLOAT;
pointDataTypeMap["INTEGER"]=Tsu::pt_PointInitData::INTEGER;
pointDataTypeMap["DOUBLE"]=Tsu::pt_PointInitData::DOUBLE;
pointDataTypeMap["BOOLEAN"]=Tsu::pt_PointInitData::BOOLEAN;
pointDataTypeMap["CHARACTER"]=Tsu::pt_PointInitData::CHARACTER;
pointDataTypeMap["SHORT"]=Tsu::pt_PointInitData::SHORT;
pointDataTypeMap["UNDEFINED"]=Tsu::pt_PointInitData::UNDEFINED;

string fileName(POINT_FILENAME);
ifstream infile((getName() + fileName).c_str());

char directory[1024];

Simulation Engine Interface Programmers Guide 34


Architecture Overview

GetCurrentDirectory(1024,directory);

if(!infile)
{
char errMsg[256];
sprintf(errMsg,"Could not open points file -- Exiting: %s\\%s",
directory,(getName() + fileName).c_str());
MessageBox( NULL,errMsg, "YGSim", MB_OK | MB_ICONINFORMATION );
shutdown();
exit(EXIT_FAILURE);
}

#ifdef _USR_DEBUG
ofile << curDateTime() << "Reading points\n";
#endif

//read all the points from file and add them to SETKs point symbol table.
while(!infile.eof())
{
getline(infile, buffer, '\n'); //read a line into buffer

size_t i;
i = buffer.find("//"); //detect a comment line

if (i != string::npos)
continue; //skip the commented line

i = buffer.find(',');
string::size_type start=0;
int index=-1;

while(i != string::npos && index<NO_OF_ATTRIBS)


{
fileAttributes[++index] = buffer.substr(start,i-start);
trim(fileAttributes[index]);
++i;
start = i;
i = buffer.find(',', i);
#ifdef _USR_DEBUG
ofile << fileAttributes[index] << ",";
#endif
}
fileAttributes[++index]=buffer.substr(start,buffer.size()-start);
trim(fileAttributes[index]);

#ifdef _USR_DEBUG
ofile << fileAttributes[index] << endl;
ofile.flush();
#endif

if(index==NO_OF_ATTRIBS-1)
{
points.push_back(attr(fileAttributes[0].c_str(),
fileAttributes[1].c_str(),
pointDataTypeMap[fileAttributes[2]] ,
fileAttributes[3].c_str(),
atof(fileAttributes[4].c_str()),
fileAttributes[5].c_str(),
fileAttributes[6].c_str())
);
}

} //end of while EOF

// name class type


description value uomType units
// ----- ------- ------ --------
----- ------ ------- ------

Simulation Engine Interface Programmers Guide 35


Architecture Overview

points.push_back(attr("TIME", "DYNAMIC", Tsu::pt_PointInitData::DOUBLE,


"Simulation time", 0.0, "FineTime", "sec"));
points.push_back(attr("DELT", "GRAPHIC", Tsu::pt_PointInitData::FLOAT,
"Time increment", delt, "FineTime", "sec"));
points.push_back(attr("MODE", "GRAPHIC", Tsu::pt_PointInitData::INTEGER,
"Simulation mode", static_cast<float>(FREEZE_MODE), "", ""));

#if _DEBUG
long beginTime=clock();
#endif

pt_DynamicPoint<float>::setMaintainSaveRestoreTable(false);
pt_DynamicPoint<intfour>::setMaintainSaveRestoreTable(false);
pt_DynamicPoint<bool>::setMaintainSaveRestoreTable(false);
pt_DynamicPoint<double>::setMaintainSaveRestoreTable(false);

Tsu::RequiredPointsTable::instance()->addRequiredPoints(points);

pt_DynamicPoint<float>::createSaveRestoreTable();
pt_DynamicPoint<intfour>::createSaveRestoreTable();
pt_DynamicPoint<bool>::createSaveRestoreTable();
pt_DynamicPoint<double>::createSaveRestoreTable();

pt_DynamicPoint<float>::setMaintainSaveRestoreTable(true);
pt_DynamicPoint<intfour>::setMaintainSaveRestoreTable(true);
pt_DynamicPoint<bool>::setMaintainSaveRestoreTable(true);
pt_DynamicPoint<double>::setMaintainSaveRestoreTable(true);

#if _DEBUG
long endTime=clock();
cout << " time taken to initialize " << (long) points.size() << ":" <<
(double) (endTime - beginTime) / CLOCKS_PER_SEC << " secs" << endl;
#endif

// Make the required table, the preferred one


Tsu::pt_SymbolTable::setPreferredTable("ESSCOR_REQUIRED");

mode = dynamic_cast<Tsu::pt_Point*>(Tsu::pt_SymbolTable::find("MODE"));
simTime = dynamic_cast<Tsu::pt_Point*>(Tsu::pt_SymbolTable::find("TIME"));
simDelt = dynamic_cast<Tsu::pt_Point*>(Tsu::pt_SymbolTable::find("DELT"));

#ifdef TRN_TREND_IMPLEMENTED
// NS added call to testTrends()
testTrends();
#endif

#ifdef CONVFUNC_IMPLEMENTED
// NS added call to testConvFuncs()
testConvFuncs();
#endif

#ifdef SCENARIOS_IMPLEMENTED
testScenarioListeners();
#endif

} // end YGSim::firstPassInit()

//------------------------------------------------------------------------------

void YGSim::
executeCalculationCycle()
{
mode->setValue( static_cast<long>(getSimMode()) );
float ntime = simTime->getFloatValue() + simDelt->getFloatValue();
simTime->setValue(ntime);
#ifdef _DEBUG
cout << " simulation time : " << ntime << endl;
#endif
} // end YGSim::executeCalculationCycle()

//------------------------------------------------------------------------------

Simulation Engine Interface Programmers Guide 36


Architecture Overview

SimEngine::SymbolInfo YGSim::
getSymbolInfo(
const string& symbolName)
throw(SymbolNotFoundException)
{
// find the symbol
Tsu::pt_Symbol *symbol = Tsu::pt_SymbolTable::find(symbolName);
// make sure that the symbol is a valid pointer
if (symbol)
{
Tsu::SimEngine::SymbolInfo info;
info.name = symbolName;
info.description = symbol->getDescription();
info.className = symbol->getSymbolID().getClassName();
Tsu::pt_Point* point = dynamic_cast<Tsu::pt_Point*>(symbol);
if (point != 0)
{
info.type = Tsu::SimEngine::POINT;
switch (point->getType())
{
case Tsu::pt_PointInitData::DOUBLE:
info.symbolDataType = Tsu::ISimPoint::DOUBLE;
break;
case Tsu::pt_PointInitData::FLOAT:
info.symbolDataType = Tsu::ISimPoint::FLOAT;
break;
case Tsu::pt_PointInitData::INTEGER:
info.symbolDataType = Tsu::ISimPoint::INTEGER;
break;
case Tsu::pt_PointInitData::BOOLEAN:
info.symbolDataType = Tsu::ISimPoint::BOOLEAN;
break;
default:
info.symbolDataType = Tsu::ISimPoint::DOUBLE;
break;
}
info.units = point->getUnitsType();
}
else
{
info.type = Tsu::SimEngine::MODEL_OBJECT;
info.symbolDataType = Tsu::ISimPoint::DOUBLE; // dummy
info.units = "UNDEFINED";
}

#ifdef _USR_DEBUG
ofile << "getSymbolInfo called\n"<< endl;
#endif

return info;
}
// else throw an exception
else
{
#ifdef _USR_DEBUG
ofile << "getSymbolInfo exception\n"<< endl;
#endif
cout << "exception" << endl;
Tsu::SymbolNotFoundException exc(std::string("Symbol not found: ")+symbolName);
throw exc;
}
} //getSymbolInfo()

//------------------------------------------------------------------------------

bool YGSim::
isValidSymbol(
const string& symbolName)
{
return Tsu::pt_SymbolTable::find(symbolName) != 0;

Simulation Engine Interface Programmers Guide 37


Architecture Overview

//------------------------------------------------------------------------------

void YGSim::
saveIC(
const string& directoryName,
const SnapshotOptions& )
{
#ifdef _USR_DEBUG
ofile << curDateTime() << "Saving IC\n";
#endif
saveSnapshot(directoryName);
}

//------------------------------------------------------------------------------

void YGSim::
loadIC(
const string& directoryName,
const SnapshotOptions& )
{
#ifdef _USR_DEBUG
ofile << curDateTime() << "Loading IC\n";
ofile.flush();
#endif
loadSnapshot(directoryName);

#ifdef SCENARIOS_IMPLEMENTED
addOrRemoveListeners(); //only for testing
#endif

#ifdef OP_ACTION_RECORD
logEngineAction(); //only for testing
#endif

//------------------------------------------------------------------------------

void YGSim::
deleteIC(
const string& directoryName,
const SnapshotOptions& )
{
#ifdef _USR_DEBUG
ofile << curDateTime() << "deleting IC\n";
ofile.flush();
#endif
deleteSnapshot(directoryName);

//------------------------------------------------------------------------------

void YGSim::
saveBacktrack(
const string& directoryName,
const SnapshotOptions& )
{
#ifdef _USR_DEBUG
ofile << curDateTime() << "saving Backtrack\n";
ofile.flush();
#endif
saveSnapshot(directoryName);
}

//------------------------------------------------------------------------------

void YGSim::
loadBacktrack(

Simulation Engine Interface Programmers Guide 38


Architecture Overview

const string& directoryName,


const SnapshotOptions& )
{
#ifdef _USR_DEBUG
ofile << curDateTime() << "loading Backtrack\n";
ofile.flush();
#endif
loadSnapshot(directoryName);
}

//------------------------------------------------------------------------------

void YGSim::
deleteBacktrack(
const string& directoryName,
const SnapshotOptions& )
{
#ifdef _USR_DEBUG
ofile << curDateTime() << "deleting Backtrack\n";
ofile.flush();
#endif
deleteSnapshot(directoryName);
}

//------------------------------------------------------------------------------

void YGSim::
saveSnapshot(
const std::string& directoryName)
{
// Construct the full pathname for the file to save.
std::string file(directoryName + getName());

// get the main thread key


acquireMainThreadKey();

// use the snapshot manager to save the file


Tsu::pt_PointsSnapshotManager::instance().saveSnapshot( file );

// release the main thread key


releaseMainThreadKey();

// notify that the operation is complete


engineOperationComplete();
}

//------------------------------------------------------------------------------

void YGSim::
loadSnapshot(
const std::string& directoryName)
{
// Construct the full pathname for the file to save.
std::string file(directoryName + getName());

// get the main thread key


acquireMainThreadKey();

// use the snapshot manager to restore the snapshot


Tsu::pt_PointsSnapshotManager::instance().loadSnapshot( file );

// release the main thread key


releaseMainThreadKey();

// notify that the operation is complete


engineOperationComplete();
}

//------------------------------------------------------------------------------

void YGSim::

Simulation Engine Interface Programmers Guide 39


Architecture Overview

deleteSnapshot(
const std::string& ssDir)
{

// Build up name of file to delete


std::string engineName(getName());
std::string file = ssDir + engineName;

// Make sure the file exists


if( _access(file.c_str(),00) != -1 )
{
if( remove(file.c_str()) != 0 )
{
std::string errMsg = "Error Deleting file - " + file + ".";
S4M::MessageManagerInterface::instance()->reportWarning(errMsg,errMsg);
}
}
// notify that the operation is complete
engineOperationComplete();

return;
}

//------------------------------------------------------------------------------

ISimPoint* YGSim::
getSimPoint(
const string& name,
const string& units /* = "" */)
throw(SymbolNotFoundException)
{
#ifdef _USR_DEBUG
ofile << curDateTime() << "fetching simPoint:" << name <<endl;
ofile.flush();
#endif
return new Tsu::YGSimPoint(name);

} // end YGSim::getSimPoint(const string&, const string&)

//------------------------------------------------------------------------------

void YGSim::
shutdown()
{
#ifdef TRN_TREND_IMPLEMENTED
trend_shutdown();
#endif
#ifdef _USR_DEBUG
ofile << curDateTime() << "shutting down YGsim Engine\n";
ofile.flush();
#endif

#ifdef SIM_EVENT_IMPLEMENTED
unRegisterEvent(""); //remove all listeners of this engine
#endif

SimEngine::shutdown();
}

//------------------------------------------------------------------------------

void YGSim::
setSimMode(
const SimEngine::SimMode& mode)
{
SimEngine::setSimMode(mode);
} // end YGSim::setSimMode(const SimEngine::SimMode&)

//------------------------------------------------------------------------------

std::string YGSim::

Simulation Engine Interface Programmers Guide 40


Architecture Overview

getDefaultUnitsForUOMType(const std::string &uomType) const


{
#ifdef _USR_DEBUG
ofile << curDateTime() << "getDefaultUnitsForUOMType is not implemented \n";
ofile.flush();
#endif
return string("not implemented");
}

//------------------------------------------------------------------------------

long YGSim::
simulationEvent(const std::string &eventType)
{
string msg="Simulation event :" + eventType + " begin";
setk_MessageManagerInterface::instance()->reportInformationOnly(msg, msg,"0");

if (eventType == EventType::LOAD_IC_COMPLETE)
{
for(int ii=0; ii < 60; ++ii)
{
Sleep(1000);
}
}
if (eventType == EventType::POST_LOAD_IC_ACTION)
{
for(int ii=0; ii < 60; ++ii)
{
Sleep(1000);
}
}

msg="Simulation event :" + eventType + " complete";


setk_MessageManagerInterface::instance()->reportInformationOnly(msg, msg,"0");

return 0;
}

long YGSim::
getSimEvents()
{
long retValue=0;

//if sim event is not implemented, do nothing


#ifdef SIM_EVENT_IMPLEMENTED
//the file has the form [engineName]_SimEvents.txt
string fileName(getName() + SIM_EVENT_FILE_NAME);
std::ifstream filePtr(fileName.c_str());
string msg;
if(!filePtr) {
msg = "File [";
msg += fileName;
msg += "] with listening events not found, no call back will be received";
setk_MessageManagerInterface::instance()->reportInformationOnly(msg, msg,"0");
return 1;
}

std::string eventType;
while (std::getline(filePtr, eventType))
{
if ((eventType[0] == '#') ||
(eventType[0] == '\n') ||
(eventType[0] == '\0') ||
(eventType[0] == '/'))
continue;

long ret=0;
ret = registerEvent(eventType);
retValue += ret;
switch (ret)
{

Simulation Engine Interface Programmers Guide 41


Architecture Overview

case 1:
msg = "Unknown event type : [" + eventType + "]";
setk_MessageManagerInterface::instance()->reportError(msg, msg,"0");
break;
case 2:
msg = "Simulation event not implemented ";
setk_MessageManagerInterface::instance()->reportError(msg, msg,"0");
break;
default:
break;
}
}
filePtr.close();
#endif

return retValue;
}

#ifdef TRN_TREND_IMPLEMENTED
//------------------------------------------------------------------------------
// implement pure virtual methods inherited from EngineTrendListener
//------------------------------------------------------------------------------
void YGSim::
dataValueAdded(long itemID, Tsu::TrendValue *tv)
{
cout << "in YGSim::dataValueAdded()for item # " << itemID << " : " << tv->value <<
" : " << tv->time << endl;
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
void YGSim::
dataHistoryChanged(long itemID, std::vector<TrendValue *> *v_tv)
{
cout << "in YGSim::dataHisoryChanged()" << endl;
static int first_time = 0;

if(first_time > 1)
{
cout << " Item ID : Name = " << itemID << " : " <<
itemIdToNameMap.find(itemID)->second << endl;
for(int ii = 0; ii < v_tv->size(); ii++)
{
TrendValue * tmp = (*v_tv)[ii];
cout << " time:value => " << tmp->time << " : " << tmp->value <<
endl;
}
}
else
{
if(first_time < 2)
{
first_time++;
}
}
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
void YGSim::
trend_shutdown()
{
// delete all the listeners

// could also do this by using getItemIdFromName to make sure ID is correct


for(TrendItemMap::iterator it = trendItemListenerMap.begin();
it != trendItemListenerMap.end();
it++)
{
TrendProxy::instance()->removeDataItemListenerByName(it->first.c_str(),it-
>second);

Simulation Engine Interface Programmers Guide 42


Architecture Overview

trendItemListenerMap.clear();

// remove data items....not absolutedly necessary, but here to test


for(TrendItemMap::iterator iitt = trendItemIdMap.begin();
iitt != trendItemIdMap.end();
iitt++)
{
TrendProxy::instance()->removeDataItem(iitt->second);
}
trendItemIdMap.clear();

//TrendProxy::instance()->removeGenericTrendListener();

// delete all the items ...


// not sure we can do this currently... might need to
// write DataCollectionManagerImpl::getIDfromName(string name)

}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
void YGSim::
testTrends()
{
// NS trends addition....
// look for point named "ONE" in symbol table...
// Find the symbol
long period = 100;
float interval = 1.0;

pt_Symbol* symbol1 = static_cast<pt_Symbol*>(pt_SymbolTable::find("ONE"));


pt_Symbol* symbol2 = static_cast<pt_Symbol*>(pt_SymbolTable::find("TWO"));
pt_Symbol* symbol3 = static_cast<pt_Symbol*>(pt_SymbolTable::find("THREE"));
if(symbol1 && symbol2 && symbol3)
{
try
{
// get next collection listener ID
//long coll_id = TrendProxy::instance()-
>getDataCollectionListenerID();
// get next Item listener ID
//long item_id = TrendProxy::instance()->getDataItemListenerID();

// Test all the different addDataItem signatures


long item1 = -1;
// add the data item (creates new trend if necessary)
item1 = TrendProxy::instance()->addDataItem(
const_cast<char *>("ONE"));
trendItemIdMap["ONE"] = item1;
itemIdToNameMap[item1] = "ONE";

long item2 = -1;


item2 = TrendProxy::instance()->addDataItem(
const_cast<char *>("TWO"),
period,
interval);
trendItemIdMap["TWO"] = item2;
itemIdToNameMap[item2] = "TWO";

TP_TrendItem * ti3 = new TP_TrendItem();


ti3->name = "THREE";
ti3->collectionSetName = "Medium";

long item3 = -1;


item3 = TrendProxy::instance()->addDataItem(*ti3);
trendItemIdMap["THREE"] = item3;

Simulation Engine Interface Programmers Guide 43


Architecture Overview

itemIdToNameMap[item3] = "THREE";

// add the item listeners


long id_L1 = TrendProxy::instance()-
>addDataItemListener(item1,1,"","");
trendItemListenerMap["ONE"] = id_L1;

long id_L2 = TrendProxy::instance()-


>addDataItemListenerByName("TWO","Fast","","");
trendItemListenerMap["TWO"] = id_L2;

long id_L3 = TrendProxy::instance()-


>addDataItemListenerByName(ti3->name.c_str(),ti3->collectionSetName.c_str(),"","");
trendItemListenerMap["THREE"] = id_L3;

// test item IDs

long test3 = -2;


long test2 = -2;
long test1 = -2;
test3 = TrendProxy::instance()->getItemIdFromName("THREE");
test2 = TrendProxy::instance()->getItemIdFromName("TWO");
test1 = TrendProxy::instance()->getItemIdFromName("ONE");

cout << "\nItem Name:ItemID" << endl;


cout << " ONE : " << test1 << endl;
cout << " TWO : " << test2 << endl;
cout << " THREE : " << test3 << endl;

long sample_sz = TrendProxy::instance()->getSampleSize();


cout << "\n--- SAMPLE SIZE = " << sample_sz << endl;

TP_DHCollectionSetList *tp_dhcs_list = new


TP_DHCollectionSetList();
tp_dhcs_list = TrendProxy::instance()->getCollectionSets();

cout << "\nCOLLECTION SET LIST INFORMATION" << endl;


cout << " NAME ID DURATION" << endl;
cout << " ----------------------" << endl;

for(unsigned int zz = 0; zz < tp_dhcs_list->size(); zz++)


{
cout << " " << (*tp_dhcs_list)[zz]->name << " : "
<< (*tp_dhcs_list)[zz]->id << " : "
<< (*tp_dhcs_list)[zz]->duration
<< endl;
}

// Enable "Very Fast" for "ONE"


// bit 1 sets very fast... default is binary 1110 (hex = 0xe) set
in DataItem constructor
// need to change to 1111 (0xf)
TrendProxy::instance()->modifyDataItem(test1,0xf);

TrendProxy::instance()->exportDH(0,"Fast","fast_dh.txt");
TrendProxy::instance()->exportDH(0,"Very Fast","v_fast_dh.txt");
TrendProxy::instance()-
>exportDHUOMChecked(0,"Medium","medium_dh_uomf.txt",false);
TrendProxy::instance()-
>exportDHUOMChecked(1,"Medium","medium_dh_uomt.txt",true);

TP_DHCollectionSet *dhcset = new TP_DHCollectionSet();


dhcset->name = "Very Fast";
dhcset->id = 1;
dhcset->duration = 60;
// strange.... adjusting the duration, which is really all we can
do aside from
// changing the name, adjusts the collection frequency of other
collection sets.

Simulation Engine Interface Programmers Guide 44


Architecture Overview

// I think this has to do with the way the collection set


frequency is calculated in initializeCollectionSets()
// (I don't think it is quite correct). If duration is set to
120, the frequency
// of the "Fast" collection goes to 1.25s (from 2.5s). If
duration is set to 30,
// the "fast" frequency goes to 5s.
TrendProxy::instance()->configureCollectionSet(dhcset);

tp_dhcs_list->clear();
tp_dhcs_list = TrendProxy::instance()->getCollectionSets();

cout << "\nCOLLECTION SET LIST INFORMATION" << endl;


cout << " NAME ID DURATION" << endl;
cout << " ----------------------" << endl;

for(unsigned int zz = 0; zz < tp_dhcs_list->size(); zz++)


{
cout << " " << (*tp_dhcs_list)[zz]->name << " : "
<< (*tp_dhcs_list)[zz]->id << " : "
<< (*tp_dhcs_list)[zz]->duration
<< endl;
}

// test getDHItem(item_id)
cout << "\n--------------------------"
<< "\n getDHItem tests"
<< "\n--------------------------" << endl;

TP_DHItem * dhi_1 = new TP_DHItem();


dhi_1 = TrendProxy::instance()->getDHItem(item1);
cout << "\nDHItem for item ID " << item1 << endl;
cout << " name = " << dhi_1->name << endl;
cout << " collectionoption = " << dhi_1->collectionOption <<
endl;
cout << " queindex = " << dhi_1->queindex << endl;
cout << " symbolType = " << dhi_1->symbolType << endl;

// check item 2
dhi_1 = TrendProxy::instance()->getDHItem(item2);
cout << "\nDHItem for item ID " << item2 << endl;
cout << " name = " << dhi_1->name << endl;
cout << " collectionoption = " << dhi_1->collectionOption <<
endl;
cout << " queindex = " << dhi_1->queindex << endl;
cout << " symbolType = " << dhi_1->symbolType << endl;

// check item 3
dhi_1 = TrendProxy::instance()->getDHItem(item3);
cout << "\nDHItem for item ID " << item3 << endl;
cout << " name = " << dhi_1->name << endl;
cout << " collectionoption = " << dhi_1->collectionOption <<
endl;
cout << " queindex = " << dhi_1->queindex << endl;
cout << " symbolType = " << dhi_1->symbolType << endl;

// test getAllDHItems()
cout << "\n--------------------------"
<< "\n getAllDHItems test"
<< "\n--------------------------" << endl;

TP_DHItemList * dhil = new TP_DHItemList();


dhil = TrendProxy::instance()->getAllDHItems();
for(long l = 0; l < dhil->size(); l++)
{
cout << "\nDHItem for list index " << l << endl;
cout << " name = " << (*dhil)[l]->name << endl;
cout << " collectionoption = " << ((*dhil)[l]-
>collectionOption) << endl;
cout << " queindex = " << (*dhil)[l]->queindex << endl;

Simulation Engine Interface Programmers Guide 45


Architecture Overview

cout << " symbolType = " << (*dhil)[l]->symbolType << endl;


}
}
catch (...)
{
cout << "Exception initializing trend information" << endl;
string msg = "Uncaught CORBA::Exception in YGSimEngine";
setk_MessageManagerInterface::instance()->reportSevereError(msg,
msg,"0");
}

}
else
{
cout <<
"***********************************************************************************" <<
endl;
cout << "TRENDS NOT TESTED! Points named ONE, TWO, and THREE all need to
exist!" << endl;
cout << "Please create points with names ONE, TWO and THREE and restart to test
trends." << endl;
cout <<
"***********************************************************************************" <<
endl;
}

}
#endif
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
#ifdef CONVFUNC_IMPLEMENTED
void YGSim::
testConvFuncs()
{
string symbolName = "ONE";
Tsu::pt_Symbol *symbol = Tsu::pt_SymbolTable::find(symbolName);
// make sure that the symbol is a valid pointer
if (symbol)
{
ISimPoint* ygpoint = getSimPoint(symbolName);

cout << "\n\n-----------------------------------------------"


<< "\n******* conversion function check *************"
<< "\n-----------------------------------------------" << endl;

cout << "ONE - should have no conversion type to start with"


<< "\n ONE: Call to getConvFuncName yields: " << ygpoint-
>getConvFuncName().c_str() << endl;

cout << "\nNow set the conversion factor to FOXSCI_16 " << endl;
ygpoint->setConvFuncName("N10");

cout << "\n ONE: Call to getConvFuncName yields: " << ygpoint-
>getConvFuncName().c_str() << endl;

}
}
#endif

//------------------------------------------------------------------------------

void YGSim::
testScenarioListeners()
{
mSceListener = new YGSIMScenarioListener;
mPlaybackListener = new YGSIMPlaybackListener;

addOrRemoveListeners();

Simulation Engine Interface Programmers Guide 46


Architecture Overview

//------------------------------------------------------------------------------

void YGSim::
logEngineAction()
{
static counter=0;
ostringstream actionNamestream;

actionNamestream << string("dummyAction") << counter++;

Tsu::SimEngine::EngineAction action;
action.engineName = "ysimengine";

action.name = actionNamestream.str();
action.options = "empty";
BktRplyProxy::instance()->logEngineAction(action);

ofile << curDateTime() << "engine action " << action.name


<< " logged " << endl;
ofile.flush();

//------------------------------------------------------------------------------

void YGSim::
performEngineAction(
const EngineAction& action)
{
cout << "perform Engine Action " << action.name << endl;
ofile << curDateTime() << "perform Engine called " << action.name << endl;
ofile.flush();
}

//------------------------------------------------------------------------------
void YGSim::
addOrRemoveListeners()
{
if (mListenersAdded)
{
ScenarioProxy::instance()->removeScenarioListener(mSceListener);
ScenarioProxy::instance()->removePlaybackListener(mPlaybackListener);
mListenersAdded = false;
cout << "-------------------------------------------" << endl;
cout << "Scenario listeners removed" << endl;
cout << "-------------------------------------------" << endl;
ofile << curDateTime() << "Scenario listeners removed\n";
ofile.flush();
}
else
{
ScenarioProxy::instance()->addScenarioListener(mSceListener);
ScenarioProxy::instance()->addPlaybackListener(mPlaybackListener);
mListenersAdded = true;
cout << "-------------------------------------------" << endl;
cout << "Scenario listeners added" << endl;
cout << "-------------------------------------------" << endl;
ofile << curDateTime() << "Scenario listeners added\n";
ofile.flush();
}

//------------------------------------------------------------------------------

Simulation Engine Interface Programmers Guide 47


Architecture Overview

YGSimPoint.h

//YGSimPoint.h

/*
* Copyright(c) 2005 by SIMSCI-ESSCOR Inc. All Rights Reserved.
*
* This software is the confidential and proprietary information of SIMSCI-ESSCOR Inc.
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the
* license agreement you entered into with SIMSCI-ESSCOR.
*
* SIMSCI-ESSCOR MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
* NON-INFRINGEMENT. SIMSCI-ESSCOR SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
* LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR
* ITS DERIVATIVES.
*/
/*
* YGSimPoint.h
*
*
* Abstract
*
* Implements the ISimPoint interface for the YGSim engine
*/
#ifndef _YGSimPOINT_H
#define _YGSimPOINT_H

//#include <environ.h>
#include <string>
#include <Tsunami/ISimPoint.h>

// Forward declarations.
namespace Tsu
{
class pt_Point;
}

namespace Tsu
{

class YGSimPoint : public Tsu::ISimPoint


{

private:

/** name of point */


std::string name;
/** description for point */
//std::string description;
/** value type */
//ISimPoint::PointDataType type;
/** The actual data value in memory*/
//float* datavalue;

/** optional conversion function implementation */


std::string sConvFuncName;

/** conversion function value */


double cf_dbl;
float m_minScale;
float m_maxScale;
float m_loLim;

Simulation Engine Interface Programmers Guide 48


Architecture Overview

float m_hiLim;

//satj
pt_Point *point;

/**
* Internal copy routine
*/
void makeCopy(const YGSimPoint & copy);

public:

/**
* Constructors
*/

YGSimPoint();
YGSimPoint(const std::string &pointName);

/*YGSimPoint(
const std::string &name,
const std::string &units = "",
const float value = 0.0);

YGSimPoint(
const YGSimPoint* pnt);
*/

/**
* Destructor
*/
virtual ~YGSimPoint();

/**
* Copy constructor
*/
YGSimPoint(const YGSimPoint& copy);

/**
* Assignment operator
*/
//YGSimPoint&
//operator=(const YGSimPoint& copy);

/**
* Gets the name of the point
*
* returns: name of point
*/
virtual std::string
getName() const;

/**
* Gets the description of the point
*
* returns: description of point
*/
virtual std::string
getDescription() const;

/**
* Is this a valid point (was it found in the symbol table)
*
* returns: true if a point exists
*/
virtual bool
isValidPoint() const;

Simulation Engine Interface Programmers Guide 49


Architecture Overview

/**
* Returns the Internal data type of this point
*
* returns: data type of this point.
*/
virtual ISimPoint::PointDataType
getDataType() const;

/**
* Get what units of measure (UOM) type this point is. For example;
* a UOM type would be specified as "Pressure" or "Temperature".
*
* The exact UOM strings will be specific to the engine, so it can
* be assumed that the strings passed into this method are the same
* strings that the particular engine can make sense of.
*
* For engines that do not implement UOM conversions, the default
* implementation of this method is acceptable.
*
* returns: UOM Typ
*/
virtual std::string
getUOMType() const;

/**
* Sets the default interface units of measure (UOM). This units
* of measure will be the type of units that all values passed
* in and out through the setValue and getValue methods.
*
* If the string is an empty string (ie: ""), then the values
* passed in and out will be in internal units of measure (no
* conversion needed).
*
* For clarity, the units here might be strings like "psia" or "kPa",
* and should not by confused with the UOM TYPE, which would be a
* string something like "Pressure"
*
* If the units string is not recognized by the engine UOM converter,
* then a WARNING message should be sent, and the default UOM should
* be set to "" (ie: internal units)
*
* For engines that do not implement UOM conversions, any call to
* this method, where the "units" parameter is NOT an empty string
* should generate a WARNING message.
*
* param: units in: units of measure
*/
virtual void
setDefaultUOM(
const std::string &units);

/**
* Gets the default units of measure. If this has been previously
* specified by the setDefaultUOM method or in the constructor,
* then it will return the string as passed in by that. Otherwise,
* it will return the internal units of the point
*
* returns: units string
*/
virtual std::string
getDefaultUOM() const;

/**
* This method should return true, if it is OK for the user to set
* the value interactively from the GUI. For many engines, setting
* of dynamically changing values will be allowed, however, the
* setting of parametric values or values that define the structure
* of the logic being processed will not be allowed.

Simulation Engine Interface Programmers Guide 50


Architecture Overview

*
* returns: true of interactive value setting is allowed
*/
virtual bool
isValueSettableByUser() const;

/**
* Sets the value of the point.
*
* If the units string is empty (ie: ""), then it is assumed that
* the UOM of the "val" parameter is in the units specified by
* the last call to setDefaultUOM, or that specified during
* construction.
*
* If the units string is specified, then the "val" parameter is
* in the units specified, and should be converted from that
* into internal units.
*
* For clarity, the units here might be strings like "psia" or "kPa",
* and should not by confused with the UOM TYPE, which would be a
* string something like "Pressure"
*
* If the units string is not recognized by the engine UOM converter,
* then a WARNING message should be sent, and the value should be
* set assuming the units string was set to "" (ie: revert to previously
* specified default UOM)
*
* For engines that do not implement UOM conversions, any call to
* this method, where the "units" parameter is NOT an empty string
* should generate a WARNING message.
*
* param: val IN: value to set point to
* param: units IN: units of measure that the value is in
*/
virtual void
setValue(
const double &val,
const std::string &units = "");

/**
* Sets the value of the point.
*
* If the units string is empty (ie: ""), then it is assumed that
* the UOM of the "val" parameter is in the units specified by
* the last call to setDefaultUOM, or that specified during
* construction.
*
* If the units string is specified, then the "val" parameter is
* in the units specified, and should be converted from that
* into internal units.
*
* For clarity, the units here might be strings like "psia" or "kPa",
* and should not by confused with the UOM TYPE, which would be a
* string something like "Pressure"
*
* If the units string is not recognized by the engine UOM converter,
* then a WARNING message should be sent, and the value should be
* set assuming the units string was set to "" (ie: revert to previously
* specified default UOM)
*
* For engines that do not implement UOM conversions, any call to
* this method, where the "units" parameter is NOT an empty string
* should generate a WARNING message.
*
* param: val IN: value to set point to
* param: units IN: units of measure that the value is in
*/
virtual void
setValue(
const float &val,
const std::string &units = "");

Simulation Engine Interface Programmers Guide 51


Architecture Overview

/**
* Sets the value of the point.
*
* param: val IN: value to set point to
*/
virtual void
setValue(
const long &val);

/**
* Sets the value of the point.
*
* param: val IN: value to set point to
*/
virtual void
setValue(
const bool &val);

/**
* Obtains the value of the point, cast as a specific type
* regardless of the internal type of the point.
*
* If the units string is empty (ie: ""), then it is assumed that
* the UOM of the return value will be in the units specified by
* the last call to setDefaultUOM, or that specified during
* construction.
*
* If the units string is specified, then the return value will be
* in the units specified, and should be converted from internal
* units into that.
*
* For clarity, the units here might be strings like "psia" or "kPa",
* and should not by confused with the UOM TYPE, which would be a
* string something like "Pressure"
*
* If the units string is not recognized by the engine UOM converter,
* then a WARNING message should be sent, and the value should be
* returned assuming the units string was set to "" (ie: revert to previously
* specified default UOM)
*
* For engines that do not implement UOM conversions, any call to
* this method, where the "units" parameter is NOT an empty string
* should generate a WARNING message.
*
* param: units IN: units of measure that the value is in
*
* returns: value of point
*/
virtual double
getDoubleValue(
const std::string &units = "") const;

/**
* Obtains the value of the point, cast as a specific type
* regardless of the internal type of the point
*
* If the units string is empty (ie: ""), then it is assumed that
* the UOM of the return value will be in the units specified by
* the last call to setDefaultUOM, or that specified during
* construction.
*
* If the units string is specified, then the return value will be
* in the units specified, and should be converted from internal
* units into that.
*
* For clarity, the units here might be strings like "psia" or "kPa",
* and should not by confused with the UOM TYPE, which would be a
* string something like "Pressure"
*
* If the units string is not recognized by the engine UOM converter,

Simulation Engine Interface Programmers Guide 52


Architecture Overview

* then a WARNING message should be sent, and the value should be


* returned assuming the units string was set to "" (ie: revert to previously
* specified default UOM)
*
* For engines that do not implement UOM conversions, any call to
* this method, where the "units" parameter is NOT an empty string
* should generate a WARNING message.
*
* param: units IN: units of measure that the value is in
*
* returns: value of point
*/
virtual float
getFloatValue(
const std::string &units = "") const;

/**
* Obtains the value of the point, cast as a specific type
* regardless of the internal type of the point
*
* returns: value of point
*/
virtual long
getIntValue() const;

/**
* Obtains the value of the point, cast as a specific type
* regardless of the internal type of the point
*
* returns: value of point
*/
virtual bool
getBoolValue() const;

virtual std::string
getConvFuncName() const;

virtual void
setConvFuncName(const std::string &conv_func_name);

double
getConversionFactor() const;

virtual void
setHiLimit(const float hi_lim)
{
m_hiLim = hi_lim;
}

virtual float
getHiLimit() const
{
return m_hiLim;
}

virtual void
setLowLimit(const float lo_lim)
{
m_loLim = lo_lim;
}

virtual float
getLowLimit() const
{
return m_loLim;
}

virtual void
setMaxScale(const float max_scale)
{

Simulation Engine Interface Programmers Guide 53


Architecture Overview

m_maxScale = max_scale;
}

virtual float
getMaxScale() const
{
return m_maxScale;
}

virtual void
setMinScale(const float min_scale)
{
m_minScale = min_scale;
}

virtual float
getMinScale() const
{
return m_minScale;
}

void
checkLimits(double &val);

void
checkScale(double &val);
};

}; // end namespace Tsu

#endif // Don't add anything after this endif!

YGSimPoint.cpp
//YGSimPoint.cpp

/*
* Copyright(c) 2005 by SIMSCI-ESSCOR Inc. All Rights Reserved.
*
* This software is the confidential and proprietary information of SIMSCI-ESSCOR Inc.
* ("Confidential Information"). You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the
* license agreement you entered into with SIMSCI-ESSCOR.
*
* SIMSCI-ESSCOR MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
* NON-INFRINGEMENT. SIMSCI-ESSCOR SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
* LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR
* ITS DERIVATIVES.
*/

/*
* YGSimPoint.cpp
* 23-Mar-09 Satish Jonnadula
* enhancements
* 05-May-06 A.D. Mills
* new
*
*
*-Revision Control:
*/

#include <Tsunami/pt_SymbolTable.h>
#include <Tsunami/pt_PointInitData.h>

Simulation Engine Interface Programmers Guide 54


Architecture Overview

#include "YGSimPoint.h"
#include "YGSim.h"

#include <iostream>

using namespace std;


using namespace Tsu;

const double INVALID_DOBL_VAL = -999.0;

/*
*==============================================================================
* CONSTRUCTORS
*==============================================================================
*/

YGSimPoint::
YGSimPoint():
point(0)
{
name = "not defined";
// making all limit and scale values zero
// ensures they will not be used unless set
// in the CrossReference file.
m_maxScale = 0.0f;
m_minScale = 0.0f;
m_loLim = 0.0f;
m_hiLim = 0.0f;
cf_dbl = 1.0f;
}

//------------------------------------------------------------------------------

YGSimPoint::
YGSimPoint(const string &pointName):
point(0)
{
name = pointName;

// ensures they will not be used unless set


// in the CrossReference file.
m_maxScale = 0.0f;
m_minScale = 0.0f;
m_loLim = 0.0f;
m_hiLim = 0.0f;

cf_dbl = 1.0f;

// Find the symbol


pt_Symbol* symbol = static_cast<pt_Symbol*>(pt_SymbolTable::find(name));
if(symbol)
{
if(symbol->getSymbolID() == "POINT")
{
point = static_cast<pt_Point*>(symbol);

// set the conversion factor if it exists


switch (point->getType())
{
case pt_PointInitData::FLOAT:
cout << name.c_str() << " : FLOAT = " << endl;
break;
case pt_PointInitData::INTEGER:
cout << name.c_str() << " : INTEGER = " << endl;
break;
case pt_PointInitData::DOUBLE:
cout << name.c_str() << " : DOUBLE = " << endl;
break;
default:
break;

Simulation Engine Interface Programmers Guide 55


Architecture Overview

}
}
}

/*
*==============================================================================
* DESTRUCTORS
*==============================================================================
*/
//------------------------------------------------------------------------------
YGSimPoint::
~YGSimPoint()
{
} // end YGSimPoint::~YGSimPoint()

/*
*==============================================================================
* METHODS
*==============================================================================
*/

std::string YGSimPoint::
getName() const
{
return name;
}

//------------------------------------------------------------------------------

std::string YGSimPoint::
getDescription() const
{
if (point)
{
return point->getDescription();
}
else
{
return "not available";
}
}

//------------------------------------------------------------------------------

bool YGSimPoint::
isValidPoint() const
{
return (point != 0);
}

//------------------------------------------------------------------------------

ISimPoint::PointDataType YGSimPoint::
getDataType() const
{
if(!point)
{
return ISimPoint::UNDEFINED;
}
else
{
switch (point->getType())
{
case pt_PointInitData::FLOAT:
return FLOAT;
case pt_PointInitData::INTEGER:
return INTEGER;

Simulation Engine Interface Programmers Guide 56


Architecture Overview

case pt_PointInitData::DOUBLE:
return DOUBLE;
case pt_PointInitData::BOOLEAN:
return BOOLEAN;
default:
return INTEGER;
}
}

} // getDataType()

//------------------------------------------------------------------------------

std::string YGSimPoint::
getUOMType() const
{
if(!point)
{
return "not available";
}
else
{
return point->getUnitsType();
}
}

//------------------------------------------------------------------------------

void YGSimPoint::
setDefaultUOM(
const std::string &input)
{
std::cout << "setDefaultUOM is not implemented" << std::endl;
}

//------------------------------------------------------------------------------

string YGSimPoint::
getDefaultUOM() const
{
return point->getInternalUnits();
}

//------------------------------------------------------------------------------

bool YGSimPoint::
isValueSettableByUser() const
{
// if the point is a static point, do not allow the value
// to be set
if (point)
{
return (!(point->getSymbolID() == "STATIC") ||
(point->getSymbolID() == "GRAPHIC") );
}
else
{
return false;
}

//------------------------------------------------------------------------------

void YGSimPoint::
setValue(
const double &val,
const std::string &inunits)
{

#ifdef CONVFUNC_IMPLEMENTED

Simulation Engine Interface Programmers Guide 57


Architecture Overview

// Test to check conversion factor, limits, and scaling


// for SeTK pt_Point modifications August 2009.
double tmp_val = val;
tmp_val = val*cf_dbl;
checkLimits(tmp_val);
checkScale(tmp_val);

if(point)
point->setValue(tmp_val);
#else

if(point)
point->setValue(val);
#endif
}

//------------------------------------------------------------------------------

void YGSimPoint::
setValue(
const float &val,
const std::string &inunits)
{

#ifdef CONVFUNC_IMPLEMENTED
// Test to check conversion factor, limits, and scaling
// for SeTK pt_Point modifications August 2009.
double tmp_val = val;
tmp_val = val*cf_dbl;
checkLimits(tmp_val);
checkScale(tmp_val);

if(point)
point->setValue(static_cast<float>(tmp_val));
#else

if(point)
point->setValue(val);
#endif
}

//------------------------------------------------------------------------------

void YGSimPoint::
setValue(
const long &val)
{

#ifdef CONVFUNC_IMPLEMENTED
// Test to check conversion factor, limits, and scaling
// for SeTK pt_Point modifications August 2009.
double tmp_val = val;
tmp_val = val*cf_dbl;
checkLimits(tmp_val);
checkScale(tmp_val);

if(point)
point->setValue(static_cast<long>(tmp_val));
#else

if(point)
point->setValue(val);
#endif
}

//------------------------------------------------------------------------------

void YGSimPoint::
setValue(
const bool &val)
{

Simulation Engine Interface Programmers Guide 58


Architecture Overview

if(point)
point->setValue(val);
}

//------------------------------------------------------------------------------

double YGSimPoint::
getDoubleValue(
const std::string &inunits) const
{
if (point)
return point->getDoubleValue();
else
return INVALID_DOBL_VAL;
}

//------------------------------------------------------------------------------

float YGSimPoint::
getFloatValue(
const std::string &inunits) const
{
if (point)
return point->getFloatValue();
else
return (float)INVALID_DOBL_VAL;
}

//------------------------------------------------------------------------------

long YGSimPoint::
getIntValue() const
{
if (point)
return point->getInt4Value();
else
return (int)INVALID_DOBL_VAL;
}

//------------------------------------------------------------------------------

bool YGSimPoint::
getBoolValue() const
{
if (point)
return (point->getBoolValue());
else
return false;
}

//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
double YGSimPoint::
getConversionFactor() const
{
// default the conversion factor to 1.0 so nothing happens
// if no conversion factor is assigned.
double retval = 1.0;

if(sConvFuncName != "")
{
if(sConvFuncName == "N10")
{
retval = 10.0;
}
else if(sConvFuncName == "N2")
{
retval = 2.0;
}
else if(sConvFuncName == "N_5")

Simulation Engine Interface Programmers Guide 59


Architecture Overview

{ // could do a type check, if type != INTEGER to preven


// integer implentations of this conversion factor
// which would often lead to truncation.
retval = 0.5;
}
}

return retval;
}

//------------------------------------------------------------------------------
std::string YGSimPoint::
getConvFuncName() const
{
return sConvFuncName;
}
//------------------------------------------------------------------------------
void YGSimPoint::
setConvFuncName(const std::string &conv_func_name)
{
sConvFuncName = conv_func_name;

// Once the conversion function is set, the new conversion


// factor must be obtained and the conversion factor member
// variable must be assigned. It is better to do this here
// than run-time.
cf_dbl = getConversionFactor();
cout << name.c_str() << " conversion factor = " << cf_dbl << endl;

}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
void YGSimPoint::
checkLimits(
double &val)
{
if( m_hiLim <= m_loLim )
return;

if( val > m_hiLim )


{
val = m_hiLim;
}
if( val < m_loLim )
{
val = m_loLim;
}

}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
void YGSimPoint::
checkScale(
double &val)
{
if( m_maxScale <= m_minScale )
return;

val = (val-m_minScale)/(m_maxScale-m_minScale)*100.0;
}
//------------------------------------------------------------------------------

Simulation Engine Interface Programmers Guide 60

You might also like