突破1k !具身智能中文教程项目火了
Datawhale干货作者李昀迪every-embodied团队学完具身导航基础课还是一头雾水不会动手实践复现顶会代码被复杂逻辑绕晕摸不清算法流程环境配置地狱、数据集超大、下载繁琐想结合大模型却无从下手别慌这套具身导航综合入门实战直接救场从环境搭建、模型权重下载到算法拆解与全流程整合一步一步讲透仅需半天就能完整跑通「感知→决策→规划→控制」全链路算法不管是入门启蒙还是深入科研都能直接拿来用轻松为你的科研之路添砖加瓦完整开源项目直达https://github.com/datawhalechina/every-embodied效果演示机器人任务在完全未知的室内环境中自主寻找两个目标物体 ——chair 椅子在另一个房间couch 沙发在当前房间整套流程完全靠感知→决策→导航闭环实现机器人一边探索环境一边用视觉模型检测物体每找到一个目标就自动记入历史记录同步给大模型作为下一步决策依据全程不需要人为干预直到把两个目标全部找完完成物体搜寻任务。想不想自己复现一遍从环境搭建到 VLM 决策一套流程直接跑通让你的 AI 机器人真正实现 “自主导航”一、开箱即用零环境配置也能玩嫌配环境麻烦直接用现成镜像懒人福音。Autodl 镜像地址https://www.autodl.art/i/datawhalechina/every-embodied/datawhale-navigationAutodl镜像README中有详细的镜像运行说明gpu-free中也提供了镜像支持可以在镜像中搜索datawhale选择加载具身导航综合入门实践镜像。进入镜像4 行命令直接跑起来conda activate navigationcd /root/every_embodied_navigation/export LD_PRELOAD/lib/x86_64-linux-gnu/libGLX_nvidia.so.0:/lib/x86_64-linux-gnu/libGLdispatch.so.0python main.py二、从零搭建打造你的专属具身导航框架1. 配置conda环境conda activate navigationcd /root/every_embodied_navigation/export LD_PRELOAD/lib/x86_64-linux-gnu/libGLX_nvidia.so.0:/lib/x86_64-linux-gnu/libGLdispatch.so.0python main.py2. 配置算法环境# 安装视觉感知算法模块pip install ultralytics# 安装大模型所需要的相关组件pip install openaipip install transformers# 下载算法运行的仿真环境注意网络问题python -m habitat_sim.utils.datasets_download --uids habitat_test_scenes --data-path /data✅ 到这里API 调用版环境全部搞定有的同学要问了同学同学有没有本地部署的版本有的同学有的如果想要本地部署的同学可以继续以下的环境配置想直接用API的可以跳过下面的内容直接查看第三部分当然~本地部署也不是很复杂哦~# 依赖安装pip install acceleratepip install modelscope# 下载模型权重modelscope download --model Qwen/Qwen3-VL-4B-Instruct --local_dir /root/every_embodied_navigation/Qwen3-VL-4B-Instruct/这里的路径可以自行修改比如我的主函数是在every_embodied_navigation文件夹下也需要在every_embodied_navigation下再加一个Qwen3-VL-4B-Instruct这个文件夹用来存放模型权重如果不加Qwen3-VL-4B-Instruct这个文件夹则会出现模型权重文件全下载到主函数的文件夹下的情况。这里由于云端内存的原因下载了Qwen3-VL-4B的模型大家自行可以去modelscope下载Qwen3-VL-8B或者其他的模型进行测试仅需修改vlm文件夹下的文件navigator.py文件以及config.py文件即可。下载完成后清爽目录结构长这样模块清晰超好改every_embodied_navigation/├── main.py # 主函数入口支持 --mode local/api├── navigator.py # 核心导航器│├── config/│ └── config.py # 统一配置│├── utils/ # 仿真几何计算工具│ ├── simulator.py│ └── geometry.py │├── perception/ # YOLO视觉感知│ └── detector.py│├── mapping/ # 建图前沿点检测│ └── map_utils.py │├── planning/ # 路径规划执行│ └── planner.py│├── vlm/ # 多模态大模型决策核心│ ├── base_engine.py│ ├── local_engine.py │ ├── api_engine.py │ └── __init__.py │└── output/ # 可视化视频保存│ └── visualizer.py │└── Qwen3-VL-4B-Instruct/ # 权重文件安装全程不卡壳新手也能轻松搞定。三、路径 参数设置一遍就会1. 修改大模型调用形式主函数改mode参数一键切换本地部署 / API 调用2. config参数路径修改场景文件用的是相对路径一般不需要修改本地 VLM 路径建议用绝对路径否则会触发 huggingface 联网报错API 对接阿里云百炼用通义模型无需改地址填 API_KEY 和模型名即可参数配完直接运行零障碍启动四、代码运行看机器人自主导航配置完成一行命令启动python main.py如果出现BUG可以优先参考第七部分“远离BUG”。1. 实时打印大模型思考全过程决策逻辑一目了然还会自动保存日志 大模型完整思考过程--- 决策 #1 --- 位置: [0.9390037655830383, -1.5215539932250977, -2.021697998046875] 检测: 13 物体, 前沿: 1 个 动作: go_to_object 置信: 0.85 思考: 当前图像显示的是百叶窗未发现目标物体。YOLO检测结果显示有多个沙发couch目标但距离较远3.94m至4.00m且未访问过。根据规则应优先选择最近的未访问目标。最近的沙发在索引9距离2.36m符合优先导航条件。因此应导航至该沙发。--- 决策 #2 --- 位置: [2.7892143726348877, -1.600250005722046, -0.646697998046875] 检测: 17 物体, 前沿: 3 个 动作: explore_frontier 置信: 0.85 思考: 当前检测到的目标物体中couch已访问待寻找的chair未被检测到。YOLO结果中未出现chair的检测结果因此无法直接导航到目标。根据规则3应选择最优前沿点进行探索。可选前沿点中[1]位置[2.44, -1.60, 2.33]距离3.00m朝向未探索区域且距离适中符合探索优先级。因此选择该前沿点进行探索。--- 决策 #3 --- 位置: [2.423809766769409, -1.600250005722046, 2.2950756549835205] 检测: 8 物体, 前沿: 5 个 动作: go_to_object 置信: 0.81 思考: 我看到了多个椅子目标其中最近的椅子在[4.55, -2.64, 3.86]距离2.84米置信度0.81符合优先导航到最近目标的规则。虽然有多个椅子但最近的未访问目标是当前最优选择。因此我决定导航到最近的椅子。2. 自动保存导航视频左屏机器人第一视角实时画面右屏2D 占据地图黄色 未探索前沿、绿色 前沿点、深蓝 机器人、浅蓝 行走路径、紫色 规划路径3. 独立测试文件轻松调试为了方便大家学习我们还为大家准备了单独运行调试的文件不需要额外下载任何依赖单独运行文件即可。介绍如下local_test.py具身导航框架代码中使用的是transformers库调用的本地部署文件单独测试文件local_test.py给大家提供了另一种本地部署的方法用modelscope来本地部署。文件中仅需修改已经下载的模型权重文件路径以及图片路径即可图片已经为大家准备好了。代码的运行输出如下[This is a close-up, eye-level photograph of a small, fluffy white dog, likely a Samoyed or a similar breed like a Pomeranian, sitting indoors on a light-colored wooden floor.\n\nThe dog has a thick, luxurious coat of pure white fur that looks soft and voluminous, especially around its neck and chest. Its ears are pointed and erect, with a slightly pinkish inner lining visible. The dog’s face is round and expressive, featuring large, dark, round eyes that look directly at the camera with an innocent and curious gaze. It has a small, black nose and a gentle, slightly open mouth that gives]api_test.py这个是使用api运行的大模型文件仅需填入按照上文获取的大模型api修改图片路径即可注意原来官网代码的api调用不支持图片的直接输入需要进行转换这里已经提供为了方便大家理解提供了两种格式的图片文件一个是png图片另一个是webp文件可以看出除了路径以外还需要修改base64_url中的格式这个也与具身导航框架中的图片转换内容一致。代码的运行输出如下图中描绘的是一只可爱的白色小狗它正坐在室内木地板上面向镜头。小狗毛发蓬松洁白眼睛乌黑明亮鼻子是黑色的表情显得非常温顺和呆萌。背景较为模糊可以看到部分家具或装饰物整体氛围温馨舒适。这只小狗看起来像一只萨摩耶犬或类似品种的小型犬。yolo_test.py除了具身导航框架中的yolov8以外还提供了yolo-world的测试仅需几行代码即可完成视觉检测需要注意的是yolo-world开放视觉检测需要提前定义分类的类型。yolov8l-world.pt由于模型过大因此请前往https://docs.ultralytics.com/zh/models/yolo-world/下载。两种yolo模型的检测结果如下可以看出yolo-world提前定义之后可以很清楚的识别出萨摩耶小狗五、代码全拆解搞懂具身导航核心逻辑具身导航中大部分算法应该大家都有所了解例如yolo视觉算法大语言模型以及规划算法如何将这些算法应用到具身导航是我们需要探索和学习的本课程主要就是为了让大家了解和熟悉具身导航整个流程给大家讲解分享学习时踩到的坑为大家后续的研究起到一点点的帮助就心满意足啦~下面开始具体的算法讲解主要围绕具身导航各个算法的结合与具身导航需要额外添加学习的代码部分来进行讲解各个算法的原理可以参考datawhale的其他教程例如yolo和大语言模型算法都有很好的讲解。先看VLM 一次决策完整流程8 步走完智能导航1.旋转观察 → 2. 结果去重 → 3. 提取前沿点 → 4. 构造 VLM 输入5.大模型决策 → 6. 执行动作 → 7. 到达判断 → 8. 任务终止检查这就是具身导航一次决策的完整流程相信大家对整个代码有了一个初步的认知下面对代码文件各个模块进行详细的讲解。1. config 参数调优经验YOLO_CONF_THRESHOLD 0.35TARGET_REACH_DIST 1.5MODEL_TEMPERATURE 0.3除了先前配置文件中的一些参数这里再讲解一下这里各个参数的调试依据。1YOLO_CONF_THRESHOLD 设 0.35 是经验值。太低0.1会把墙上的阴影也检测成椅子太高0.6在光线暗的场景里会漏掉目标。2TARGET_REACH_DIST 设 1.5 米。太小0.5m机器人会撞墙太大3mVLM会误判机器人已经到达。3MODEL_TEMPERATURE 对决策质量影响很大。0.3 是比较保守的选择输出更稳定。调高到 0.8 以上时模型可能会出现幻觉出现一些不存在的物体。2. utils2D→3D 坐标转换核心1simulator.py这个文件中主要用来创建habitat环境如果有不懂的可以参考every-embodied项目中的https://github.com/datawhalechina/every-embodied/tree/main/08-%E5%85%B7%E8%BA%AB%E5%AF%BC%E8%88%AA%E5%8F%8AVLN有基础的讲解。2geometry.pydef depth_to_3d_world(depth_map: np.ndarray, bbox, agent_state, K: np.ndarray): x1, y1, x2, y2 [int(v) for v in bbox] mx max(1, (x2 - x1) // 4) my max(1, (y2 - y1) // 4) region depth_map[y1 my:y2 - my, x1 mx:x2 - mx] if region.size 0: return None valid region[region 0] if valid.size 0: return None d float(np.median(valid)) if d 0 or d 10.0: return None cx_px (x1 x2) / 2.0 cy_px (y1 y2) / 2.0 fx, fy K[0, 0], K[1, 1] cx_c, cy_c K[0, 2], K[1, 2] point_cam np.array([ (cx_px - cx_c) * d / fx, -(cy_px - cy_c) * d / fy, -d, 1.0, ]) rot agent_state.rotation q np.array([rot.w, rot.x, rot.y, rot.z]) R quaternion_to_rotation_matrix(q) T np.eye(4) T[:3, :3] R T[:3, 3] np.array(agent_state.position) return (T point_cam)[:3]depth_to_3d_world函数把 YOLO 像素框 深度图转换成 3D 世界坐标是视觉→导航的关键桥梁3. perception视觉感知感知模块不做过多的介绍代码很简单就是利用yolo做了一个视觉检测。4. mapping前沿点检测def detect_frontiers(full_map: np.ndarray, explored_mask: np.ndarray, min_area: int 8): navigable (full_map 0).astype(np.uint8) explored (explored_mask 0).astype(np.uint8) unexplored_nav (navigable (1 - explored)).astype(np.uint8) border cv2.morphologyEx(explored, cv2.MORPH_GRADIENT, np.ones((3, 3), np.uint8)) frontier_mask (border unexplored_nav).astype(np.uint8) n, labels, stats, centroids cv2.connectedComponentsWithStats(frontier_mask, 8) pts [] for i in range(1, n): if stats[i, cv2.CC_STAT_AREA] min_area: c centroids[i] pts.append(np.array([int(c[1]), int(c[0])])) # row, col return pts, frontier_maskmapping建图中最重要的就是前沿点检测这个也是大部分未知环境导航论文中都使用到的模块但是其实原理并不复杂border cv2.morphologyEx(explored, cv2.MORPH_GRADIENT, np.ones((3, 3), np.uint8)) frontier_mask (border unexplored_nav).astype(np.uint8)这两行代码就是找出已探索区域的边缘线边缘线 未探索可通行区域 前沿线。n, labels, stats, centroids cv2.connectedComponentsWithStats(frontier_mask, 8)然后每个独立的前沿区域取质心也就是一个前沿点。是不是很简单~5. vlm机器人的智能大脑传统导航用规则来决策离目标近就走过去否则探索最近前沿而我们用多模态大模型来理解场景并做出更智能的决策。1base_engine.pybase_engine.py主要作用是prompt构建、用户文本格式化、JSON解析、规则降级、日志记录。api和本地部署共用这一套逻辑这是多模态大模型共用的输入。def _build_system_prompt(self) - str: return f你是一个具身智能导航机器人的决策大脑。你的任务是在室内环境中找到以下全部目标物体: {self.targets}你需要根据当前观察到的图像、YOLO检测结果含物体3D坐标和距离、可探索的前沿点做出导航决策。决策规则:1. 如果检测到了目标物体且距离合理( 8米), 优先导航到目标物体2. 如果检测到多个目标物体, 选择最近的未访问目标3. 如果没有检测到目标物体, 选择最优的前沿点进行探索4. 选择前沿点时, 优先选择距离适中、朝向较大未探索区域的方向5. 如果所有目标都已访问, 返回 task_complete严格以以下JSON格式回复, 不要输出其他内容:{{ thinking: 你的详细思考过程: 1)看到了什么 2)分析各选项 3)做出决策的理由, action: go_to_object 或 explore_frontier 或 task_complete, target_index: 选择的目标在对应列表中的索引(从0开始), confidence: 0到1之间的置信度}}system_prompt主要是告诉大模型他是谁需要严格遵守的规则有哪些明确角色你是具身智能导航机器人的决策大脑给出5条清晰的决策规则优先级从高到低强制输出格式严格JSON防止模型自由发挥def _build_user_text(self, agent_pos, visited_targets, detection_summary, frontier_info, nav_history) - str: text f## 第 {self.count} 次决策### 当前状态- Agent位置: [{agent_pos[0]:.2f}, {agent_pos[1]:.2f}, {agent_pos[2]:.2f}]- 已访问目标: {visited_targets if visited_targets else 无}- 待寻找目标: {[t for t in self.targets if t not in visited_targets]}### YOLO 检测结果 (原地旋转360°汇总) if detection_summary: for i, d in enumerate(detection_summary): p (f[{d[world_pos][0]:.2f}, {d[world_pos][1]:.2f}, {d[world_pos][2]:.2f}] if d.get(world_pos) else 未知) dist f{d[distance]:.2f}m if d.get(distance) is not None else 未知 tag 目标 if d[is_target] else 非目标 text f [{i}] {d[class]} (置信度:{d[confidence]:.2f}) 3D位置:{p} 距离:{dist} {tag}\n else: text 当前旋转一圈未检测到任何物体\n text \n### 可用前沿点\n if frontier_info: for i, f in enumerate(frontier_info): text (f [{i}] 位置:[{f[position][0]:.2f}, {f[position][1]:.2f}, f{f[position][2]:.2f}] 距离:{f[distance]:.2f}m\n) else: text 无可用前沿点\n text f\n### 导航历史\n{nav_history}\n return textuser_prompt中主要包含喂给大模型的信息主要包含视觉图像旋转一圈中均匀采样4帧关键帧压缩为JPEG base64检测结果文字摘要类别、置信度、3D坐标、距离、是否是目标前沿点信息最多8个候选前沿点的位置和距离导航历史最近5次决策记录让模型知道自己走了哪里def _fallback(self, dets, fronts, visited) - dict: VLM 调用失败时的规则降级策略。 if dets: tgts [d for d in dets if d[is_target] and d[class] not in visited and d.get(distance) is not None and d[distance] 8] if tgts: tgts.sort(keylambda x: x[distance]) idx dets.index(tgts[0]) return {action: go_to_object, target_index: idx, reasoning: f[降级] 检测到 {tgts[0][class]}, confidence: 0.6} if fronts: return {action: explore_frontier, target_index: 0, reasoning: [降级] 无目标, 探索前沿, confidence: 0.3} return {action: explore_frontier, target_index: 0, reasoning: [降级] 随机探索, confidence: 0.1}最后一个是为了保证在实机部署中网络断了或者模型崩了之后能有个兜底的代码使得系统能够正常运行。6. planning路径执行这一部分主要是采用habitat-sim中自己的habitat_sim.GreedyGeodesicFollower并输出动作执行这一部分可以在得到目标点后自行根据仿真环境修改可以自己添加和替换规划器并添加控制器以达到更好的效果。7. output可视化这一部分就是可视化的内容也可以自行修改。恭喜大家完成了代码讲解的阅读相信大家已经对代码有了更深的了解对各个模块已经非常的熟悉最后navigator.py将各个模块结合并再main.py中运行。之前也提到本课程写了api调用和local本地部署两个单的具身导航文件如果对各个模块之间的调用不理解的也可以直接使用单个文件进行运行和学习本课程主要就是想竭尽全力让大家简单清晰的学习到具身导航的基础流程并能够为大家今后的科研或者学习提供一点点小小的帮助希望没有让大家失望~后续是当前代码存在的一些问题的改进建议和一些前沿的方案由于本教程希望能够用最小的代码和安装流程为大家讲清楚整个最基础的具身导航框架流程同时上传云端的内存也有限制因此并没有添加一些比较复杂的例如图像分割3D高斯建图vllm部署等内容大家可以自行学习添加。六、坦诚交底项目现存问题 进阶方案这个具身导航框架中存在的问题还是要向大家说明它并不是完美无缺的也希望这些问题能够给各位在今后的科研中提供一点小小的思路能够帮助到大家是我的荣幸也是做这个课程的初衷~1. 感知模块的误检问题在前面yolo单个文件运行的结果中可以看出yolov8在检测的时候会存在误检的问题有人说用yolo-world开放检测自己定义不就没有问题了吗在我的科研过程中实际测试表明用yolo-world开放检测也不能够完全的解决误检的问题对于不太常规的物体依旧不能够检测成功因此需要对感知模块进行改进。2. 2D转3D的问题在仅执行找到chair椅子和couch沙发这两个物体的时候我发现没什么特别大的问题甚至运行的很完美当时还很开心这个问题是我想要多测试几遍在让系统找到TV电视时偶然发现的有没有会觉得当时的我会很苦恼不发现这个问题的时候我依然很开心毕竟科研嘛能发现问题就代表需要解决这个问题这样不就能在这个领域留下哪怕很微弱的贡献了吗 大模型完整思考过程--- 决策 #1 --- 位置: [0.9390037655830383, -1.5215539932250977, -2.021697998046875] 检测: 13 物体, 前沿: 1 个 动作: go_to_object 置信: 0.63 思考: 当前检测到多个目标物体包括tv距离4.56m、couch距离3.94m和bed非目标。根据规则2应选择最近的未访问目标。couch在3.94m处tv在4.56m处因此优先选择couch。前沿点距离2.86m但目标优先级更高故不选择探索。置信度基于检测结果选择couch的置信度0.63较高。--- 决策 #2 --- 位置: [3.9896955490112305, -1.600250005722046, -0.521697998046875] 检测: 14 物体, 前沿: 4 个 动作: go_to_object 置信: 0.61 思考: 当前检测到两个目标物体tv距离2.64m和未访问的chair。但检测结果中未出现chair因此无法直接导航到chair。根据规则应优先选择最近的未访问目标。tv距离最近2.64m且在待寻找目标中因此选择tv作为目标。置信度为0.61表明识别可靠。--- 决策 #3 --- 位置: [3.0499484539031982, -1.600250005722046, 2.3973488807678223] 检测: 14 物体, 前沿: 3 个 动作: go_to_object 置信: 0.85 思考: 当前检测到多个椅子目标且距离均在8米内符合优先导航到目标物体的规则。已访问couch和tv剩余目标为chair。检测到的椅子中距离最近的是[12]位置[4.61, -2.42, 3.64]距离2.16米置信度0.79是当前最优选择。因此应导航到最近的未访问椅子。为什么这个全是前往物体的思考过程我看大模型也有前往前沿点的过程啊大家请看有没有发现大模型一直都是go_to_object没有探索前沿点的过程我的chair明明在另一个房间他是怎么不探索前沿点去的呢他真的成长成超级人工智能了不是的大家请看在这个图片中这个是机器人到达couch沙发附近后又发现了挂在墙上的tv并导航到他的附近问题就出在这里在2d转3d坐标的过程中因为tv很薄又贴着墙算法将坐标转到了墙后这个是算法转换误差导致的因此机器人直接运行到了墙后也就是chair椅子所在的房间大家可以看下图。可以看出导航到有椅子这个房间后由于贴着墙系统判断机器人到达了tv电视的附近所以视频的左上角显示找到了tv并重新开始检测又在这个房间中发现了chair椅子因此才出现了大模型决策过程中只有三个go_to_object这个问题。那怎么解决呢给大家推荐几个有代码的文章方便大家学习1.https://ieeexplore.ieee.org/abstract/document/10870413/单位中国科学技术大学项目主页https://xiaohanlei.github.io/projects/GaussNav/代码链接https://github.com/XiaohanLei/GaussNav解决路径主要通过3DGS来实现物体实例级3D定位与导航。2.https://arxiv.org/abs/2510.21307单位浙江大学项目主页https://sage-3d.github.io/代码链接https://github.com/Galery23/SAGE-3D_Official?tabreadme-ov-file解决路径为VLN构建语义和物理对齐的3DGS环境提供可执行的物体3D定位与交互。3.https://arxiv.org/abs/2408.11811单位清华大学项目主页https://xuxw98.github.io/ESAM/代码链接https://github.com/xuxw98/ESAM?tabreadme-ov-file解决路径实时在线3D实例分割用SAM的2D Mask转3D点云Mask为具身导航提供物体3D坐标。七、远离 BUG常见问题一键修复愿我们大家都远离BUG愿大家调BUG一调就通~BUG-1ImportError: libEGL.so.1: cannot open shared object file: No such file or directory遇到libEGL.so.1这个BUG时只需要更新和安装以下库即可apt updateapt install -y libegl1-mesa libegl1-mesa-dev libgl1-mesa-glxBUG-2GL::Context: cannot retrieve OpenGL version: GL::Renderer::Error::InvalidValue遇到GL这个BUG时可以通过运行以下代码来避免export LD_PRELOAD/lib/x86_64-linux-gnu/libGLX_nvidia.so.0:/lib/x86_64-linux-gnu/libGLdispatch.so.0如果大家遇到了其他的BUG欢迎指出一起“点赞”三连↓
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2499727.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!