Skip to content

Commit d7ab05f

Browse files
author
David Conner
committed
Merge branch 'ros2-devel' into jazzy
2 parents e642815 + 92abd9c commit d7ab05f

87 files changed

Lines changed: 2120 additions & 689 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/flexbe_ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ jobs:
1010
matrix:
1111
ros: [jazzy]
1212
include:
13+
# - os: ubuntu-24.04
14+
# ros: rolling
15+
# python: python3
16+
# ci_branch: ros2-devel
1317
- os: ubuntu-24.04
1418
ros: jazzy
1519
python: python3

README.md

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
FlexBE is a high-level behavior engine coordinating the capabilities of a robot in order to solve complex tasks.
44
Behaviors are modeled as hierarchical state machines (HFSM) where states correspond to active actions
55
and transitions describe the reaction to outcomes.
6-
Main advantage over similar approaches is the good operator integration and an
7-
intuitive user interface.
6+
7+
The main advantage of FlexBE over similar approaches is the good operator integration and an intuitive user interface.
88
Besides executing behaviors in full autonomy, the operator can restrict execution of certain transitions or trigger them manually.
99
Furthermore, FlexBE supports modifying the whole structure of a behavior during its execution without restarting it.
1010
The user interface features a runtime control interface as well as a graphical editor for state machines.
@@ -17,48 +17,78 @@ You may also want to check out the quick start tutorial demonstrations at [FlexB
1717

1818
Jazzy ![ROS Build Farm](https://build.ros2.org/job/Jdev__flexbe_behavior_engine__ubuntu_noble_amd64/badge/icon)
1919

20+
> Note: This version 4+ breaks compatibility with the FlexBE App. You must use the FlexBE WebUI [flexbe_webui](https://github.com/FlexBE/flexbe_webui.git) now.
21+
22+
2023
## Installation
2124

22-
For released versions, FlexBE is available as ` apt install` package `ros-<DISTRO>-flexbe-*`
25+
For released versions, FlexBE is available as `apt install` package `ros-<DISTRO>-flexbe-*`
2326

2427
To build from source, execute the following commands to install FlexBE for ROS 2 systems:
2528

26-
cd "ros2_ws"/src
27-
git clone https://github.com/FlexBE/flexbe_behavior_engine.git
29+
`cd "ros2_ws"/src`
30+
31+
`git clone https://github.com/FlexBE/flexbe_behavior_engine.git`
2832

2933
Next, navigate to the "ros2_ws" top-level directory and build FlexBE:
3034

31-
colcon build
35+
`colcon build`
36+
37+
## Creating new FlexBE Behavior packages
38+
39+
To begin, create your own repository for behavior development in the `${WORKSPACE_ROOT}/src` folder:
40+
41+
`ros2 run flexbe_widget create_repo [your_project_name] <meta_package_name> <--non-interactive>`
42+
43+
This will clone a project template (requires internet access) that contains examples and proper package definitions,
44+
and create the ROS 2 package structure and three subfolders.
3245

33-
Furthermore, create your own repository for behavior development (contains examples):
46+
For example, running
3447

35-
ros2 run flexbe_widget create_repo [your_project_name]
48+
`ros2 run flexbe_widget create_repo my_project my_flexbe_project`
3649

37-
This version of the flexbe_behavior_engine requires version 4.0+ of the FlexBE user interface.
50+
from the `${WORKSPACE_ROOT}/src` folder will create:
51+
- `${WORKSPACE_ROOT}/src/my_flexbe_project`
52+
- `${WORKSPACE_ROOT}/src/my_flexbe_project/my_flexbe_project` - the ROS meta package
53+
- `${WORKSPACE_ROOT}/src/my_flexbe_project/my_project_flexbe_behaviors`
54+
- `${WORKSPACE_ROOT}/src/my_flexbe_project/my_project_flexbe_states`
3855

39-
It is recommended to install the FlexBE user interface by following one of these steps:
40-
* https://github.com/FlexBE/flexbe_app.git - classic FlexBE App (iron or ros2-devel branches)
41-
* https://github.com/FlexBE/flexbe_webui.git - new Python-based webserver version
56+
These are intended to contain your custom FlexBE state implementations and HFSM-based behaviors.
57+
58+
This release of the FlexBE Behavior Engine requires version 4.1+ of the FlexBE UI.
59+
This breaks compatibility with the older FlexBE App and now requires use of the FlexBE WebUI tool.
60+
61+
It is recommended to install the FlexBE WebUI user interface:
62+
63+
[FlexBE WebUI](https://github.com/FlexBE/flexbe_webui.git) - Python-based webserver version
4264

4365

4466
## Usage
4567

4668
Use the following launch file for running the onboard engine:
4769

48-
ros2 launch flexbe_onboard behavior_onboard.launch.py
70+
`ros2 launch flexbe_onboard behavior_onboard.launch.py`
4971

5072
Use the following launch file for running the operator control station (requires the FlexBE App or WebUI):
5173

52-
ros2 launch flexbe_webui flexbe_ocs.launch.py
74+
`ros2 launch flexbe_webui flexbe_ocs.launch.py`
75+
76+
During testing is is recommended to start the base nodes and the UI client separately:
5377

54-
> Note: replace `flexbe_webui` with `flexbe_app` to run the "classic" UI (after `ros2 run flexbe_app nwjs_install`).
78+
`ros2 launch flexbe_webui flexbe_ocs.launch.py headless:=True`
5579

56-
Use the following launch file to run both of the above, e.g., for testing on a single computer:
80+
`ros2 run flexbe_webui webui_client`
5781

58-
ros2 launch flexbe_webui flexbe_full.launch.py
82+
See the `flexbe_webui` README for more details.
83+
84+
85+
Use the following launch file to run the entire FlexBE system, both onboard and OCS, e.g., for testing on a single computer:
86+
87+
`ros2 launch flexbe_webui flexbe_full.launch.py`
5988

6089
For running tests use:
61-
`colcon test --ctest-args --packages-select <flexbe_package>`
90+
91+
`colcon test --ctest-args --packages-select <flexbe_package>`
6292

6393
## Next Steps
6494

@@ -94,4 +124,4 @@ Let us know if you know a paper which should be added to the list.
94124
## Maintainers
95125

96126
- Philipp Schillinger ([@pschillinger](https://github.com/pschillinger), [Contact](http://philserver.bplaced.net/fbe/contact.php))
97-
- David Conner ([@dcconner](https://github.com/dcconner))
127+
- David Conner ([@dcconner](https://github.com/dcconner)) [Contact](https://flexbe.readthedocs.io/en/latest/contactinfo.html)

flexbe_behavior_engine/CHANGELOG.rst

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,19 @@
22
Changelog for package flexbe_behavior_engine
33
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44

5-
3.0.6 (2024-08-05)
5+
4.0.1 (2024-09-26)
6+
------------------
7+
8+
4.0.0 (2024-08-24)
69
------------------
10+
* Version 4.0.0 release using state_id for communication
11+
* this breaks API with flexbe_app and requires version 4.1.0+ of the FlexBE WebUI API
712

13+
3.0.7 (2024-08-24)
14+
------------------
15+
16+
3.0.6 (2024-08-05)
17+
------------------
818

919
3.0.5 (2024-07-02)
1020
------------------

flexbe_behavior_engine/package.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0"?>
22
<package format="2">
33
<name>flexbe_behavior_engine</name>
4-
<version>3.0.6</version>
4+
<version>4.0.1</version>
55
<description>
66
A meta-package to aggregate all the FlexBE packages
77
</description>

flexbe_core/CHANGELOG.rst

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,33 @@
22
Changelog for package flexbe_core
33
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44

5+
4.0.1 (2024-09-26)
6+
------------------
7+
* codespell clean up
8+
* exception inside concurrency will get re-thrown to preempt behavior
9+
* report all states in deep_states including containers and finished states
10+
* re-request outcome on sync request
11+
* notify skipped for containers
12+
* remove some stray spam;
13+
* use jazzy test and increase some loop timings in tests due to intermittent test failure
14+
15+
4.0.0 (2024-08-24)
16+
------------------
17+
* Version 4.0.0 release using state_id for communication
18+
* this breaks API with flexbe_app and requires version 4.1.0+ of the FlexBE WebUI API
19+
* use state id consistently to avoid long path strings
20+
* modify preempt and published outcome to improve sync
21+
* add flexbe_outcome_listener node for simple monitoring
22+
23+
3.0.7 (2024-08-24)
24+
------------------
25+
* reduce default wait durations on proxy start ups; reduce start up spam
26+
* clarify state map message
27+
* allow controllable OSM and concurrency outputs; improve sync handling; unhandled state exception stops behavior
28+
* modify clear action handling; retain action result status; reduce startup spam
29+
* add initialize_flexbe_core for common initialization
30+
* updates to ConcurrencyContainer and StateMachine to handle sync and forced outcomes
31+
532
3.0.6 (2024-08-05)
633
------------------
734
* update cancel for action client
@@ -319,7 +346,7 @@ Changelog for package flexbe_core
319346
* [flexbe_core] Added priority container
320347
* [flexbe_core] Added some more documentation
321348
* [flexbe_core] Fixed initialization of input userdata in inner statemachines
322-
* [flexbe_core] Correctly preempt auxilliary control flows in concurrency container
349+
* [flexbe_core] Correctly preempt auxiliary control flows in concurrency container
323350
* [flexbe_core] Fixed a bug with concurrent execution:
324351
State machines inside state machine inside concurrency containers still blocked during execution.
325352
* [flexbe_core] Slightly reworked monitoring state

flexbe_core/flexbe_core/__init__.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,34 @@
4343
from .logger import Logger # noqa: F401
4444
from .state_logger import StateLogger # noqa: F401
4545

46-
MIN_UI_VERSION = '4.0.0' # Minimum FlexBE App or UI version required to interact with this version of flexbe_core
46+
MIN_UI_VERSION = '4.1.0' # Minimum FlexBE UI version required to interact with this version of flexbe_core
4747

4848
# pylint: disable=R0903
4949

5050

51-
def set_node(node):
51+
def initialize_flexbe_core(node):
5252
"""Set node information and initialize classes."""
5353
from .proxy import initialize_proxies # pylint: disable=C0415
5454
from .core import RosState, RosStateMachine # pylint: disable=C0415
5555
Logger.initialize(node)
56+
Logger.localinfo('Initialize ROS enabled classes ...')
5657
StateLogger.initialize_ros(node)
5758
initialize_proxies(node)
5859
RosState.initialize_ros(node)
5960
RosStateMachine.initialize_ros(node)
6061

6162

63+
def set_node(node):
64+
"""Set node information and initialize classes."""
65+
import warnings
66+
warnings.warn(
67+
'set_node function is deprecated and will be removed in a future version. Use initialize_flexbe_core(node) instead!',
68+
DeprecationWarning,
69+
stacklevel=2
70+
)
71+
initialize_flexbe_core(node)
72+
73+
6274
class Autonomy:
6375
"""Provides constants for the available required Autonomy Levels."""
6476

@@ -93,14 +105,15 @@ class Autonomy:
93105

94106

95107
__all__ = [
108+
'Autonomy'
96109
'Behavior',
97110
'BehaviorLibrary',
98111
'ConcurrencyContainer',
99112
'EventState',
113+
'Logger',
100114
'OperatableStateMachine',
101115
'PriorityContainer',
102-
'Logger',
103116
'StateLogger',
104-
'set_node',
105-
'Autonomy'
117+
'initialize_flexbe_core',
118+
'set_node', # To be deprecated in future release
106119
]

flexbe_core/flexbe_core/behavior.py

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131

3232
"""This defines the superclass for all implemented behaviors."""
33-
from flexbe_core.core import LockableStateMachine, OperatableStateMachine, PreemptableState
33+
from flexbe_core.core import LockableStateMachine, OperatableStateMachine, PreemptableState, StateMap
3434
from flexbe_core.logger import Logger
3535

3636
from flexbe_msgs.msg import BehaviorSync
@@ -44,14 +44,15 @@ def __init__(self):
4444
self._state_machine = None
4545
self.name = 'unnamed behavior'
4646
self.beh_id = 0 # Behavior id checksum assigned by processing the file contents
47+
self._state_map = None
4748

4849
self.contains = {}
4950
self._behaviors = {}
5051

5152
self._autonomy_level = 3
5253
self._debug = False
5354

54-
self.requested_state_path = None
55+
self.requested_state_id = None
5556

5657
# Please implement this abstract method:
5758
def create(self):
@@ -178,15 +179,25 @@ def set_parameter(self, name, value):
178179

179180
def confirm(self):
180181
"""Confirm that this behavior is ready for execution."""
181-
LockableStateMachine.path_for_switch = self.requested_state_path
182-
183-
self._state_machine.confirm(self.name, self.beh_id)
184-
185-
# def define_structure(self):
186-
# """
187-
# Calculate all state ids and prepare the ContainerStructure message
188-
# """
189-
# self._state_machine.define_structure()
182+
self._state_map = StateMap()
183+
self._state_machine.confirm(self.name, self.beh_id, self._state_map)
184+
LockableStateMachine.path_for_switch = None
185+
if self.requested_state_id is not None:
186+
requested_state = self._state_map[self.requested_state_id]
187+
LockableStateMachine.path_for_switch = requested_state.path
188+
189+
@property
190+
def state_map_items(self):
191+
"""Return two lists of keys and values from state map."""
192+
if self._state_machine is not None:
193+
return list(zip(*self._state_map.items))
194+
return [], []
195+
196+
def get_state_by_id(self, st_id):
197+
"""Return state reference from state map by id."""
198+
if self._state_map is not None:
199+
return self._state_map.get(st_id)
200+
return None
190201

191202
def execute(self):
192203
"""
@@ -225,7 +236,7 @@ def prepare_for_switch(self, state):
225236
sm.replace_userdata(state_container.userdata)
226237
state_container = state_container._parent
227238
states[1].replace_state(state) # add to new state machine
228-
self.requested_state_path = state.path # set start after switch
239+
self.requested_state_id = state.state_id # set start after switch
229240

230241
def get_current_states(self):
231242
"""Get all currently active (sub-)states."""

flexbe_core/flexbe_core/behavior_library.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def get_behavior(self, be_key):
131131
try:
132132
return self._behavior_lib[be_key]
133133
except KeyError:
134-
Logger.logwarn(f"Did not find ID '{be_key}' in libary, updating...")
134+
Logger.logwarn(f"Did not find ID '{be_key}' in library, updating...")
135135
self.parse_packages()
136136
return self._behavior_lib.get(be_key, None)
137137

@@ -166,12 +166,12 @@ def __find_behavior():
166166
try:
167167
return __find_behavior()
168168
except StopIteration:
169-
Logger.logwarn("Did not find behavior '%s' in current libary, updating..." % be_name)
169+
Logger.logwarn("Did not find behavior '%s' in current library, updating..." % be_name)
170170
self.parse_packages()
171171
try:
172172
return __find_behavior()
173173
except StopIteration:
174-
Logger.logerr("Still cannot find behavior '%s' in libary after update, giving up!" % be_name)
174+
Logger.logerr("Still cannot find behavior '%s' in library after update, giving up!" % be_name)
175175
return None, None
176176

177177
def count_behaviors(self):

flexbe_core/flexbe_core/core/__init__.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131

3232
from .concurrency_container import ConcurrencyContainer # noqa: F401
3333
from .event_state import EventState # noqa: F401
34+
from .exceptions import StateError # noqa: F401
35+
from .exceptions import StateMachineError # noqa: F401
36+
from .exceptions import UserDataError # noqa: F401
3437
from .lockable_state import LockableState # noqa: F401
3538
from .lockable_state_machine import LockableStateMachine # noqa: F401
3639
from .manually_transitionable_state import ManuallyTransitionableState # noqa: F401
@@ -44,23 +47,28 @@
4447
from .state import State # noqa: F401
4548
from .state_machine import StateMachine # noqa: F401
4649
from .state_map import StateMap # noqa: F401
50+
from .topics import Topics
4751
from .user_data import UserData # noqa: F401
4852

4953
__all__ = [
50-
'PreemptableStateMachine',
51-
'OperatableStateMachine',
52-
'LockableStateMachine',
53-
'RosStateMachine',
54-
'StateMachine',
5554
'ConcurrencyContainer',
56-
'PriorityContainer',
57-
'State',
58-
'RosState',
59-
'ManuallyTransitionableState',
55+
'EventState',
6056
'LockableState',
61-
'PreemptableState',
57+
'LockableStateMachine',
58+
'ManuallyTransitionableState',
6259
'OperatableState',
63-
'EventState',
60+
'OperatableStateMachine',
61+
'PreemptableState',
62+
'PreemptableStateMachine',
63+
'PriorityContainer',
64+
'RosState',
65+
'RosStateMachine',
66+
'State',
67+
'StateError',
68+
'StateMachine',
69+
'StateMachineError',
6470
'StateMap',
65-
'UserData'
71+
'Topics',
72+
'UserData',
73+
'UserDataError'
6674
]

0 commit comments

Comments
 (0)