Skip to content

3.3 Slaves

Christian Kater edited this page Feb 14, 2019 · 1 revision

Include

The class DcpManagerSlave implements the maangement of the DCP logic. To use this class include the following:

#include <dcp/logic/DcpManagerSlave.hpp>

Instantiation

To instantiate a DcpManagerSlave you need to pass a slave description object and a driver object. The slave description contains all relevant characteristics of the slave. The driver puts the DCP PDUs to the transport protocol and listen for incoming PDUs. See slave description or driver to find more information about these.

DcpManagerSlave manager(slaveDescription, driver);

Binding Callbacks and Listeners

The DcpManagerSlave provides std::function objects as callback for certain mechanisms in the DCP protocol. The std::bind function can be used to bind member functions to the DCP manager:

#include <dcp/logic/DcpManagerSlave.hpp>

class DcpSlave {

public:
    
    DcpSlave(){
        [...]
        manager->setRunningStepCallback<SYNC>(
                std::bind(&DcpSlave::doStep, this, std::placeholders::_1));
        [...]
    }

	void doStep(uint64_t steps){
	    //Perform calculation
		[...]
	}
	
	[...]
};

SYNC vs ASYNC

By setting a callback or listener you have to decide if the the framework should block (SYNC) or proceed asynchroniously (ASYNC) after calling the bound function. A asynchronious Callback (denoted by the suffix Callback) needs to call the corresponding *Finished function of the DCPManagerSlave has to inidicate that the coprresponding action finished. In all other cases (SYNC or suffix Listener) the called function just need to exit.

Logging

To enable a slave to listen to log messages (either defined by DCPLib or custom) a LogListener has to be registered. A very simple log listener is the class OstreamLog. This takes the logs and writes their string representation to a given ostream, like std::out or a std::ofstream to write the logs into a file. To replace the placeholders of the log messages with the real values, setGenerateLogString has to be set to true. If only log listener, which make no use of the string representation, this can be set to false. Then the placeholders will not be replaced and calculation time can be saved.

#include <dcp/logic/DcpManagerSlave.hpp>
#include <dcp/log/OstreamLog.hpp>

class Slave {
private:
    DcpManagerSlave manager;
    OstreamLog stdLog;
    [...]
public:
    Slave() : stdLog(std::cout) {
         [...]
         manager.addLogListener(
             std::bind(&OstreamLog::logOstream, stdLog, std::placeholders::_1));
         manager.setGenerateLogString(true);
    }
    [...]
};

To define custom log messages a LogTemplate object has to be created.

const LogTemplate SIM_LOG = LogTemplate(
            LOG_ID, LOG_CATEGORY, DcpLogLevel::LVL_INFORMATION,
            "Time = %float64, vr = %uint64, value = %float64",
            {DcpDataType::float64, DcpDataType::uint64, DcpDataType::float64});

Together with this LogTemplate object a log can be made by calling the Log method of the DcpManagerSlave object. The LogTemplate object, followed by the values according to the defined placeholders in the log message has to be passed to the method.

manager->Log(SIM_LOG, simulationTime, x_vr, *x);

If in the slave description canProvideLogOnRequest or canProvideLogOnNotification is set to true, this log call is also handled by DCP mechanism, depending on how the master has configured the logging of the slave.