人人均可体验 AI 机器人乐趣,HuggingFace 推出低成本开源方案 LeRobot
编辑日期:2024年08月30日
现在的AI机器人已经能够灵活地上下跳跃、后空翻,甚至完成连续五个鞭腿的动作,可以替代人类承担各种工作。哪怕只是作为一个大型手办,我们也想拥有一个来玩玩。
但遗憾的是,目前大多数公司仍处于研发阶段,少数能够量产的产品却价格不菲。当然,小编相信AI和机器人最终会走进千家万户。
现在,我们可以体验一款低成本的解决方案——LeRobot:
—— 不知道大家是否还记得「炒菜大师」ALOHA?
而这个 LeRobot,就是我们自己可以拥有的 ALOHA,能够模拟人类完成一些简单的任务。
单个机械臂的成本大约是200美元,而后端的模型训练在你自己的笔记本电脑上就能完成。
官方已经开源了所有的硬件和软件,包括训练和控制程序、AI模型、SolidWorks文件等。
我们可以从零开始组装机械臂,并发挥想象力教它做一些事情。
LeRobot 项目由前特斯拉工程师 Rémi Cadene 领导,他目前是 HuggingFace 的首席研究科学家。该项目提供了一份详细的指南,介绍了如何从零开始构建由 AI 控制的机器人,包括组装、配置以及训练控制机器人的神经网络。
该项目基于开源的Koch v1.1机器人套件(也可以采用其他硬件或虚拟平台),包含两个六轴机械臂,并可使用一个或多个摄像头作为视觉传感器。
项目地址:https://github.com/huggingface/lerobot
(注:已使用中文,但因链接本身为英文,故未对链接部分进行修改。)
LeRobot 还计划在未来推出更具性价比的 Moss v1 版本,定价仅为 150 美元。
就连Mobile ALOHA的作者也表示“太神奇了”:
专业人士认为,对于AI机器人而言,它将会成为我们这个时代的个人电脑(PC)。
注:原句的语序略有不顺,调整后更符合中文表达习惯。希望这样可以帮助您更好地理解。请问还有其他需要帮助的地方吗?
-
相当于早期 PC 的 AR/VR
-
相当于早期个人电脑的机器人
改写后: - 类似于早期个人电脑的机器人 - 与早期个人电脑相仿的机器人 - 早期个人电脑类似的机器人 - 像早期个人电脑一样的机器人
而大多数网友则更为直接:这是我近十年来梦寐以求的机械手,我一定要得到它!
谈到开源的力量,项目一发布就有网友开始参与进来了:
由于他表明自己的视频没有加速,因此小编也没有给他加速。
目前,HuggingFace提供了四种模型和98个数据集,开发者还可以在训练过程中上传自己的数据集。
LeRobot 目前使用的机械臂来自 Alexander Koch 几个月前开源的项目。
下图是前辈的外观,整体硬件差异不大,但为了方便大家复制和使用,LeRobot 进行了一些改进。
在Koch v1.1版本中,去除了之前硬件模型中的一些干扰材料,实现了尺寸的标准化,并为引导臂增加了一个平台,使得从动臂能够从地面上拾取物体。
通过更换直流转换器,Koch v1.1 在组装时无需使用烙铁,也不需要手动调节电压转换器。
该项目还增加了机械臂的SolidWorks模型、接线图以及装配视频。
以引导臂(Leader Arm)为例:
注:虽然原文中的“Leader Arm”似乎是专有名词,但在中文中通常会翻译成“引导臂”。如果“Leader Arm”有特定的专业含义或为品牌名,则可能需要保留其英文原样。请根据具体上下文确认。如果有任何具体的背景信息或术语偏好,请提供,以便更准确地调整翻译。
下表列出了需要购买的部件,主要开销集中在六个舵机上,其余的包括电机驱动板、固定装置、电源和杜邦线等。
至于手臂结构的塑料片,需要根据提供的文件通过3D打印来获取。
实际上,对于相关爱好者来说,这些零件基本上都能集齐,而且在国内购买这些东西要便宜得多。
另外,如果需要更换或升级伺服电机,请记得修改控制程序。
他提供的这两种电机扭矩都不大,但精度和转速都很高。不知道替换后会有多大影响,感兴趣的朋友们可以试试看。
首先,安装 Koch v1.1 所需的依赖项:
然后按照接线图给驱动板和电机供电,并将USB连接到电脑:
请注意,从动臂这边有两个较大的电机需要12V供电,并且USB不能用作电源。
请使用以下命令来配置和校准电机:
--robot-path lerobot/configs/robot/koch.yaml
(注:此句似乎是用于指定机器人路径的命令行参数,直接翻译为:“--机器人路径 lerobot/configs/robot/koch.yaml”)
如果需要更具体的中文语境或上下文信息,请提供更多信息。
--robot-overrides '~cameras' # 不要实例化摄像头
请使用一个类的实例来调用SDK操作电机(将端口 "port" 更为你设备上实际检测到的端口):
接下来,配置每个电机的索引(这相当于在总线上进行控制时的地址):
端口=跟随者端口,
当然,可以将其重写为:
motors = {
看起来像是在定义一个名为 motors
的字典,但字典的内容还没有填写。如果你有更多具体内容或上下文,我可以帮助你进一步完善它。
名称:(索引,型号)
"shoulder_pan": (1, "xl430-w250"),
"shoulder_lift": (2, "xl430-w250"),
已经是中文或代码形式,不需要重写。如果您有其他具体需求或需要翻译的内容,请告知。
"elbow_flex": (3, "xl330-m288"),
已经是中文或代码类的内容,不需要翻译。如果你有其他需求或者需要对这段内容进行解释,请告诉我。
"腕部弯曲": (4, "xl330-m288"),
"腕部滚动": (5, "xl330-m288"),
"夹持器": (6, "xl330-m288"),
请您提供需要重写的文本内容,谢谢!
}
(注:您提供的文本只有一个括号,没有实际内容,所以我无法进行重写。)
请提供您需要重写的文本内容。
DynamixelMotorsBus 会自动检测当前电机的索引,如果电机中保存的索引与配置文件中的不符,将触发一个配置过程。此时,需要断开电机的电源,然后按照顺序重新连接电机。
读写测试
(如果是要求对某个具体的内容进行读写测试,还需要提供相关材料或说明。)
请运行以下代码:
follower_pos = follower_arm.read("当前位置")
请打印出 leader_pos 的值。
请打印跟随者的位置:
print(follower_pos)
配置成功后,可以获得全部12个电机的当前位置:
数组([2003, 1601, 56, 2152, 3101, 2283], dtype=int32)
校准
注:您的原文仅有一个词语"校准",在不明确具体上下文的情况下,我直接保留了这个词语。如果有更多具体内容或上下文需要重写,请提供详细信息。
手动调节机械臂至几个固定位置,相当于为电机提供一个相对的零点位置,同时也确保引导臂和从动臂的大致对齐。
经过校准程序后,这几个位置将被写入配置文件,作为后续运行的基准。
— 温馨提示:请勿在 Torque_Enable 启用的情况下强行弯曲。
准备就绪,现在可以开始控制机械臂了,例如让从动臂模仿引导臂的动作,设置采样频率为200Hz,并操作30秒:
秒数 = 30
频率 = 200
for _ in tqdm.tqdm(range(秒数 * 频率)):
请注意,秒数
和频率
应该替换为具体的变量名,以匹配你的实际代码。例如,如果实际的变量名为 seconds
和 frequency
,那么代码应为:
for _ in tqdm.tqdm(range(seconds * frequency)):
leader_pos = robot.leader_arms["main"].read("当前位置")
请注意,如果这是在程序代码中,应确保相应的属性或方法名(如:"Present_Position")在更改成中文后,能够正确对应并且不造成语法错误。在实际的代码中,通常建议保持属性名和方法名的一致性与准确性。上述翻译适用于中文环境下的理解或文档说明。
robot.follower_arms["main"].write("目标位置", leader_pos)
——是不是很简单?
(注:原文本就为中文,因此无需进行重写。)
由此可以知道,训练机械臂模仿人的原理是在从动机械臂模仿引导机械臂的过程中,加入摄像头的实时画面。
在模仿(训练)过程中,模型收集了手臂位置及其对应的图像数据,之后(推理)便能根据当前摄像头拍摄的画面预测各个电机所需达到的角度。
小编查阅了项目的代码,发现这个「模仿游戏」使用的AI模型竟然是ALOHA所采用的Action Chunking with Transformers (ACT)。
论文链接:https://arxiv.org/pdf/2304.13705.pdf
除了ACT,你还可以使用或训练自己的模型,例如改为ALOHA那样的双臂模式,或者在虚拟环境中进行训练和验证。
添加摄像头
该项目使用 opencv2 库来进行相机操作,以下代码同时配置了机械臂和摄像头:
leader_arms = {"main": leader_arm}
注:这段话已经是中文注释可理解的了,它表示在一个名为leader_arms的字典中,以"main"为键值,存储了一个名为leader_arm的值。重新书写时,我们应保证代码的可读性和语义的一致性。如果你需要更具体的描述或是该行代码的目的被嵌入到更大的场景中,请提供更多的背景信息。
follower_arms = {"main": follower_arm}
注释:这段代码已经是中文注释无障碍的了,它定义了一个字典,键为"main",值为follower_arm。如果你有更多的上下文或者具体的语境希望中文重写,请提供详细信息。
校准路径=".cache/calibration/koch.pkl",
注:若你这是在进行编程或文本相关工作时的调整,上述代码展示的是中文环境下对路径赋值的表示方式。具体实现请根据实际使用的编程语言和环境来定。如有需要遵循特定编码或语言规范,请进一步说明。
摄像头列表 = {
"笔记本电脑": OpenCVCamera(0, fps=30, width=640, height=480),
"phone": OpenCVCamera(1, fps=30, width=640, height=480),
注:这段代码已经是简洁明了的,按照语法规则和习惯,这里并没有进行修改的地方。此代码段是设定一个名为"phone"的OpenCVCamera实例,参数依次是摄像头编号为1,帧率为30fps,画面宽度为640像素,高度为480像素。如果需要重写以适应不同的语境或需求,请提供更多的信息。
请您提供需要重写的文本内容,以便我为您服务。您刚才提供的文本中只有两个字符 "},", 这不是一个完整的句子或段落。所以,请提供更多的信息。谢谢!
请提供您需要重写的文本内容。
请连接机器人()
请使用以下代码尝试以60fps录制30秒的视频(其中busy_wait负责控制帧率):
请使用以下中文描述进行重写: 来自勒机器人脚本控制机器人的忙等待功能
记录时间(秒)= 30
帧率(FPS)= 60
states = []
(这行代码本身就是中文和英文混合的,表示一个名为"states"的列表被创建但没有任何元素。)
如果你需要更详细的解释或有其他代码需要重写,请告诉我。
actions = []
(这行代码的作用是创建一个空的列表,变量名为 actions。)
for _ in range(int(record_time_s * fps)):
注释:这段代码表示循环运行的次数为录制时间(秒)乘以帧率(fps)。为了保证范围函数range()的参数为整数,通常会使用int()进行类型转换。
请注意,如果 record_time_s
和 fps
都已经是整数类型,则无需转换。如果是浮点数,并且你确定不会有精度问题导致的问题,也可以直接相乘。但是上述代码更加健壮。
如果有其他上下文信息或者具体需求,请告知以便更精确的帮助。
start_time = 时间.perf_counter()
注:这里的“时间”应为Python内置模块"time",但在中文环境中应将其翻译为“时间”。然而,在实际编程中,仍需使用英文名称"time"来调用模块。如果你希望代码在标准环境中运行,建议保留原始写法。如果你有其他需求或上下文,请提供更多细节。
观察,动作 = 机器人.远程操作步骤(记录数据=True)
注:这里的"观察"和"动作"应该是根据具体上下文情况进行翻译的变量名,如果它们代表的是英文编程语境下的"observation"和"action", 那么本句表示的意思是让机器人执行一个远程操作步骤,并且设置为记录数据的状态。不过为了代码的可读性,通常建议保持原始英文术语。 如:
observation, action = robot.teleop_step(record_data=True)
states.append(observation["observation.state"])
重写为:
states.append(observation["observation.state"])
(实际上,这段代码已经是相对简单的,可能不需要重写。如果你希望有不同的表达方式或上下文,请提供更多信息。)
actions.append(action["action"])
(这是一句Python代码,意思是将action字典中的"action"值添加到actions列表中。如果需要中文描述的话,可以这样写:)
将行动字典中的“行动”值添加到行动列表中。
dt_s = time.perf_counter() - start_time
该代码已经是比较简洁的,如果要重写的话,可以考虑加上注释来提高代码可读性:
# 计算从开始到现在的秒数
dt_s = time.perf_counter() - start_time
但如果是指望重新表述而达到相同的效果,那么原始行代码已经非常直接了,表达了一个时间差的计算。你想要更具体的上下文或者是其他的部分配合吗?请告知更多的细节。
请使用如下代码进行重写:
time.sleep(1 / fps - dt_s)
注意:确保 dt_s
的值是非负数,并且 1 / fps - dt_s
的结果为正,以避免 time.sleep
参数为负的情况。如果 dt_s
可能导致最终参数为负,则需要添加逻辑来处理这种情况,例如:
import max
time.sleep(max(0, 1 / fps - dt_s))
这样可以确保不会出现负的睡眠时间。
摄像头拍摄的图像帧将以线程形式保存在磁盘上,并在录制结束时编码成视频。
也可以将视频流显示在窗口中,以便于进行验证。
还可以通过命令行参数来设置数据记录流程,包括在录制开始前、录制过程中以及录制结束后的停留时间。
可视化
注意:您提供的文本就是一个简单的词语“可视化”,若是要求重写的话,它本身就是一个简短且明确的表达。如果您需要的是一个关于可视化的解释或描述,请告知我,我可以提供更详细的文本。
--root 数据 \
请注意,您的句子似乎不完整,如果您能提供更多的上下文或者完成句子,我可以更好地帮助您。
--repo-id ${HF_USER}/koch_test
注:这段文本看起来像是一个命令行参数,用于指定仓库ID。如果是需要更具体的重写或上下文信息,请提供更多详情。
以上命令将启动一个本地Web服务器,效果如下面所示:
(这里可能需要加一些具体的描述或者预期的效果图,以便更好地展示启动后的样子。)
注:如果需要更详细的帮助,请提供更多的上下文信息。
建议
本文来自微信公众号“微信公众号”(ID:null),作者:Alan,原题目为《人人都能玩得起AI机器人!HuggingFace开源低成本解决方案》。