Skip to content

Commit

Permalink
Merge pull request #879 from DLR-RM/develop
Browse files Browse the repository at this point in the history
Merge develop with version 2.1.0
  • Loading branch information
JohannesErnst authored Feb 29, 2024
2 parents 22d8b3b + 26fd3bd commit a456b41
Show file tree
Hide file tree
Showing 154 changed files with 1,054 additions and 1,049 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 2.0.0
current_version = 2.1.0

[bumpversion:glob:**/pyproject.toml]
search = version = "{current_version}" # Handled by bump2version
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,6 @@ requirements.txt

# do not ignore bump2version config
!.bumpversion.cfg

# Vscode
.vscode/
58 changes: 37 additions & 21 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@ details can be found in the `GIT commit log <https://github.com/DLR-RM/RAFCON/co
Future Release
"""""""

2.1.0
""""""
- Features:
- Added option to disable popups in the config file
- Display warning when saving new state machine (and overwriting) in already existing folder

- Bug fixes:
- Fixing segmentation fault when changing state type in gui via state editor
- Fixing decider node is not preempted in concurrency state
- Fixed warnings and bugs in unit tests
- More minor bugfixes

- Miscellaneous:
- Checked dependencies and deprecations for libraries
- Updated shebang versions to python3
- Removed some warnings resulting from old python conventions

2.0.0
""""""
- Features:
Expand All @@ -17,21 +34,21 @@ Future Release
1.3.0
"""""""
- Features:
Add possibility to only release rafcon-core
- Add possibility to only release rafcon-core

1.2.1
"""""""
- Features:
Add __main__.py
- Add __main__.py

1.2.0
"""""""
- Features:
Support python 3.10
- Support python 3.10

1.1.1
"""""""
- Bug Fixes:
- Bug Fixes:
- Fix a few GUI bugs

1.1.0
Expand All @@ -56,25 +73,24 @@ Future Release

1.0.0
"""""""
- Features:
- Not supporting Python 2 anymore
- Run this state
- Only run this state
- Add singleton pattern
- Add new hooks before and after running each state
- Add new memory profiling test to assert the memory leak during running sequential & concurrency state machines
- Update gaphas to 2.1.2
- Update libsass to the latest version of dart sass
- Replace gtkmvc3 with two separated mvc and observer patterns
- Run this state

- Features:
- Not supporting Python 2 anymore
- Run this state
- Only run this state
- Add singleton pattern
- Add new hooks before and after running each state
- Add new memory profiling test to assert the memory leak during running sequential & concurrency state machines
- Update gaphas to 2.1.2
- Update libsass to the latest version of dart sass
- Replace gtkmvc3 with two separated mvc and observer patterns
- Run this state

- Bug Fixes:
- Fix GUI freezing during keeping undo/redo shortcuts
- Bug Fixes:
- Fix GUI freezing during keeping undo/redo shortcuts

- Miscellaneous:
- Remove last update field to improve versioning control
- Remove a big amount of the dead codes and comments
- Miscellaneous:
- Remove last update field to improve versioning control
- Remove a big amount of the dead codes and comments


0.15.4
Expand Down
2 changes: 1 addition & 1 deletion CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
cff-version: "1.0.3"
message: "If you use this software, please cite it using these metadata."
title: RAFCON
version: 2.0.0 # Handled by bump2version
version: 2.1.0 # Handled by bump2version
date-released: 2019-07-29
license: EPL-1.0
doi: "10.5281/zenodo.1493058"
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.0.0
2.1.0
5 changes: 2 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "rafcon"
version = "2.0.0" # Handled by bump2version
version = "2.1.0" # Handled by bump2version
description = "Develop your robotic tasks with hierarchical state machines using an intuitive graphical user interface"
keywords = ["state machine", "robotic", "FSM", "development", "GUI", "visual programming"]
readme = "README.rst"
Expand Down Expand Up @@ -55,8 +55,7 @@ dev = [
"monitoring==0.9.12",
"objgraph==3.5.0",
"profiling==0.1.3",
"pykeyboard==0.1.2",
"pymouse==1.0",
"pyuserinput==0.1.11",
"pytest-faulthandler~=1.6.0",
"pytest-mock>=1.9.0,<3",
"pytest-timeout",
Expand Down
2 changes: 1 addition & 1 deletion source/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ dependencies = [
"jsonconversion<1.0.0,>=0.2.13",
]
name = "rafcon-core"
version = "2.0.0" # Handled by bump2version
version = "2.1.0" # Handled by bump2version
description = "Develop your robotic tasks with hierarchical state machines"
keywords = [
"state machine",
Expand Down
10 changes: 6 additions & 4 deletions source/rafcon/core/script.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"""

import os
import imp
import importlib
import _imp
import yaml
from rafcon.design_patterns.observer.observable import Observable

Expand Down Expand Up @@ -126,20 +127,21 @@ def compile_module(self):
:raises exceptions.IOError: if the compilation of the script module failed
"""
try:
imp.acquire_lock()
_imp.acquire_lock()

code = compile(self.script, '%s (%s)' % (self.filename, self._script_id), 'exec')
# load module
module_name = os.path.splitext(self.filename)[0] + str(self._script_id)
tmp_module = imp.new_module(module_name)
module_spec = importlib.machinery.ModuleSpec(module_name, None)
tmp_module = importlib.util.module_from_spec(module_spec)
exec(code, tmp_module.__dict__)
# return the module
self.compiled_module = tmp_module
except Exception as e:
self.compiled_module = None
raise
finally:
imp.release_lock()
_imp.release_lock()

@property
def parent(self):
Expand Down
2 changes: 1 addition & 1 deletion source/rafcon/core/start.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3

# Copyright (C) 2015-2018 DLR
#
Expand Down
40 changes: 21 additions & 19 deletions source/rafcon/core/states/barrier_concurrency_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,25 +129,27 @@ def run(self):
return self.finalize_backward_execution()
else:
self.backward_execution = False
#######################################################
# execute decider state
#######################################################
decider_state_error = self.run_decider_state(decider_state, child_errors, final_outcomes_dict)
#######################################################
# handle no transition
#######################################################
transition = self.get_transition_for_outcome(decider_state, decider_state.final_outcome)
if transition is None:
# final outcome is set here
transition = self.handle_no_transition(decider_state)
# if the transition is still None, then the child_state was preempted or aborted, in this case return
decider_state.state_execution_status = StateExecutionStatus.INACTIVE
if transition is None:
self.output_data["error"] = RuntimeError("state aborted")
else:
if decider_state_error:
self.output_data["error"] = decider_state_error
self.final_outcome = self.outcomes[transition.to_outcome]
# Run only if it wasn't preempted by a higher level concurrency state
if not self.preempted:
#######################################################
# execute decider state
#######################################################
decider_state_error = self.run_decider_state(decider_state, child_errors, final_outcomes_dict)
#######################################################
# handle no transition
#######################################################
transition = self.get_transition_for_outcome(decider_state, decider_state.final_outcome)
if transition is None:
# final outcome is set here
transition = self.handle_no_transition(decider_state)
# if the transition is still None, then the child_state was preempted or aborted, in this case return
decider_state.state_execution_status = StateExecutionStatus.INACTIVE
if transition is None:
self.output_data["error"] = RuntimeError("state aborted")
else:
if decider_state_error:
self.output_data["error"] = decider_state_error
self.final_outcome = self.outcomes[transition.to_outcome]
return self.finalize_concurrency_state(self.final_outcome)

except Exception as e:
Expand Down
12 changes: 6 additions & 6 deletions source/rafcon/core/storage/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import copy
import yaml
import warnings
from distutils.version import StrictVersion
from packaging.version import Version

import rafcon

Expand Down Expand Up @@ -298,15 +298,15 @@ def load_state_machine_from_path(base_path, state_machine_id=None):

state_machine_dict = storage_utils.load_objects_from_json(state_machine_file_path)
if 'used_rafcon_version' in state_machine_dict:
previously_used_rafcon_version = StrictVersion(state_machine_dict['used_rafcon_version']).version
active_rafcon_version = StrictVersion(rafcon.__version__).version
previously_used_rafcon_version = Version(state_machine_dict['used_rafcon_version'])
active_rafcon_version = Version(rafcon.__version__)
rafcon_older_than_sm_version = "You are trying to load a state machine that was stored with an newer " \
"version of RAFCON ({0}) than the one you are using ({1}).".format(
state_machine_dict['used_rafcon_version'], rafcon.__version__)
note_about_possible_incompatibility = "The state machine will be loaded with no guarantee of success."
if active_rafcon_version[0] < previously_used_rafcon_version[0] or \
(active_rafcon_version[0] == previously_used_rafcon_version[0] and
active_rafcon_version[1] < previously_used_rafcon_version[1]):
if active_rafcon_version.major < previously_used_rafcon_version.major or \
(active_rafcon_version.major == previously_used_rafcon_version.major and
active_rafcon_version.minor < previously_used_rafcon_version.minor):
logger.warning(rafcon_older_than_sm_version)
logger.warning(note_about_possible_incompatibility)

Expand Down
2 changes: 1 addition & 1 deletion source/rafcon/gui/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def configure_colors(self):
lines = f.readlines()

for line in lines:
match = re.match("\s*@define-color (\w*) (#[\w]{3,6})", line)
match = re.match("\\s*@define-color (\\w*) (#[\\w]{3,6})", line)
if match:
# css colors are mapped to capital-case color names
# these colors can then be used in the colors definition file for the gaphas colors (e.g., colors.json)
Expand Down
8 changes: 4 additions & 4 deletions source/rafcon/gui/controllers/menu_bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ def on_start_activate(self, widget, data=None):
def on_start_from_selected_state_activate(self, widget, data=None):
logger.debug("Run from selected state ...")
selection = gui_singletons.state_machine_manager_model.get_selected_state_machine_model().selection
if len(selection.states) is not 1:
if len(selection.states) != 1:
logger.error("Exactly one state must be selected!")
else:
self.state_machine_execution_engine.start(self.model.selected_state_machine_id,
Expand All @@ -688,7 +688,7 @@ def on_start_from_selected_state_activate(self, widget, data=None):
def on_run_selected_state_activate(self, widget, data=None):
logger.debug("Run selected state ...")
selection = gui_singletons.state_machine_manager_model.get_selected_state_machine_model().selection
if len(selection.states) is not 1:
if len(selection.states) != 1:
logger.error("Exactly one state must be selected!")
else:
self.state_machine_execution_engine.run_selected_state(selection.get_selected_state().state.get_path(),
Expand All @@ -697,7 +697,7 @@ def on_run_selected_state_activate(self, widget, data=None):
def on_run_only_selected_state_activate(self, widget, data=None):
logger.debug("Only run selected state ...")
selection = gui_singletons.state_machine_manager_model.get_selected_state_machine_model().selection
if len(selection.states) is not 1:
if len(selection.states) != 1:
logger.error("Exactly one state must be selected!")
else:
self.state_machine_execution_engine.run_only_selected_state(
Expand Down Expand Up @@ -730,7 +730,7 @@ def on_run_to_selected_state_activate(self, widget, data=None):
logger.debug("Run to selected state ...")

selection = gui_singletons.state_machine_manager_model.get_selected_state_machine_model().selection
if len(selection.states) is not 1:
if len(selection.states) != 1:
logger.error("Exactly one state must be selected!")
else:
self.state_machine_execution_engine.run_to_selected_state(selection.get_selected_state().state.get_path(),
Expand Down
20 changes: 11 additions & 9 deletions source/rafcon/gui/controllers/notification_bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

from rafcon.gui.controllers.utils.extended_controller import ExtendedController
from rafcon.utils import log, log_helpers
from rafcon.gui.config import global_gui_config
logger = log.get_logger(__name__)


Expand All @@ -37,15 +38,16 @@ def destroy(self):
super(NotificationBarController, self).destroy()

def print_message(self, message, log_level):
if self.view is None:
return
if not self._handle_log_level(log_level):
return
message_text = ": ".join(message.split(": ")[2:]) # remove time, log level and source
now = time.time() * 1000
if self.last_notification_timestamp is None or self.last_notification_timestamp + 100 < now:
self.view.show_notification(message_text, log_level)
self.last_notification_timestamp = now
if global_gui_config.get_config_value('LOGGING_SHOW_POPUP', True):
if self.view is None:
return
if not self._handle_log_level(log_level):
return
message_text = ": ".join(message.split(": ")[2:]) # remove time, log level and source
now = time.time() * 1000
if self.last_notification_timestamp is None or self.last_notification_timestamp + 100 < now:
self.view.show_notification(message_text, log_level)
self.last_notification_timestamp = now

def _handle_log_level(self, log_level):
minimum_low_level = self.model.config.get_config_value("NOTIFICATIONS_MINIMUM_LOG_LEVEL", 30)
Expand Down
11 changes: 6 additions & 5 deletions source/rafcon/gui/controllers/preferences_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -592,12 +592,13 @@ def _config_chooser_dialog(self, title_text, description):
:param title_text: Title text
:param description: Description
"""
dialog = Gtk.Dialog(title_text, self.view["preferences_window"],
flags=0, buttons=
(Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT,
Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT))
dialog = Gtk.Dialog(title=title_text, transient_for=self.view["preferences_window"], flags=0)
dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT, Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT)
label = Gtk.Label(label=description)
label.set_padding(xpad=10, ypad=10)
label.set_margin_start(10)
label.set_margin_end(10)
label.set_margin_top(10)
label.set_margin_bottom(10)
dialog.vbox.pack_start(label, True, True, 0)
label.show()
self._gui_checkbox = Gtk.CheckButton(label="GUI Config")
Expand Down
8 changes: 8 additions & 0 deletions source/rafcon/gui/controllers/state_editor/overview.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,12 @@ def change_name(self, new_name):
self.view['entry_name'].set_text(self.model.state.name)

def change_type(self, widget, model=None, info=None):
# Define global variable for usage in extended_controller
# (hacky soloution for a GTK segmentation fault error)
global on_change
on_change = True

# Get the desired type and change it
state_class_name = widget.get_active_text()
for state_class in self.allowed_state_classes:
if state_class.__name__ == state_class_name:
Expand All @@ -192,6 +198,8 @@ def change_type(self, widget, model=None, info=None):

gui_helper_state_machine.change_state_type_with_error_handling_and_logger_messages(self.model, state_class)

del on_change

def check_for_enter(self, entry, event):
key_name = Gdk.keyval_name(event.keyval)
if key_name in ["Return", "KP_Enter"]:
Expand Down
Loading

0 comments on commit a456b41

Please sign in to comment.