@@ -43,8 +43,8 @@ def extract_state(text, var, controlperiod):
4343 :type text: str
4444 :param var: The variable name.
4545 :type var: str
46- :param controlperiod: The interval duration after which the controller can change the control setting,
47- given in Uppaal Stratego time units.
46+ :param controlperiod: The interval duration after which the controller can change the control
47+ setting, given in Uppaal Stratego time units.
4848 :type controlperiod: int
4949 :return: The value of the variable at the end of *controlperiod*.
5050 :rtype: float
@@ -112,7 +112,8 @@ def array_to_stratego(arr):
112112
113113 :param arr: The array string to convert.
114114 :type arr: str
115- :return: An array string where ``"["`` and ``"]"`` are replaced by ``"{"`` and ``"}"``, respectively.
115+ :return: An array string where ``"["`` and ``"]"`` are replaced by ``"{"`` and ``"}"``,
116+ respectively.
116117 :rtype: str
117118 """
118119 arrstr = str (arr )
@@ -158,15 +159,15 @@ def run_stratego(modelfile, queryfile="", learning_args=None, verifyta_command="
158159 Run command line version of Uppaal Stratego.
159160
160161 :param modelfile: The file name of the model.
161- :type model_file : str
162+ :type modelfile : str
162163 :param queryfile: The file name of the query.
163164 :type queryfile: str
164165 :param learning_args: Dictionary containing the learning parameters and their values. The
165166 learning parameter names should be those used in the command line interface of Uppaal
166167 Stratego. You can also include non-learning command line parameters in this dictionary.
167168 If a non-learning command line parameter does not take any value, include the empty
168169 string ``""`` as value.
169- :type learning_arg : dict
170+ :type learning_args : dict
170171 :param verifyta_command: The command name for running Uppaal Stratego at the user's machine.
171172 :type verifyta_command: str
172173 :return: The output as produced by Uppaal Stratego.
@@ -201,7 +202,7 @@ def successful_result(text):
201202 return result is not None
202203
203204
204- def print_progress_bar (i , max , postText ):
205+ def print_progress_bar (i , max , post_text ):
205206 """
206207 Print a progress bar to sys.stdout.
207208
@@ -214,13 +215,13 @@ def print_progress_bar(i, max, postText):
214215 :type i: int
215216 :param max: The maximum number of steps for process to be completed.
216217 :type max: int
217- :param postText : The text to display after the progress bar.
218- :type postText : str
218+ :param post_text : The text to display after the progress bar.
219+ :type post_text : str
219220 """
220221 n_bar = 20 # Size of progress bar.
221222 j = i / max
222223 sys .stdout .write ('\r ' )
223- sys .stdout .write (f"[{ '=' * int (n_bar * j ):{n_bar }s} ] { int (100 * j )} % { postText } " )
224+ sys .stdout .write (f"[{ '=' * int (n_bar * j ):{n_bar }s} ] { int (100 * j )} % { post_text } " )
224225 sys .stdout .flush ()
225226
226227
@@ -247,7 +248,7 @@ class StrategoController:
247248 def __init__ (self , modeltemplatefile , model_cfg_dict , cleanup = True ):
248249 self .templatefile = modeltemplatefile
249250 self .simulationfile = modeltemplatefile .replace (".xml" , "_sim.xml" )
250- self .cleanup = cleanup # TODO: this variable seems to be not used. Can it be safely removed?
251+ self .cleanup = cleanup # TODO: this variable seems to be not used. Can it be safely removed?
251252 self .states = model_cfg_dict .copy ()
252253 self .tagRule = "//TAG_{}"
253254
@@ -344,7 +345,7 @@ def run(self, queryfile="", learning_args=None, verifyta_command="verifyta"):
344345 Stratego. You can also include non-learning command line parameters in this dictionary.
345346 If a non-learning command line parameter does not take any value, include the empty
346347 string ``""`` as value.
347- :type learning_arg : dict
348+ :type learning_args : dict
348349 :param verifyta_command: The command name for running Uppaal Stratego at the user's machine.
349350 :type verifyta_command: str
350351 :return: The output generated by Uppaal Stratego.
@@ -373,9 +374,9 @@ class MPCsetup:
373374 :param learning_args: Dictionary containing the learning parameters and their values. The
374375 learning parameter names should be those used in the command line interface of Uppaal
375376 Stratego. You can also include non-learning command line parameters in this dictionary. If
376- a non-learning command line parameter does not take any value, include the empty string ``""``
377- as value.
378- :type learning_arg : dict
377+ a non-learning command line parameter does not take any value, include the empty string
378+ ``""`` as value.
379+ :type learning_args : dict
379380 :param verifyta_command: The command name for running Uppaal Stratego at the user's machine.
380381 :type verifyta_command: str
381382 :param external_simulator: Whether an external simulator is used to obtain the true state after
@@ -402,11 +403,83 @@ def __init__(self, modeltemplatefile, output_file_path=None, queryfile="", model
402403 self .learning_args = {} if learning_args is None else learning_args
403404 self .verifyta_command = verifyta_command
404405 self .external_simulator = external_simulator
405- if external_simulator : assert (action_variable in model_cfg_dict .keys ())
406+ if external_simulator :
407+ assert (action_variable in model_cfg_dict .keys ())
406408 self .action_variable = action_variable
407409 self .debug = debug
408410 self .controller = StrategoController (self .modeltemplatefile , self .model_cfg_dict )
409411
412+ def step_without_sim (self , controlperiod , horizon , duration , step , ** kwargs ):
413+ """
414+ Perform a step in the basic MPC scheme without the simulation of the synthesized strategy.
415+
416+ :param controlperiod: The interval duration after which the controller can change the
417+ control setting, given in Uppaal Stratego time units.
418+ :type controlperiod: int
419+ :param horizon: The inval duration for which Uppaal stratego synthesizes a control strategy
420+ each MPC step. Is given in the number of control periods.
421+ :type horizon: int
422+ :param duration: The number of times (steps) the MPC scheme should be performed, given as
423+ the number of control periods. Is only forwarded to
424+ :meth:`~MPCsetup.perform_at_start_iteration`.
425+ :type duration: int
426+ :param step: The current iteration step in the basic MPC loop.
427+ :type step: int
428+ :param kwargs: Any additional parameters are forwarded to
429+ :meth:`~MPCsetup.perform_at_start_iteration`.
430+ :return: The output generated by Uppaal Stratego.
431+ :rtype: str
432+ """
433+ # Perform some customizable preprocessing at each step.
434+ self .perform_at_start_iteration (controlperiod , horizon , duration , step , ** kwargs )
435+
436+ # At each MPC step we want a clean template copy to insert variables.
437+ self .controller .init_simfile ()
438+
439+ # Insert current state into simulation template.
440+ self .controller .insert_state ()
441+
442+ # To debug errors from verifyta one can save intermediate simulation file.
443+ if self .debug :
444+ self .controller .debug_copy (self .modeltemplatefile .replace (".xml" , "_debug.xml" ))
445+
446+ # Create the new query file for the next step.
447+ final = horizon * controlperiod + self .controller .get_state ("t" )
448+ self .create_query_file (horizon , controlperiod , final )
449+
450+ # Run a verifyta query to simulate optimal strategy.
451+ result = self .run_verifyta (horizon , controlperiod , final )
452+
453+ return result
454+
455+ def run_single (self , controlperiod , horizon , ** kwargs ):
456+ """
457+ Run the basic MPC scheme a single step where a single controller strategy is calculated,
458+ where the strategy synthesis looks the horizon ahead, and continues for the duration of the
459+ experiment.
460+
461+ The control period is in Uppaal Stratego time units. Horizon have control period as time
462+ unit.
463+
464+ :param controlperiod: The interval duration after which the controller can change the
465+ control setting, given in Uppaal Stratego time units.
466+ :type controlperiod: int
467+ :param horizon: The inval duration for which Uppaal stratego synthesizes a control strategy
468+ each MPC step. Is given in the number of control periods.
469+ :type horizon: int
470+ :param `**kwargs`: Any additional parameters are forwarded to
471+ :meth:`~MPCsetup.perform_at_start_iteration`.
472+ :return: The control action chosen for the first control period.
473+ """
474+ if not check_tool_existance (self .verifyta_command ):
475+ raise RuntimeError (
476+ "Cannot find the supplied verifyta command: " + self .verifyta_command )
477+
478+ result = self .step_without_sim (controlperiod , horizon , 1 , 0 , ** kwargs )
479+ chosen_action = self .extract_control_action_from_stratego (result )
480+
481+ return chosen_action
482+
410483 def run (self , controlperiod , horizon , duration , ** kwargs ):
411484 """
412485 Run the basic MPC scheme where the controller can changes its strategy once every period,
@@ -416,14 +489,14 @@ def run(self, controlperiod, horizon, duration, **kwargs):
416489 The control period is in Uppaal Stratego time units. Both horizon and duration have control
417490 period as time unit.
418491
419- :param controlperiod: The interval duration after which the controller can change the control setting,
420- given in Uppaal Stratego time units.
492+ :param controlperiod: The interval duration after which the controller can change the
493+ control setting, given in Uppaal Stratego time units.
421494 :type controlperiod: int
422495 :param horizon: The inval duration for which Uppaal stratego synthesizes a control strategy
423496 each MPC step. Is given in the number of control periods.
424497 :type horizon: int
425- :param duration: The number of times (steps) the MPC scheme should be performed, given as the
426- number of control periods.
498+ :param duration: The number of times (steps) the MPC scheme should be performed, given as
499+ the number of control periods.
427500 :type duration: int
428501 :param `**kwargs`: Any additional parameters are forwarded to
429502 :meth:`~MPCsetup.perform_at_start_iteration`.
@@ -433,50 +506,36 @@ def run(self, controlperiod, horizon, duration, **kwargs):
433506 self .print_state ()
434507
435508 if not check_tool_existance (self .verifyta_command ):
436- raise RuntimeError ("Cannot find the supplied verifyta command: " + self .verifyta_command )
509+ raise RuntimeError (
510+ "Cannot find the supplied verifyta command: " + self .verifyta_command )
437511
438512 for step in range (duration ):
439513 # Only print progress to stdout if results are printed to a file.
440- if (self .output_file_path ): print_progress_bar (step , duration , "progress" )
514+ if self .output_file_path :
515+ print_progress_bar (step , duration , "progress" )
441516
442- # Perform some customizable preprocessing at each step.
443- self .perform_at_start_iteration (controlperiod , horizon , duration , step , ** kwargs )
444-
445- # At each MPC step we want a clean template copy to insert variables.
446- self .controller .init_simfile ()
447-
448- # Insert current state into simulation template.
449- self .controller .insert_state ()
450-
451- # To debug errors from verifyta one can save intermediate simulation file.
452- if self .debug :
453- self .controller .debug_copy (self .modeltemplatefile .replace (".xml" , "_debug.xml" ))
454-
455- # Create the new query file for the next step.
456- final = horizon * controlperiod + self .controller .get_state ("t" )
457- self .create_query_file (horizon , controlperiod , final )
458-
459- # Run a verifyta query to simulate optimal strategy.
460- result = self .run_verifyta (horizon , controlperiod , final )
517+ result = self .step_without_sim (controlperiod , horizon , duration , step , ** kwargs )
461518
462519 if self .external_simulator :
463520 # An external simulator is used to generate the new 'true' state.
464- chosen_action = self .extract_control_action_from_Stratego (result )
465- new_state = self .run_external_simulator (chosen_action , controlperiod , step , ** kwargs )
521+ chosen_action = self .extract_control_action_from_stratego (result )
522+ new_state = self .run_external_simulator (chosen_action , controlperiod , step ,
523+ ** kwargs )
466524 self .controller .update_state (new_state )
467525
468526 else :
469527 # Extract the state from Uppaal results. This requires that the query file also
470528 # includes a simulate query (see default query generator).
471- self .extract_states_from_Stratego (result , controlperiod )
529+ self .extract_states_from_stratego (result , controlperiod )
472530
473531 # Print output.
474532 self .print_state ()
475- if (self .output_file_path ): print_progress_bar (duration , duration , "finished" )
533+ if self .output_file_path :
534+ print_progress_bar (duration , duration , "finished" )
476535
477536 def perform_at_start_iteration (self , * args , ** kwargs ):
478537 """
479- Performs some customizable preprocessing steps at the start of each MPC iteration. This
538+ Perform some customizable preprocessing steps at the start of each MPC iteration. This
480539 method can be overritten for specific models.
481540 """
482541 pass
@@ -491,8 +550,8 @@ def create_query_file(self, horizon, period, final):
491550 :param horizon: The inval duration for which Uppaal stratego synthesizes a control strategy
492551 each MPC step. Is given in the number of periods.
493552 :type horizon: int
494- :param period: The interval duration after which the controller can change the control setting,
495- given in Uppaal Stratego time units.
553+ :param period: The interval duration after which the controller can change the control
554+ setting, given in Uppaal Stratego time units.
496555 :type period: int
497556 :param final: The time that should be reached by the synthesized strategy, given in Uppaal
498557 Stratego time units. Most likely this will be current time + *horizon* x *period*.
@@ -513,24 +572,26 @@ def run_verifyta(self, *args, **kwargs):
513572 :meth:`~SafeMPCSetup.run_verifyta` in :class:`~SafeMPCSetup`.
514573 :param `**kwargs`: Is not used in this method; it is used in the overriding method
515574 :meth:`~SafeMPCSetup.run_verifyta` in :class:`~SafeMPCSetup`.
575+ :return: The output generated by Uppaal Stratego.
576+ :rtype: str
516577 """
517578 result = self .controller .run (queryfile = self .queryfile , learning_args = self .learning_args ,
518- verifyta_path = self .verifyta_command )
579+ verifyta_command = self .verifyta_command )
519580
520581 if self .controller .cleanup :
521582 self .controller .remove_simfile ()
522583 return result
523584
524- def extract_states_from_Stratego (self , result , controlperiod ):
585+ def extract_states_from_stratego (self , result , controlperiod ):
525586 """
526587 Extract the new state values from the simulation output of Stratego.
527588
528589 The extracted values are directly saved in the :attr:`~MPCsetup.controller`.
529590
530591 :param result: The output as generated by Uppaal Stratego.
531592 :type result: str
532- :param controlperiod: The interval duration after which the controller can change the control setting,
533- given in Uppaal Stratego time units.
593+ :param controlperiod: The interval duration after which the controller can change the
594+ control setting, given in Uppaal Stratego time units.
534595 :type controlperiod: int
535596 """
536597 new_state = {}
@@ -541,21 +602,22 @@ def extract_states_from_Stratego(self, result, controlperiod):
541602 new_state [var ] = new_value
542603 self .controller .update_state (new_state )
543604
544- def extract_control_action_from_Stratego (self , result ):
605+ def extract_control_action_from_stratego (self , result ):
545606 """
546607 Extract the chosen control action for the first control period from the simulation output
547608 of Stratego.
548609
549610 :param result: The output as generated by Uppaal Stratego.
550611 :type result: str
551612 :return: The control action chosen for the first control period.
613+ :rtype: float
552614 """
553615 float_re = r"[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?"
554616 pattern = self .action_variable + r":\n\[0\]:( \(" + float_re + "," + float_re + r"\))*"
555617 result = re .search (pattern , result )
556618 float_tuples = get_float_tuples (result .group ())
557619 lastvalue = 0.0
558-
620+
559621 # The last tuple at time 0 represents the chosen control action.
560622 for t in float_tuples :
561623 if t [0 ] == 0 :
@@ -588,7 +650,7 @@ def print_state_vars(self):
588650 printed to the standard output.
589651 """
590652 content = self .controller .get_var_names_as_string () + "\n "
591- if ( self .output_file_path is None ) :
653+ if self .output_file_path is None :
592654 sys .stdout .write (content )
593655 else :
594656 with open (self .output_file_path , "w" ) as f :
@@ -600,7 +662,7 @@ def print_state(self):
600662 standard output.
601663 """
602664 content = self .controller .get_state_as_string () + "\n "
603- if ( self .output_file_path is None ) :
665+ if self .output_file_path is None :
604666 sys .stdout .write (content )
605667 else :
606668 with open (self .output_file_path , "a" ) as f :
@@ -628,14 +690,14 @@ def run_verifyta(self, horizon, controlperiod, final, *args, **kwargs):
628690 :param horizon: The inval duration for which Uppaal stratego synthesizes a control strategy
629691 each MPC step. Is given in the number of periods.
630692 :type horizon: int
631- :param period : The interval duration after which the controller can change the control setting,
632- given in Uppaal Stratego time units.
633- :type period : int
693+ :param controlperiod : The interval duration after which the controller can change the
694+ control setting, given in Uppaal Stratego time units.
695+ :type controlperiod : int
634696 :param final: The time that should be reached by the synthesized strategy, given in Uppaal
635697 Stratego time units. Most likely this will be current time + *horizon* x *period*.
636698 :type final: int
637- :param `*args`: Is not used in this method; it is included here to safely override the original
638- method.
699+ :param `*args`: Is not used in this method; it is included here to safely override the
700+ original method.
639701 :param `**kwargs`: Is not used in this method; it is included here to safely override the
640702 original method.
641703 """
@@ -659,8 +721,8 @@ def create_alternative_query_file(self, horizon, period, final):
659721 :param horizon: The inval duration for which Uppaal stratego synthesizes a control strategy
660722 each MPC step. Is given in the number of periods.
661723 :type horizon: int
662- :param period: The interval duration after which the controller can change the control setting,
663- given in Uppaal Stratego time units.
724+ :param period: The interval duration after which the controller can change the control
725+ setting, given in Uppaal Stratego time units.
664726 :type period: int
665727 :param final: The time that should be reached by the synthesized strategy, given in Uppaal
666728 Stratego time units. Most likely this will be current time + *horizon* x *period*.
0 commit comments