增加顾客记忆

This commit is contained in:
ChenXL97 2023-11-18 12:07:30 +08:00
parent da4ed7280e
commit 935c359317
13 changed files with 185 additions and 15 deletions

View File

@ -83,6 +83,7 @@ class Bahavior(ptree.behaviour.Behaviour):
# let behavior node interact with the scene
def set_scene(self, scene):
self.scene = scene
self.robot = scene.robot
def setup(self, **kwargs: Any) -> None:
return super().setup(**kwargs)

View File

@ -10,6 +10,9 @@ class DealChat(Act):
def _update(self) -> ptree.common.Status:
# if self.scene.status?
name,sentence = self.scene.state['chat_list'][0]
chat = self.scene.state['chat_list'].pop()
if isinstance(chat,set):
self.create_sub_task(chat)

View File

@ -0,0 +1,31 @@
import py_trees as ptree
from robowaiter.behavior_lib._base.Act import Act
from robowaiter.algos.navigator.navigate import Navigator
class GreetCustomer(Act):
can_be_expanded = True
num_args = 0
valid_args = ()
def __init__(self, *args):
super().__init__(*args)
@classmethod
def get_info(cls):
info = {}
info['pre'] = set()
info["add"] = set()
info["del_set"] = set()
info['cost']=0
return info
def _update(self) -> ptree.common.Status:
goal = Act.place_xyz_dic['Bar']
self.scene.walk_to(goal[0]-5,goal[1], 180, 180, 0)
self.scene.chat_bubble("欢迎光临!请问有什么可以帮您?")
customer_name = self.scene.state['attention']['customer']
self.scene.state['greeted_customers'].add(customer_name)
return ptree.common.Status.RUNNING

View File

@ -2,7 +2,7 @@ import py_trees as ptree
from robowaiter.behavior_lib._base.Act import Act
from robowaiter.algos.navigator.navigate import Navigator
class GreatCustomer(Act):
class ServeCustomer(Act):
can_be_expanded = False
num_args = 0
valid_args = ()
@ -14,7 +14,7 @@ class GreatCustomer(Act):
def get_info(cls):
info = {}
info['pre'] = set()
info["add"] = set()
info["add"] = {"CustomerServed()"}
info["del_set"] = set()
info['cost']=0
return info

View File

@ -0,0 +1,24 @@
import py_trees as ptree
from typing import Any
from robowaiter.behavior_lib._base.Cond import Cond
import itertools
class CustomerServed(Cond):
can_be_expanded = True
def __init__(self,*args):
super().__init__(*args)
def _update(self) -> ptree.common.Status:
# if self.scene.status?
if self.name in self.scene.state["condition_set"]:
return ptree.common.Status.SUCCESS
else:
return ptree.common.Status.FAILURE
# if self.scene.state['chat_list'] == []:
# return ptree.common.Status.FAILURE
# else:
# return ptree.common.Status.SUCCESS

View File

@ -18,14 +18,21 @@ class DetectCustomer(Cond):
# bar (247.0, 520.0, 100.0)
close_to_bar = False
scene = self.scene.status
queue_list = []
for walker in scene.walkers:
x, y, yaw = walker.pose.X, walker.pose.Y, walker.pose.Yaw
# 到达一定区域就打招呼
if y >= 450 and y <= 620 and x >= 40 and x <= 100 and yaw>=-10 and yaw <=10:
close_to_bar = True
break
# close_to_bar = True
queue_list.append((x,y,walker.name))
if close_to_bar:
if queue_list == []:
return ptree.common.Status.FAILURE
queue_list.sort()
x,y,name = queue_list[0]
if name not in self.scene.state["greet_set"]:
self.scene.state['attention']["customer"] = name
return ptree.common.Status.SUCCESS
else:
return ptree.common.Status.FAILURE

View File

@ -36,7 +36,7 @@ if __name__ == "__main__":
question = input("\n顾客:")
data_memory = [{
"role": "system",
"content": "你是RoboWaiter,一个由HPCL团队开发的机器人服务员你在咖啡厅工作。接受顾客的指令并调用工具函数来完成各种服务任务。",
"content": "你是RoboWaiter,一个由HPCL团队开发的机器人服务员你在咖啡厅工作。接受顾客的指令并调用工具函数来完成各种服务任务。如果顾客问你们这里有什么,或者想要点单,你说我们咖啡厅提供咖啡,水,点心,酸奶等食物。如果顾客不需要你了,你就回到吧台招待。",
},]
n = 1
max_retry = 5

View File

@ -49,6 +49,7 @@ def show_image(camera_data):
class Scene:
robot = None
event_list = []
new_event_list = []
show_bubble = False
default_state = {
@ -62,7 +63,12 @@ class Scene:
"condition_set": {'At(Robot,Bar)', 'Is(AC,Off)',
'Holding(Nothing)','Exist(Yogurt)','Exist(BottledDrink)','On(Yogurt,Bar)','On(BottledDrink,Table1)',
'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)'},
"obj_mem":{},
"customer_mem":{},
"served_mem":{},
"greeted_customers":set(),
"attention":{}
}
"""
status:
@ -143,9 +149,20 @@ class Scene:
self.time = time.time() - self.start_time
self.deal_event()
self.deal_new_event()
self._step()
self.robot.step()
def deal_new_event(self):
if len(self.new_event_list)>0:
next_event = self.new_event_list[0]
t,func,args = next_event
if self.time >= t:
print(f'event: {t}, {func.__name__}')
self.new_event_list.pop(0)
func(*args)
def deal_event(self):
if len(self.event_list)>0:
next_event = self.event_list[0]
@ -171,6 +188,10 @@ class Scene:
return set_sub_task
def new_set_goal(self,goal):
g = eval("{'" + goal + "'}")
self.state['chat_list'].append(g)
@property
def status(self):
@ -196,7 +217,6 @@ class Scene:
pass
def walker_control_generator(self, walkerID, autowalk, speed, X, Y, Yaw):
if self.use_offset:
X, Y = X + loc_offset[0], Y + loc_offset[1]
@ -216,6 +236,10 @@ class Scene:
return scene
def walker_walk_to(self,walkerID,X,Y,speed=50,Yaw=0):
self.control_walker(
[self.walker_control_generator(walkerID=walkerID, autowalk=False, speed=speed, X=X, Y=Y, Yaw=Yaw)])
def reachable_check(self, X, Y, Yaw):
if self.use_offset:
@ -243,9 +267,19 @@ class Scene:
print('当前位置不可达,无法初始化NPC')
else:
walker_list.append(
GrabSim_pb2.WalkerList.Walker(id=id+5, pose=GrabSim_pb2.Pose(X=loc[0], Y=loc[1], Yaw=loc[2])))
GrabSim_pb2.WalkerList.Walker(id=id, pose=GrabSim_pb2.Pose(X=loc[0], Y=loc[1], Yaw=loc[2])))
stub.AddWalker(GrabSim_pb2.WalkerList(walkers=walker_list, scene=self.sceneID))
w = self.status.walkers
num_customer = len(w)
self.state["customer_mem"][w[-1].name] = num_customer-1
def walker_index2mem(self,index):
for mem,i in self.state["customer_mem"].items():
if index == i:
return mem
def add_walkers(self,walker_loc=[[0, 880], [250, 1200], [-55, 750], [70, -200]]):
print('------------------add_walkers----------------------')
for id,walker in enumerate(walker_loc):
@ -267,8 +301,16 @@ class Scene:
# walkerID is the index of the walker in status.walkers.
# Since status.walkers is a list, some walkerIDs would change after removing a walker.
remove_list.append(walkerID)
index_shift_list = [ 0 for _ in range(len(self.state["customer_mem"])) ]
stub.RemoveWalkers(GrabSim_pb2.RemoveList(IDs=remove_list, scene=self.sceneID))
w = self.status.walkers
for i in range(len(w)):
self.state["customer_mem"][w[i].name] = i
def clean_walker(self):
stub.CleanWalkers(GrabSim_pb2.SceneID(value=self.sceneID))
@ -382,11 +424,15 @@ class Scene:
)
)
# def walker_bubble(self, message):
# status = self.status
# walker_name = status.walkers[0].name
# talk_content = walker_name + ":" + message
# self.control_robot_action(0, 0, 3, talk_content)
def walker_bubble(self, name, message):
talk_content = name + ":" + message
self.control_robot_action(0, 3, talk_content)
def customer_say(self,name,sentence,show_bubble=True):
print(f'{name} say: {sentence}')
if show_bubble:
self.walker_bubble(name,sentence)
self.state['chat_list'].append((name,sentence))
# def control_robot_action(self, scene_id=0, type=0, action=0, message="你好"):
# print('------------------control_robot_action----------------------')
@ -474,6 +520,8 @@ class Scene:
scene = stub.Do(action)
print("After Walk Position:", [scene.location.X, scene.location.Y, scene.rotation.Yaw])
# 相应的行动,由主办方封装
def control_robot_action(self, type=0, action=0, message="你好"):
scene = stub.ControlRobot(

View File

@ -32,7 +32,6 @@ class SceneAT(Scene):
pass
if __name__ == '__main__':
import os
from robowaiter.robot.robot import Robot
robot = Robot()

View File

@ -0,0 +1,57 @@
"""
人提出请求机器人完成任务
1. 做咖啡固定动画接收到做咖啡指令走到咖啡机拿杯子操作咖啡机取杯子送到客人桌子上
2. 倒水
3. 夹点心
具体描述设计一套点单规则如菜单包含咖啡点心等按照规则拟造随机的订单在收到订单后通过大模型让机器人输出合理的备餐计划并尝试在模拟环境中按照这个规划实现任务
"""
# todo: 接收点单信息,大模型生成任务规划
from robowaiter.scene.scene import Scene
class SceneOT(Scene):
def __init__(self, robot):
super().__init__(robot)
# 在这里加入场景中发生的事件
self.new_event_list = [
# (9,self.add_walkers,([[0, 880]],)),
# (10,self.walker_walk_to,(2,50,500))
# (5, self.set_goal("On(Yogurt,Table4)"))
# (5, self.set_goal("At(Robot,BrightTable4)"))
]
def _reset(self):
# self.add_walkers([[0, 880], [250, 1200]])
# 展示顾客前8个id是小孩后面都是大人
for i in range(4):
self.add_walker(i,50,300 + i * 50)
name1 = self.walker_index2mem(1)
name2 = self.walker_index2mem(3)
self.remove_walker(0,2)
index1 = self.state["customer_mem"][name1]
index2 = self.state["customer_mem"][name2]
self.walker_bubble(name1,f"我是第{index1}")
self.walker_bubble(name2,f"我是第{index2}")
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()

View File