====== Subsystems ======
A subsystem is a block containing several other blocks. It is often advantageous to pack several blocks which belong together into a subsystem. Consider the example of an observer. An observer might be part of your control system and it will itself contain a multitude of blocks.
[{{ :eeros_architecture:control_system:subsystems.png?400 |//An observer packed into a subsystem//}}]
===== Define a Subsystem =====
In order to create a subsystem you can extend the available block ''Subio'' or you have to create a custom made block (see [[eeros_architecture:control_system:custom_blocks|]]).
==== Using Subio Block ====
Define the number of inputs and outputs of your sysbsystem together with the necessary inner blocks in your custom class. In the constructor you create the inner blocks and connect them among each other. The run-method must call all the run-methods of the inner blocks. Set the outputs of your subsystem to suitable outputs of your inner blocks.
class Observer : public eeros::control::Subio<1,1,Vector2,Vector2> {
public:
Observer() : gain1({5.0, 2.2}) ... {
sum1.getIn(1).connect(sum2.getOut());
sum1.negateInput(1);
setOut(sum1.getOut());
...
}
virtual void run() {
sum2.run();
sum1.run();
...
gain1.run();
}
private:
eeros::control::Gain gain1;
eeros::control::Sum<2, Vector2> sum1, sum2;
...
};
The whole subsystem is now a block for itself. It can be added to a control system (or an outer subsystem). Its run-method will be called automatically as soon as it is added to a time domain which itself must be started by the executor.
For an example study the tutorial at [[getting_started:tutorials:subsystem|]] .
==== Using Custom Block ====
Define the necessary inner blocks in your custom class. In the constructor you create the inner blocks and connect them among each other. The run-method must call all the run-methods of the inner blocks. Write getter methods for all the inputs into and outputs out of the new subsystem
class Observer : public eeros::control::Blockio<0,0> {
public:
Observer() : gain1({5.0, 2.2}) ... {
sum1.getIn(1).connect(sum2.getOut());
sum1.negateInput(1);
...
}
virtual void run() {
sum2.run();
sum1.run();
...
gain1.run();
}
virtual eeros::control::Input& getSum1In() {return sum1.getIn();}
virtual eeros::control::Input& getSum2In() {return sum2.getIn();}
virtual eeros::control::Output& getGain1Out() {return gain1.getOut();}
private:
eeros::control::Gain gain1;
eeros::control::Sum<2, Vector2> sum1, sum2;
...
};
The whole subsystem is now a block for itself. It can be added to a control system (or an outer subsystem). Its run-method will be called automatically as soon as it is added to a time domain which itself must be started by the executor.
===== Using Input Signals =====
Consider the following example
[{{ :eeros_architecture:control_system:subsystems2.png?300 |//An observer packed into a subsystem//}}]
This subsystem has an input which is used by several blocks within the subsystem. In order to be able to connect these blocks to the input, you have to define the input as being of type ''InputSub'' instead of simply ''Input''.
InputSub<> in;
The getter function for this input will be
virtual Input<>& getIn() {return in;}
See Tutorial for a example of using a subsystem.