pycram.plan
===========

.. py:module:: pycram.plan


Classes
-------

.. autoapisummary::

   pycram.plan.Plan
   pycram.plan.PlanNode
   pycram.plan.DesignatorNode
   pycram.plan.ActionNode
   pycram.plan.ResolvedActionNode
   pycram.plan.MotionNode


Functions
---------

.. autoapisummary::

   pycram.plan.managed_node
   pycram.plan.with_plan


Module Contents
---------------

.. py:class:: Plan(root: PlanNode)

   Bases: :py:obj:`networkx.DiGraph`


   Represents a plan structure, typically a tree, which can be changed at any point in time. Performing the plan will
   traverse the plan structure in depth first order and perform each PlanNode


   .. py:attribute:: current_plan
      :type:  Plan
      :value: None



   .. py:attribute:: on_start_callback
      :type:  typing_extensions.Dict[typing_extensions.Optional[typing_extensions.Type[pycram.designator.ActionDescription]], typing_extensions.List[typing_extensions.Callable]]


   .. py:attribute:: on_end_callback
      :type:  typing_extensions.Dict[typing_extensions.Optional[typing_extensions.Type[pycram.designator.ActionDescription]], typing_extensions.List[typing_extensions.Callable]]


   .. py:attribute:: root
      :type:  PlanNode


   .. py:attribute:: current_node
      :type:  PlanNode


   .. py:method:: mount(other: Plan, mount_node: PlanNode = None)

      Mounts another plan to this plan. The other plan will be added as a child of the mount_node.

      :param other: The plan to be mounted
      :param mount_node: A node of this plan to which the other plan will be mounted. If None, the root of this plan will be used.



   .. py:method:: merge_nodes(node1: PlanNode, node2: PlanNode)

      Merges two nodes into one. The node2 will be removed and all its children will be added to node1.

      :param node1: Node which will remain in the plan
      :param node2: Node which will be removed from the plan



   .. py:method:: add_node(node_for_adding: PlanNode, **attr)

      Adds a node to the plan. The node will not be connected to any other node of the plan.

      :param node_for_adding: Node to be added
      :param attr: Additional attributes to be added to the node



   .. py:method:: add_edge(u_of_edge, v_of_edge, **attr)

      Adds an edge to the plan. If one or both nodes are not in the plan, they will be added to the plan.

      :param u_of_edge: Origin node of the edge
      :param v_of_edge: Target node of the edge
      :param attr: Additional attributes to be added to the edge



   .. py:method:: add_edges_from(ebunch_to_add: typing_extensions.Iterable[typing_extensions.Tuple[PlanNode, PlanNode]], **attr)

      Adds edges to the plan from an iterable of tuples. If one or both nodes are not in the plan, they will be added to the plan.

      :param ebunch_to_add: Iterable of tuples of nodes to be added
      :param attr: Additional attributes to be added to the edges



   .. py:method:: add_nodes_from(nodes_for_adding: typing_extensions.Iterable[PlanNode], **attr)

      Adds nodes from an Iterable of nodes.

      :param nodes_for_adding: The iterable of nodes
      :param attr: Addotional attributes to be added



   .. py:method:: insert_below(insert_node: PlanNode, insert_below: PlanNode)

      Inserts a node below the given node.

      :param insert_node: The node to be inserted
      :param insert_below: A node of the plan below which the given node should be added



   .. py:method:: perform() -> typing_extensions.Any

      Performs the root node of this plan.

      :return: The return value of the root node



   .. py:method:: resolve()

      Resolves the root node of this plan if it is a DesignatorNode

      :return: The resolved designator



   .. py:method:: flattened_parameters()

      The atomic parameter of this plan, as dict with paths as keys and the atomic type as value

      :return: A dict of the atomic types



   .. py:method:: re_perform()


   .. py:property:: actions
      :type: typing_extensions.List[ActionNode]



   .. py:method:: plot()

      Plots the plan using matplotlib and networkx. The plan is plotted as a tree with the root node at the bottom and
      the children nodes above.



   .. py:method:: add_on_start_callback(callback: typing_extensions.Callable[[PlanNode], None], action_type: typing_extensions.Optional[typing_extensions.Type[pycram.designator.ActionDescription], typing_extensions.Type[PlanNode]] = None)
      :classmethod:


      Adds a callback to be called when an action of the given type is started.

      :param callback: The callback to be called
      :param action_type: The type of the action, if None, the callback will be called for all actions



   .. py:method:: add_on_end_callback(callback: typing_extensions.Callable[[PlanNode], None], action_type: typing_extensions.Optional[typing_extensions.Type[pycram.designator.ActionDescription], typing_extensions.Type[PlanNode]] = None)
      :classmethod:


      Adds a callback to be called when an action of the given type is ended.

      :param callback: The callback to be called
      :param action_type: The type of the action



   .. py:method:: remove_on_start_callback(callback: typing_extensions.Callable[[PlanNode], None], action_type: typing_extensions.Optional[typing_extensions.Type[pycram.designator.ActionDescription], typing_extensions.Type[PlanNode]] = None)
      :classmethod:


      Removes a callback to be called when an action of the given type is started.

      :param callback: The callback to be removed
      :param action_type: The type of the action



   .. py:method:: remove_on_end_callback(callback: typing_extensions.Callable[[PlanNode], None], action_type: typing_extensions.Optional[typing_extensions.Type[pycram.designator.ActionDescription], typing_extensions.Type[PlanNode]] = None)
      :classmethod:


      Removes a callback to be called when an action of the given type is ended.

      :param callback: The callback to be removed
      :param action_type: The type of the action



   .. py:method:: _create_pure_networkx_graph(attributes: typing_extensions.List[str]) -> networkx.DiGraph[int]

      Creates a pure networkx graph of this plan and adds the given attributes of nodes as networkx Node attributes.

      :param attributes: A list of attributes from the nodes which should be contained in the returned graph
      :return: A NetworkX graph from hash values of the PlanNodes




   .. py:method:: plot_bokeh(attributes: typing_extensions.List[str] = None)

      Plots the plan using bokeh and networkx. The plan is plotted as a tree with the root node at the bottom and
      PlanNode.action attributes as labels.
      The plot features a hover tool showing the attributes of the nodes when the mouse is over them. Shown attributes
      can be configured using the attributes parameter. The attributes have to be a subset of the PlanNode attributes.

      :param attributes: A list of attributes from the nodes which should be shown in the hover tool.



   .. py:method:: _create_labels()

      Creates a label set for the plan visualization. Labels are the PlanNode.action attribute.

      :return: A LabelSet object which can be added to a bokeh plot.



.. py:function:: managed_node(func: typing_extensions.Callable) -> typing_extensions.Callable

   Decorator which manages the state of a node, including the start and end time, status and reason of failure as well
   as the setting of the current node in the plan.

   :param func: Reference to the perform function of the node
   :return: The wrapped perform function


.. py:class:: PlanNode

   .. py:attribute:: status
      :type:  pycram.datastructures.enums.TaskStatus

      The status of the node from the TaskStatus enum.



   .. py:attribute:: start_time
      :type:  typing_extensions.Optional[datetime.datetime]

      The starting time of the function, optional



   .. py:attribute:: end_time
      :type:  typing_extensions.Optional[datetime.datetime]
      :value: None


      The ending time of the function, optional



   .. py:attribute:: reason
      :type:  typing_extensions.Optional[pycram.failures.PlanFailure]
      :value: None


      The reason of failure if the action failed.



   .. py:attribute:: plan
      :type:  Plan
      :value: None


      Reference to the plan to which this node belongs



   .. py:attribute:: result
      :type:  typing_extensions.Any
      :value: None


      Result from the execution of this node



   .. py:property:: parent
      :type: PlanNode


      The parent node of this node, None if this is the root node

      :return: The parent node



   .. py:property:: children
      :type: typing_extensions.List[PlanNode]


      All children nodes of this node

      :return:  A list of child nodes



   .. py:property:: recursive_children
      :type: typing_extensions.List[PlanNode]


      Recursively lists all children and their children.

      :return: A list of all nodes below this node



   .. py:property:: subtree
      :type: Plan


      Creates a new plan with this node as the new root

      :return: A new plan



   .. py:property:: all_parents
      :type: typing_extensions.List[PlanNode]


      Returns all nodes above this node until the root node. The order is from this node to the root node.

      :return: A list of all nodes above this



   .. py:property:: is_leaf
      :type: bool


      Returns True if this node is a leaf node

      :return: True if this node is a leaf node



   .. py:method:: flattened_parameters()

      The atomic types pf this node as dict

      :return: The flattened parameter



   .. py:method:: __hash__()


   .. py:method:: perform(*args, **kwargs)


   .. py:method:: interrupt()

      Interrupts the execution of this node and all nodes below



   .. py:method:: resume()

      Resumes the execution of this node and all nodes below



   .. py:method:: pause()

      Suspends the execution of this node and all nodes below.



.. py:class:: DesignatorNode

   Bases: :py:obj:`PlanNode`


   .. py:attribute:: designator_ref
      :type:  typing_extensions.Any
      :value: None


      Reference to the Designator in this node



   .. py:attribute:: action
      :type:  typing_extensions.Optional[typing_extensions.Any]
      :value: None


      The action and that is performed or None if nothing was performed



   .. py:attribute:: kwargs
      :type:  typing_extensions.Dict[str, typing_extensions.Any]
      :value: None


      kwargs of the action in this node



   .. py:method:: __hash__()


   .. py:method:: __repr__(*args, **kwargs)


   .. py:method:: flattened_parameters() -> typing_extensions.Dict[str, pycram.has_parameters.leaf_types]

      The atomic types of the parameters of this node as dict with paths as keys and the atomic type as value.
      This resolves the parameters to its type not the actual value.

      :return: The atomic types of this action



   .. py:method:: flatten() -> typing_extensions.Dict[str, pycram.has_parameters.leaf_types]

      Flattens the parameters of this node to a dict with the parameter as  key and the value as value.

      :return: A dict of the flattened parameters



.. py:class:: ActionNode

   Bases: :py:obj:`DesignatorNode`


   A node in the plan representing an ActionDesignator description


   .. py:attribute:: action_iter
      :type:  typing_extensions.Iterator[pycram.designator.ActionDescription]
      :value: None


      Iterator over the current evaluation state of the ActionDesignator Description



   .. py:attribute:: action
      :type:  pycram.designator.ActionDescription
      :value: None


      The action and that is performed or None if nothing was performed



   .. py:method:: __hash__()


   .. py:method:: perform()

      Performs this node by resolving the ActionDesignator description to the next resolution and then performing the
      result.

      :return: Return value of the resolved action node



   .. py:method:: __repr__(*args, **kwargs)


.. py:class:: ResolvedActionNode

   Bases: :py:obj:`DesignatorNode`


   A node representing a resolved ActionDesignator with fully specified parameters


   .. py:attribute:: designator_ref
      :type:  pycram.designator.ActionDescription
      :value: None


      Reference to the Designator in this node



   .. py:attribute:: action
      :type:  pycram.designator.ActionDescription
      :value: None


      The action and that is performed or None if nothing was performed



   .. py:method:: __hash__()


   .. py:method:: perform()

      Performs this node by performing the resolved action designator in zit

      :return: The return value of the resolved ActionDesignator



   .. py:method:: __repr__(*args, **kwargs)


.. py:class:: MotionNode

   Bases: :py:obj:`DesignatorNode`


   A node in the plan representing a MotionDesignator


   .. py:attribute:: designator_ref
      :type:  pycram.designator.BaseMotion
      :value: None


      Reference to the MotionDesignator



   .. py:method:: __hash__()


   .. py:method:: perform()

      Performs this node by performing the respective MotionDesignator. Additionally, checks if one of the parents has
      the status INTERRUPTED and aborts the perform if that is the case.

      :return: The return value of the Motion Designator



   .. py:method:: __repr__(*args, **kwargs)


   .. py:method:: flatten()

      Flattens the parameters of this node to a dict with the parameter as  key and the value as value.

      :return: A dict of the flattened parameters



   .. py:method:: flattened_parameters()

      The atomic types of the parameters of this node as dict with paths as keys and the atomic type as value.
      This resolves the parameters to its type not the actual value.

      :return: The atomic types of this action



.. py:function:: with_plan(func: typing_extensions.Callable) -> typing_extensions.Callable

   Decorator which wrapps the decorated designator into a node, creates a new plan with the node as root and returns
   the plan.

   :param func: The decorator which should be inserted into a plan
   :return: A plan with the designator as root node


