Table of Contents

Overview

Making a module can be done through the following steps:

  1. Create a configuration class [optional]
    • Copy and paste the template
    • Add some variables
  2. Create a memory class [optional]
    • Copy and paste the template
    • Add some variables
  3. Create the module class
    • Copy and paste the template
    • Add ports (signal, slot, in, out)
  4. Write a SkyAI module declaration
    • Just write a single line macro

You can easily modify any parts later; take it easy!

Include

The header skyai/skyai.h is needed:

#include <skyai/skyai.h>

Configuration Class

  1. Copy and paste the template
    //===========================================================================================
    class TXxConfigurations
    //===========================================================================================
    {
    public:
    
      TReal   TestC;
    
      TXxConfigurations (var_space::TVariableMap &mmap) :
          TestC     (0.0l)
        {
          Register(mmap);
        }
      void Register (var_space::TVariableMap &mmap)
        {
          #define ADD(x_member)  AddToVarMap(mmap, #x_member, x_member)
          ADD( TestC );
          #undef ADD
        }
    };
    //-------------------------------------------------------------------------------------------
  2. Add some variables
    • In the above template, a variable TestC is added. Remove it and add your configuration variables.
    • You need to write each variable three times:
      1. Declaration (e.g. TReal TestC;)
      2. Initialization at the constructor [optional] (e.g. TestC(0.0l))
      3. Register (e.g. ADD(TestC);)
Note
If you want to add std::vector etc., include lora/variable_space_impl.h.
#include <lora/variable_space_impl.h>

Memory Class

  1. Copy and paste the template
    //===========================================================================================
    class TXxMemory
    //===========================================================================================
    {
    public:
    
      TReal   TestM;
    
      TXxMemory (var_space::TVariableMap &mmap) :
          TestM     (0.0l)
        {
          Register(mmap);
        }
      void Register (var_space::TVariableMap &mmap)
        {
          #define ADD(x_member)  AddToVarMap(mmap, #x_member, x_member)
          ADD( TestM );
          #undef ADD
        }
    };
    //-------------------------------------------------------------------------------------------
  2. Add some variables
    • Same as the configuration class

Module class

  1. Copy and paste the template
    Simple template:
    //===========================================================================================
    //!\brief XX module
    class MXxModule
        : public MParentModule
    //===========================================================================================
    {
    public:
      typedef MParentModule       TParent;
      typedef MXxModule           TThis;
      SKYAI_MODULE_NAMES(MXxModule)
    
      MXxModule (const std::string &v_instance_name)
        : TParent        (v_instance_name),
          conf_          (TParent::param_box_config_map()),
          mem_           (TParent::param_box_memory_map())
        {
        }
    
    protected:
    
      TXxConfigurations  conf_;
      TXxMemory          mem_;
    
    };  // end of MXxModule
    //-------------------------------------------------------------------------------------------
    Verbose template:
    //===========================================================================================
    //!\brief XX module
    class MXxModule
        : public MParentModule
    //===========================================================================================
    {
    public:
      typedef MParentModule       TParent;  // optional
      typedef MXxModule           TThis;    // optional
      SKYAI_MODULE_NAMES(MXxModule)  // mandatory
    
      MXxModule (const std::string &v_instance_name)
        : TParent        (v_instance_name),   // mandatory
          conf_          (TParent::param_box_config_map()),
          mem_           (TParent::param_box_memory_map()),
          slot_slot1     (*this),   // optional
          signal_signal1 (*this),   // optional
          out_out1       (*this),   // optional
          in_in1         (*this)    // optional
        {
          add_slot_port (slot_slot1);         // optional
          add_signal_port (signal_signal1);   // optional
          add_out_port (out_out1);            // optional
          add_in_port (in_in1);               // optional
        }
    
    protected:
    
      TXxConfigurations  conf_;   // optional
      TXxMemory          mem_;    // optional
    
      MAKE_SLOT_PORT(slot_slot1, TOutType, (const TInType &x), (x), TThis);        // optional
    
      MAKE_SIGNAL_PORT(signal_signal1, const TOutType& (const TInType &), TThis);  // optional
    
      MAKE_OUT_PORT(out_out1, const TOutType&, (const TInType &x), (x), TThis);    // optional
    
      MAKE_IN_PORT(in_in1, const TOutType& (const TInType &), TThis);              // optional
    
      virtual TOutType slot_slot1_exec (const TInType &x)                          // optional
        {
          ...
        }
    
      virtual const TOutType& out_out1_get (const TInType &x) const                // optional
        {
          ...
        }
    };  // end of MXxModule
    //-------------------------------------------------------------------------------------------
  2. If you do not use the configuration box or the memory box, you can remove conf_ or mem_ (of course, remove the declaration). Otherwise, replace TXxConfigurations and/or TXxMemory by your own class name.
  3. Replace every MXxModule by the name of your module.
  4. Replace every MParentModule by the parent module (usually, use TModuleInterface).
  5. Add ports
    • Adding a slot port:
      1. Declare at the protected section:
        MAKE_SLOT_PORT(slot_slot1, TOutType, (const TInType &x), (x), TThis);
        // change slot1 to the name of the slot port
        // change TOutType to the return type of the callback function
        // change const TInType &x to the parameter list of the callback function
        // change x to the argument list of the callback function
        // e.g.  MAKE_SLOT_PORT(slot_action, void, (const TReal &x,const TReal &y), (x,y), TThis);
      2. Write the initialization at the constructor:
        MXxModule (const std::string &v_instance_name)
          : ...
            slot_slot1 (*this),  // like this
            ...
      3. Use the add_slot_port function at the constructor:
        add_slot_port (slot_slot1);
      4. Implement the callback function:
        // change slot1 to the name of the slot port
        virtual TOutType slot_slot1_exec (const TInType &x)
        {
          ...
        }
    • Adding a signal port:
      1. Declare at the protected section:
        MAKE_SIGNAL_PORT(signal_signal1, const TOutType& (const TInType &), TThis);
        // change signal1 to the name of the signal port
        // change TOutType to the return type of the callback function
        // change const TInType & to the parameter list of the callback function
        // e.g.  MAKE_SIGNAL_PORT(signal_action, void (const TReal &x,const TReal &y), TThis)
      2. Write the initialization at the constructor:
        MXxModule (const std::string &v_instance_name)
          : ...
            signal_signal1 (*this),  // like this
            ...
      3. Use the add_signal_port function at the constructor:
        add_signal_port (signal_signal1);
    • Adding an out port:
      1. Declare at the protected section:
        MAKE_OUT_PORT(out_out1, const TOutType&, (const TInType &x), (x), TThis);
        // change out1 to the name of the out port
        // change TOutType to the return type of the function
        // change const TInType &x to the parameter list of the function
        // change x to the argument list of the function
        // e.g.  MAKE_OUT_PORT(out_state, const TRealVector&, (void), (), TThis);
      2. Write the initialization at the constructor:
        MXxModule (const std::string &v_instance_name)
          : ...
            out_out1 (*this),  // like this
            ...
      3. Use the add_out_port function at the constructor:
        add_out_port (out_out1);
      4. Implement the function:
        // change out1 to the name of the out port
        virtual const TOutType& out_out1_get (const TInType &x) const
        {
          ...
        }
    • Adding an in port:
      1. Declare at the protected section:
        MAKE_IN_PORT(in_in1, const TOutType& (const TInType &), TThis);
        // change in1 to the name of the in port
        // change TOutType to the return type of the function
        // change const TInType &x to the parameter list of the function
        // e.g.  MAKE_IN_PORT(in_state, const TRealVector& (void), TThis);
      2. Write the initialization at the constructor:
        MXxModule (const std::string &v_instance_name)
          : ...
            in_in1 (*this),  // like this
            ...
      3. Use the add_in_port function at the constructor:
        add_in_port (in_in1);

SkyAI Module Declaration

  1. Just write a single line macro at the source code (do not write in a header)
    SKYAI_ADD_MODULE(MXxModule)

Implementing Functions

In the member functions of a module including the callbacks of slot ports and the functions of out ports, the following elements are important:

Emit Signal

In order to emit a signal at a signal port, write as follows:

signal_signal1.ExecAll(x,y);

The member function ExecAll emits a signal to every slot ports connected to the signal port. The return values are ignored. If no slot port is connected, nothing happens.

Call Function

In order to use a function connected to an in port, write as follows:

TRealVector y= in_in1.GetFirst(x);

Here, the member function GetFirst execute the function of the first out port connected to the in port with an argument x, whose return is stored in y. Recall that in default, only one out port can be connected to an in port.

If no out port is connected, GetFirst causes an error. In order to avoid the error, you need to check the size of connections by:

in_in1.ConnectionSize()

this returns the number of connected out ports.

We suggest to wrap the GetFirst by using a macro as follows:

MAKE_IN_PORT(in_state, const TRealVector& (void), TThis);
MAKE_IN_PORT(in_func, const TReal& (const TReal &x), TThis);

#define GET_FROM_IN_PORT(x_in,x_return_type,x_arg_list,x_param_list)   \
  x_return_type  get_##x_in x_arg_list const                                                  \
    {                                                                                         \
      if (in_##x_in.ConnectionSize()==0)                                                      \
        {LERROR("in "<<ModuleUniqueCode()<<", in_" #x_in " must be connected."); lexit(df);}  \
      return in_##x_in.GetFirst x_param_list;                                                 \
    }

GET_FROM_IN_PORT(state, const TRealVector&, (void), ())
GET_FROM_IN_PORT(func, const TReal&, (const TReal &x), (x))

#undef GET_FROM_IN_PORT

Then, we can use get_state and get_func like a normal function; e.g.

TRealVector x= get_state();
TReal y= get_func(1.2);

The macro GET_FROM_IN_PORT is generic, so you can copy and paste it in your code as is. Do not forget to un-define it (i.e. #undef GET_FROM_IN_PORT).

 

 



Front page   Edit Freeze Diff Backup Upload Copy Rename Reload   New List of pages Search Recent changes   Help   RSS of recent changes
Last-modified: 2012-07-18 (Wed) 03:15:22 (4298d)