MCA Logo
MCA Online Reference Documentation
Main Index

1.2. Modules with variable IOs or variable parameters

Sometimes modules contain variable IOs that depend on constructor parameters. Especially very common modules as they are realized in our general subdirectory are of that kind. In such cases the IOs can not be named with enums and their descriptions cannot be written in a static constant array of the class. There is a need for creating them within the constructor automatically.

The following example works like the ReplyValue module from the general subdirectory. It gets values from controller input and copies them to sensor output. The dimension of the controller input and sensor output is specified by a constructor parameter:

Example 1-9. variable IO definition and initialization

 mReplyValues::mReplyValues(tParent *parent,int dimension,bool fixit)
  :tModule(parent)
 {
   int i;
   tDescription descriptions[dimension+1];
   tDescription buffer[20];
   for (i=0;i < dimension;i++)
   {
       snprintf(buffer,20,"value %i",i);
       descriptions[i]=strdup(buffer);
   }
   descriptions[dimension]=cDATA_VECTOR_END_MARKER;
   InitControllerInput(dimension,description);
   InitSensorOutput(dimension,description);
   if (fixit) FixIt();
 }

In this example first the necessary descriptions are created. They are stored in a temporary array. The last array element must contain cDATA_VECTOR_END_MARKER, because this value is used in order to check the end of IO descriptions. A very usual fault is that the programmer makes a mistake while creating descriptions. The Init... functions therefore checks specified dimension and end of description array. A message is written to standard output in case of such error.

Of course these descriptions need to be deleted within the destructor of the module. As the descriptions are joined between controller intput and sensor output we need to delete only one. If the descriptions were set individually they have to be deleted seperatly, of course.

Example 1-10. destructor deletes variable IOs

 mReplyValues::~mReplyValues()
 {
   int i;
   for (i=0;i<ControllerInputDimension();i++)
   {
       delete ControllerInputDescription(i);
   }
 }

Often, parameters depend on the dimension of the IOs. Just think of a module that multiplies its inputs with constant factors and then writes them to the outputs. If each value needs an individual multiplication factor and the user wants to change these factors during execution, he has to define them as parameters. This is where he potentially uses variable parameters. The following example shows the constructor of such a multiply module:

Example 1-11. Defining variable parameters

 mMultiply::mMultiply(tParent *parent,int dimension,float min,float max,bool fixit)
  :tModule(parent)
 {
   int i;
   // variable IOs
   tDescription descriptions[dimension+1];
   tDescription buffer[20];
   for (i=0;i < dimension;i++)
   {
       snprintf(buffer,20,"value %i",i);
       descriptions[i]=strdup(buffer);
   }
   descriptions[dimension]=cDATA_VECTOR_END_MARKER;
   InitControllerInput(dimension,description);
   InitControllerOutput(dimension,description);

   // Now define the parameters
   tParameterBase* parameters[dimension]
   for (i=0;i < dimension;i++)
   {
       snprintf(buffer,20,"factor %i",i);
       parameters[i]=new tParameterFloat(strdup(buffer),min,max,0);
   }
   if (fixit) FixIt();
 }

As default parameter values always 0 is specified. We recommend to set the used parameter values in most cases from outside the class, using the SetParameters(number_of_parameters,...) function. In this example it may be used like:

Example 1-12. Setting parameter values from outside

  mMultiply *multiply=new mMultiply(this,3,0,5.7,true);
  multiply->SetParameters(3,
                          0,1.9,
			  1,3.7,
			  2,4.6);

In most cases, the InitParameter and InitIO functions are called using constant descriptions. Then copying the values is not necessary. This is the reason why the copying is not done within these function. The user has to do it before calling them, as demonstrated in the above examples.