diff --git a/doc/rtd/content/99_appendices/appendix2/sub/core/mlpro_bf/layer3_application_support/images/MLPro-BF-Control_class_diagram.drawio b/doc/rtd/content/99_appendices/appendix2/sub/core/mlpro_bf/layer3_application_support/images/MLPro-BF-Control_class_diagram.drawio
index 68274d0ab..cf359d944 100644
--- a/doc/rtd/content/99_appendices/appendix2/sub/core/mlpro_bf/layer3_application_support/images/MLPro-BF-Control_class_diagram.drawio
+++ b/doc/rtd/content/99_appendices/appendix2/sub/core/mlpro_bf/layer3_application_support/images/MLPro-BF-Control_class_diagram.drawio
@@ -1 +1 @@
-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
\ No newline at end of file
+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
\ No newline at end of file
diff --git a/doc/rtd/content/99_appendices/appendix2/sub/core/mlpro_bf/layer3_application_support/images/MLPro-BF-Control_class_diagram.drawio.png b/doc/rtd/content/99_appendices/appendix2/sub/core/mlpro_bf/layer3_application_support/images/MLPro-BF-Control_class_diagram.drawio.png
index 83b092cd4..82373cc38 100644
Binary files a/doc/rtd/content/99_appendices/appendix2/sub/core/mlpro_bf/layer3_application_support/images/MLPro-BF-Control_class_diagram.drawio.png and b/doc/rtd/content/99_appendices/appendix2/sub/core/mlpro_bf/layer3_application_support/images/MLPro-BF-Control_class_diagram.drawio.png differ
diff --git a/src/mlpro/bf/control/__init__.py b/src/mlpro/bf/control/__init__.py
index 97d3cbcfc..98bcfd07a 100644
--- a/src/mlpro/bf/control/__init__.py
+++ b/src/mlpro/bf/control/__init__.py
@@ -1 +1 @@
-from mlpro.bf.control.basics import SetPoint, CTRLError, Controller, MultiController, ControlSystem
+from mlpro.bf.control.basics import SetPoint, ControlError, Controller, MultiController, ControlSystem, ControlCycle, ControlScenario
diff --git a/src/mlpro/bf/control/basics.py b/src/mlpro/bf/control/basics.py
index 53f362bb8..97d0c8086 100644
--- a/src/mlpro/bf/control/basics.py
+++ b/src/mlpro/bf/control/basics.py
@@ -8,18 +8,21 @@
## -- 2024-08-31 0.0.0 DA Creation
## -- 2024-09-04 0.1.0 DA Updates on class design
## -- 2024-09-07 0.2.0 DA Classes CTRLError, Controller: design updates
+## -- 2024-09-11 0.3.0 DA - class CTRLError renamed ControlError
+## -- - new class ControlPanel
## -------------------------------------------------------------------------------------------------
"""
-Ver. 0.2.0 (2024-09-07)
+Ver. 0.3.0 (2024-09-11)
This module provides basic classes around the topic closed-loop control.
"""
-from mlpro.bf.various import Log
+from mlpro.bf.math.basics import Element
+from mlpro.bf.various import Log, TStampType
from mlpro.bf.mt import Task, Workflow
-from mlpro.bf.math import Function
+from mlpro.bf.math import Element, Function
from mlpro.bf.streams import InstDict, Instance, StreamTask, StreamWorkflow, StreamShared, StreamScenario
from mlpro.bf.systems import ActionElement, Action, System
from mlpro.bf.various import Log
@@ -33,6 +36,18 @@ class SetPoint (Instance):
"""
"""
+## -------------------------------------------------------------------------------------------------
+ def __init__( self,
+ p_setpoint_data: Element,
+ p_tstamp: TStampType = None,
+ **p_kwargs ):
+
+ super().__init__( p_feature_data = p_setpoint_data,
+ p_label_data = None,
+ p_tstamp = p_tstamp,
+ **p_kwargs )
+
+
## -------------------------------------------------------------------------------------------------
def _get_values(self):
return self.get_feature_data().get_values()
@@ -52,7 +67,7 @@ def _set_values(self, p_values):
## -------------------------------------------------------------------------------------------------
## -------------------------------------------------------------------------------------------------
-class CTRLError (Instance):
+class ControlError (Instance):
"""
"""
@@ -96,7 +111,7 @@ def _run(self, p_inst: InstDict):
## -------------------------------------------------------------------------------------------------
- def compute_action(self, p_ctrl_error: CTRLError) -> Action:
+ def compute_action(self, p_ctrl_error: ControlError) -> Action:
"""
Custom method to compute and return an action based on an incoming control error.
@@ -116,7 +131,7 @@ def compute_action(self, p_ctrl_error: CTRLError) -> Action:
## -------------------------------------------------------------------------------------------------
def _compute_action( self,
- p_ctrl_error : CTRLError,
+ p_ctrl_error : ControlError,
p_action_element : ActionElement,
p_ctrl_id : int = 0,
p_ae_id : int = 0 ):
@@ -198,7 +213,7 @@ def set_parameter(self, **p_param):
## -------------------------------------------------------------------------------------------------
- def compute_action(self, p_ctrl_error: CTRLError) -> Action:
+ def compute_action(self, p_ctrl_error: ControlError) -> Action:
raise NotImplementedError
@@ -254,11 +269,98 @@ def __init__( self,
## -------------------------------------------------------------------------------------------------
## -------------------------------------------------------------------------------------------------
-class ControlShared (StreamShared):
+class ControlPanel (Log):
+ """
+ Enables external control of a closed-loop control.
+ """
+
+ C_TYPE = 'Control Panel'
+ C_NAME = '????'
+
+## -------------------------------------------------------------------------------------------------
+ def start(self):
+ """
+ (Re-)starts a closed-loop control.
+ """
+
+ self.log(Log.C_LOG_TYPE_S, 'Control process started')
+ self._start()
+
+
+## -------------------------------------------------------------------------------------------------
+ def _start(self):
+ """
+ Custom method to (re-)start a closed-loop control.
+ """
+
+ raise NotImplementedError
+
+
+## -------------------------------------------------------------------------------------------------
+ def stop(self):
+ """
+ Ends a closed-loop control.
+ """
+
+ self.log(Log.C_LOG_TYPE_S, 'Control process stopped')
+ self._stop()
+
+
+## -------------------------------------------------------------------------------------------------
+ def _stop(self):
+ """
+ Custom method to end a closed-loop control.
+ """
+
+ raise NotImplementedError
+
+
+## -------------------------------------------------------------------------------------------------
+ def change_setpoint( self, p_setpoint : SetPoint ):
+ """
+ Changes the setpoint values of a closed-loop control.
+
+ Parameters
+ ----------
+ p_setpoint: SetPoint
+ New setpoint values.
+ """
+
+ self.log(Log.C_LOG_TYPE_S, 'Setpoint values changed to', p_setpoint.values)
+ self._change_setpoint( p_setpoint = p_setpoint )
+
+
+## -------------------------------------------------------------------------------------------------
+ def _change_setpoint( self, p_setpoint : SetPoint ):
+ """
+ Custom method to change setpoint values.
+ """
+
+ raise NotImplementedError
+
+
+
+
+
+## -------------------------------------------------------------------------------------------------
+## -------------------------------------------------------------------------------------------------
+class ControlShared (StreamShared, ControlPanel):
+
+## -------------------------------------------------------------------------------------------------
+ def _start(self):
+
+ raise NotImplementedError
+
## -------------------------------------------------------------------------------------------------
- def change_setpoint( p_setpoint : SetPoint ):
+ def _stop(self):
+
+ raise NotImplementedError
+
+## -------------------------------------------------------------------------------------------------
+ def _change_setpoint(self, p_setpoint: SetPoint):
+
raise NotImplementedError
@@ -303,6 +405,27 @@ class ControlScenario ( StreamScenario ):
"""
## -------------------------------------------------------------------------------------------------
- def get_control_board(self) -> ControlShared:
+ def __init__( self,
+ p_mode,
+ p_cycle_limit=0,
+ p_visualize:bool=False,
+ p_logging=Log.C_LOG_ALL ):
+
+ self._control_cycle : ControlCycle = None
+
+ super.__init__( p_mode,
+ p_cycle_limit=p_cycle_limit,
+ p_auto_setup=True,
+ p_visualize=p_visualize,
+ p_logging=p_logging )
+
- raise NotImplementedError
+## -------------------------------------------------------------------------------------------------
+ def get_control_panel(self) -> ControlPanel:
+ """
+ Returns
+ -------
+ panel : ControlPanel
+ Object that enables the external control of a closed-loop control process.
+ """
+ return self._control_cycle.get_so()
diff --git a/test/howtos/bf/control/.gitkeep b/test/howtos/bf/control/.gitkeep
deleted file mode 100644
index e69de29bb..000000000
diff --git a/test/howtos/bf/control/howto_bf_control_001_basic_control_loop.py b/test/howtos/bf/control/howto_bf_control_001_basic_control_loop.py
new file mode 100644
index 000000000..e6487b7ef
--- /dev/null
+++ b/test/howtos/bf/control/howto_bf_control_001_basic_control_loop.py
@@ -0,0 +1,91 @@
+## -------------------------------------------------------------------------------------------------
+## -- Project : MLPro - The integrative middleware framework for standardized machine learning
+## -- Package : mlpro.bf.control
+## -- Module : howto_bf_control_001_basic_control_loop.py
+## -------------------------------------------------------------------------------------------------
+## -- History :
+## -- yyyy-mm-dd Ver. Auth. Description
+## -- 2024-09-11 0.0.0 DA Creation
+## -------------------------------------------------------------------------------------------------
+
+"""
+Ver. 0.0.0 (2024-09-11)
+
+This module demonstrates ...
+
+You will learn:
+
+1) How to ...
+
+2) How to ...
+
+3) How to ...
+
+"""
+
+from time import sleep
+
+from mlpro.bf.control import Controller, ControlSystem, ControlCycle, ControlScenario
+
+
+
+
+## -------------------------------------------------------------------------------------------------
+## -------------------------------------------------------------------------------------------------
+class MyController (Controller):
+ pass
+
+
+
+## -------------------------------------------------------------------------------------------------
+## -------------------------------------------------------------------------------------------------
+class MyControlSystem (ControlSystem):
+ pass
+
+
+
+## -------------------------------------------------------------------------------------------------
+## -------------------------------------------------------------------------------------------------
+class MyControlScenario (ControlScenario):
+ pass
+
+
+
+
+# 1 Preparation of demo/unit test mode
+if __name__ == '__main__':
+ # 1.1 Parameters for demo mode
+ cycle_limit = 200
+ logging = Log.C_LOG_ALL
+ visualize = True
+
+else:
+ # 1.2 Parameters for internal unit test
+ cycle_limit = 2
+ logging = Log.C_LOG_NOTHING
+ visualize = False
+
+
+
+# 2 Init control scenario
+myscenario = MyControlScenario()
+panel = myscenario.get_control_panel()
+
+
+
+# 3 Start the control process asynchronously
+myscenario.run()
+panel.start()
+
+
+
+# 4 Change setpoint value in a loop
+for i in range(10):
+ sleep(1)
+ panel.change_setpoint()
+
+
+
+# 5 Stop control process
+panel.stop()
+