Webots Supervisor 教程:用机器人上帝视角操控仿真世界(移动、生成、追踪与变色全实战) 科研自动驾驶物理引擎【免费下载链接】webotsWebots Robot Simulator项目地址https://gitcode.com/gh_mirrors/web/webots点击查看免费下载Webots 中的 Supervisor 是一个拥有特殊权限的机器人它既能像普通 Robot 一样驱动设备、运行控制器主循环又能越过物理引擎直接读取和改写整个场景树Scene Tree中的节点与字段。本篇文章基于 Webots 官方教程 Tutorial 8: The Supervisor 展开带领读者从零搭建一个包含 BB-8 机器人与 Supervisor 的仿真环境并逐步实现瞬移物体、删除并动态生成新节点、追踪物体位置、按条件修改颜色四大核心能力最终沉淀为一套可直接复用的场景控制代码模板。读完本文你将掌握 Supervisor API 的核心调用链getFromDef → getField → set*/getRoot → importMFNodeFromString并能独立实现比赛计分、自动重置出界物体、动态布景等高级仿真逻辑。Supervisor 是什么一个可以作弊的 Robot在 Webots 的世界模型中Supervisor 本质上就是 Robot 节点加上一个开关只要把某个 Robot 节点的supervisor字段设为TRUE它就获得了对整个仿真世界的读写权限。官方文档总结得很形象——Supervisor 拥有无限权力它可以获取或设置任意节点的位置、旋转、尺寸等字段删除场景中的节点或按字符串描述动态生成新节点读取节点在世界坐标系下的实时位置追踪仿真演进修改对象的颜色、灯光、物理参数等一切字段。从 Supervisor API 参考 可以看到这一能力对应着wb_supervisor_node_*、wb_supervisor_field_*两族 C 函数以及 C/Python/Java/MATLAB 中对应的类方法。有一点需要特别提醒即使启用了 supervisor 选项也无法直接读取挂载在其它机器人身上的传感器测量值传感器数据只能由设备所在的控制器读取。Supervisor 的上帝视角作用于场景树本身而不是别的机器人的感知结果。环境搭建创建项目并添加一个 SupervisorHands-on #1逐步创建 my_supervisor 项目通过File / New / New Project Directory...新建项目并按以下步骤调整将项目目录命名为my_supervisor替换默认的my_project将世界文件命名为my_supervisor.wbt替换默认的empty.wbt勾选向导中所有复选框特别注意默认未勾选的 Add a rectangle arena为了获得更大空间将竞技场的floorSize字段改为 10×10 米点击Add按钮从PROTO nodes (Webots projects) / robots / sphero / bb8路径添加 BB-8 机器人由于本教程不需要 BB-8 自主行动点击其controller字段再点Select按钮从列表中选择none移除默认控制器在base nodes分类中添加一个基础 Robot 节点并将其name字段改为supervisor关键一步将该 Robot 节点的supervisor字段设为TRUE它才真正变成 Supervisor通过File / New / New Robot Controller...新建控制器Python 命名为supervisor_controllerC/Java 命名为SupervisorController展开 Robot 节点点击controller字段并Select把刚创建的控制器挂到 supervisor 上保存世界。完成后的环境应如下图所示左侧场景树中除了WorldInfo、Viewpoint等常规节点外还有一个名字为supervisor的 Robot 节点。从普通控制器改造为 Supervisor 控制器通过New Robot Controller生成的默认代码是针对普通 Robot 的。要使用 Supervisor 能力只需做两处修改导入 Supervisor 库/模块代替 Robot 库并把Robot实例换成Supervisor实例。注意Supervisor 是 Robot 的超集因此while robot.step(TIME_STEP) ! -1这类主循环节奏完全不需要改动。以 Python 为例替换后的控制器骨架如下C/C/Java/MATLAB 结构完全一致仅 API 命名不同from controller import Supervisor robot Supervisor() # create Supervisor instance timestep int(robot.getBasicTimeStep()) # [CODE PLACEHOLDER 1] i 0 while robot.step(timestep) ! -1: # [CODE PLACEHOLDER 2] i 1对应地C 语言使用#include webots/supervisor.h与wb_robot_init()C 使用#include webots/Supervisor.hpp与Supervisor *robot new Supervisor()Java 导入com.cyberbotics.webots.controller.SupervisorMATLAB 则直接调用wb_supervisor_*系列函数。下面的所有 Hands-on 都围绕这两个占位符展开最终会合并成完整控制器。用 Supervisor 瞬移物体Hands-on #2Supervisor 移动物体本质上就是修改它的translation字段——与在场景树编辑器里手工改数值完全等价只不过由代码在运行期完成。这种移动完全忽略物理规律把 BB-8传送到目标位置这正是 Supervisor 可以扭曲规则的体现。第一步获取节点引用世界可能非常复杂需要一种唯一标识对象的手段。教程采用 Tutorial 2 介绍过的DEF机制在场景树中点击 BB-8 节点将其DEF名设为BB-8保存世界。随后在CODE PLACEHOLDER 1中用getFromDef获取节点引用。查看底层实现 src/controller/c/supervisor.c 可以发现wb_supervisor_node_get_from_def会先校验 supervisor 使能状态再在维护的节点列表中按 DEF 名查找并缓存引用bb8_node robot.getFromDef(BB-8)第二步获取字段引用拿到节点后用getField获取translation字段的引用。字段是值的容器字段引用是后续所有读写操作的对象translation_field bb8_node.getField(translation)第三步写入新值translation的类型是SFVec3三维向量。在CODE PLACEHOLDER 2中当第 0 步执行时把它设置为[2.5, 0, 0]if i 0: new_value [2.5, 0, 0] translation_field.setSFVec3f(new_value)保存并运行仿真BB-8 会在第一个时间步被瞬间传送到 (2.5, 0, 0)。这一取节点引用 → 取字段引用 → 按类型写值的模式可以推广到任意字段放大物体scale、改变颜色color、调整光照条件乃至出界后重置位置——参考 Supervisor API 参考 中完整的字段类型 setter 列表即可。在 C 端wb_supervisor_field_set_sf_vec3f会先校验字段类型确实是WB_SF_VEC3F且传入数组非空见 supervisor.c这也提醒我们写值前必须确认字段名与类型匹配。动态生成与删除节点Hands-on #3Supervisor 还能动态地布景本节将第 10 步删除 BB-8第 20 步在它原来的位置附近生成一个 Nao 人形机器人。删除节点只需节点引用删除比插入更简单——只需要节点的引用本身调用remove()即可。if条件并非必需只是制造 10 步延时让删除过程更明显if i 10: bb8_node.remove()对应的 C API 是wb_supervisor_node_remove其实现supervisor.c会拒绝删除Viewpoint和WorldInfo这类特殊节点——它们是被 Webots 强制保留的基础节点。生成节点定位到字段从字符串导入插入节点前必须先回答一个问题新节点要挂到场景树的哪个位置教程中的关键认知是场景树顶层其实是一个 Group 节点即root节点WorldInfo、Viewpoint、TexturedBackground等都是它的 children 子节点。因此要在场景顶层插入 Nao需要的不是节点引用而是 root 节点children字段的引用root_node robot.getRoot() children_field root_node.getField(children)在插入 Nao 之前还要先在 Webots 界面中把它声明为可导入的 PROTO点击场景树顶部的IMPORTABLE EXTERNPROTO按钮在字段编辑器出现的面板中点击 Insert new从PROTO nodes (Webots Projects)中选择 Nao.proto 并 Insert保存世界文件以固化这一声明。随后在第 20 步用importMFNodeFromString把 VRML97 格式的字符串描述导入到 children 字段if i 20: children_field.importMFNodeFromString(-1, Nao { })这里两个参数的语义需要吃透-1是插入位置负数会被解析为从末尾倒数-1表示插入到最后位置源码 supervisor.c 中越界校验通过后会把负数位置规范化为count position 1其中count是字段当前元素个数Nao { }是节点描述字符串使用与.wbt世界文件完全相同的 VRML97 语法。函数名中的MFNode/SFNode表示目标字段的类型children是多值字段Multi-Field所以用importMFNodeFromString若目标是单值字段Single-Field如某节点的endPoint则应使用importSFNodeFromString对应 supervisor.c且该实现要求目标字段必须为空。直接在字符串里指定属性想让 Nao 恰好出生在 BB-8 原来的位置不必先生成再移动——直接把translation写进字符串即可children_field.importMFNodeFromString(-1, Nao { translation 2.5 0 0.334 })同理controller、cameraWidth等任何 PROTO 参数都可以用字段名 值的形式写进字符串。技巧如果你不熟悉 VRML97 语法可以先用 Webots 界面手工搭好对象、保存世界再用文本编辑器打开.wbt文件把对应节点那段文本直接复制进字符串——Webots 已经帮你完成了对象 → 文本的翻译。追踪物体位置并改变颜色Hands-on #4Supervisor 的另一种典型用法是观察者追踪仿真中物体的演化并在满足条件时改写属性。本节的场景是生成一个球让它自由下落持续打印位置一旦触地y 坐标小于球半径就把它染成红色。生成球并获取引用先把 Ball 声明为IMPORTABLE EXTERNPROTO步骤同 Nao然后在CODE PLACEHOLDER 1中生成球DEF BALL让后续可以用 DEF 名找回引用同时拿到它的color字段children_field.importMFNodeFromString(-1, DEF BALL Ball { translation 0 1 1 }) ball_node robot.getFromDef(BALL) color_field ball_node.getField(color)运行仿真球会出现在 (0, 1, 1) 并在重力作用下下落直至与地面碰撞。读取世界坐标虽然可以通过翻译字段读取位置但 Supervisor 提供了更直接的专用 API——getPosition()它返回物体在世界坐标系而非父节点坐标系下的实时位置position ball_node.getPosition() print(Ball position: %f %f %f\n %(position[0], position[1], position[2]))C 端对应wb_supervisor_node_get_position见 supervisor.c返回一个指向三维数组的指针该实现同样先校验节点引用有效性再通过一次同步通信向仿真内核请求位置。按条件修改颜色球的默认半径是 0.2 米因此当 y 坐标小于 0.2 时即可判定已接触地面。color字段类型为SFColor也是三个 0~1 之间的分量用setSFColor写入红色if position[2] 0.2: red_color [1, 0, 0] color_field.setSFColor(red_color)注意这里的坐标约定position[0]对应 X、position[1]对应 Y、position[2]对应 Z教程判断的是 Z 分量C 端wb_supervisor_field_set_sf_color会校验 RGB 分量都在 [0,1] 区间内见 supervisor.c这为我们在代码里安全传值提供了保障。运行仿真你会看到球在下落过程中持续输出坐标触地瞬间变为红色。完整控制器代码将以上四节代码合并到两个占位符中即得到完整的控制器。这里给出 Python 完整版C、C、Java、MATLAB 版思路与 API 一一对应可在 Webots 文档的 tab 中查看from controller import Supervisor robot Supervisor() # create Supervisor instance timeStep int(robot.getBasicTimeStep()) # [CODE PLACEHOLDER 1] bb8_node robot.getFromDef(BB-8) translation_field bb8_node.getField(translation) root_node robot.getRoot() children_field root_node.getField(children) children_field.importMFNodeFromString(-1, DEF BALL Ball { translation 0 1 1 }) ball_node robot.getFromDef(BALL) color_field ball_node.getField(color) i 0 while robot.step(timeStep) ! -1: # [CODE PLACEHOLDER 2] if (i 0): new_value [2.5, 0, 0] translation_field.setSFVec3f(new_value) if i 10: bb8_node.remove() if i 20: children_field.importMFNodeFromString(-1, Nao { }) position ball_node.getPosition() print(Ball position: %f %f %f\n %(position[0], position[1], position[2])) if position[2] 0.2: red_color [1, 0, 0] color_field.setSFColor(red_color) i 1时间线回顾第 0 步 BB-8 被瞬移到 (2.5, 0, 0)第 10 步 BB-8 从场景中消失第 20 步 Nao 在 (2.5, 0, 0.334) 出生与此同时球从 (0, 1, 1) 下落并被实时追踪触地瞬间变红。小结Supervisor 编程的心智模型完成本教程后你已经掌握了 Supervisor 编程的三条核心法则官方教程 Tutorial 8 的结论节选Supervisor 就是带额外权限的 Robot所有Robot能做的事读传感器、控制电机、维持step主循环Supervisor都能做无需同时持有两种实例Supervisor 不受物理约束它可以作弊——瞬移、凭空生成、强制改色这正是构建自动化场景与仿真后处理逻辑的基础任何场景树操作都从引用开始且引用类型取决于操作类型插入节点→ 需要目标容器字段的引用通常先getRoot()再getField(children)再importMFNodeFromString删除节点→ 需要该节点本身的引用getFromDefremove修改参数translation、color、scale 等→ 需要该字段的引用getField 对应类型的 setter。动态生成对象的前置条件将 PROTO 声明为IMPORTABLE EXTERNPROTOWebots 场景树顶部的按钮完成再通过wb_supervisor_field_import_mf_node_from_string/importMFNodeFromString以 VRML97 字符串完成导入。这套引用 类型化读写的心智模型是理解 Supervisor API 参考 全部接口的钥匙。在此基础上你完全可以把教程中的球体追踪逻辑扩展为自动重置出界物体、把Nao { }字符串替换成随机参数实现程序化布景、或把颜色改写替换为计分与胜负判定——Supervisor 的边界只取决于你的想象力。赞分享科研自动驾驶物理引擎【免费下载链接】webotsWebots Robot Simulator项目地址https://gitcode.com/gh_mirrors/web/webots点击查看免费下载相关推荐Webots Supervisor 编程实战用 wb_supervisor_* API 追踪、重置与自动化控制仿真场景Webots Supervisor 编程实战用 wb_supervisor_ API 追踪、重置与自动化控制仿真场景 Supervisor 是 Webots科研自动驾驶物理引擎Webots 机器人仿真入门世界World、控制器Controller与 Supervisor 核心机制详解Webots 机器人仿真入门世界World、控制器Controller与 Supervisor 核心机制详解 Webots 是一个面向移动机器人领域的科研自动驾驶物理引擎Webots 机器人仿真器入门指南开源移动机器人仿真平台概述Webots 机器人仿真器入门指南开源移动机器人仿真平台概述 Webots 是一款开源的三维移动机器人仿真软件本指南 前言原文 https://link.科研自动驾驶物理引擎上一篇戴森球计划终极工厂蓝图库3000设计方案解决太空工厂建设难题下一篇攻克GB级Excel导出难题Excelize流式写入防损坏实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考