Merge branch 'main' of https://github.com/HPCL-EI/RoboWaiter into main
This commit is contained in:
commit
e9444e65c0
75
README.md
75
README.md
|
@ -1,15 +1,65 @@
|
|||
# RoboWaiter
|
||||
大模型具身智能比赛-机器人控制端
|
||||
|
||||
### 机器人控制
|
||||
1. 加载场景
|
||||
```python
|
||||
from scene_utils import control
|
||||
control.init_world(scene_num=1, mapID=3)
|
||||
```
|
||||
当前只有一个咖啡馆场景。加载操作只需要执行一遍,当引擎进入相应场景后,可以用`control.reset()`重置场景。
|
||||
# 项目安装(必看)
|
||||
## 环境要求
|
||||
Python=3.10
|
||||
|
||||
2. 物品类别
|
||||
### 安装步骤
|
||||
```shell
|
||||
cd RoboWaiter
|
||||
pip install -e .
|
||||
```
|
||||
以上步骤将完成robowaiter项目以及相关依赖库的安装
|
||||
|
||||
### 快速入门
|
||||
1. 安装UE及Harix插件,打开默认项目并运行
|
||||
2. 运行 run_robowaiter.py 文件即可实现机器人控制端与仿真器的交互
|
||||
|
||||
|
||||
# 运行流程介绍
|
||||
run_robowaiter.py 入口文件如下:
|
||||
```python
|
||||
import os
|
||||
from robowaiter import Robot, task_map
|
||||
|
||||
TASK_NAME = 'GQA'
|
||||
|
||||
# create robot
|
||||
project_path = "./robowaiter"
|
||||
ptml_path = os.path.join(project_path, 'robot/Default.ptml')
|
||||
behavior_lib_path = os.path.join(project_path, 'behavior_lib')
|
||||
|
||||
robot = Robot(ptml_path,behavior_lib_path)
|
||||
|
||||
# create task
|
||||
task = task_map[TASK_NAME](robot)
|
||||
task.reset()
|
||||
task.run()
|
||||
```
|
||||
|
||||
## Robot
|
||||
Robot是机器人类,包括从ptml加载行为树的方法,以及执行行为树的方法等
|
||||
|
||||
|
||||
## task_map
|
||||
task_map是任务字典,通过任务缩写来返回相应的场景类。
|
||||
|
||||
| 缩写 | 任务 |
|
||||
|----|---------|
|
||||
| AEM | 主动探索和记忆 |
|
||||
| GQA | 具身多轮对话 |
|
||||
| VLN | 视觉语言导航 |
|
||||
| VLM | 视觉语言操作 |
|
||||
| OT | 复杂开放任务 |
|
||||
| AT | 自主任务 |
|
||||
|
||||
|
||||
## Scene
|
||||
Scene是场景基类,task_map返回的任务场景都继承于Scene。
|
||||
该类实现了一些通用的场景操作接口。
|
||||
|
||||
### 场景中物品类别
|
||||
|
||||
| ID | Item |
|
||||
|-----|----------------------|
|
||||
|
@ -115,4 +165,11 @@ control.init_world(scene_num=1, mapID=3)
|
|||
| 252 | Floor |
|
||||
| 253 | Roof |
|
||||
| 254 | Wall |
|
||||
注意:78及以后无法使用add_object方法生成
|
||||
注意:78及以后无法使用add_object方法生成
|
||||
|
||||
# 调用大模型接口
|
||||
运行llm_client.py文件调用大模型进行多轮对话。
|
||||
```shell
|
||||
python llm_client.py
|
||||
```
|
||||
输入字符即可等待回答,输入end表示对话结束。
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
import requests
|
||||
import urllib3
|
||||
|
||||
########################################
|
||||
# 该文件实现了与大模型的简单通信、多轮对话,输入end表示对话结束
|
||||
########################################
|
||||
|
||||
# 忽略https的安全性警告
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
url = "https://45.125.46.134:25344/v1/chat/completions"
|
||||
headers = {"Content-Type": "application/json"}
|
||||
|
||||
#在这里输入你的问题
|
||||
k=input()
|
||||
data_memory=[]
|
||||
n=1
|
||||
while k!='end':
|
||||
question_now=k
|
||||
user_dict={"role": "user","content":question_now}
|
||||
data_memory.append(user_dict)
|
||||
#print(data_memory)
|
||||
response = requests.post(url, headers=headers, json={"messages":data_memory, "repetition_penalty": 1.0}, verify=False)
|
||||
answer=response.json()['choices'][n]['message']['content']
|
||||
print(answer)
|
||||
assistant_dict={"role": "assistant","content":answer}
|
||||
data_memory.append(assistant_dict)
|
||||
n=n+2
|
||||
k=input()
|
|
@ -1,28 +0,0 @@
|
|||
import requests
|
||||
import urllib3
|
||||
|
||||
########################################
|
||||
# 该文件实现了与大模型的简单通信
|
||||
########################################
|
||||
|
||||
# 忽略https的安全性警告
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
#在这里输入你的问题
|
||||
question = "假设你是一个咖啡厅的机器人服务员,有一个顾客的请求是'请给我一杯咖啡',请生成对应的行为树来控制机器人完成该动作"
|
||||
|
||||
url = "https://45.125.46.134:25344/v1/completions"
|
||||
headers = {"Content-Type": "application/json"}
|
||||
data = {
|
||||
"prompt": question
|
||||
}
|
||||
|
||||
response = requests.post(url, headers=headers, json=data, verify=False)
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
print(f'问题:{question}')
|
||||
print('回答:' + result['choices'][0]['text'])
|
||||
else:
|
||||
print("请求失败:", response.status_code)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
antlr4-python3-runtime
|
||||
py_trees
|
||||
shortuuid
|
||||
protobuf==3.20.0
|
||||
gym==0.21.0
|
||||
grpcio==1.53.0
|
||||
requests
|
||||
urllib3
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
from robowaiter.robot.robot import Robot
|
||||
from robowaiter.scene import task_map
|
|
@ -0,0 +1,22 @@
|
|||
import py_trees as ptree
|
||||
from typing import Any
|
||||
|
||||
# base Behavior
|
||||
class Bahavior(ptree.behaviour.Behaviour):
|
||||
scene = None
|
||||
def __init__(self, name: str, scene):
|
||||
super().__init__(name)
|
||||
self.scene = scene
|
||||
|
||||
def setup(self, **kwargs: Any) -> None:
|
||||
return super().setup(**kwargs)
|
||||
|
||||
def initialise(self) -> None:
|
||||
return super().initialise()
|
||||
|
||||
def update(self) -> ptree.common.Status:
|
||||
print("this is a base behavior node.")
|
||||
return ptree.common.Status.SUCCESS
|
||||
|
||||
def terminate(self, new_status: ptree.common.Status) -> None:
|
||||
return super().terminate(new_status)
|
|
@ -1,10 +1,10 @@
|
|||
import py_trees as ptree
|
||||
from typing import Any
|
||||
from robowaiter.behavior_lib.Behavior import Bahavior
|
||||
|
||||
|
||||
class CoffeeCupFound(ptree.behaviour.Behaviour):
|
||||
class CoffeeCupFound(Bahavior):
|
||||
def __init__(self, name: str, scene):
|
||||
super().__init__(name)
|
||||
super().__init__(name, scene)
|
||||
|
||||
def setup(self, **kwargs: Any) -> None:
|
||||
return super().setup(**kwargs)
|
|
@ -1,10 +1,11 @@
|
|||
import py_trees as ptree
|
||||
from typing import Any
|
||||
from robowaiter.behavior_lib.Behavior import Bahavior
|
||||
|
||||
class CoffeeCupGrasped(ptree.behaviour.Behaviour):
|
||||
|
||||
class CoffeeCupGrasped(Bahavior):
|
||||
def __init__(self, name: str, scene):
|
||||
super().__init__(name)
|
||||
super().__init__(name, scene)
|
||||
|
||||
|
||||
def setup(self, **kwargs: Any) -> None:
|
||||
return super().setup(**kwargs)
|
|
@ -0,0 +1,20 @@
|
|||
import py_trees as ptree
|
||||
from typing import Any
|
||||
from robowaiter.behavior_lib.Behavior import Bahavior
|
||||
|
||||
class IsChatting(Bahavior):
|
||||
def __init__(self, name: str, scene):
|
||||
super().__init__(name, scene)
|
||||
|
||||
def setup(self, **kwargs: Any) -> None:
|
||||
return super().setup(**kwargs)
|
||||
|
||||
def initialise(self) -> None:
|
||||
return super().initialise()
|
||||
|
||||
def update(self) -> ptree.common.Status:
|
||||
# if self.scene.status?
|
||||
return ptree.common.Status.SUCCESS
|
||||
|
||||
def terminate(self, new_status: ptree.common.Status) -> None:
|
||||
return super().terminate(new_status)
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
# from robowaiter.behavior_tree.behavior_tree import BehaviorTree
|
||||
from robowaiter.behavior_tree.behavior_tree import load_bt_from_ptml
|
|
@ -0,0 +1,19 @@
|
|||
import py_trees as ptree
|
||||
from robowaiter.behavior_tree.ptml import ptmlCompiler
|
||||
|
||||
|
||||
def load_bt_from_ptml(scene, ptml_path, behavior_lib_path):
|
||||
ptml_bt = ptmlCompiler.load(scene, ptml_path, behavior_lib_path)
|
||||
bt = ptree.trees.BehaviourTree(ptml_bt)
|
||||
|
||||
with open(ptml_path, 'r') as f:
|
||||
ptml = f.read()
|
||||
|
||||
print(f'BT loaded: \n {ptml}')
|
||||
|
||||
# print(ptree.display.unicode_tree(root=bt.root, show_status=True))
|
||||
return bt
|
||||
|
||||
# class BehaviorTree(ptree):
|
||||
# def __init__(self):
|
||||
# super().__init__()
|
|
@ -1,35 +1,35 @@
|
|||
//sequence:
|
||||
// act action1()
|
||||
// act action2(2, 2.3, True)
|
||||
//
|
||||
// parallel 2:
|
||||
// act action3(int a, float b)
|
||||
// act action4()
|
||||
|
||||
sequence{
|
||||
selector{
|
||||
cond CoffeeCupFound()
|
||||
task FindCoffeeCup()
|
||||
sequence{
|
||||
cond SeqTest()
|
||||
task Move(1.2, 2, 2.3, True)
|
||||
task Grasp()
|
||||
parallel 3 {
|
||||
cond Istask()
|
||||
task TestTask()
|
||||
}
|
||||
}
|
||||
}
|
||||
selector{
|
||||
cond CoffeeCupGrasped()
|
||||
task GraspCoffeeCup()
|
||||
}
|
||||
selector{
|
||||
cond DestinationAReached()
|
||||
task ReachDestinationA()
|
||||
}
|
||||
selector{
|
||||
cond CoffeeCupPlaced()
|
||||
task PlaceCoffeeCup()
|
||||
}
|
||||
}
|
||||
//sequence:
|
||||
// act action1()
|
||||
// act action2(2, 2.3, True)
|
||||
//
|
||||
// parallel 2:
|
||||
// act action3(int a, float b)
|
||||
// act action4()
|
||||
|
||||
sequence{
|
||||
selector{
|
||||
cond CoffeeCupFound()
|
||||
task FindCoffeeCup()
|
||||
sequence{
|
||||
cond SeqTest()
|
||||
task Move(1.2, 2, 2.3, True)
|
||||
task Grasp()
|
||||
parallel 3 {
|
||||
cond Istask()
|
||||
task TestTask()
|
||||
}
|
||||
}
|
||||
}
|
||||
selector{
|
||||
cond CoffeeCupGrasped()
|
||||
task GraspCoffeeCup()
|
||||
}
|
||||
selector{
|
||||
cond DestinationAReached()
|
||||
task ReachDestinationA()
|
||||
}
|
||||
selector{
|
||||
cond CoffeeCupPlaced()
|
||||
task PlaceCoffeeCup()
|
||||
}
|
||||
}
|
|
@ -1,16 +1,16 @@
|
|||
import os
|
||||
import py_trees as ptree
|
||||
|
||||
from scene_utils import control
|
||||
from scene import scene
|
||||
from ptmlCompiler import load
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
project_path = "."
|
||||
|
||||
project_path = ""
|
||||
|
||||
ptml_path = os.path.join(project_path, 'CoffeeDelivery.ptml')
|
||||
behavior_lib_path = os.path.join(project_path, 'behaviour_lib')
|
||||
behavior_lib_path = os.path.join(project_path, '../../behavior_lib')
|
||||
|
||||
scene = control.Scene(sceneID=0)
|
||||
# load
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
import requests
|
||||
import urllib3
|
||||
|
||||
########################################
|
||||
# 该文件实现了与大模型的简单通信
|
||||
########################################
|
||||
|
||||
# 忽略https的安全性警告
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
def ask_llm(question):
|
||||
url = "https://45.125.46.134:25344/v1/completions"
|
||||
headers = {"Content-Type": "application/json"}
|
||||
data = {
|
||||
"prompt": question
|
||||
}
|
||||
|
||||
response = requests.post(url, headers=headers, json=data, verify=False)
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
return result['choices'][0]['text']
|
||||
else:
|
||||
return "大模型请求失败:", response.status_code
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
question = "假设你是一个咖啡厅的机器人服务员,有一个顾客的请求是'请给我一杯咖啡',请生成对应的行为树来控制机器人完成该动作"
|
||||
|
||||
print(ask_llm(question))
|
|
@ -0,0 +1,105 @@
|
|||
//sequence:
|
||||
// act action1()
|
||||
// act action2(2, 2.3, True)
|
||||
//
|
||||
// parallel 2:
|
||||
// act action3(int a, float b)
|
||||
// act action4()
|
||||
|
||||
sequence{
|
||||
selector{
|
||||
cond CoffeeCupFound()
|
||||
task FindCoffeeCup()
|
||||
sequence{
|
||||
cond SeqTest()
|
||||
task Move(1.2, 2, 2.3, True)
|
||||
task Grasp()
|
||||
parallel 3 {
|
||||
cond Istask()
|
||||
task TestTask()
|
||||
}
|
||||
}
|
||||
}
|
||||
selector{
|
||||
cond CoffeeCupGrasped()
|
||||
task GraspCoffeeCup()
|
||||
}
|
||||
selector{
|
||||
cond DestinationAReached()
|
||||
task ReachDestinationA()
|
||||
}
|
||||
selector{
|
||||
cond CoffeeCupPlaced()
|
||||
task PlaceCoffeeCup()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
sequence{
|
||||
cond NotAt(Coffee,Table)
|
||||
selector{
|
||||
cond Holding(Coffee)
|
||||
sequence{
|
||||
selector{
|
||||
cond At(Bar)
|
||||
task MoveTo(Bar)
|
||||
}
|
||||
task Grasp(Coffee)
|
||||
}
|
||||
}
|
||||
selector{
|
||||
cond At(Table)
|
||||
task MoveTo(Table)
|
||||
}
|
||||
Put(Coffee)
|
||||
}
|
||||
|
||||
|
||||
selector{
|
||||
sequence{
|
||||
cond At(Table)
|
||||
cond Holding(Coffee)
|
||||
task Put(Table)
|
||||
}
|
||||
sequence{
|
||||
cond NotHolding(Coffee)
|
||||
task MoveTo(Table)
|
||||
}
|
||||
sequence{
|
||||
cond At(Bar)
|
||||
task Grasp(Coffee)
|
||||
}
|
||||
task MoveTo(Table)
|
||||
|
||||
|
||||
|
||||
sequence{
|
||||
cond Coffee()
|
||||
task FindCoffeeCup()
|
||||
sequence{
|
||||
cond SeqTest()
|
||||
task Move(1.2, 2, 2.3, True)
|
||||
task Grasp()
|
||||
parallel 3 {
|
||||
cond Istask()
|
||||
task TestTask()
|
||||
}
|
||||
}
|
||||
}
|
||||
selector{
|
||||
cond At(Table,Coffee)
|
||||
task GraspCoffeeCup()
|
||||
}
|
||||
selector{
|
||||
cond DestinationAReached()
|
||||
task ReachDestinationA()
|
||||
}
|
||||
selector{
|
||||
cond CoffeeCupPlaced()
|
||||
task PlaceCoffeeCup()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import os
|
||||
import py_trees as ptree
|
||||
|
||||
from robowaiter.behavior_tree import load_bt_from_ptml
|
||||
|
||||
class Robot(object):
|
||||
scene = None
|
||||
def __init__(self,ptml_path,behavior_lib_path):
|
||||
self.ptml_path = ptml_path
|
||||
self.behavior_lib_path = behavior_lib_path
|
||||
|
||||
def set_scene(self,scene):
|
||||
self.scene = scene
|
||||
|
||||
def load_BT(self):
|
||||
self.bt = load_bt_from_ptml(self.scene, self.ptml_path,self.behavior_lib_path)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pass
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
from .scene import Scene
|
||||
from robowaiter.scene.tasks.AEM import SceneAEM
|
||||
from robowaiter.scene.tasks.GQA import SceneGQA
|
||||
from robowaiter.scene.tasks.VLN import SceneVLN
|
||||
from robowaiter.scene.tasks.VLM import SceneVLM
|
||||
from robowaiter.scene.tasks.Open_tasks import SceneOT
|
||||
from robowaiter.scene.tasks.Auto_tasks import SceneAT
|
||||
|
||||
task_map = {
|
||||
"AEM": SceneAEM,
|
||||
"GQA": SceneGQA,
|
||||
"VLN": SceneVLN,
|
||||
"VLM": SceneVLM,
|
||||
"OT": SceneOT,
|
||||
"AT": SceneAT,
|
||||
}
|
|
@ -1,12 +1,10 @@
|
|||
import time
|
||||
import gym
|
||||
import grpc
|
||||
import numpy as np
|
||||
|
||||
from proto import GrabSim_pb2
|
||||
from proto import GrabSim_pb2_grpc
|
||||
from robowaiter.proto import GrabSim_pb2
|
||||
from robowaiter.proto import GrabSim_pb2_grpc
|
||||
|
||||
from ptml import ptmlCompiler
|
||||
|
||||
channel = grpc.insecure_channel(
|
||||
"localhost:30001",
|
||||
|
@ -21,7 +19,7 @@ animation_step = [4, 5, 7, 3, 3]
|
|||
loc_offset = [-700, -1400]
|
||||
|
||||
|
||||
def init_world(scene_num, mapID):
|
||||
def init_world(scene_num=1, mapID=3):
|
||||
stub.SetWorld(GrabSim_pb2.BatchMap(count=scene_num, mapID=mapID))
|
||||
time.sleep(3) # wait for the map to load
|
||||
|
||||
|
@ -34,7 +32,21 @@ def image_extract(camera_data):
|
|||
|
||||
|
||||
class Scene:
|
||||
robot = None
|
||||
state = {}
|
||||
"""
|
||||
# 当前场景的状态
|
||||
state: {
|
||||
"chat_pool": [ #未处理的顾客的对话池
|
||||
{
|
||||
"pos": 顾客的位置,
|
||||
"chat": 顾客对话的内容
|
||||
}
|
||||
],
|
||||
|
||||
"status": # 仿真器中的观测信息,见下方详细解释
|
||||
}
|
||||
|
||||
status:
|
||||
location: Dict[X: float, Y: float]
|
||||
rotation: Dict[Yaw: float]
|
||||
|
@ -47,18 +59,40 @@ class Scene:
|
|||
collision: str, info: str
|
||||
"""
|
||||
|
||||
def __init__(self, sceneID=0):
|
||||
def __init__(self,robot, sceneID=0):
|
||||
self.sceneID = sceneID
|
||||
self.use_offset = True
|
||||
self.BT = None
|
||||
|
||||
# init robot
|
||||
robot.set_scene(self)
|
||||
robot.load_BT()
|
||||
self.robot = robot
|
||||
|
||||
|
||||
def run(self):
|
||||
pass
|
||||
|
||||
|
||||
@property
|
||||
def status(self):
|
||||
return stub.Observe(GrabSim_pb2.SceneID(value=self.sceneID))
|
||||
|
||||
def reset(self):
|
||||
def reset_sim(self):
|
||||
stub.Reset(GrabSim_pb2.ResetParams(scene=self.sceneID))
|
||||
|
||||
# reset world
|
||||
init_world()
|
||||
|
||||
# reset state
|
||||
self.state = {
|
||||
"chatting_list": []
|
||||
}
|
||||
|
||||
|
||||
|
||||
def reset(self):
|
||||
self.reset_sim()
|
||||
|
||||
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]
|
||||
|
@ -239,5 +273,3 @@ class Scene:
|
|||
def animation_reset(self):
|
||||
stub.ControlRobot(GrabSim_pb2.ControlInfo(scene=self.sceneID, type=0, action=0))
|
||||
|
||||
def load_BT(self, ptml_path, behaviour_lib_path):
|
||||
self.BT = ptmlCompiler.load(self, ptml_path, behaviour_lib_path)
|
|
@ -0,0 +1,26 @@
|
|||
"""
|
||||
环境主动探索和记忆
|
||||
要求输出探索结果(语义地图)对环境重点信息记忆。生成环境的语义拓扑地图,和不少于10个环境物品的识别和位置记忆,可以是图片或者文字或者格式化数据。
|
||||
"""
|
||||
|
||||
from robowaiter.scene.scene import Scene
|
||||
|
||||
class SceneAEM(Scene):
|
||||
def __init__(self, robot):
|
||||
super().__init__(robot)
|
||||
|
||||
# control.init_world(1, 3)
|
||||
|
||||
def reset(self):
|
||||
self.reset_sim()
|
||||
|
||||
self.add_object(0, 570, 1600, 85.5) # type与物品编号对应,具体参考README.md
|
||||
self.add_object(1, 570, 1630, 85.5)
|
||||
self.add_object(2, 570, 1660, 85.5)
|
||||
self.add_object(3, 580, 1680, 85.5)
|
||||
|
||||
# todo: 探索并获得语义地图
|
||||
print(self.status.objects) # 全部的物品信息,包括名称、位置等,与获得的语义地图进行对比
|
||||
|
||||
def run(self):
|
||||
pass
|
|
@ -0,0 +1,26 @@
|
|||
"""
|
||||
在特定环境下,机器人发现目标,可自主完成任务
|
||||
1. 打扫地面:地面有垃圾,机器人主动扫地、清理地面垃圾
|
||||
2. 收拾桌子:桌子上的污渍,机器人主动擦桌子
|
||||
3. 摆椅子:椅子不正,机器人主动摆正椅子
|
||||
4. 开灯:室内光线暗,机器人主动打开房屋的灯
|
||||
"""
|
||||
|
||||
# todo: 通过行为树控制自动任务
|
||||
|
||||
from robowaiter.scene.scene import Scene
|
||||
|
||||
|
||||
class SceneAT(Scene):
|
||||
def __init__(self, robot):
|
||||
super().__init__(robot)
|
||||
|
||||
def reset(self):
|
||||
self.reset_sim()
|
||||
|
||||
self.add_walker(1085, 2630, 220)
|
||||
self.control_walker([self.walker_control_generator(0, False, 100, 755, 1900, 180)])
|
||||
|
||||
def run(self):
|
||||
self.chat_bubble("顾客说:请给我一杯咖啡")
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
"""
|
||||
具身多轮对话
|
||||
具身多轮对话 GQA
|
||||
点餐(order)的对话,咖啡厅服务员可以为客人(NPC)完成点餐基本对话
|
||||
场景对话(GQA)结合场景:询问卫生间、附近娱乐场所(数据来源自主定义)
|
||||
开始条件:顾客NPC发出点餐指令
|
||||
|
@ -8,3 +8,21 @@
|
|||
|
||||
# todo: 使用大模型进行对话,获得指令信息,适时结束对话
|
||||
# order = {...}
|
||||
|
||||
from robowaiter.scene.scene import Scene
|
||||
|
||||
class SceneGQA(Scene):
|
||||
def __init__(self, robot):
|
||||
super().__init__(robot)
|
||||
|
||||
def reset(self):
|
||||
self.reset_sim()
|
||||
|
||||
self.add_walker(1085, 2630, 220)
|
||||
self.control_walker([self.walker_control_generator(0, False, 100, 755, 1900, 180)])
|
||||
|
||||
|
||||
def run(self):
|
||||
self.chat_bubble("顾客说:123546567")
|
||||
|
||||
|
|
@ -8,12 +8,24 @@
|
|||
|
||||
"""
|
||||
|
||||
from scene_utils import control
|
||||
|
||||
# control.init_world(1, 3)
|
||||
|
||||
scene = control.Scene(sceneID=0)
|
||||
|
||||
scene.reset()
|
||||
|
||||
# todo: 接收点单信息,大模型生成任务规划
|
||||
|
||||
from robowaiter.scene.scene import Scene
|
||||
|
||||
class SceneOT(Scene):
|
||||
def __init__(self, robot):
|
||||
super().__init__(robot)
|
||||
|
||||
def reset(self):
|
||||
self.reset_sim()
|
||||
|
||||
self.add_walker(1085, 2630, 220)
|
||||
self.control_walker([self.walker_control_generator(0, False, 100, 755, 1900, 180)])
|
||||
|
||||
|
||||
def run(self):
|
||||
self.chat_bubble("顾客说:请给我一杯咖啡")
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
"""
|
||||
视觉语言操作
|
||||
机器人根据指令人的指令调节空调,自主探索环境导航到目标点,通过手臂的运动规划能力操作空调,比如开关按钮、调温按钮、显示面板
|
||||
"""
|
||||
|
||||
import time
|
||||
from robowaiter.scene.scene import Scene
|
||||
|
||||
|
||||
class SceneVLM(Scene):
|
||||
def __init__(self, robot):
|
||||
super().__init__(robot)
|
||||
|
||||
def reset(self):
|
||||
self.reset_sim()
|
||||
|
||||
self.add_walker(1085, 2630, 220)
|
||||
self.control_walker([self.walker_control_generator(0, False, 100, 755, 1900, 180)])
|
||||
|
||||
def run(self):
|
||||
# 空调操作
|
||||
self.walk_to(950, 1260, 90) # 没法转向?
|
||||
# todo: 手臂操作
|
||||
time.sleep(5)
|
||||
self.walk_to(947, 1900, 0)
|
||||
|
||||
# 物品挪动
|
||||
# todo: 视觉导航至目标点,操作手臂至可抓位置
|
||||
"""
|
||||
scene.grasp(1, your_objectID)
|
||||
"""
|
||||
|
||||
# todo: 视觉导航至目标点,找准释放位置
|
||||
"""
|
||||
scene.release(1)
|
||||
"""
|
|
@ -0,0 +1,39 @@
|
|||
"""
|
||||
视觉语言导航
|
||||
识别顾客(NPC)靠近、打招呼、对话、领位导航到适合人数的空闲餐桌
|
||||
开始条件:监测到顾客靠近
|
||||
结束条件:完成领位,语音:“请问您想喝点什么?”,并等待下一步指令
|
||||
"""
|
||||
|
||||
from robowaiter.scene.scene import Scene
|
||||
|
||||
|
||||
class SceneVLN(Scene):
|
||||
def __init__(self, robot):
|
||||
super().__init__(robot)
|
||||
|
||||
def reset(self):
|
||||
self.reset_sim()
|
||||
|
||||
self.add_walker(1085, 2630, 220)
|
||||
self.control_walker([self.walker_control_generator(0, False, 100, 755, 1900, 180)])
|
||||
|
||||
def run(self):
|
||||
# 实现单顾客领位
|
||||
self.add_walker(1085, 2630, 220)
|
||||
self.control_walker([self.walker_control_generator(0, False, 100, 755, 1900, 180)])
|
||||
|
||||
# todo: 监测到顾客靠近,打招呼,对话,识别获取空闲餐桌位置
|
||||
# 可以使用scene.chat_bubble(message)函数实现对话
|
||||
|
||||
"""
|
||||
scene.walk_to(your_free_table_location)
|
||||
time.sleep(5)
|
||||
scene.control_walker([scene.walker_control_generator(your_free_table_location)])
|
||||
"""
|
||||
|
||||
reach = True
|
||||
if reach:
|
||||
self.chat_bubble("请问您想喝点什么?")
|
||||
|
||||
print(self.status.walkers)
|
|
@ -0,0 +1,16 @@
|
|||
import os
|
||||
from robowaiter import Robot, task_map
|
||||
|
||||
TASK_NAME = 'GQA'
|
||||
|
||||
# create robot
|
||||
project_path = "./robowaiter"
|
||||
ptml_path = os.path.join(project_path, 'robot/Default.ptml')
|
||||
behavior_lib_path = os.path.join(project_path, 'behavior_lib')
|
||||
|
||||
robot = Robot(ptml_path,behavior_lib_path)
|
||||
|
||||
# create task
|
||||
task = task_map[TASK_NAME](robot)
|
||||
task.reset()
|
||||
task.run()
|
|
@ -1 +0,0 @@
|
|||
from . import control
|
|
@ -0,0 +1,22 @@
|
|||
from setuptools import setup, find_packages
|
||||
import os
|
||||
|
||||
with open('requirements.txt') as f:
|
||||
required = f.read().splitlines()
|
||||
|
||||
setup(
|
||||
name='robowaiter',
|
||||
version='0.1.0',
|
||||
packages=['robowaiter'],
|
||||
install_requires=required,
|
||||
author='HPCL-EI',
|
||||
author_email='hpcl_ei@163.com',
|
||||
description='RoboWaiter',
|
||||
url='https://github.com/HPCL-EI/RoboWaiter',
|
||||
classifiers=[
|
||||
'Programming Language :: Python :: 3',
|
||||
'License :: OSI Approved :: MIT License',
|
||||
'Operating System :: OS Independent',
|
||||
],
|
||||
)
|
||||
|
20
tasks/AEM.py
20
tasks/AEM.py
|
@ -1,20 +0,0 @@
|
|||
"""
|
||||
环境主动探索和记忆
|
||||
要求输出探索结果(语义地图)对环境重点信息记忆。生成环境的语义拓扑地图,和不少于10个环境物品的识别和位置记忆,可以是图片或者文字或者格式化数据。
|
||||
"""
|
||||
|
||||
from scene_utils import control
|
||||
|
||||
# control.init_world(1, 3)
|
||||
|
||||
scene = control.Scene(sceneID=0)
|
||||
|
||||
scene.reset()
|
||||
scene.add_object(0, 570, 1600, 85.5) # type与物品编号对应,具体参考README.md
|
||||
scene.add_object(1, 570, 1630, 85.5)
|
||||
scene.add_object(2, 570, 1660, 85.5)
|
||||
scene.add_object(3, 580, 1680, 85.5)
|
||||
|
||||
# todo: 探索并获得语义地图
|
||||
|
||||
print(scene.status.objects) # 全部的物品信息,包括名称、位置等,与获得的语义地图进行对比
|
|
@ -1,9 +0,0 @@
|
|||
"""
|
||||
在特定环境下,机器人发现目标,可自主完成任务
|
||||
1. 打扫地面:地面有垃圾,机器人主动扫地、清理地面垃圾
|
||||
2. 收拾桌子:桌子上的污渍,机器人主动擦桌子
|
||||
3. 摆椅子:椅子不正,机器人主动摆正椅子
|
||||
4. 开灯:室内光线暗,机器人主动打开房屋的灯
|
||||
"""
|
||||
|
||||
# todo: 通过行为树控制自动任务
|
29
tasks/VLM.py
29
tasks/VLM.py
|
@ -1,29 +0,0 @@
|
|||
"""
|
||||
视觉语言操作
|
||||
机器人根据指令人的指令调节空调,自主探索环境导航到目标点,通过手臂的运动规划能力操作空调,比如开关按钮、调温按钮、显示面板
|
||||
"""
|
||||
|
||||
import time
|
||||
from scene_utils import control
|
||||
|
||||
# control.init_world(1, 3)
|
||||
|
||||
scene = control.Scene(sceneID=0)
|
||||
|
||||
scene.reset()
|
||||
|
||||
# 空调操作
|
||||
scene.walk_to(950, 1260, 90) # 没法转向?
|
||||
# todo: 手臂操作
|
||||
time.sleep(5)
|
||||
scene.walk_to(947, 1900, 0)
|
||||
|
||||
# 物品挪动
|
||||
# todo: 视觉导航至目标点,操作手臂至可抓位置
|
||||
"""
|
||||
scene.grasp(1, your_objectID)
|
||||
"""
|
||||
# todo: 视觉导航至目标点,找准释放位置
|
||||
"""
|
||||
scene.release(1)
|
||||
"""
|
32
tasks/VLN.py
32
tasks/VLN.py
|
@ -1,32 +0,0 @@
|
|||
"""
|
||||
视觉语言导航
|
||||
识别顾客(NPC)靠近、打招呼、对话、领位导航到适合人数的空闲餐桌
|
||||
开始条件:监测到顾客靠近
|
||||
结束条件:完成领位,语音:“请问您想喝点什么?”,并等待下一步指令
|
||||
"""
|
||||
|
||||
from scene_utils import control
|
||||
|
||||
# control.init_world(1, 3)
|
||||
|
||||
scene = control.Scene(sceneID=0)
|
||||
|
||||
# 实现单顾客领位
|
||||
scene.reset()
|
||||
scene.add_walker(1085, 2630, 220)
|
||||
scene.control_walker([scene.walker_control_generator(0, False, 100, 755, 1900, 180)])
|
||||
|
||||
# todo: 监测到顾客靠近,打招呼,对话,识别获取空闲餐桌位置
|
||||
# 可以使用scene.chat_bubble(message)函数实现对话
|
||||
|
||||
"""
|
||||
scene.walk_to(your_free_table_location)
|
||||
time.sleep(5)
|
||||
scene.control_walker([scene.walker_control_generator(your_free_table_location)])
|
||||
"""
|
||||
|
||||
reach = True
|
||||
if reach:
|
||||
scene.chat_bubble("请问您想喝点什么?")
|
||||
|
||||
print(scene.status.walkers)
|
Loading…
Reference in New Issue