深圳wap网站建设,店铺设计分析,广州口碑好的网站建设,上海一个人如何注册公司这是最近斯坦福的李飞飞团队的一篇论文:VoxPoser: Composable 3D Value Maps for Robotic Manipulation with Language Models 主要是通过大语言模型LLM和视觉语言模型VLM结合#xff0c;来对机器人做各种日常操作#xff0c;我们可以先来看下实际效果#xff1a;大语言模型…这是最近斯坦福的李飞飞团队的一篇论文:VoxPoser: Composable 3D Value Maps for Robotic Manipulation with Language Models 主要是通过大语言模型LLM和视觉语言模型VLM结合来对机器人做各种日常操作我们可以先来看下实际效果大语言模型加视觉模型的通用机器人 可以看到在不同的实际场景中都可以很好的进行日常操作而且具备对机器人不需要进行训练的优势。对于这篇论文的解读尽量通俗的按照自己的理解来表达希望对大家有帮助当然水平有限有误之处欢迎指正一起进步。
1、VoxPoser开发的初衷
在以往的机器人操作当中我们都是需要先预定义轨迹这就使得机器人变得比较局限更重要的是大规模的机器人数据的获取都是比较困难的这就限制了机器人领域的发展。而ChatGPT4的出色回答让我们感到让机器人成为通用机器人成为可能可以利用这样的LLM来进行推理然后给出机器人一些有用的步骤再通过VLM来规划路径这样理论上就做到了机器人可以通过自然语言而跟现实世界进行交互了。所以VoxPoser就被开发出来了这个工作的目标就是合成机器人轨迹也就是接下来将要介绍的使用6自由度的末端执行器规划路径点序列还开放了指令集和对象集。 我们先来看一张VOXPOSER示意图 左边是VoxPoser的概览图右边是一些操作的演示。 可以看到我们是在大语言模型提取了支持和约束(这里的支持就是机器人的操作目标下面也可能有叫功能或功能可见性等叫法意思是一样的约束就是机器人在操作过程中要避开的东西)也可能叫做回避比如这里的“Open the top drawer, and watch out for that vase!”(打开最上面的抽屉小心那个花瓶!)故这里的抽屉就是支持花瓶就是约束。 得到的步骤如下 1、应抓住最上面的抽屉把手 2、把手需要向外平移 3、机器人应远离花瓶 这些步骤再结合视觉语言模型使用VOXPOSER提供的代码接口就能够规划出机器人的轨迹。
2、VoxPoser原理实现
上面我们大概介绍了VOXPOSER接下来具体介绍VOXPOSER的原理上面的示意图我们仔细观察左边那个机器人所在的空间会发现每个区域的颜色是有区别的看那个颜色条左边是high cost右边是high reward也就是成本越高颜色是红颜色高奖励的地方是蓝色这样就会让机器人对此作出路径规划。
2.1、LLMVLM
那具体是如何去实现的呢同样的来看一张示意图 这里给出了两个函数的代码affordance_map()和constraint_map()分别表示需要操作的目标和需要避开的目标的映射。 大语言模型生成与视觉语言模型交互的代码以此来生成基于机器人观察空间的一系列3D功能图和约束图(统称为值图)然后合成的值图作为运动规划者合成机器人操作轨迹的目标函数。 从两个函数来看大同小异都是先初始化一个三维数组(张量)映射然后各自检测目标detect(handle)和detect(vase)不同点就是affordance_map是需要将目标对象的位置(top_handle.pos)都设置为1在constraint_map里面是将检测到的对象所占用的格子(vase.occupancy_grid)的位置都设置为-1最后两个分别返回其对应的值图。 经过上述处理之后就有了Motion Planning运动规划一种在机器人学和自动控制领域中用于规划物体在空间中的运动路径的方法以避免碰撞并满足其他约束条件。
2.2、方法与公式
我们知道语言所表达出来的东西是比较自由的或者说比较的宽泛而机器人需要的是具体的有针对性的操作指令。
比如说“打开最上面的抽屉”单纯根据这句话可能生成轨迹就很困难所以我们将一个问题进行分解拆分成具体的子任务明确地去指定操作任务可以分解为“抓住顶层抽屉的把手”和“拉开抽屉”这种由高级规划器(如LLM或基于搜索的规划器)得到的具体子任务就变得可操作性了。 接下来就是将每个子任务进行优化这里的子任务是LLM语言指令和机器人的运动路径其中运动路径是由操作空间控制器执行的密集末端执行器路径点序列每个路径点是由6自由度末端执行器姿态、末端执行器速度和夹持器动作组成。
我们将这些表述为如下的一个公式 环境状态的演化 机器人轨迹 相关的动力学和运动学约束subject to 受制于的意思。 完成指令的程度进行评分 指定控制成本例如鼓励 最小化总控制时间 通过对每个子任务求解这个优化问题我们得到一系列机器人轨迹这些轨迹共同完成指令L指定的总体任务。
对于自由形式的语言指令计算是极具挑战性的不仅因为语义语言可以传达的空间丰富而且因为缺乏机器人标记数据。然而我们提供了一个关键的观察结果即在机器人的观察空间中大量的任务可以用一个体素值映射来表征。这里的体素值可以理解成空间三维的数组或坐标然后做映射。 “抓住顶层抽屉把手”(由LLMs推断)。“感兴趣的实体”是机器人的末端执行器体素值映射应该反映对抽屉手柄的吸引力。通过进一步命令“小心花瓶”地图也可以更新以反映来自花瓶的排斥。 我们表示“感兴趣的实体”为e其轨迹为使用给定指令的体素值映射 任务可以通过累加遍历的e值来近似公式如下
其中的是e在第j步的离散(x, y, z)的位置由于这些位置是稀疏的我们通过平滑操作来增加体素地图的密度鼓励运动规划器优化更平滑的轨迹。 由于VoxPoser使用具有丰富常识的大语言模型来合成机器人轨迹因此零射击合成轨迹 可以作为行动抽样分布 的有用的先验偏差这可以显著加快学习过程。在实践中这可以通过在 附近的采样动作来实现通过添加小噪声ε来鼓励局部探索而不是在整个行动空间中探索。
2.3、重建点云
LLM使用他们自己生成的代码其中每个语言模型程序language model program(LMP)负责一个独特的功能(例如处理感知调用)。本论文用的是OpenAI的GPT-4开放的API。 我们先来看下对比基线的实验结果 可以看到VoxPoser有着很高的执行日常任务的成功率不仅在可见任务有着高成功率而且在不可见的任务中同样有着差不多的成功率。 具体有哪些操作呢 给定来自LLM的对象/部件的查询我们首先调用open-vocab检测器OWL-ViT获取边界框将其馈入到Segment Anything (Meta的分割一切对象模型)获取掩码并使用视频跟踪器XMEM (基于Atkinson-Shiffrin记忆模型的长视频对象分割)跟踪掩码。利用跟踪掩码与RGB-D观测相结合重建目标或部分的点云。
2.4、值图(映射)与运动规划器
我们定义了以下类型的值图affordance功能可见、avoidance回避、end-effector velocity末端执行器速度、end-effector rotation末端执行器旋转和gripper action抓取动作。 每种类型使用不同的语言模型程序(LMP)它接受指令并输出形状为(100,100,100,k)的体素图其中k对于每个值图是不同的(例如k1用于功能可见和回避k4用于旋转) 我们将Euclidean distance欧氏距离变换应用于功能可见性的映射高斯滤波器则应用于回避映射。在值映射LMP的基础上我们定义了两个高级LMPs来协调它们的行为planner规划器以用户指令L作为输入(例如“打开抽屉”)并输出一系列子任务然后composer以子任务为输入并调用相关的值映射LMPs并进行详细的语言参数化。
接下来就是构造运动规划器在规划器优化中只考虑可见性映射和回避映射使用贪心搜索找到一系列无碰撞的末端执行器位置。然后我们通过剩余的值映射(例如旋转映射速度映射)在每个p上强制其他参数化。运动规划器使用的代价映射被计算为权值为2和1的归一化可视性和回避映射的加权和的负数合成6自由度轨迹后执行第一个航路点然后以5Hz的频率重新规划新的轨迹。
具体来说我们首先使用VoxPoser合成k个不同的轨迹每个轨迹都表示为一系列末端执行器路径点。然后我们学习了一个MLP动态模型通过迭代过程从和预测其中代理在数据收集和模型学习之间交替进行。在MPC的动作抽样分布中我们加入将初始合成轨迹作为先验到中的每个路径点鼓励本地探索使用这些轨迹作为先验探索我们可以在不到3分钟的在线交互中学习有效的动力学模型从而获得较高的最终成功率。相比之下如果没有先验学习动态模型是非常困难的因为大多数动作不会导致有意义的环境变化。
3、应对突发状况
大模型的一些不可预测现象如何应对这里我们使用了LLM有着丰富的世界知识。特别是我们将研究重点放在VoxPoser独有的行为能力上。我们观察到以下能力 1.估计物理性质给定两个未知质量的块机器人的任务是使用可用的工具进行物理实验以确定哪个块更重。2.行为常识推理在机器人布置桌子的任务中用户可以指定行为偏好例如“我是左撇子”这需要机器人在任务的上下文中理解其含义。3.细粒度的语言纠错对于“用壶盖盖住茶壶”等要求高精度的任务用户可以给机器人精确的指令比如“你向左偏差了1cm”这种精确的要求也可以没有问题的。4.多步可视化程序给定一个“精确打开抽屉一半”的任务由于对象模型不可用信息不足VoxPoser可以提出多步操作策略根据视觉反馈首先在记录手柄位移的同时将抽屉完全打开然后将其关闭回中点以满足要求。 上述的应急能力对应体现在如下图 4、VoxPoser局限性
在这项工作中我们提出了VoxPoser一个通用的机器人操作框架从LLM中提取功能和约束为开放集指令和对象提供了显著的泛化优势。特别是我们使用代码编写LLM与VLM进行交互以组成基于观测空间的3D值图用于合成日常操作任务的轨迹。此外我们展示了VoxPoser可以通过有效地学习一个动态模型来完成丰富的接触任务从而从在线交互中受益。 当然VoxPoser也存在下面几点的限制 首先它依赖于外部感知模块这在需要整体视觉推理或理解细粒度物体几何形状的任务中受到限制。 其次虽然适用于高效的动态学习但仍然需要一个通用的动态模型来实现具有相同泛化水平的多接触任务。 第三我们的运动规划器只考虑末端执行器轨迹而全臂规划也是可行的可能是更好的设计选择。 5、VoxPoser的Transforms3d
其中VoxPoser的核心就是向LLM提供代码支持除了有Numpy和Transforms3d库之外还提供了很多APIs Transforms3d库的详细说明http://matthew-brett.github.io/transforms3d/index.html 安装transforms3d命令带上阿里云镜像速度快点pip install transforms3d -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
再检验下是否安装成功
import transforms3d
transforms3d.__version__
#0.4.1
dir(transforms3d)
#[__builtins__, __cached__, __doc__, __file__, __loader__, __name__, __package__, __path__, __spec__, __version__, _version, affines, axangles, euler, quaternions, reflections, shears, taitbryan, utils, zooms]
这个库主要是矩阵变换、欧拉角、四元数等等的转换具体详细用法可以看前面给出的链接。
6、VoxPoser的APIs
我们来看下VoxPoser提供了哪些对外接口detect(obj name)接受一个对象名并返回一个字典列表其中每个字典对应于匹配对象的一个实例包含中心位置、占用网格和平均法向量(正态均值向量)
execute(movable,affordance map,avoidance map,rotation map,velocity map,gripper map)接受“感兴趣的实体”作为“可移动的”(由detect返回的字典)和(可选的)值映射列表并调用运动规划器来执行轨迹。请注意在MPC设置中“可移动”和输入值映射是可以重新评估以反映最新环境观察的函数另外这里的感兴趣实体就是机器人的末端执行器通过它的移动来操作目标。
cm2index(cm,direction)沿方向获取所需的偏移距离(以厘米为单位)并返回以体素坐标反映位移的三维向量
index2cm(index,direction)接受一个整数“索引”和一个“方向”向量并返回被体素坐标中的“整数”所取代的世界坐标中的距离
pointat2quat(vector)为末端执行器获取所需的指向方向并返回一个令人满意的目标四元数
set_voxel_by_radius(voxel_map,voxel_xyz,radius_cm,value)从“voxel_map体素图”中的“voxel_xyz”中为“半径”内的voxel体素分配值。
get_empty_affordance_map()返回初始化为0的功能可见性图(映射)其中高值将吸引实体。 其中对affordance的翻译比较多有功能可见性功能可供性自解释性启示等初次接触可能有点懵没有关系这里的关键点是需要知道具体是什么意思就行了。意思是说这个东西自己呈现出来的功能自然会联想到怎么去使用它比如看到抽屉手柄就会想着去拉或者推看到家里的水龙头就可能是旋转进行关停看到按钮就知道是按压这就是所谓的功能可见性。
get_empty_avoidance_map(): 返回初始化为0的避障图(映射)其中高值将排斥实体。
get_empty_rotation_map()返回用当前末端执行器四元数初始化的默认旋转映射。
get_empty_gripper_map()返回用当前抓取器动作初始化的默认抓取器映射其中1表示“关闭”0表示“打开”
get_empty_velocity_map()返回一个初始化为1的默认功能映射其中数字表示比例因子(例如0.5表示默认速度的一半)
reset_to_default_pose()重置机器人为休息姿势
7、Prompts提示
最后是将上述在日常操作任务中需要用到的提示以及一些不可见的属性之类的分解成具体的步骤。当然目前站点对下面这些代码还没有公开后期应该会很快开放。
7.1、planner计划器
接收用户指令L并生成一系列子任务这些子任务被送入composer(注意在模拟中不使用计划器因为评估的任务由单个操作阶段组成)。https://voxposer.github.io/prompts/real_planner_prompt.txt 摘要如下
import numpy as np
from env_utils import execute
from perception_utils import parse_query_obj
import action_utils import composerobjects [blue block, yellow block, mug]# [蓝色块,黄色块,马克杯]
# Query: place the blue block on the yellow block, and avoid the mug at all time.
# 把蓝色块放在黄色块上并且一直避免杯子composer(grasp the blue block while keeping at least 15cm away from the mug)#抓住蓝色方块同时与杯子保持至少15厘米的距离
composer(back to default pose)#回到默认姿势
composer(move to 5cm on top of the yellow block while keeping at least 15cm away from the mug)#移动到黄色方块上方5厘米处同时与杯子保持至少15厘米的距离
composer(open gripper)# 打开抓取器
可以看到提供的方法还是很清晰简洁的首先就是保存需要关注和避开的objects对象列表然后通过composer去解析每条具体的语言指令。
7.2、composer编写器
接受子任务指令调用必要的值映射LMPs组成功能映射和约束映射。 下面都将分为模拟器和真实环境 simulation: https://voxposer.github.io/prompts/sim_composer_prompt.txt real-world: https://voxposer.github.io/prompts/real_composer_prompt.txt 摘要如下
import numpy as np
from env_utils import execute, reset_to_default_pose
from perception_utils import parse_query_obj
from plan_utils import get_affordance_map, get_avoidance_map, get_velocity_map, get_rotation_map, get_gripper_map# Query: move ee forward for 7cm.
# 将对象ee向前移动7厘米
movable parse_query_obj(ee)
affordance_map get_affordance_map(fa point 7cm in front of {movable.position})
execute(movable, affordance_map)
7.3、parse_query_obj
接受对象/部件名称的文本查询并返回一个字典列表其中每个字典对应于包含中心位置、占用网格和正态均值向量的匹配对象的一个实例。 simulation: https://voxposer.github.io/prompts/sim_parse_query_obj_prompt.txt real-world: https://voxposer.github.io/prompts/real_parse_query_obj_prompt.txt 摘要如下
import numpy as np
from perception_utils import detectobjects [green block, yellow line]
# Query: ee.
ee detect(ee)[0]
ret_val eeobjects [drawer, blue block, yellow block]
# Query: topmost handle.
# 顶层把手
handles detect(drawer handle)
# topmost so sort by z, take the last one
# 最上面按z排序取最后一个
handles sorted(handles, keylambda x: x.position[2])
top_handle handles[-1]
ret_val top_handle
7.4、get_affordance_map
从编写器接受自然语言参数化并返回NumPy数组用于任务提供映射。 simulation: https://voxposer.github.io/prompts/sim_get_affordance_map_prompt.txt real-world: https://voxposer.github.io/prompts/real_get_affordance_map_prompt.txt 摘要如下
import numpy as np
from perception_utils import parse_query_obj
from plan_utils import get_empty_affordance_map, set_voxel_by_radius, cm2index# Query: a point 10cm in front of [10, 15, 60].
# 在[10,15,60]位置前面10cm处的一个点
affordance_map get_empty_affordance_map()
# 10cm in front of so we add to x-axis
# 在前面10cm处我们添加到x轴
x 10 cm2index(10, x)
y 15
z 60
affordance_map[x, y, z] 1
ret_val affordance_map# Query: a point on the right side of the table.
# 表右侧的一个点
affordance_map get_empty_affordance_map()
table parse_query_obj(table)
(min_x, min_y, min_z), (max_x, max_y, max_z) table.aabb
center_x, center_y, center_z table.position
# right side so y max_y
x center_x
y max_y
z center_z
affordance_map[x, y, z] 1
ret_val affordance_map
7.5、get_avoidance_map
从编写器接受自然语言参数化并返回NumPy数组用于任务回避映射。 simulation: https://voxposer.github.io/prompts/sim_get_avoidance_map_prompt.txt real-world: https://voxposer.github.io/prompts/real_get_avoidance_map_prompt.txt 摘要如下
import numpy as np
from perception_utils import parse_query_obj
from plan_utils import get_empty_avoidance_map, set_voxel_by_radius, cm2index# Query: 10cm from the bowl.
# 离碗10cm
avoidance_map get_empty_avoidance_map()
bowl parse_query_obj(bowl)
set_voxel_by_radius(avoidance_map, bowl.position, radius_cm10, value1)
ret_val avoidance_map
7.6、get_rotation_map
从编写器中接受自然语言参数化并返回末端执行器旋转图的NumPy数组。 simulation: https://voxposer.github.io/prompts/sim_get_rotation_map_prompt.txt real-world: https://voxposer.github.io/prompts/real_get_rotation_map_prompt.txt 摘要如下:
import numpy as np
from plan_utils import get_empty_rotation_map, set_voxel_by_radius, cm2index, vec2quat
from perception_utils import parse_query_obj
from transforms3d.euler import euler2quat, quat2euler
from transforms3d.quaternions import qmult, qinverse# Query: face the support surface of the bowl.
# 面朝碗的支撑面
rotation_map get_empty_rotation_map()
bowl parse_query_obj(bowl)
target_rotation vec2quat(-bowl.normal)
rotation_map[:, :, :] target_rotation
ret_val rotation_map
7.7、get_gripper_map
从编写器接受自然语言参数化并为抓手动作图返回NumPy数组 simulation: https://voxposer.github.io/prompts/sim_get_gripper_map_prompt.txt real-world: https://voxposer.github.io/prompts/real_get_gripper_map_prompt.txt 摘要如下
import numpy as np
from perception_utils import parse_query_obj
from plan_utils import get_empty_gripper_map, set_voxel_by_radius, cm2index# Query: open everywhere except 1cm around the green block.
# 除绿色块周围1cm外所有地方都打开
gripper_map get_empty_gripper_map()
# open everywhere
gripper_map[:, :, :] 0
# close when 1cm around the green block
green_block parse_query_obj(green block)
set_voxel_by_radius(gripper_map, green_block.position, radius_cm1, value1)
ret_val gripper_map
7.8、get_velocity_map
从编写器中接受自然语言参数化并返回末端执行器速度图的NumPy数组。 simulation: https://voxposer.github.io/prompts/sim_get_velocity_map_prompt.txt real-world: https://voxposer.github.io/prompts/real_get_velocity_map_prompt.txt 摘要如下
import numpy as np
from plan_utils import get_empty_velocity_map, set_voxel_by_radius, cm2index
from perception_utils import parse_query_obj# Query: faster when on the right side of the table and slower when on the left side of the table.
# 在桌子右边时速度更快在桌子左边时速度更慢
velocity_map get_empty_velocity_map()
table parse_query_obj(table)
center_x, center_y, center_z table.position
# faster on right side so 1.5 when y center_y, slower on left side so 0.5 when y center_y
velocity_map[:, center_y:, :] 1.5
velocity_map[:, :center_y, :] 0.5
ret_val velocity_map
更多的细节建议看论文原文这里主要是个人对其的理解有错误之处还请指正。引用 voxposerhttps://voxposer.github.io/ XMemhttps://github.com/hkchengrex/XMem