增加行为树对比和测试
This commit is contained in:
parent
73a51b417d
commit
a5978ff37a
|
@ -15,24 +15,17 @@ class Bahavior(ptree.behaviour.Behaviour):
|
||||||
scene = None
|
scene = None
|
||||||
print_name_prefix = ""
|
print_name_prefix = ""
|
||||||
tables_for_placement = {'Bar', 'Bar2', 'WaterTable', 'CoffeeTable', 'Table1', 'Table2', 'Table3',"BrightTable6"}
|
tables_for_placement = {'Bar', 'Bar2', 'WaterTable', 'CoffeeTable', 'Table1', 'Table2', 'Table3',"BrightTable6"}
|
||||||
# all_object = {'Coffee', 'Water', 'Dessert', 'Softdrink', 'BottledDrink', 'Yogurt', 'ADMilk', 'MilkDrink', 'Milk',
|
|
||||||
# 'VacuumCup'}
|
|
||||||
|
|
||||||
all_object = {
|
all_object = {
|
||||||
'Coffee', 'Water', 'Dessert', 'Softdrink', 'BottledDrink', 'Yogurt', 'ADMilk', 'MilkDrink', 'Milk','VacuumCup',
|
'Coffee', 'Water', 'Dessert', 'Softdrink', 'BottledDrink', 'Yogurt', 'ADMilk', 'MilkDrink', 'Milk','VacuumCup',
|
||||||
'Chips', 'NFCJuice', 'Bernachon', 'ADMilk', 'SpringWater'}
|
'Chips', 'NFCJuice', 'Bernachon', 'ADMilk', 'SpringWater'}
|
||||||
|
|
||||||
# BrightTable5 = Table4
|
|
||||||
tables_for_guiding = {"QuietTable1","QuietTable2",
|
tables_for_guiding = {"QuietTable1","QuietTable2",
|
||||||
"BrightTable1","BrightTable2","BrightTable3","BrightTable4","BrightTable5","BrightTable6"
|
"BrightTable1","BrightTable2","BrightTable3","BrightTable4","BrightTable5","BrightTable6"
|
||||||
'CoffeeTable','WaterTable','Table1', 'Table2', 'Table3'}
|
'CoffeeTable','WaterTable','Table1', 'Table2', 'Table3'}
|
||||||
|
|
||||||
# all_place = {'Bar', 'WaterTable', 'CoffeeTable'}
|
|
||||||
# all_object = {'Coffee', 'Water', 'Dessert', 'Softdrink', 'Yogurt'}
|
|
||||||
# all_object = {'Coffee', 'Water'}
|
|
||||||
|
|
||||||
# all_object = set()
|
# tables_for_placement = {'Bar', 'WaterTable', 'CoffeeTable'}
|
||||||
# all_place=set()
|
# all_object = {'Coffee', 'Water', 'Dessert', 'Softdrink', 'Yogurt'}
|
||||||
|
|
||||||
|
|
||||||
num_of_obj_on_place={
|
num_of_obj_on_place={
|
||||||
'Bar': 0, # (247.0, 520.0, 100.0)
|
'Bar': 0, # (247.0, 520.0, 100.0)
|
||||||
|
|
|
@ -15,7 +15,8 @@ class FreeHands(Act):
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_info(cls):
|
def get_info(cls):
|
||||||
info = {}
|
info = {}
|
||||||
info["pre"]= set()
|
# info["pre"]= set()
|
||||||
|
info["pre"] ={f'Holding(Nothing)'}
|
||||||
info['add'] = {f'Holding(Nothing)'}
|
info['add'] = {f'Holding(Nothing)'}
|
||||||
info['del_set'] = {f'Holding({obj})' for obj in cls.all_object}
|
info['del_set'] = {f'Holding({obj})' for obj in cls.all_object}
|
||||||
info['cost'] = 0
|
info['cost'] = 0
|
||||||
|
|
|
@ -0,0 +1,297 @@
|
||||||
|
import random
|
||||||
|
import numpy as np
|
||||||
|
import copy
|
||||||
|
import time
|
||||||
|
from robowaiter.behavior_tree.obtea.BehaviorTree import Leaf,ControlBT
|
||||||
|
from robowaiter.behavior_tree.obtea.OptimalBTExpansionAlgorithm import Action,generate_random_state,state_transition,conflict
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 本文所提出的完备规划算法
|
||||||
|
class BTalgorithm:
|
||||||
|
def __init__(self,verbose=False):
|
||||||
|
self.bt = None
|
||||||
|
self.nodes = []
|
||||||
|
self.traversed = []
|
||||||
|
self.conditions = []
|
||||||
|
self.conditions_index = []
|
||||||
|
self.verbose = verbose
|
||||||
|
# print (self.conditions_list[0])
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
self.bt = None
|
||||||
|
self.nodes = []
|
||||||
|
self.traversed = []
|
||||||
|
self.conditions = []
|
||||||
|
self.conditions_index = []
|
||||||
|
|
||||||
|
# 运行规划算法,从初始状态、目标状态和可用行动,计算行为树self.bt
|
||||||
|
def run_algorithm(self, start, goal, actions):
|
||||||
|
# 初始行为树只包含目标条件
|
||||||
|
self.bt = ControlBT(type='cond')
|
||||||
|
g_node = Leaf(type='cond', content=goal,mincost=0)
|
||||||
|
self.bt.add_child([g_node])
|
||||||
|
|
||||||
|
self.conditions.append(goal)
|
||||||
|
self.nodes.append(g_node) # condition node list
|
||||||
|
# 尝试在初始状态执行行为树
|
||||||
|
val, obj = self.bt.tick(start)
|
||||||
|
canrun = False
|
||||||
|
if val == 'success' or val == 'running':
|
||||||
|
canrun = True
|
||||||
|
# 循环扩展,直到行为树能够在初始状态运行
|
||||||
|
while not canrun:
|
||||||
|
index = -1
|
||||||
|
for i in range(0, len(self.nodes)):
|
||||||
|
if self.nodes[i].content in self.traversed:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
c_node = self.nodes[i]
|
||||||
|
index = i
|
||||||
|
break
|
||||||
|
if index == -1: # 树中结点扩展完毕,仍无法运行行为树,返回失败
|
||||||
|
print('Failure')
|
||||||
|
return False
|
||||||
|
# 根据所选择条件结点扩展子树
|
||||||
|
subtree = ControlBT(type='?')
|
||||||
|
subtree.add_child([copy.deepcopy(c_node)]) # 子树首先保留所扩展结点
|
||||||
|
c = c_node.content # 子树所扩展结点对应的条件(一个文字的set)
|
||||||
|
|
||||||
|
for i in range(0, len(actions)): # 选择符合条件的行动,
|
||||||
|
# print("have action")
|
||||||
|
if not c & ((actions[i].pre | actions[i].add) - actions[i].del_set) <= set():
|
||||||
|
# print ("pass add")
|
||||||
|
if (c - actions[i].del_set) == c:
|
||||||
|
# print("pass delete")
|
||||||
|
c_attr = (actions[i].pre | c) - actions[i].add
|
||||||
|
valid = True
|
||||||
|
|
||||||
|
# 这样剪枝存在错误性
|
||||||
|
if conflict(c_attr):
|
||||||
|
continue
|
||||||
|
|
||||||
|
for j in self.traversed: # 剪枝操作
|
||||||
|
if j <= c_attr:
|
||||||
|
valid = False
|
||||||
|
break
|
||||||
|
|
||||||
|
if valid:
|
||||||
|
# print("pass prune")
|
||||||
|
# 构建行动的顺序结构
|
||||||
|
sequence_structure = ControlBT(type='>')
|
||||||
|
c_attr_node = Leaf(type='cond', content=c_attr, mincost=0)
|
||||||
|
a_node = Leaf(type='act', content=actions[i], mincost=0)
|
||||||
|
sequence_structure.add_child([c_attr_node, a_node])
|
||||||
|
# 将顺序结构添加到子树
|
||||||
|
subtree.add_child([sequence_structure])
|
||||||
|
|
||||||
|
self.nodes.append(c_attr_node)
|
||||||
|
# 将原条件结点c_node替换为扩展后子树subtree
|
||||||
|
parent_of_c = c_node.parent
|
||||||
|
parent_of_c.children[0] = subtree
|
||||||
|
# 记录已扩展条件
|
||||||
|
self.traversed.append(c)
|
||||||
|
# 尝试在初始状态运行行为树
|
||||||
|
val, obj = self.bt.tick(start)
|
||||||
|
canrun = False
|
||||||
|
if val == 'success' or val == 'running':
|
||||||
|
canrun = True
|
||||||
|
return True
|
||||||
|
|
||||||
|
def print_solution(self):
|
||||||
|
print(len(self.nodes))
|
||||||
|
# for i in self.nodes:
|
||||||
|
# if isinstance(i,Node):
|
||||||
|
# print (i.content)
|
||||||
|
# else:
|
||||||
|
# print (i)
|
||||||
|
|
||||||
|
# 树的dfs
|
||||||
|
def dfs_ptml(self,parnode,is_root=False):
|
||||||
|
for child in parnode.children:
|
||||||
|
if isinstance(child, Leaf):
|
||||||
|
if child.type == 'cond':
|
||||||
|
|
||||||
|
if is_root and len(child.content) > 1:
|
||||||
|
# 把多个 cond 串起来
|
||||||
|
self.ptml_string += "sequence{\n"
|
||||||
|
self.ptml_string += "cond "
|
||||||
|
c_set_str = '\n cond '.join(map(str, child.content)) + "\n"
|
||||||
|
self.ptml_string += c_set_str
|
||||||
|
self.ptml_string += '}\n'
|
||||||
|
else:
|
||||||
|
self.ptml_string += "cond "
|
||||||
|
c_set_str = '\n cond '.join(map(str, child.content)) + "\n"
|
||||||
|
self.ptml_string += c_set_str
|
||||||
|
|
||||||
|
elif child.type == 'act':
|
||||||
|
if '(' not in child.content.name:
|
||||||
|
self.ptml_string += 'act ' + child.content.name + "()\n"
|
||||||
|
else:
|
||||||
|
self.ptml_string += 'act ' + child.content.name + "\n"
|
||||||
|
elif isinstance(child, ControlBT):
|
||||||
|
if child.type == '?':
|
||||||
|
self.ptml_string += "selector{\n"
|
||||||
|
self.dfs_ptml(parnode=child)
|
||||||
|
elif child.type == '>':
|
||||||
|
self.ptml_string += "sequence{\n"
|
||||||
|
self.dfs_ptml( parnode=child)
|
||||||
|
self.ptml_string += '}\n'
|
||||||
|
|
||||||
|
|
||||||
|
def get_ptml(self):
|
||||||
|
self.ptml_string = "selector{\n"
|
||||||
|
self.dfs_ptml(self.bt.children[0],is_root=True)
|
||||||
|
self.ptml_string += '}\n'
|
||||||
|
return self.ptml_string
|
||||||
|
|
||||||
|
|
||||||
|
def save_ptml_file(self,file_name):
|
||||||
|
self.ptml_string = "selector{\n"
|
||||||
|
self.dfs_ptml(self.bt.children[0])
|
||||||
|
self.ptml_string += '}\n'
|
||||||
|
with open(f'./{file_name}.ptml', 'w') as file:
|
||||||
|
file.write(self.ptml_string)
|
||||||
|
return self.ptml_string
|
||||||
|
|
||||||
|
|
||||||
|
# 所对比的基准算法,具体扩展细节有差异
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
random.seed(1)
|
||||||
|
# 设置生成规划问题集的超参数:文字数、解深度、迭代次数
|
||||||
|
literals_num = 10
|
||||||
|
depth = 10
|
||||||
|
iters = 10
|
||||||
|
total_tree_size = []
|
||||||
|
total_action_num = []
|
||||||
|
total_state_num = []
|
||||||
|
total_steps_num = []
|
||||||
|
# fail_count=0
|
||||||
|
# danger_count=0
|
||||||
|
success_count = 0
|
||||||
|
failure_count = 0
|
||||||
|
planning_time_total = 0.0
|
||||||
|
# 实验1000次
|
||||||
|
for count in range(0, 1000):
|
||||||
|
# 生成一个规划问题,包括随机的状态和行动,以及目标状态
|
||||||
|
states = []
|
||||||
|
actions = []
|
||||||
|
start = generate_random_state(literals_num)
|
||||||
|
state = start
|
||||||
|
states.append(state)
|
||||||
|
# print (state)
|
||||||
|
for i in range(0, depth):
|
||||||
|
a = Action()
|
||||||
|
a.generate_from_state(state, literals_num)
|
||||||
|
if not a in actions:
|
||||||
|
actions.append(a)
|
||||||
|
state = state_transition(state, a)
|
||||||
|
if state in states:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
states.append(state)
|
||||||
|
# print(state)
|
||||||
|
|
||||||
|
goal = states[-1]
|
||||||
|
state = start
|
||||||
|
for i in range(0, iters):
|
||||||
|
a = Action()
|
||||||
|
a.generate_from_state(state, literals_num)
|
||||||
|
if not a in actions:
|
||||||
|
actions.append(a)
|
||||||
|
state = state_transition(state, a)
|
||||||
|
if state in states:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
states.append(state)
|
||||||
|
state = random.sample(states, 1)[0]
|
||||||
|
# 选择测试本文算法btalgorithm,或对比算法weakalgorithm
|
||||||
|
algo = BTalgorithm()
|
||||||
|
# algo = Weakalgorithm()
|
||||||
|
start_time = time.time()
|
||||||
|
if algo.run_algorithm(start, goal, list(actions)): # 运行算法,规划后行为树为algo.bt
|
||||||
|
total_tree_size.append(algo.bt.count_size() - 1)
|
||||||
|
else:
|
||||||
|
print("error")
|
||||||
|
end_time = time.time()
|
||||||
|
planning_time_total += (end_time - start_time)
|
||||||
|
|
||||||
|
# 开始从初始状态运行行为树,测试
|
||||||
|
state = start
|
||||||
|
steps = 0
|
||||||
|
val, obj = algo.bt.tick(state) # tick行为树,obj为所运行的行动
|
||||||
|
while val != 'success' and val != 'failure': # 运行直到行为树成功或失败
|
||||||
|
state = state_transition(state, obj)
|
||||||
|
val, obj = algo.bt.tick(state)
|
||||||
|
if (val == 'failure'):
|
||||||
|
print("bt fails at step", steps)
|
||||||
|
steps += 1
|
||||||
|
if (steps >= 500): # 至多运行500步
|
||||||
|
break
|
||||||
|
if not goal <= state: # 错误解,目标条件不在执行后状态满足
|
||||||
|
# print ("wrong solution",steps)
|
||||||
|
failure_count += 1
|
||||||
|
|
||||||
|
else: # 正确解,满足目标条件
|
||||||
|
# print ("right solution",steps)
|
||||||
|
success_count += 1
|
||||||
|
total_steps_num.append(steps)
|
||||||
|
algo.clear()
|
||||||
|
total_action_num.append(len(actions))
|
||||||
|
total_state_num.append(len(states))
|
||||||
|
print(success_count, failure_count) # 算法成功和失败次数
|
||||||
|
|
||||||
|
print(np.mean(total_tree_size), np.std(total_tree_size, ddof=1)) # 1000次测试树大小
|
||||||
|
print(np.mean(total_steps_num), np.std(total_steps_num, ddof=1))
|
||||||
|
print(np.mean(total_state_num)) # 1000次问题的平均状态数
|
||||||
|
print(np.mean(total_action_num)) # 1000次问题的平均行动数
|
||||||
|
print(planning_time_total, planning_time_total / 1000.0)
|
||||||
|
|
||||||
|
# print(total_state_num)
|
||||||
|
|
||||||
|
# casestudy begin 对应论文的case study,包含三个行动的移动机械臂场景
|
||||||
|
|
||||||
|
actions = []
|
||||||
|
a = Action(name='movebtob')
|
||||||
|
a.pre = {1, 2}
|
||||||
|
a.add = {3}
|
||||||
|
a.del_set = {1, 4}
|
||||||
|
actions.append(a)
|
||||||
|
a = Action(name='moveatob')
|
||||||
|
a.pre = {1}
|
||||||
|
a.add = {5, 2}
|
||||||
|
a.del_set = {1, 6}
|
||||||
|
actions.append(a)
|
||||||
|
a = Action(name='moveatoa')
|
||||||
|
a.pre = {7}
|
||||||
|
a.add = {8, 2}
|
||||||
|
a.del_set = {7, 6}
|
||||||
|
actions.append(a)
|
||||||
|
|
||||||
|
start = {1, 7, 4, 6}
|
||||||
|
goal = {3}
|
||||||
|
algo = BTalgorithm()
|
||||||
|
algo.clear()
|
||||||
|
algo.run_algorithm(start, goal, list(actions))
|
||||||
|
state = start
|
||||||
|
steps = 0
|
||||||
|
val, obj = algo.bt.tick(state)
|
||||||
|
while val != 'success' and val != 'failure':
|
||||||
|
state = state_transition(state, obj)
|
||||||
|
print(obj.name)
|
||||||
|
val, obj = algo.bt.tick(state)
|
||||||
|
if (val == 'failure'):
|
||||||
|
print("bt fails at step", steps)
|
||||||
|
steps += 1
|
||||||
|
if not goal <= state:
|
||||||
|
print("wrong solution", steps)
|
||||||
|
else:
|
||||||
|
print("right solution", steps)
|
||||||
|
# algo.bt.print_nodes()
|
||||||
|
print(algo.bt.count_size() - 1)
|
||||||
|
algo.clear()
|
||||||
|
|
||||||
|
# case study end
|
|
@ -20,6 +20,24 @@ class Action:
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
# 从状态随机生成一个行动
|
||||||
|
def generate_from_state(self,state,num):
|
||||||
|
for i in range(0,num):
|
||||||
|
if i in state:
|
||||||
|
if random.random() >0.5:
|
||||||
|
self.pre.add(i)
|
||||||
|
if random.random() >0.5:
|
||||||
|
self.del_set.add(i)
|
||||||
|
continue
|
||||||
|
if random.random() > 0.5:
|
||||||
|
self.add.add(i)
|
||||||
|
continue
|
||||||
|
if random.random() >0.5:
|
||||||
|
self.del_set.add(i)
|
||||||
|
def print_action(self):
|
||||||
|
print (self.pre)
|
||||||
|
print(self.add)
|
||||||
|
print(self.del_set)
|
||||||
|
|
||||||
#生成随机状态
|
#生成随机状态
|
||||||
def generate_random_state(num):
|
def generate_random_state(num):
|
||||||
|
@ -68,9 +86,9 @@ class OptBTExpAlgorithm:
|
||||||
self.conditions_index = []
|
self.conditions_index = []
|
||||||
|
|
||||||
#运行规划算法,从初始状态、目标状态和可用行动,计算行为树self.bt
|
#运行规划算法,从初始状态、目标状态和可用行动,计算行为树self.bt
|
||||||
def run_algorithm(self,goal,actions,scene):
|
# def run_algorithm(self,goal,actions,scene):
|
||||||
|
def run_algorithm(self, start, goal, actions):
|
||||||
self.scene = scene
|
# self.scene = scene
|
||||||
|
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
print("\n算法开始!")
|
print("\n算法开始!")
|
||||||
|
@ -113,7 +131,6 @@ class OptBTExpAlgorithm:
|
||||||
min_cost = cond_anc_pair.cond_leaf.mincost
|
min_cost = cond_anc_pair.cond_leaf.mincost
|
||||||
pair_node = copy.deepcopy(cond_anc_pair)
|
pair_node = copy.deepcopy(cond_anc_pair)
|
||||||
index = i
|
index = i
|
||||||
break
|
|
||||||
|
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
print("选择扩展条件结点:",pair_node.cond_leaf.content)
|
print("选择扩展条件结点:",pair_node.cond_leaf.content)
|
||||||
|
@ -141,7 +158,8 @@ class OptBTExpAlgorithm:
|
||||||
subtree.add_child([copy.deepcopy(sequence_structure)]) # subtree 是回不断变化的,它的父亲是self.bt
|
subtree.add_child([copy.deepcopy(sequence_structure)]) # subtree 是回不断变化的,它的父亲是self.bt
|
||||||
self.expanded.append(copy.deepcopy(pair_node))
|
self.expanded.append(copy.deepcopy(pair_node))
|
||||||
# 增加实时条件判断,满足条件就不再扩展
|
# 增加实时条件判断,满足条件就不再扩展
|
||||||
if c <= self.scene.state["condition_set"]:
|
# if c <= self.scene.state["condition_set"]:
|
||||||
|
if c <= start:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
subtree.add_child([copy.deepcopy(pair_node.act_leaf)])
|
subtree.add_child([copy.deepcopy(pair_node.act_leaf)])
|
||||||
|
@ -158,6 +176,11 @@ class OptBTExpAlgorithm:
|
||||||
current_mincost = pair_node.cond_leaf.mincost # 当前的最短路径是多少
|
current_mincost = pair_node.cond_leaf.mincost # 当前的最短路径是多少
|
||||||
|
|
||||||
for i in range(0, len(actions)):
|
for i in range(0, len(actions)):
|
||||||
|
|
||||||
|
|
||||||
|
if actions[i].name == 'FreeHands()':
|
||||||
|
kk=1
|
||||||
|
|
||||||
if not c & ((actions[i].pre | actions[i].add) - actions[i].del_set) <= set():
|
if not c & ((actions[i].pre | actions[i].add) - actions[i].del_set) <= set():
|
||||||
if (c - actions[i].del_set) == c:
|
if (c - actions[i].del_set) == c:
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
from robowaiter.behavior_tree.obtea.OptimalBTExpansionAlgorithm import Action,OptBTExpAlgorithm,state_transition # 调用最优行为树扩展算法
|
from robowaiter.behavior_tree.obtea.OptimalBTExpansionAlgorithm import Action,OptBTExpAlgorithm,state_transition # 调用最优行为树扩展算法
|
||||||
|
from robowaiter.behavior_tree.obtea.BTExpansionAlgorithm import BTalgorithm # 调用最优行为树扩展算法
|
||||||
|
|
||||||
from robowaiter.behavior_tree.obtea.examples import *
|
from robowaiter.behavior_tree.obtea.examples import *
|
||||||
|
|
||||||
|
@ -23,6 +24,8 @@ class BTOptExpInterface:
|
||||||
self.has_processed = False
|
self.has_processed = False
|
||||||
|
|
||||||
self.scene = scene
|
self.scene = scene
|
||||||
|
self.bt_algo_opt = self.scene.bt_algo_opt
|
||||||
|
|
||||||
|
|
||||||
def process(self, goal):
|
def process(self, goal):
|
||||||
"""
|
"""
|
||||||
|
@ -31,9 +34,15 @@ class BTOptExpInterface:
|
||||||
:return: A PTML string representing the outcome of the behavior tree.
|
:return: A PTML string representing the outcome of the behavior tree.
|
||||||
"""
|
"""
|
||||||
self.goal = goal
|
self.goal = goal
|
||||||
|
if self.bt_algo_opt:
|
||||||
self.algo = OptBTExpAlgorithm(verbose=False)
|
self.algo = OptBTExpAlgorithm(verbose=False)
|
||||||
|
else:
|
||||||
|
self.algo = BTalgorithm(verbose=False)
|
||||||
|
|
||||||
self.algo.clear()
|
self.algo.clear()
|
||||||
self.algo.run_algorithm(self.goal, self.actions,self.scene) # 调用算法得到行为树保存至 algo.bt
|
self.algo.run_algorithm(self.scene.state["condition_set"],self.goal, self.actions) # 调用算法得到行为树保存至 algo.bt
|
||||||
|
|
||||||
|
|
||||||
self.ptml_string = self.algo.get_ptml()
|
self.ptml_string = self.algo.get_ptml()
|
||||||
self.has_processed = True
|
self.has_processed = True
|
||||||
# algo.print_solution() # print behavior tree
|
# algo.print_solution() # print behavior tree
|
||||||
|
|
|
@ -222,12 +222,6 @@ get_object_info
|
||||||
好的,我明白了,那么我们推荐您到大厅的桌子,那里的空间比较宽敞,环境也比较明亮,适合带着孩子一起用餐。
|
好的,我明白了,那么我们推荐您到大厅的桌子,那里的空间比较宽敞,环境也比较明亮,适合带着孩子一起用餐。
|
||||||
|
|
||||||
|
|
||||||
冰红茶
|
|
||||||
好的
|
|
||||||
create_sub_task
|
|
||||||
{"goal":"On(Yogurt,WaterTable)"}
|
|
||||||
|
|
||||||
|
|
||||||
水杯
|
水杯
|
||||||
好的
|
好的
|
||||||
create_sub_task
|
create_sub_task
|
||||||
|
@ -259,3 +253,8 @@ create_sub_task
|
||||||
好的
|
好的
|
||||||
create_sub_task
|
create_sub_task
|
||||||
{"goal":"On(Dessert,Bar)"}
|
{"goal":"On(Dessert,Bar)"}
|
||||||
|
|
||||||
|
打开空调并降低空调温度
|
||||||
|
好的,没问题
|
||||||
|
create_sub_task
|
||||||
|
{"goal":"Is(ACTemperature,Down)"}
|
|
@ -19,7 +19,7 @@ root_path = get_root_path()
|
||||||
ptml_path = os.path.join(root_path, 'robowaiter/robot/Default.ptml')
|
ptml_path = os.path.join(root_path, 'robowaiter/robot/Default.ptml')
|
||||||
behavior_lib_path = os.path.join(root_path, 'robowaiter/behavior_lib')
|
behavior_lib_path = os.path.join(root_path, 'robowaiter/behavior_lib')
|
||||||
|
|
||||||
|
from robowaiter.utils.bt.draw import render_dot_tree
|
||||||
|
|
||||||
class Robot(object):
|
class Robot(object):
|
||||||
scene = None
|
scene = None
|
||||||
|
@ -79,6 +79,7 @@ class Robot(object):
|
||||||
file.write(ptml_string)
|
file.write(ptml_string)
|
||||||
|
|
||||||
sub_task_bt = load_bt_from_ptml(self.scene, file_path,self.behavior_lib_path)
|
sub_task_bt = load_bt_from_ptml(self.scene, file_path,self.behavior_lib_path)
|
||||||
|
render_dot_tree(sub_task_bt.root, target_directory=self.scene.output_path, name="expanded_bt", png_only=False)
|
||||||
|
|
||||||
# 加入删除子树的节点
|
# 加入删除子树的节点
|
||||||
seq = Sequence(name="Sequence", memory=False)
|
seq = Sequence(name="Sequence", memory=False)
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
digraph pastafarianism {
|
||||||
|
ordering=out;
|
||||||
|
graph [fontname="times-roman"];
|
||||||
|
node [fontname="times-roman"];
|
||||||
|
edge [fontname="times-roman"];
|
||||||
|
"87355232-8ad6-484e-b363-38536e737846" [fillcolor=cyan, fontcolor=black, fontsize=20, height=0.01, label=Selector, shape=diamond, style=filled, width=0.01];
|
||||||
|
"3f017683-7aa3-40d3-b2be-cc32784313a1" [fillcolor=yellow, fontcolor=black, fontsize=20, label="Is(ACTemperature,Down)", shape=ellipse, style=filled];
|
||||||
|
"87355232-8ad6-484e-b363-38536e737846" -> "3f017683-7aa3-40d3-b2be-cc32784313a1";
|
||||||
|
"b900e9cb-c0a8-4e8d-8a9b-d871012abefb" [fillcolor=orange, fontcolor=black, fontsize=20, height=0.01, label=Sequence, shape=octagon, style=filled, width=0.01];
|
||||||
|
"87355232-8ad6-484e-b363-38536e737846" -> "b900e9cb-c0a8-4e8d-8a9b-d871012abefb";
|
||||||
|
"10ef3ff4-7acb-4991-9e63-6e489c3ef22d" [fillcolor=yellow, fontcolor=black, fontsize=20, label="Holding(Nothing)", shape=ellipse, style=filled];
|
||||||
|
"b900e9cb-c0a8-4e8d-8a9b-d871012abefb" -> "10ef3ff4-7acb-4991-9e63-6e489c3ef22d";
|
||||||
|
"a3869371-404d-4085-932b-232e188fb133" [fillcolor=yellow, fontcolor=black, fontsize=20, label="Is(AC,On)", shape=ellipse, style=filled];
|
||||||
|
"b900e9cb-c0a8-4e8d-8a9b-d871012abefb" -> "a3869371-404d-4085-932b-232e188fb133";
|
||||||
|
"3a5cbe8f-7672-4a34-91d1-87502aed457c" [fillcolor=lawngreen, fontcolor=black, fontsize=20, label="Turn(ACTemperature,Down)", shape=box, style=filled];
|
||||||
|
"b900e9cb-c0a8-4e8d-8a9b-d871012abefb" -> "3a5cbe8f-7672-4a34-91d1-87502aed457c";
|
||||||
|
"b64db1a4-d79f-47b4-99db-f184b38d1361" [fillcolor=orange, fontcolor=black, fontsize=20, height=0.01, label=Sequence, shape=octagon, style=filled, width=0.01];
|
||||||
|
"87355232-8ad6-484e-b363-38536e737846" -> "b64db1a4-d79f-47b4-99db-f184b38d1361";
|
||||||
|
"c6eca6dd-9fca-4bd3-b054-9b43fe02613a" [fillcolor=yellow, fontcolor=black, fontsize=20, label="Is(AC,On)", shape=ellipse, style=filled];
|
||||||
|
"b64db1a4-d79f-47b4-99db-f184b38d1361" -> "c6eca6dd-9fca-4bd3-b054-9b43fe02613a";
|
||||||
|
"df04f6f4-d471-4519-ab9e-5d5bd8dfbd4c" [fillcolor=lawngreen, fontcolor=black, fontsize=20, label="FreeHands()", shape=box, style=filled];
|
||||||
|
"b64db1a4-d79f-47b4-99db-f184b38d1361" -> "df04f6f4-d471-4519-ab9e-5d5bd8dfbd4c";
|
||||||
|
"8108bcba-dbeb-4784-8f1f-eb9ede4ffb0e" [fillcolor=orange, fontcolor=black, fontsize=20, height=0.01, label=Sequence, shape=octagon, style=filled, width=0.01];
|
||||||
|
"87355232-8ad6-484e-b363-38536e737846" -> "8108bcba-dbeb-4784-8f1f-eb9ede4ffb0e";
|
||||||
|
"82a23405-c3c6-47dc-bf7b-0636e3efe52c" [fillcolor=yellow, fontcolor=black, fontsize=20, label="Holding(Nothing)", shape=ellipse, style=filled];
|
||||||
|
"8108bcba-dbeb-4784-8f1f-eb9ede4ffb0e" -> "82a23405-c3c6-47dc-bf7b-0636e3efe52c";
|
||||||
|
"010d42ee-18b3-4a0e-9be1-eab67afaca60" [fillcolor=yellow, fontcolor=black, fontsize=20, label="Is(AC,Off)", shape=ellipse, style=filled];
|
||||||
|
"8108bcba-dbeb-4784-8f1f-eb9ede4ffb0e" -> "010d42ee-18b3-4a0e-9be1-eab67afaca60";
|
||||||
|
"90cdf2ff-98b0-4454-803b-feee5f5475bf" [fillcolor=lawngreen, fontcolor=black, fontsize=20, label="Turn(AC,On)", shape=box, style=filled];
|
||||||
|
"8108bcba-dbeb-4784-8f1f-eb9ede4ffb0e" -> "90cdf2ff-98b0-4454-803b-feee5f5475bf";
|
||||||
|
"e65ce322-edaa-4677-ab68-4795e57648da" [fillcolor=orange, fontcolor=black, fontsize=20, height=0.01, label=Sequence, shape=octagon, style=filled, width=0.01];
|
||||||
|
"87355232-8ad6-484e-b363-38536e737846" -> "e65ce322-edaa-4677-ab68-4795e57648da";
|
||||||
|
"7d0c1403-c5d9-4bcd-a0db-f3e527a3be93" [fillcolor=yellow, fontcolor=black, fontsize=20, label="Is(AC,Off)", shape=ellipse, style=filled];
|
||||||
|
"e65ce322-edaa-4677-ab68-4795e57648da" -> "7d0c1403-c5d9-4bcd-a0db-f3e527a3be93";
|
||||||
|
"931d4ea6-c661-4ea8-9016-2d4e17d30b19" [fillcolor=lawngreen, fontcolor=black, fontsize=20, label="FreeHands()", shape=box, style=filled];
|
||||||
|
"e65ce322-edaa-4677-ab68-4795e57648da" -> "931d4ea6-c661-4ea8-9016-2d4e17d30b19";
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 84 KiB |
|
@ -0,0 +1,199 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||||
|
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<!-- Generated by graphviz version 9.0.0 (20230911.1827)
|
||||||
|
-->
|
||||||
|
<!-- Title: pastafarianism Pages: 1 -->
|
||||||
|
<svg width="1818pt" height="235pt"
|
||||||
|
viewBox="0.00 0.00 1817.82 234.53" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 230.53)">
|
||||||
|
<title>pastafarianism</title>
|
||||||
|
<polygon fill="white" stroke="none" points="-4,4 -4,-230.53 1813.82,-230.53 1813.82,4 -4,4"/>
|
||||||
|
<!-- 87355232-8ad6-484e-b363-38536e737846 -->
|
||||||
|
<g id="node1" class="node">
|
||||||
|
<title>87355232-8ad6-484e-b363-38536e737846</title>
|
||||||
|
<polygon fill="cyan" stroke="black" points="825.2,-226.53 741.7,-195.28 825.2,-164.03 908.7,-195.28 825.2,-226.53"/>
|
||||||
|
<text text-anchor="middle" x="825.2" y="-187.9" font-family="Times New Roman,serif" font-size="20.00">Selector</text>
|
||||||
|
</g>
|
||||||
|
<!-- 3f017683-7aa3-40d3-b2be-cc32784313a1 -->
|
||||||
|
<g id="node2" class="node">
|
||||||
|
<title>3f017683-7aa3-40d3-b2be-cc32784313a1</title>
|
||||||
|
<ellipse fill="yellow" stroke="black" cx="282.2" cy="-104.11" rx="161.93" ry="22.1"/>
|
||||||
|
<text text-anchor="middle" x="282.2" y="-96.74" font-family="Times New Roman,serif" font-size="20.00">Is(ACTemperature,Down)</text>
|
||||||
|
</g>
|
||||||
|
<!-- 87355232-8ad6-484e-b363-38536e737846->3f017683-7aa3-40d3-b2be-cc32784313a1 -->
|
||||||
|
<g id="edge1" class="edge">
|
||||||
|
<title>87355232-8ad6-484e-b363-38536e737846->3f017683-7aa3-40d3-b2be-cc32784313a1</title>
|
||||||
|
<path fill="none" stroke="black" d="M768.11,-184.91C679.84,-170.41 508.52,-142.28 394.73,-123.59"/>
|
||||||
|
<polygon fill="black" stroke="black" points="395.49,-120.17 385.05,-122 394.35,-127.08 395.49,-120.17"/>
|
||||||
|
</g>
|
||||||
|
<!-- b900e9cb-c0a8-4e8d-8a9b-d871012abefb -->
|
||||||
|
<g id="node3" class="node">
|
||||||
|
<title>b900e9cb-c0a8-4e8d-8a9b-d871012abefb</title>
|
||||||
|
<polygon fill="orange" stroke="black" points="606.72,-94.2 606.72,-114.02 564.24,-128.03 504.16,-128.03 461.68,-114.02 461.68,-94.2 504.16,-80.19 564.24,-80.19 606.72,-94.2"/>
|
||||||
|
<text text-anchor="middle" x="534.2" y="-96.74" font-family="Times New Roman,serif" font-size="20.00">Sequence</text>
|
||||||
|
</g>
|
||||||
|
<!-- 87355232-8ad6-484e-b363-38536e737846->b900e9cb-c0a8-4e8d-8a9b-d871012abefb -->
|
||||||
|
<g id="edge2" class="edge">
|
||||||
|
<title>87355232-8ad6-484e-b363-38536e737846->b900e9cb-c0a8-4e8d-8a9b-d871012abefb</title>
|
||||||
|
<path fill="none" stroke="black" d="M780.05,-180.44C731.03,-165.43 652.4,-141.33 597.29,-124.44"/>
|
||||||
|
<polygon fill="black" stroke="black" points="598.63,-121.19 588.04,-121.61 596.58,-127.89 598.63,-121.19"/>
|
||||||
|
</g>
|
||||||
|
<!-- b64db1a4-d79f-47b4-99db-f184b38d1361 -->
|
||||||
|
<g id="node7" class="node">
|
||||||
|
<title>b64db1a4-d79f-47b4-99db-f184b38d1361</title>
|
||||||
|
<polygon fill="orange" stroke="black" points="897.72,-94.2 897.72,-114.02 855.24,-128.03 795.16,-128.03 752.68,-114.02 752.68,-94.2 795.16,-80.19 855.24,-80.19 897.72,-94.2"/>
|
||||||
|
<text text-anchor="middle" x="825.2" y="-96.74" font-family="Times New Roman,serif" font-size="20.00">Sequence</text>
|
||||||
|
</g>
|
||||||
|
<!-- 87355232-8ad6-484e-b363-38536e737846->b64db1a4-d79f-47b4-99db-f184b38d1361 -->
|
||||||
|
<g id="edge6" class="edge">
|
||||||
|
<title>87355232-8ad6-484e-b363-38536e737846->b64db1a4-d79f-47b4-99db-f184b38d1361</title>
|
||||||
|
<path fill="none" stroke="black" d="M825.2,-163.59C825.2,-155.97 825.2,-147.74 825.2,-139.93"/>
|
||||||
|
<polygon fill="black" stroke="black" points="828.7,-140.04 825.2,-130.04 821.7,-140.04 828.7,-140.04"/>
|
||||||
|
</g>
|
||||||
|
<!-- 8108bcba-dbeb-4784-8f1f-eb9ede4ffb0e -->
|
||||||
|
<g id="node10" class="node">
|
||||||
|
<title>8108bcba-dbeb-4784-8f1f-eb9ede4ffb0e</title>
|
||||||
|
<polygon fill="orange" stroke="black" points="1264.72,-94.2 1264.72,-114.02 1222.24,-128.03 1162.16,-128.03 1119.68,-114.02 1119.68,-94.2 1162.16,-80.19 1222.24,-80.19 1264.72,-94.2"/>
|
||||||
|
<text text-anchor="middle" x="1192.2" y="-96.74" font-family="Times New Roman,serif" font-size="20.00">Sequence</text>
|
||||||
|
</g>
|
||||||
|
<!-- 87355232-8ad6-484e-b363-38536e737846->8108bcba-dbeb-4784-8f1f-eb9ede4ffb0e -->
|
||||||
|
<g id="edge9" class="edge">
|
||||||
|
<title>87355232-8ad6-484e-b363-38536e737846->8108bcba-dbeb-4784-8f1f-eb9ede4ffb0e</title>
|
||||||
|
<path fill="none" stroke="black" d="M874.69,-182.25C938.8,-166.68 1050.9,-139.44 1123.3,-121.85"/>
|
||||||
|
<polygon fill="black" stroke="black" points="1123.77,-125.34 1132.66,-119.58 1122.11,-118.54 1123.77,-125.34"/>
|
||||||
|
</g>
|
||||||
|
<!-- e65ce322-edaa-4677-ab68-4795e57648da -->
|
||||||
|
<g id="node14" class="node">
|
||||||
|
<title>e65ce322-edaa-4677-ab68-4795e57648da</title>
|
||||||
|
<polygon fill="orange" stroke="black" points="1674.72,-94.2 1674.72,-114.02 1632.24,-128.03 1572.16,-128.03 1529.68,-114.02 1529.68,-94.2 1572.16,-80.19 1632.24,-80.19 1674.72,-94.2"/>
|
||||||
|
<text text-anchor="middle" x="1602.2" y="-96.74" font-family="Times New Roman,serif" font-size="20.00">Sequence</text>
|
||||||
|
</g>
|
||||||
|
<!-- 87355232-8ad6-484e-b363-38536e737846->e65ce322-edaa-4677-ab68-4795e57648da -->
|
||||||
|
<g id="edge13" class="edge">
|
||||||
|
<title>87355232-8ad6-484e-b363-38536e737846->e65ce322-edaa-4677-ab68-4795e57648da</title>
|
||||||
|
<path fill="none" stroke="black" d="M888.12,-187.06C1027.4,-171.08 1361.75,-132.71 1518.47,-114.72"/>
|
||||||
|
<polygon fill="black" stroke="black" points="1518.4,-118.25 1527.94,-113.63 1517.61,-111.3 1518.4,-118.25"/>
|
||||||
|
</g>
|
||||||
|
<!-- 10ef3ff4-7acb-4991-9e63-6e489c3ef22d -->
|
||||||
|
<g id="node4" class="node">
|
||||||
|
<title>10ef3ff4-7acb-4991-9e63-6e489c3ef22d</title>
|
||||||
|
<ellipse fill="yellow" stroke="black" cx="114.2" cy="-22.1" rx="114.2" ry="22.1"/>
|
||||||
|
<text text-anchor="middle" x="114.2" y="-14.72" font-family="Times New Roman,serif" font-size="20.00">Holding(Nothing)</text>
|
||||||
|
</g>
|
||||||
|
<!-- b900e9cb-c0a8-4e8d-8a9b-d871012abefb->10ef3ff4-7acb-4991-9e63-6e489c3ef22d -->
|
||||||
|
<g id="edge3" class="edge">
|
||||||
|
<title>b900e9cb-c0a8-4e8d-8a9b-d871012abefb->10ef3ff4-7acb-4991-9e63-6e489c3ef22d</title>
|
||||||
|
<path fill="none" stroke="black" d="M481.26,-87.23C471.95,-84.69 462.32,-82.24 453.2,-80.19 358.23,-58.91 333.16,-60.42 237.2,-44.19 228.06,-42.65 218.55,-41.03 209.03,-39.41"/>
|
||||||
|
<polygon fill="black" stroke="black" points="209.82,-35.99 199.38,-37.76 208.65,-42.89 209.82,-35.99"/>
|
||||||
|
</g>
|
||||||
|
<!-- a3869371-404d-4085-932b-232e188fb133 -->
|
||||||
|
<g id="node5" class="node">
|
||||||
|
<title>a3869371-404d-4085-932b-232e188fb133</title>
|
||||||
|
<ellipse fill="yellow" stroke="black" cx="317.2" cy="-22.1" rx="71.24" ry="22.1"/>
|
||||||
|
<text text-anchor="middle" x="317.2" y="-14.72" font-family="Times New Roman,serif" font-size="20.00">Is(AC,On)</text>
|
||||||
|
</g>
|
||||||
|
<!-- b900e9cb-c0a8-4e8d-8a9b-d871012abefb->a3869371-404d-4085-932b-232e188fb133 -->
|
||||||
|
<g id="edge4" class="edge">
|
||||||
|
<title>b900e9cb-c0a8-4e8d-8a9b-d871012abefb->a3869371-404d-4085-932b-232e188fb133</title>
|
||||||
|
<path fill="none" stroke="black" d="M486.58,-85.55C453,-73.17 407.91,-56.55 372.7,-43.56"/>
|
||||||
|
<polygon fill="black" stroke="black" points="374.13,-40.36 363.53,-40.18 371.71,-46.93 374.13,-40.36"/>
|
||||||
|
</g>
|
||||||
|
<!-- 3a5cbe8f-7672-4a34-91d1-87502aed457c -->
|
||||||
|
<g id="node6" class="node">
|
||||||
|
<title>3a5cbe8f-7672-4a34-91d1-87502aed457c</title>
|
||||||
|
<polygon fill="lawngreen" stroke="black" points="661.82,-40.1 406.57,-40.1 406.57,-4.1 661.82,-4.1 661.82,-40.1"/>
|
||||||
|
<text text-anchor="middle" x="534.2" y="-14.72" font-family="Times New Roman,serif" font-size="20.00">Turn(ACTemperature,Down)</text>
|
||||||
|
</g>
|
||||||
|
<!-- b900e9cb-c0a8-4e8d-8a9b-d871012abefb->3a5cbe8f-7672-4a34-91d1-87502aed457c -->
|
||||||
|
<g id="edge5" class="edge">
|
||||||
|
<title>b900e9cb-c0a8-4e8d-8a9b-d871012abefb->3a5cbe8f-7672-4a34-91d1-87502aed457c</title>
|
||||||
|
<path fill="none" stroke="black" d="M534.2,-79.97C534.2,-71.24 534.2,-61.2 534.2,-52.01"/>
|
||||||
|
<polygon fill="black" stroke="black" points="537.7,-52.11 534.2,-42.11 530.7,-52.11 537.7,-52.11"/>
|
||||||
|
</g>
|
||||||
|
<!-- c6eca6dd-9fca-4bd3-b054-9b43fe02613a -->
|
||||||
|
<g id="node8" class="node">
|
||||||
|
<title>c6eca6dd-9fca-4bd3-b054-9b43fe02613a</title>
|
||||||
|
<ellipse fill="yellow" stroke="black" cx="751.2" cy="-22.1" rx="71.24" ry="22.1"/>
|
||||||
|
<text text-anchor="middle" x="751.2" y="-14.72" font-family="Times New Roman,serif" font-size="20.00">Is(AC,On)</text>
|
||||||
|
</g>
|
||||||
|
<!-- b64db1a4-d79f-47b4-99db-f184b38d1361->c6eca6dd-9fca-4bd3-b054-9b43fe02613a -->
|
||||||
|
<g id="edge7" class="edge">
|
||||||
|
<title>b64db1a4-d79f-47b4-99db-f184b38d1361->c6eca6dd-9fca-4bd3-b054-9b43fe02613a</title>
|
||||||
|
<path fill="none" stroke="black" d="M803.79,-79.97C795.77,-71.29 786.55,-61.33 778.1,-52.18"/>
|
||||||
|
<polygon fill="black" stroke="black" points="780.67,-49.81 771.31,-44.85 775.53,-54.56 780.67,-49.81"/>
|
||||||
|
</g>
|
||||||
|
<!-- df04f6f4-d471-4519-ab9e-5d5bd8dfbd4c -->
|
||||||
|
<g id="node9" class="node">
|
||||||
|
<title>df04f6f4-d471-4519-ab9e-5d5bd8dfbd4c</title>
|
||||||
|
<polygon fill="lawngreen" stroke="black" points="957.82,-40.1 840.57,-40.1 840.57,-4.1 957.82,-4.1 957.82,-40.1"/>
|
||||||
|
<text text-anchor="middle" x="899.2" y="-14.72" font-family="Times New Roman,serif" font-size="20.00">FreeHands()</text>
|
||||||
|
</g>
|
||||||
|
<!-- b64db1a4-d79f-47b4-99db-f184b38d1361->df04f6f4-d471-4519-ab9e-5d5bd8dfbd4c -->
|
||||||
|
<g id="edge8" class="edge">
|
||||||
|
<title>b64db1a4-d79f-47b4-99db-f184b38d1361->df04f6f4-d471-4519-ab9e-5d5bd8dfbd4c</title>
|
||||||
|
<path fill="none" stroke="black" d="M846.6,-79.97C855.58,-70.26 866.06,-58.93 875.29,-48.94"/>
|
||||||
|
<polygon fill="black" stroke="black" points="877.77,-51.42 881.99,-41.71 872.63,-46.67 877.77,-51.42"/>
|
||||||
|
</g>
|
||||||
|
<!-- 82a23405-c3c6-47dc-bf7b-0636e3efe52c -->
|
||||||
|
<g id="node11" class="node">
|
||||||
|
<title>82a23405-c3c6-47dc-bf7b-0636e3efe52c</title>
|
||||||
|
<ellipse fill="yellow" stroke="black" cx="1090.2" cy="-22.1" rx="114.2" ry="22.1"/>
|
||||||
|
<text text-anchor="middle" x="1090.2" y="-14.72" font-family="Times New Roman,serif" font-size="20.00">Holding(Nothing)</text>
|
||||||
|
</g>
|
||||||
|
<!-- 8108bcba-dbeb-4784-8f1f-eb9ede4ffb0e->82a23405-c3c6-47dc-bf7b-0636e3efe52c -->
|
||||||
|
<g id="edge10" class="edge">
|
||||||
|
<title>8108bcba-dbeb-4784-8f1f-eb9ede4ffb0e->82a23405-c3c6-47dc-bf7b-0636e3efe52c</title>
|
||||||
|
<path fill="none" stroke="black" d="M1162.42,-79.75C1150.89,-70.71 1137.61,-60.29 1125.6,-50.87"/>
|
||||||
|
<polygon fill="black" stroke="black" points="1127.93,-48.25 1117.9,-44.83 1123.61,-53.76 1127.93,-48.25"/>
|
||||||
|
</g>
|
||||||
|
<!-- 010d42ee-18b3-4a0e-9be1-eab67afaca60 -->
|
||||||
|
<g id="node12" class="node">
|
||||||
|
<title>010d42ee-18b3-4a0e-9be1-eab67afaca60</title>
|
||||||
|
<ellipse fill="yellow" stroke="black" cx="1294.2" cy="-22.1" rx="72.3" ry="22.1"/>
|
||||||
|
<text text-anchor="middle" x="1294.2" y="-14.72" font-family="Times New Roman,serif" font-size="20.00">Is(AC,Off)</text>
|
||||||
|
</g>
|
||||||
|
<!-- 8108bcba-dbeb-4784-8f1f-eb9ede4ffb0e->010d42ee-18b3-4a0e-9be1-eab67afaca60 -->
|
||||||
|
<g id="edge11" class="edge">
|
||||||
|
<title>8108bcba-dbeb-4784-8f1f-eb9ede4ffb0e->010d42ee-18b3-4a0e-9be1-eab67afaca60</title>
|
||||||
|
<path fill="none" stroke="black" d="M1221.97,-79.75C1233.78,-70.49 1247.44,-59.78 1259.68,-50.18"/>
|
||||||
|
<polygon fill="black" stroke="black" points="1261.8,-52.96 1267.51,-44.03 1257.48,-47.45 1261.8,-52.96"/>
|
||||||
|
</g>
|
||||||
|
<!-- 90cdf2ff-98b0-4454-803b-feee5f5475bf -->
|
||||||
|
<g id="node13" class="node">
|
||||||
|
<title>90cdf2ff-98b0-4454-803b-feee5f5475bf</title>
|
||||||
|
<polygon fill="lawngreen" stroke="black" points="1511.7,-40.1 1384.7,-40.1 1384.7,-4.1 1511.7,-4.1 1511.7,-40.1"/>
|
||||||
|
<text text-anchor="middle" x="1448.2" y="-14.72" font-family="Times New Roman,serif" font-size="20.00">Turn(AC,On)</text>
|
||||||
|
</g>
|
||||||
|
<!-- 8108bcba-dbeb-4784-8f1f-eb9ede4ffb0e->90cdf2ff-98b0-4454-803b-feee5f5475bf -->
|
||||||
|
<g id="edge12" class="edge">
|
||||||
|
<title>8108bcba-dbeb-4784-8f1f-eb9ede4ffb0e->90cdf2ff-98b0-4454-803b-feee5f5475bf</title>
|
||||||
|
<path fill="none" stroke="black" d="M1244,-86.92C1283.65,-74.53 1338.64,-57.34 1381.56,-43.93"/>
|
||||||
|
<polygon fill="black" stroke="black" points="1382.53,-47.29 1391.03,-40.96 1380.44,-40.61 1382.53,-47.29"/>
|
||||||
|
</g>
|
||||||
|
<!-- 7d0c1403-c5d9-4bcd-a0db-f3e527a3be93 -->
|
||||||
|
<g id="node15" class="node">
|
||||||
|
<title>7d0c1403-c5d9-4bcd-a0db-f3e527a3be93</title>
|
||||||
|
<ellipse fill="yellow" stroke="black" cx="1602.2" cy="-22.1" rx="72.3" ry="22.1"/>
|
||||||
|
<text text-anchor="middle" x="1602.2" y="-14.72" font-family="Times New Roman,serif" font-size="20.00">Is(AC,Off)</text>
|
||||||
|
</g>
|
||||||
|
<!-- e65ce322-edaa-4677-ab68-4795e57648da->7d0c1403-c5d9-4bcd-a0db-f3e527a3be93 -->
|
||||||
|
<g id="edge14" class="edge">
|
||||||
|
<title>e65ce322-edaa-4677-ab68-4795e57648da->7d0c1403-c5d9-4bcd-a0db-f3e527a3be93</title>
|
||||||
|
<path fill="none" stroke="black" d="M1602.2,-79.97C1602.2,-72.46 1602.2,-63.99 1602.2,-55.92"/>
|
||||||
|
<polygon fill="black" stroke="black" points="1605.7,-56.06 1602.2,-46.06 1598.7,-56.06 1605.7,-56.06"/>
|
||||||
|
</g>
|
||||||
|
<!-- 931d4ea6-c661-4ea8-9016-2d4e17d30b19 -->
|
||||||
|
<g id="node16" class="node">
|
||||||
|
<title>931d4ea6-c661-4ea8-9016-2d4e17d30b19</title>
|
||||||
|
<polygon fill="lawngreen" stroke="black" points="1809.82,-40.1 1692.57,-40.1 1692.57,-4.1 1809.82,-4.1 1809.82,-40.1"/>
|
||||||
|
<text text-anchor="middle" x="1751.2" y="-14.72" font-family="Times New Roman,serif" font-size="20.00">FreeHands()</text>
|
||||||
|
</g>
|
||||||
|
<!-- e65ce322-edaa-4677-ab68-4795e57648da->931d4ea6-c661-4ea8-9016-2d4e17d30b19 -->
|
||||||
|
<g id="edge15" class="edge">
|
||||||
|
<title>e65ce322-edaa-4677-ab68-4795e57648da->931d4ea6-c661-4ea8-9016-2d4e17d30b19</title>
|
||||||
|
<path fill="none" stroke="black" d="M1640.57,-82.51C1661.56,-71.23 1687.6,-57.25 1709.14,-45.68"/>
|
||||||
|
<polygon fill="black" stroke="black" points="1710.51,-48.92 1717.67,-41.1 1707.2,-42.75 1710.51,-48.92"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 14 KiB |
|
@ -215,12 +215,14 @@ class Scene:
|
||||||
"sub_goal_list": [], # 子目标列表
|
"sub_goal_list": [], # 子目标列表
|
||||||
"status": None, # 仿真器中的观测信息,见下方详细解释
|
"status": None, # 仿真器中的观测信息,见下方详细解释
|
||||||
"condition_set": {'At(Robot,Bar)', 'Is(AC,Off)',
|
"condition_set": {'At(Robot,Bar)', 'Is(AC,Off)',
|
||||||
'Holding(Nothing)', 'Exist(Yogurt)', 'Exist(BottledDrink)',
|
'Exist(Yogurt)', 'Exist(BottledDrink)','Exist(Softdrink)',
|
||||||
'Exist(Softdrink)',
|
|
||||||
# 'On(Yogurt,Bar)','On(BottledDrink,Bar)',
|
# 'On(Yogurt,Bar)','On(BottledDrink,Bar)',
|
||||||
# 'Exist(Softdrink)', 'On(Softdrink,Table1)',
|
# 'Exist(Softdrink)', 'On(Softdrink,Table1)',
|
||||||
'Exist(Chips)', 'Exist(NFCJuice)', 'Exist(Bernachon)', 'Exist(ADMilk)', 'Exist(SpringWater)',
|
'Exist(Chips)', 'Exist(NFCJuice)', 'Exist(Bernachon)', 'Exist(ADMilk)', 'Exist(SpringWater)',
|
||||||
|
|
||||||
|
# 'Holding(Nothing)',
|
||||||
|
'Holding(Coffee)',
|
||||||
|
|
||||||
'Exist(VacuumCup)', 'On(VacuumCup,Table2)',
|
'Exist(VacuumCup)', 'On(VacuumCup,Table2)',
|
||||||
'Is(HallLight,Off)', 'Is(TubeLight,On)', 'Is(Curtain,On)',
|
'Is(HallLight,Off)', 'Is(TubeLight,On)', 'Is(Curtain,On)',
|
||||||
'Is(Table1,Dirty)', 'Is(Floor,Dirty)', 'Is(Chairs,Dirty)'},
|
'Is(Table1,Dirty)', 'Is(Floor,Dirty)', 'Is(Chairs,Dirty)'},
|
||||||
|
@ -264,7 +266,7 @@ class Scene:
|
||||||
# 是否展示UI
|
# 是否展示UI
|
||||||
self.show_ui = False
|
self.show_ui = False
|
||||||
# 图像分割
|
# 图像分割
|
||||||
self.take_picture = True
|
self.take_picture = False
|
||||||
self.map_ratio = 5
|
self.map_ratio = 5
|
||||||
self.map_map = np.zeros((math.ceil(950 / self.map_ratio), math.ceil(1850 / self.map_ratio)))
|
self.map_map = np.zeros((math.ceil(950 / self.map_ratio), math.ceil(1850 / self.map_ratio)))
|
||||||
self.db = DBSCAN(eps=self.map_ratio, min_samples=int(self.map_ratio / 2))
|
self.db = DBSCAN(eps=self.map_ratio, min_samples=int(self.map_ratio / 2))
|
||||||
|
@ -272,6 +274,8 @@ class Scene:
|
||||||
|
|
||||||
self.is_nav_walk = False
|
self.is_nav_walk = False
|
||||||
|
|
||||||
|
self.bt_algo_opt = True
|
||||||
|
|
||||||
file_name = os.path.join(root_path,'robowaiter/algos/navigator/map_5.pkl')
|
file_name = os.path.join(root_path,'robowaiter/algos/navigator/map_5.pkl')
|
||||||
if os.path.exists(file_name):
|
if os.path.exists(file_name):
|
||||||
with open(file_name, 'rb') as file:
|
with open(file_name, 'rb') as file:
|
||||||
|
@ -451,6 +455,7 @@ class Scene:
|
||||||
print(f'event: {t}, {func.__name__}')
|
print(f'event: {t}, {func.__name__}')
|
||||||
self.signal_event_list.pop(0)
|
self.signal_event_list.pop(0)
|
||||||
self.last_event_time = self.time
|
self.last_event_time = self.time
|
||||||
|
print("==== *args ======:",*args)
|
||||||
func(*args)
|
func(*args)
|
||||||
|
|
||||||
def deal_event(self):
|
def deal_event(self):
|
||||||
|
@ -474,6 +479,7 @@ class Scene:
|
||||||
def set_goal(self, goal):
|
def set_goal(self, goal):
|
||||||
g = eval("{'" + goal + "'}")
|
g = eval("{'" + goal + "'}")
|
||||||
|
|
||||||
|
print("====== g =======:",g)
|
||||||
def set_sub_task():
|
def set_sub_task():
|
||||||
self.state['chat_list'].append(("Goal", g))
|
self.state['chat_list'].append(("Goal", g))
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
"""
|
||||||
|
人提出请求,机器人完成任务
|
||||||
|
1. 做咖啡(固定动画):接收到做咖啡指令、走到咖啡机、拿杯子、操作咖啡机、取杯子、送到客人桌子上
|
||||||
|
2. 倒水
|
||||||
|
3. 夹点心
|
||||||
|
|
||||||
|
具体描述:设计一套点单规则(如菜单包含咖啡、水、点心等),按照规则拟造随机的订单。在收到订单后,通过大模型让机器人输出合理的备餐计划,并尝试在模拟环境中按照这个规划实现任务。
|
||||||
|
|
||||||
|
"""
|
||||||
|
import time
|
||||||
|
|
||||||
|
# todo: 接收点单信息,大模型生成任务规划
|
||||||
|
|
||||||
|
from robowaiter.scene.scene import Scene
|
||||||
|
|
||||||
|
class SceneOT(Scene):
|
||||||
|
|
||||||
|
def __init__(self, robot):
|
||||||
|
super().__init__(robot)
|
||||||
|
# 在这里加入场景中发生的事件
|
||||||
|
# self.event_list = [
|
||||||
|
# # (3, self.set_goal("On(VacuumCup,Bar)"))
|
||||||
|
# (3, self.set_goal("On(Yogurt,Bar)"))
|
||||||
|
# ]
|
||||||
|
self.signal_event_list =[
|
||||||
|
# (3, self.set_goal,("On(Yogurt,Bar)",)),
|
||||||
|
# (3, self.customer_say, ("System", "把盒装冰红茶放到水桌")),
|
||||||
|
(3, self.customer_say, ("System", "打开空调并降低空调温度")),
|
||||||
|
]
|
||||||
|
|
||||||
|
def _reset(self):
|
||||||
|
scene = self.add_walkers([[0, 0], [250, 1200], [-55, 750], [70, -200]])
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _run(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import os
|
||||||
|
from robowaiter.robot.robot import Robot
|
||||||
|
|
||||||
|
robot = Robot()
|
||||||
|
|
||||||
|
# create task
|
||||||
|
task = SceneOT(robot)
|
||||||
|
task.reset()
|
||||||
|
task.run()
|
Loading…
Reference in New Issue