uleroboticsgroup / yasmin

YASMIN (Yet Another State MachINe)
GNU General Public License v3.0
130 stars 25 forks source link

ros2 service for skip state #12

Open aminballoon opened 7 months ago

aminballoon commented 7 months ago

@mgonzs13 Hi, I'm ask for advice. I'm going to add code to skip the state with human trigger, I will add outcome "SKIPPED" to yasmin_ros pkg. So do you have any guide about how to trigger the state controller for set current node outcomes to "SKIPPED", I think it should be good with ros2 service call to trigger it.

I don't sure about this part we can discuss about this feature 👍 .

mgonzs13 commented 7 months ago

Hi @aminballoon, do you want a feature to skip a state and move to another state using the transitions? Maybe something similar to the state cancel from the StateMachine that can be controlled by a topic or a service. What do you think of this?

I am thinking about a node that can expose some topics and services to control a state machine.

aminballoon commented 7 months ago

@mgonzs13, I think cancel and skip is not the same situation its can be design another way , such as outcome "Cancel" while node cannot complete that task but "Skip" its only human doesn't want to wait node complete the task .

mgonzs13 commented 7 months ago

Well, another solution could be implementing a new state with a service as you suggest. What about the following code?

from typing import List, Callable
from std_srvs.srv import SetBool

from yasmin import State
from yasmin import Blackboard
from simple_node import Node
from .basic_outcomes import SKIPPED

class SkippableState(State):

    def __init__(
        self,
        node: Node,
        skip_srv_name: str,
        execute_handler: Callable,
        outcomes: List[str] = None,
    ) -> None:

        _outcomes = [SKIPPED]

        if outcomes:
            _outcomes = _outcomes + outcomes

        self._skipped = False
        self.__srv = node.create_service(
            SetBool, skip_srv_name, self._skip_state)

        self.__execute_handler = execute_handler

        super().__init__(_outcomes)

    def _skip_state(
        self,
        req: SetBool.Request,
        res: SetBool.Response
    ) -> SetBool.Response:
        self._skipped = req.data
        return SetBool.Response()

    def execute(self, blackboard: Blackboard) -> str:

        if self._skipped:
            return SKIPPED

        return self.__execute_handler(blackboard)
aminballoon commented 7 months ago

In my mind this way is very good. Does it possible to integrated skip_state to there node yasmin_ros the example case is while you are waiting to ros2_action call you can be cancel or skip that process with difference out_come .

mgonzs13 commented 7 months ago

How do you want to control the skip? I mean, in the above example, you can use the service to enable or disable if the state is skipped before executing the state, not during state execution. Do you want to skip it during the execution? In this case, as I mentioned before, the needed code could be similar but not equal to the case of canceling a state.

aminballoon commented 7 months ago

I want to skip while that node in executing, cancel state will be trigger by external process.

mgonzs13 commented 7 months ago

If you want to skip a state while executing, how do you want to stop that state, canceling it?

aminballoon commented 6 months ago

yes, that node will be cancel but skip and cancel difference outcome .

mgonzs13 commented 6 months ago

You can cancel the state inside the _skip_state:

    def _skip_state(
        self,
        req: SetBool.Request,
        res: SetBool.Response
    ) -> SetBool.Response:
        self._skipped = req.data

        if self._skipped:
            self.cancel_state()

        return SetBool.Response()
aminballoon commented 6 months ago

Okay, Next step How to cancel ros_action_client_example while client is still executing with service method like your example ?

mgonzs13 commented 6 months ago

You can use the same cancel_state function to cancel an ActionState. This will cancel the action client, which means that will cancel the action server.

mgonzs13 commented 3 months ago

Hey @aminballoon, how is this going?