Skip to content

Commit

Permalink
Merge pull request #990 from DLR-RM/develop
Browse files Browse the repository at this point in the history
Merge develop into master
  • Loading branch information
JohannesErnst authored Jan 17, 2025
2 parents 59987cd + 2658575 commit fc0afae
Show file tree
Hide file tree
Showing 592 changed files with 11,533 additions and 13,760 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.1.4
current_version = 2.2.0

[bumpversion:glob:**/pyproject.toml]
search = version = "{current_version}" # Handled by bump2version
Expand Down
21 changes: 21 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@ Changelog
Information about :ref:`RAFCON` changes in each release will be published here. More
details can be found in the `GIT commit log <https://github.com/DLR-RM/RAFCON/commits/master>`__.

2.2.0
""""""
- Features:
- Now using flat storage for state machines (removed first layer in folder structure)
- Automatic conversion to new structure when re-saving existing state machines
- Only storing meta_data for root_state if available
- Added custom color for library states
- Prevent saving a state machine inside another via GUI
- Added locking current view feature in execution history GUI
- Added open library from execution history feature in GUI

- Bug fixes:
- Fixed bug in "run only selected state"
- Fixed bug when destroying gtk controllers
- Fixed bug in automatic dataport generation for GUI
- Fixed bug in automaticly setting dataport for invalid data flows

- Miscellaneous:
- Added cheat-sheet to documentation and GitHub
- Updated package versions to support python>3.10

2.1.4
""""""
- Bug fixes:
Expand Down
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
cff-version: "1.2.0"
message: "If you use this software, please cite it using these metadata."
title: RAFCON
version: 2.1.4 # Handled by bump2version
date-released: 2024-08-12
version: 2.2.0 # Handled by bump2version
date-released: 2025-01-17
license: EPL-1.0
doi: "10.5281/zenodo.1493058"
authors:
Expand Down
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ RAFCON
* Documentation: Hosted on `Read the Docs <http://rafcon.readthedocs.io/en/latest/>`_
* Homepage: `DLR-RM.github.io/RAFCON/ <https://dlr-rm.github.io/RAFCON/>`_
* License: `EPL <https://github.com/DLR-RM/RAFCON/blob/master/LICENSE>`_
* Cheatsheet: `Download Cheatsheet <doc/_static/rafcon_cheatsheet.pdf>`_

Develop your robotic tasks using an intuitive graphical user interface
----------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.1.4
2.2.0
Binary file added doc/_static/rafcon_cheatsheet.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/rafcon_cheatsheet.pdf
Binary file not shown.
1,249 changes: 1,249 additions & 0 deletions doc/_static/rafcon_cheatsheet.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ Have a look at our `website <https://dlr-rm.github.io/RAFCON/getting_started.htm
development/development.rst
api/rafcon.rst

There is also a cheatsheet, high-resolution can be downloaded from the github repository:

.. figure:: _static/rafcon_cheatsheet.jpg
:width: 90 %
:alt: RAFCON Cheatsheet
:align: center

Indices and tables
==================
Expand Down
1,218 changes: 738 additions & 480 deletions pdm.lock

Large diffs are not rendered by default.

33 changes: 16 additions & 17 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "rafcon"
version = "2.1.4" # Handled by bump2version
version = "2.2.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 All @@ -27,36 +27,35 @@ classifiers = [
"Topic :: Utilities",
]
dependencies = [
"PyGObject==3.42.0",
"astroid>=2.0.0,<2.9.0",
"PyGObject>=3.42.0",
"wrapt>=1.14.0",
"astroid>=3.0.0",
"gaphas>=2.1.0,<2.2.0",
"jsonconversion>=1.0.0",
"jsonconversion>=1.0.2",
"psutil>=5.0.0,<6.0.0",
"pycairo>=1.11.0,<1.21.0",
"pylint>=2.11.0,<2.12.0",
"pycairo>=1.11.0",
"pylint>=2.11.0",
"simplegeneric>=0.5.0,<1.0.0",
"yaml_configuration>=0.2.5,<0.3.0",
"numpy==1.21.6; python_version >= \"3.7\" and python_full_version < \"3.7.1\"",
"numpy<2.0.0,>=1.22.4; python_version >= \"3.8\" and python_version < \"4.0\"",
"numpy>=2.0.0",
"pandas==1.1.5; python_full_version < \"3.7.1\"",
"pandas<2.0.0,>=1.2.0; python_full_version >= \"3.7.1\"",
]
license = {text = "EPL"}
requires-python = ">=3.7"
requires-python = ">=3.9"

[project.urls]
Homepage = "https://github.com/DLR-RM/RAFCON"

[tool.pdm.dev-dependencies]
dev = [
"attrs==22.2.0",
"graphviz==0.18.2",
"matplotlib==2.1.1",
"monitoring==0.9.12",
"objgraph==3.5.0",
"profiling==0.1.3",
"pyuserinput==0.1.11",
"pytest-faulthandler~=1.6.0",
"attrs>=22.2.0",
"graphviz>=0.18.2",
"matplotlib>=3.9.0",
"monitoring>=0.9.12",
"objgraph>=3.5.0",
"pyuserinput>=0.1.11",
"pytest-faulthandler>=1.6.0",
"pytest-mock>=1.9.0,<3",
"pytest-timeout",
"pytest>=6.0.0,<7.0.0",
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.1.4" # Handled by bump2version
version = "2.2.0" # Handled by bump2version
description = "Develop your robotic tasks with hierarchical state machines"
keywords = [
"state machine",
Expand Down
2 changes: 2 additions & 0 deletions source/rafcon/core/execution/execution_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def __init__(self, state_machine_manager):
self.state_counter_lock = Lock()
self.new_execution_command_handled = True
self.stop_state_machine_after_finishing_step = False
self.running_only_selected_state = False

@Observable.observed
def pause(self):
Expand Down Expand Up @@ -418,6 +419,7 @@ def _wait_if_required(self, container_state, next_child_state_to_execute, woke_u
# "run-(only)-selected-state" feature, now we just add one FORWARD_OVER step
if self._status.execution_mode is StateMachineExecutionStatus.RUN_ONLY_SELECTED_STATE:
self.stop_state_machine_after_finishing_step = True
self.running_only_selected_state = True
self._status.execution_mode = StateMachineExecutionStatus.FORWARD_OVER
self.run_to_states.remove(state_path)
# add the container state to self.run_to_states
Expand Down
2 changes: 1 addition & 1 deletion source/rafcon/core/execution/execution_history_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def __init__(self, state_machine, run_id):
self.os_environment = dict(os.environ)

def __str__(self):
return "StateMachineStartItem with name %s (time: %s)" % (self.sm_dict['root_state_storage_id'], self.timestamp)
return "StateMachineStartItem (time: {})".format(self.timestamp)

def to_dict(self, pickled=True):
record = HistoryItem.to_dict(self, pickled=pickled)
Expand Down
3 changes: 2 additions & 1 deletion source/rafcon/core/state_machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,14 @@ def update_hash(self, obj_hash):

@staticmethod
def state_machine_to_dict(state_machine):
from rafcon.core.states.execution_state import ExecutionState
from rafcon.core.storage.storage import get_storage_id_for_state
dict_representation = {
'root_state_storage_id': get_storage_id_for_state(state_machine.root_state),
'state_machine_version': state_machine.version,
'used_rafcon_version': rafcon.__version__,
'creation_time': state_machine.creation_time,
}

return dict_representation

def start(self):
Expand Down
9 changes: 8 additions & 1 deletion source/rafcon/core/states/hierarchy_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,10 @@ def run(self):
self.state_execution_status = StateExecutionStatus.EXECUTE_CHILDREN
self.backward_execution = False # TODO: why is this line needed?
if self.preempted:
if self.last_transition and self.last_transition.from_outcome == -2:
if singleton.state_machine_execution_engine.running_only_selected_state:
singleton.state_machine_execution_engine.running_only_selected_state = False
break
elif self.last_transition and self.last_transition.from_outcome == -2:
logger.debug("Execute preemption handling for '{0}'".format(self.child_state))
else:
break
Expand All @@ -122,6 +125,10 @@ def run(self):

self._execute_current_child()

# Stop after the desired state was executed if run only selected state
if execution_mode == StateMachineExecutionStatus.RUN_ONLY_SELECTED_STATE:
break

if self.backward_execution:
break_loop = self._handle_backward_execution_after_child_execution()
if break_loop:
Expand Down
7 changes: 4 additions & 3 deletions source/rafcon/core/states/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,10 +603,11 @@ def get_storage_path(self, appendix=None):
else:
return self.parent.get_storage_path(state_identifier + PATH_SEPARATOR + appendix)
else:
# the root state is located in the root state machine folder
if appendix is None:
return state_identifier
return ""
else:
return state_identifier + PATH_SEPARATOR + appendix
return appendix

def get_state_machine(self):
"""Get a reference of the state_machine the state belongs to
Expand Down Expand Up @@ -650,7 +651,7 @@ def get_temp_file_system_path(self):
The path is not fully secure because the all state ids are not globally unique.
"""
return os.path.join(RAFCON_TEMP_PATH_STORAGE, str(self.get_path()))
return os.path.join(RAFCON_TEMP_PATH_STORAGE, self.get_storage_path())

@lock_state_machine
@Observable.observed
Expand Down
13 changes: 10 additions & 3 deletions source/rafcon/core/storage/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

#: File names for various purposes
FILE_NAME_META_DATA = 'meta_data.json'
FILE_NAME_META_DATA_SM = 'sm_meta_data.json'
FILE_NAME_CORE_DATA = 'core_data.json'
FILE_NAME_CORE_DATA_OLD = 'meta.json'
SCRIPT_FILE = 'script.py'
Expand Down Expand Up @@ -250,7 +251,7 @@ def save_state_recursively(state, base_path, parent_path, as_copy=False):
from rafcon.core.states.execution_state import ExecutionState
from rafcon.core.states.container_state import ContainerState

state_path = os.path.join(parent_path, get_storage_id_for_state(state))
state_path = state.get_storage_path()
state_path_full = os.path.join(base_path, state_path)
if not os.path.exists(state_path_full):
os.makedirs(state_path_full)
Expand Down Expand Up @@ -311,13 +312,19 @@ def load_state_machine_from_path(base_path, state_machine_id=None):
logger.warning(note_about_possible_incompatibility)

state_machine = StateMachine.from_dict(state_machine_dict, state_machine_id)
if "root_state_storage_id" not in state_machine_dict:
if "root_state_storage_id" not in state_machine_dict and "root_state_id" not in state_machine_dict:
root_state_storage_id = ""
elif "root_state_storage_id" not in state_machine_dict:
root_state_storage_id = state_machine_dict['root_state_id']
state_machine.supports_saving_state_names = False
else:
root_state_storage_id = state_machine_dict['root_state_storage_id']

root_state_path = os.path.join(base_path, root_state_storage_id)
if root_state_storage_id: # deprecated, new state machines (>=2.2.0) have the root state located in the base path
root_state_path = os.path.join(base_path, root_state_storage_id)
else:
root_state_path = base_path

state_machine.file_system_path = base_path
dirty_states = []
state_machine.root_state = load_state_recursively(parent=state_machine, state_path=root_state_path,
Expand Down
Loading

0 comments on commit fc0afae

Please sign in to comment.