2023-10-10 20:47:32 +08:00
|
|
|
import shortuuid
|
|
|
|
import py_trees as ptree
|
2023-10-08 15:44:59 +08:00
|
|
|
|
2023-10-07 08:42:04 +08:00
|
|
|
from antlr4 import *
|
2023-10-10 20:47:32 +08:00
|
|
|
|
2023-10-11 20:26:58 +08:00
|
|
|
if "." in __name__:
|
|
|
|
from .ptmlListener import ptmlListener
|
|
|
|
from .ptmlParser import ptmlParser
|
|
|
|
else:
|
|
|
|
from ptmlListener import ptmlListener
|
|
|
|
from ptmlParser import ptmlParser
|
|
|
|
|
|
|
|
short_uuid = lambda: shortuuid.ShortUUID().random(length=8)
|
|
|
|
|
2023-10-07 08:42:04 +08:00
|
|
|
|
|
|
|
class ptmlTranslator(ptmlListener):
|
|
|
|
"""Translate the ptml language to BT.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
ptmlListener (_type_): _description_
|
|
|
|
"""
|
2023-10-11 20:26:58 +08:00
|
|
|
|
2023-10-17 16:28:36 +08:00
|
|
|
def __init__(self, scene, behaviour_lib_path) -> None:
|
2023-10-07 08:42:04 +08:00
|
|
|
super().__init__()
|
2023-10-10 20:47:32 +08:00
|
|
|
self.bt_root = None
|
2023-10-11 20:26:58 +08:00
|
|
|
self.stack = []
|
2023-10-17 16:28:36 +08:00
|
|
|
self.scene = scene
|
|
|
|
self.behaviour_lib_path = behaviour_lib_path
|
2023-10-11 20:26:58 +08:00
|
|
|
|
2023-10-08 15:44:59 +08:00
|
|
|
# Enter a parse tree produced by ptmlParser#root.
|
2023-10-11 20:26:58 +08:00
|
|
|
def enterRoot(self, ctx: ptmlParser.RootContext):
|
2023-10-08 15:44:59 +08:00
|
|
|
pass
|
|
|
|
|
|
|
|
# Exit a parse tree produced by ptmlParser#root.
|
2023-10-11 20:26:58 +08:00
|
|
|
def exitRoot(self, ctx: ptmlParser.RootContext):
|
2023-10-08 15:44:59 +08:00
|
|
|
pass
|
2023-10-11 20:26:58 +08:00
|
|
|
|
2023-10-07 08:42:04 +08:00
|
|
|
# Enter a parse tree produced by ptmlParser#tree.
|
2023-10-11 20:26:58 +08:00
|
|
|
def enterTree(self, ctx: ptmlParser.TreeContext):
|
2023-10-10 20:47:32 +08:00
|
|
|
type = str(ctx.internal_node().children[0])
|
2023-10-07 08:42:04 +08:00
|
|
|
|
2023-10-09 10:38:01 +08:00
|
|
|
match type:
|
2023-10-11 20:26:58 +08:00
|
|
|
case "sequence":
|
|
|
|
tag = "sequence_" + short_uuid()
|
2023-10-10 20:47:32 +08:00
|
|
|
node = ptree.composites.Sequence(name=tag, memory=False)
|
2023-10-11 20:26:58 +08:00
|
|
|
case "selector":
|
|
|
|
tag = "selector_" + short_uuid()
|
2023-10-10 20:47:32 +08:00
|
|
|
node = ptree.composites.Selector(name=tag, memory=False)
|
2023-10-11 20:26:58 +08:00
|
|
|
case "parallel":
|
|
|
|
tag = "parallel_" + short_uuid()
|
2023-10-10 20:47:32 +08:00
|
|
|
# threshold = int(ctx.children[1])
|
|
|
|
# default policy, success on all
|
|
|
|
node = ptree.composites.Parallel(
|
2023-10-11 20:26:58 +08:00
|
|
|
name=tag, policy=ptree.common.ParallelPolicy.SuccessOnAll
|
2023-10-10 20:47:32 +08:00
|
|
|
)
|
2023-10-09 10:38:01 +08:00
|
|
|
case _:
|
2023-10-11 20:26:58 +08:00
|
|
|
raise TypeError("Unknown Composite Type: {}".format(type))
|
|
|
|
|
2023-10-10 20:47:32 +08:00
|
|
|
self.stack.append(node)
|
|
|
|
|
|
|
|
# Exit a parse tree produced by ptmlParser#tree.
|
2023-10-11 20:26:58 +08:00
|
|
|
def exitTree(self, ctx: ptmlParser.TreeContext):
|
2023-10-10 20:47:32 +08:00
|
|
|
if len(self.stack) >= 2:
|
|
|
|
child = self.stack.pop()
|
|
|
|
self.stack[-1].add_child(child)
|
|
|
|
else:
|
|
|
|
self.bt_root = self.stack[0]
|
|
|
|
|
|
|
|
# Enter a parse tree produced by ptmlParser#internal_node.
|
2023-10-11 20:26:58 +08:00
|
|
|
def enterInternal_node(self, ctx: ptmlParser.Internal_nodeContext):
|
|
|
|
pass
|
2023-10-07 08:42:04 +08:00
|
|
|
|
|
|
|
# Exit a parse tree produced by ptmlParser#internal_node.
|
2023-10-11 20:26:58 +08:00
|
|
|
def exitInternal_node(self, ctx: ptmlParser.Internal_nodeContext):
|
2023-10-07 08:42:04 +08:00
|
|
|
pass
|
|
|
|
|
|
|
|
# Enter a parse tree produced by ptmlParser#action_sign.
|
2023-10-11 20:26:58 +08:00
|
|
|
def enterAction_sign(self, ctx: ptmlParser.Action_signContext):
|
2023-10-08 16:21:12 +08:00
|
|
|
# cond / task
|
2023-10-10 20:47:32 +08:00
|
|
|
node_type = str(ctx.children[0])
|
2023-10-08 16:21:12 +08:00
|
|
|
name = str(ctx.Names())
|
2023-10-11 20:26:58 +08:00
|
|
|
|
2023-10-09 10:38:01 +08:00
|
|
|
# if have params
|
2023-10-10 20:47:32 +08:00
|
|
|
args = []
|
2023-10-08 16:21:12 +08:00
|
|
|
if len(ctx.children) > 4:
|
2023-10-10 20:47:32 +08:00
|
|
|
params = ctx.action_parm()
|
2023-10-11 20:26:58 +08:00
|
|
|
|
2023-10-10 20:47:32 +08:00
|
|
|
for i in params.children:
|
|
|
|
if isinstance(i, ptmlParser.BooleanContext):
|
|
|
|
args.append(str(i.children[0]))
|
|
|
|
else:
|
|
|
|
args.append(str(i))
|
|
|
|
|
2023-10-11 20:26:58 +08:00
|
|
|
args = "".join(args)
|
|
|
|
|
2023-10-10 20:47:32 +08:00
|
|
|
import sys
|
2023-10-11 20:26:58 +08:00
|
|
|
|
2023-10-17 16:28:36 +08:00
|
|
|
sys.path.append(self.behaviour_lib_path)
|
|
|
|
|
2023-10-11 20:26:58 +08:00
|
|
|
exec("from {} import {}".format(name, name))
|
|
|
|
#
|
|
|
|
tag = "cond_" + short_uuid() if node_type == "cond" else "task_" + short_uuid()
|
2023-10-17 16:28:36 +08:00
|
|
|
|
|
|
|
node = eval(
|
|
|
|
"{}('{}', scene, {})".format(name, tag, args), {"scene": self.scene, **locals()}
|
|
|
|
)
|
2023-10-10 20:47:32 +08:00
|
|
|
|
2023-10-09 10:38:01 +08:00
|
|
|
# connect
|
2023-10-10 20:47:32 +08:00
|
|
|
self.stack[-1].add_child(node)
|
2023-10-07 08:42:04 +08:00
|
|
|
|
|
|
|
# Exit a parse tree produced by ptmlParser#action_sign.
|
2023-10-11 20:26:58 +08:00
|
|
|
def exitAction_sign(self, ctx: ptmlParser.Action_signContext):
|
2023-10-07 08:42:04 +08:00
|
|
|
pass
|
|
|
|
|
|
|
|
# Enter a parse tree produced by ptmlParser#action_parm.
|
2023-10-11 20:26:58 +08:00
|
|
|
def enterAction_parm(self, ctx: ptmlParser.Action_parmContext):
|
2023-10-07 08:42:04 +08:00
|
|
|
pass
|
|
|
|
|
|
|
|
# Exit a parse tree produced by ptmlParser#action_parm.
|
2023-10-11 20:26:58 +08:00
|
|
|
def exitAction_parm(self, ctx: ptmlParser.Action_parmContext):
|
2023-10-07 08:42:04 +08:00
|
|
|
pass
|
|
|
|
|
|
|
|
# Enter a parse tree produced by ptmlParser#boolean.
|
2023-10-11 20:26:58 +08:00
|
|
|
def enterBoolean(self, ctx: ptmlParser.BooleanContext):
|
2023-10-07 08:42:04 +08:00
|
|
|
pass
|
|
|
|
|
|
|
|
# Exit a parse tree produced by ptmlParser#boolean.
|
2023-10-11 20:26:58 +08:00
|
|
|
def exitBoolean(self, ctx: ptmlParser.BooleanContext):
|
2023-10-08 15:44:59 +08:00
|
|
|
pass
|