robosoft-ai / SMACC2

An Event-Driven, Asynchronous, Behavioral State Machine Library for ROS2 (Robotic Operating System) applications written in C++
https://smacc.dev
Apache License 2.0
223 stars 36 forks source link

[Question] Is there a way to access the event from a state that caused the transition to the current state? #544

Closed sukhrajklair closed 2 months ago

sukhrajklair commented 2 months ago

I'm looking for the best way to pass data from one state to another. I understand one way to do it is to use the global blackboard but I was wondering if the data can be passed through the events from the source state to the destination state? I think it'll be particularly useful in the following scenario:

The current state acts as an adapter/api for accepting mission goals. It then generates event to transition to the appropriate state (example a state to go to a goal pose) to complete the mission. It would be great if the adapter state can pass additional data in the event (example goal pose) to the destination state.

if its not possible to pass data through events, what is the use of the data fields in some of the default events?

┆Issue is synchronized with this Jira Task by Unito

brettpac commented 2 months ago

Hello @sukhrajklair, Thanks for the excellent question.

Ok, so the general way we've approached this is through the use of components attached to specific clients.

Going with the example you outlined above, let's name the two states StGoalEvaluator and StGoalExecutor. I'm imagining a process where StGoalEvaluator would receive and evaluate a new goal request. If the evaluation of the request succeeds, then the state would throw a success event (which it could transition on to StGoalExecutor) and during onExit, write the accepted goal to a goal queue component attached to the Nav2z Client (for instance) in the Navigation Orthogonal. The next state would select the goal from the queue and navigate to the goal pose.

Here are some components we've written before for the Nav2z Client Behavior Library that may have some of the functionality you're looking for...

https://github.com/robosoft-ai/SMACC2/tree/humble/smacc2_client_library/nav2z_client/nav2z_client/include/nav2z_client/components

This state and client behavior may also give you some inspiration...

https://github.com/robosoft-ai/SMACC2/blob/humble/smacc2_sm_reference_library/sm_dance_bot_warehouse_2/include/sm_dance_bot_warehouse_2/states/st_navigate_undo_motion.hpp

https://github.com/robosoft-ai/SMACC2/blob/humble/smacc2_client_library/nav2z_client/nav2z_client/include/nav2z_client/client_behaviors/cb_undo_path_backwards.hpp

And can be seen in this demo... https://www.youtube.com/watch?v=A3kmCQS_ww8

Regarding the use of the data fields in the events, the main purpose of the fields is to identify which runtime object threw a given event, and from what Orthogonal (to account for multiple instances of a given runtime object, say for instance in the case of a two arm robot that uses two instances of Moveit) or State (in the case of state reactors) the event was thrown from.

I suppose it would be possible to create different events able to carry other data, but I'd need to hear the specific use case first.

sukhrajklair commented 2 months ago

I hadn't thought of using components but now I can see how they can be used to carry data between states. Thanks for the suggestion and examples.