VoxPoser:使用大语言模型(GPT-4)来对机器人操作的可组合三维值图【论文解读】
这是最近斯坦福的李飞飞团队的一篇论文: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、LLM+VLM
那具体是如何去实现的呢?同样的,来看一张示意图:

这里给出了两个函数的代码,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对于每个值图是不同的(例如,k=1用于功能可见和回避,k=4用于旋转)
我们将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(f'a 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, key=lambda 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_cm=10, value=1)
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_cm=1, value=1)
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
更多的细节,建议看论文原文,这里主要是个人对其的理解,有错误之处,还请指正。
引用:
voxposer:https://voxposer.github.io/
XMem:https://github.com/hkchengrex/XMem
相关文章:
VoxPoser:使用大语言模型(GPT-4)来对机器人操作的可组合三维值图【论文解读】
这是最近斯坦福的李飞飞团队的一篇论文:VoxPoser: Composable 3D Value Maps for Robotic Manipulation with Language Models 主要是通过大语言模型LLM和视觉语言模型VLM结合,来对机器人做各种日常操作,我们可以先来看下实际效果:大语言模型…...
RISC-V公测平台发布 · 第一个WEB Server “Hello RISC-V world!”
RISC-V公测平台Web Server地址:http://175.8.161.253:8081 一、前言 Web Server是互联网应用的基础设施,无论是用户访问网站,还是后端服务提供商和开发者构建各种应用程序,Web Server都在其中扮演着至关重要的角色。 显而易见…...
Linux 发行版 CentOS 于 Ubuntu 软件的安装、卸载、查找
CentOS于Ubuntu 内核都是Linux,是一样的。 CentOS 软件格式 .rpm sudo yum [-y] [ install | remove | search ] 软件名称 install 安装 remove 移除 search 搜索 Ubuntu 软件格式 .deb sudo apt [-y] [ install | remove | search ] 软件名称 install 安装 remove…...
cmd相关操作命令
1.根据端口号查询对应进程的PID netstat -ano | findstr 端口号 例如:netstat -ano | findstr 9080;该端口所属进程的PID为6684 2.根据PID查询对应进程 tasklist | findstr PID 例如:tasklist | findstr 6684;该PID所属进程名为…...
使用EM算法完成聚类任务
EM算法(Expectation-Maximization Algorithm)是一种基于迭代优化的聚类算法,用于在无监督的情况下将数据集分成几个不同的组或簇。EM算法是一种迭代算法,包含两个主要步骤:期望步骤(E-step)和最…...
❤️创意网页:创意视觉效果粒子循环的网页动画
✨博主:命运之光 🌸专栏:Python星辰秘典 🐳专栏:web开发(简单好用又好看) ❤️专栏:Java经典程序设计 ☀️博主的其他文章:点击进入博主的主页 前言:欢迎踏入…...
【MTI 6.S081 Lab】thread
【MTI 6.S081 Lab】thread 前言调度Uthread: switching between threads (moderate)实验任务Hints解决方案thread_switchthread_create()thread_schedule() Using threads (moderate)实验任务解决方案 Barrier (moderate)实验任务解决方案 本实验前去看《操作系统导论》第29章基…...
AWS / VPC 云流量监控
由于安全性、数据现代化、增长、灵活性和成本等原因促使更多企业迁移到云,将数据存储在本地的组织正在使用云来存储其重要数据。亚马逊网络服务(AWS)仍然是最受追捧和需求的服务之一,而亚马逊虚拟私有云(VPC࿰…...
【C++学习笔记】extern “c“以及如何查看符号表
如何查看符号表 要查看.a文件的内容,可以使用ar命令。下面是一些常见的用法: 列出.a文件中包含的所有文件: ar t <filename.a>提取.a文件中的单个文件: ar x <filename.a> <filename.o>将.a文件中的所有文件提…...
24考研数据结构-数组和特殊矩阵
目录 数据结构:数组与特殊矩阵数组数组的特点数组的用途 特殊矩阵对角矩阵上三角矩阵和下三角矩阵稀疏矩阵特殊矩阵的用途 结论 3.4 数组和特殊矩阵3.4.1数组的存储结构3.4.2普通矩阵的存储3.4.3特殊矩阵的存储1. 对称矩阵(方阵)2. 三角矩阵(方阵)3. 三对角矩阵(方阵…...
服务器后台运行程序
代码运行 要让代码在服务器后台运行,有多种方法。在 Linux 系统中,最常见的有以下几种方式: **1. 使用 & 符号:** 在命令后面添加 & 符号可以让程序在后台运行。例如: bash python myscript.py &但是…...
大数据课程D7——hadoop的YARN
文章作者邮箱:yugongshiyesina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解YARN的概念和结构; ⚪ 掌握YARN的资源调度流程; ⚪ 了解Hadoop支持的资源调度器:FIFO、Capacity、Fair; ⚪ 掌握YA…...
Rust vs Go:常用语法对比(十三)
题图来自 Go vs. Rust: The Ultimate Performance Battle 241. Yield priority to other threads Explicitly decrease the priority of the current process, so that other execution threads have a better chance to execute now. Then resume normal execution and call f…...
【【51单片机DA转换模块】】
爆改直流电机,DA转换器 main.c #include <REGX52.H> #include "Delay.h" #include "Timer0.h"sbit DAP2^1;unsigned char Counter,Compare; //计数值和比较值,用于输出PWM unsigned char i;void main() {Timer0_Init();whil…...
[SQL挖掘机] - 字符串函数 - substring
介绍: substring函数是在mysql中用于提取字符串的一种函数。它接受一个字符串作为输入,并返回从该字符串中指定位置开始的一部分子串。substring函数可以用于获取字符串中的特定字符或子串,以便进行进一步的处理或分析。 用法: 下面是substring函数的…...
第一百一十六天学习记录:C++提高:STL-string(黑马教学视频)
string基本概念 string是C风格的字符串,而string本质上是一个类 string和char区别 1、char是一个指针 2、string是一个类,类内部封装了char*,管理这个字符串,是一个char型的容器。 特点: string类内部封装了很多成员方…...
Meta-Transformer 多模态学习的统一框架
Meta-Transformer是一个用于多模态学习的新框架,用来处理和关联来自多种模态的信息,如自然语言、图像、点云、音频、视频、时间序列和表格数据,虽然各种数据之间存在固有的差距,但是Meta-Transformer利用冻结编码器从共享标记空间…...
tinkerCAD案例:24.Tinkercad 中的自定义字体
tinkerCAD案例:24.Tinkercad 中的自定义字体 原文 Tinkercad Projects Tinkercad has a fun shape in the Shape Generators section that allows you to upload your own font in SVG format and use it in your designs. I’ve used it for a variety of desi…...
list与流迭代器stream_iterator
运行代码: //list与流迭代器 #include"std_lib_facilities.h" //声明Item类 struct Item {string name;int iid;double value;Item():name(" "),iid(0),value(0.0){}Item(string ss,int ii,double vv):name(ss),iid(ii),value(vv){}friend ist…...
九耶:冯·诺伊曼体系
冯诺伊曼体系(Von Neumann architecture)是一种计算机体系结构,它由匈牙利数学家冯诺伊曼于1945年提出。冯诺伊曼体系是现代计算机体系结构的基础,几乎所有的通用计算机都采用了这种体系结构。 冯诺伊曼体系的核心思想是将计算机硬…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...
[USACO23FEB] Bakery S
题目描述 Bessie 开了一家面包店! 在她的面包店里,Bessie 有一个烤箱,可以在 t C t_C tC 的时间内生产一块饼干或在 t M t_M tM 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC,tM≤109)。由于空间…...
