robokudo.tree_components.task_scheduler ======================================= .. py:module:: robokudo.tree_components.task_scheduler .. autoapi-nested-parse:: Task scheduling components for behavior trees. This module provides base classes for implementing task schedulers in behavior trees. Task schedulers are responsible for dynamically arranging and managing behavior tree nodes during execution. The module supports: * Dynamic behavior arrangement * Task scheduling policies * Job sequence management * Tree structure validation Classes ------- .. autoapisummary:: robokudo.tree_components.task_scheduler.TaskSchedulerBase robokudo.tree_components.task_scheduler.IterativeTaskScheduler Module Contents --------------- .. py:class:: TaskSchedulerBase(name: str = 'TaskSchedulerBase') Bases: :py:obj:`py_trees.behaviour.Behaviour` Base class for task scheduling behaviors. This Behaviour enables a dynamic arrangement of known Behaviours. It assumes that it is placed in a certain configuration in a behaviour tree: .. code-block:: text JOB_SCHEDULING [SEQUENCE] / | JOB_SCHEDULER JOB [SEQUENCE] | During startup this class will save the Job Sequence which contains as a (direct) children all the Annotators that might need to get scheduled. ... note:: In order to use this class, please use one of the deriving classes. :ivar fix_parent_relationships_after_plan: Whether to fix parent relationships after planning :type fix_parent_relationships_after_plan: bool .. py:attribute:: logger :value: None .. py:attribute:: fix_parent_relationships_after_plan :type: bool :value: True .. py:method:: initialise() -> None Initialize and validate tree structure. Performs sanity checks to ensure the scheduler is in a correctly configured environment. .. py:method:: plan_new_job() -> Optional[py_trees.composites.Sequence] Get the new job that should be applied by the JobScheduler. It is the responsibility of your method to return a valid py_trees.Sequence. This means especially that you have to make sure that your parent and children relations should be intact. This is important if you have to keep Instances of your Behaviours/Annotators which might get changed when being put into different py_trees.Behaviours. :return: py_trees.Sequence if it can be computed or None if no plan could be found. :rtype: Optional[py_trees.Sequence] .. py:method:: update() -> py_trees.common.Status Update the scheduler state. Called every time the behavior is ticked. This will happen only once for the job scheduling. :return: SUCCESS if job planned and added, FAILURE otherwise :rtype: :class:`py_trees.common.Status` .. py:class:: IterativeTaskScheduler(name: str = 'IterativeTaskScheduler', tree_list: list = []) Bases: :py:obj:`TaskSchedulerBase` Task scheduler that cycles through a list of subtrees. A Task Scheduler that cycles iteratively through a list of given subtrees. Repeats from the beginning after the end of the list is reached. :ivar tree_list: List of subtrees to cycle through :type tree_list: list :ivar idx: Current index in tree_list :type idx: int .. py:attribute:: tree_list :type: list :value: [] .. py:attribute:: idx :type: int :value: 0 .. py:method:: setup(timeout: float) -> bool Set up all trees in the list. TODO Since we might have the same node in multiple trees, we might call setup multiple times => Find a way to get around this .. note:: Since nodes may appear in multiple trees, setup may be called multiple times on the same node. :param timeout: Maximum time allowed for setup :type timeout: float :return: True if setup successful :rtype: bool .. py:method:: plan_new_job() -> Optional[py_trees.composites.Sequence] Plan the next job by selecting the next tree in sequence. :return: New job sequence with next tree, or None if tree_list empty :rtype: Optional[py_trees.Sequence]