- 科研
- 自动驾驶
- 物理引擎
【免费下载链接】webots
Webots Robot Simulator
导读
本文基于 Webots 开源仓库中 development-2021.md 这一 2021 年度官方 Discorddevelopment频道存档,梳理当年社区与 Cyberbotics 开发者围绕 Webots 的数十个真实技术讨论,涵盖 ROS/ROS2 集成、LiDAR 点云可视化与数据访问、URDF 导出与逆向运动学、Supervisor 编程、控制器编译与外部控制器、图像流传输与远程控制库、以及性能优化等主题。读完本文,你将掌握 2021 版 Webots(R2021a/R2021b 及其 nightly 构建)中这些高频问题的成因与官方认可的解决方案,并能结合本仓库源码(如 lidar.h、remote_control.h、robot.h)验证 API 的真实行为。
说明:该文档是聊天记录存档,其中穿插少量社区事务(如翻译贡献、Discord 语音频道等)。本文聚焦其中具有工程价值的技术议题,社区协作内容仅作简要交代,不喧宾夺主。
一、ROS / ROS2 与 Webots 集成:2021 年的关键经验
1.1 RViz2 显示异常与world → base_link静态变换
讨论中一位用户使用 Webots 导出 URDF 后在 ROS2 中启动动态 RViz,出现加载失败。开发组成员指出:RViz2 本身存在已知的显示问题,简单"取消勾选再勾选 RobotModel"即可恢复。真正的技术要点在于tf 坐标树:
- 静态机器人可直接在 launch 文件中添加
tf2_ros静态变换发布器,将world帧与base_link帧绑定:
static_tf = Node( package='tf2_ros', executable='static_transform_publisher', name='static_transform_publisher', output='log', arguments=['0.0', '0.0', '0.0', '0.0', '0.0', '0.0', 'world', 'base_link'] )- 对于移动机器人,静态变换不再适用,必须由用户自行发布
world与base_link之间的动态变换。开发组明确表示这与 Gazebo 的默认行为不同——真实世界中world → base_link变换通常不可直接获取,因此 Webots 侧不内置该发布器;用户可通过 Supervisor API 自行实现。这一讨论直接影响了后来webots_ros2生态中WebotsDifferentialDriveNode的设计方向(见下文 1.4 节)。
1.2 从 Webots 内启动 ROS launch 文件的可行性
社区用户提出"能否在 Webots 内直接启动 ROS1/ROS2 的 launch 文件"。官方的回应是:更希望在控制台层面与 ROS 交互,而非把 launch 编排塞进仿真器;不过开发组认可一种中间形态——在 launch 文件中实现事件机制(例如 Webots 重置控制器时同时重启相应的 ROS2 节点),从而免去重载世界文件的成本。这是 2021 年 ROS 集成便利性讨论的重要背景。
1.3 ROS1:webots_ros的版本分支、依赖与ros_control
针对 ROS1 用户,2021 年社区沉淀了如下可复用的经验:
webots_ros仓库仅包含示例,真正的 Webots ROS 接口实现在 Webots 本体中;使用 nightly 构建的 R2021b 时,示例代码应切换到webots_ros的develop 分支,而master分支对应最新正式版 R2021a。- 用
webots --version可确认当前生效的 Webots 版本。 - 想让 Webots 中的电机关节被 ROS 控制,自 R2021b 起
ros控制器内置ros_control支持:将机器人controller参数设为ros,并在controllerArgs中追加--use-ros-control等参数(参见 运行外部机器人控制器 相关章节的配置思路)。若不加该参数,则只能依赖set_position这类底层 service。 - 关节控制的标准通道是
trajectory_msgs/JointTrajectory话题或control_msgs::FollowJointTrajectoryAction,而joint_state_publisher只负责发布状态、不负责控制,适合 RViz 显示但不适合驱动仿真。 - 常见坑:
ros_control每个时间步都会写关节位置,若机器人初始关节位置贴近minPosition/maxPosition,会触发"too low / too big requested position"类报错,此时可先移除--use-ros-control定位问题;R2021b 开发分支早期还存在--use-sim-time参数缺失导致的仿真卡死问题,临时补上该参数即可。 - 依赖安装:ROS1 下启用 ros_control 需
sudo apt install ros-noetic-ros-controllers(melodic 同理);rosdep依据package.xml解析系统依赖,通常在源码安装包时运行。
1.4 ROS2:里程计输出与WebotsDifferentialDriveNode
针对"如何在 ROS2 中输出里程计"的问题,2021 年时有两个官方认可路径:
- 继承
webots_ros2中的WebotsDifferentialDriveNode类——它会自动创建odom话题,从轮式编码器推算并发布里程计数据,可参考 e-puck 示例(webots_ros2_epuck/driver.py)。继承后可利用self.robot对象继续调用标准 Webots API。 - 使用当时刚发布的
ros2_control集成(alpha 版):通过DiffDriverController等现成控制器输出里程计,例如 TurtleBot3 Burger 示例中的ros2control.yml与turtlebot_webots.urdf资源文件。
1.5 ROS1 常见环境问题:Boost 链接错误
多位用户在 Ubuntu 20.04 上运行 R2021b nightly 时遇到libboost_system.so.1.65.1: cannot open shared object file。排查要点包括:
- 先
source /opt/ros/<distro>/setup.bash再启动 Webots; ldd ${WEBOTS_HOME}/projects/default/controllers/ros/ros检查动态链接;apt-cache search libboost-system确认系统可用版本(Ubuntu 20.04 最低为 1.67,出现 1.65.1 说明链接到了过旧/错误的构建)。
开发组最终确认该问题出自 Webots 侧打包,并建议使用 Ubuntu 20.04 的 tarball 安装包解决(参见 安装与构建指南)。
二、URDF 导出与逆向运动学(IK)
2.1 URDF 导出:为什么视觉几何变成了包围盒?
2021 年初用户发现"将机器人导出为 URDF 时,视觉几何被导出成 boundingObject(包围盒)而不是 Shape"。官方确认这是有意的、基础实现:wb_robot_get_urdf的文档注释中已说明,URDF 导出器是一个基本实现,适用于发布 ROS 变换、计算逆运动学等多数场景,但可视化能力有限——网格提取(mesh extraction)当时尚未完整实现。该函数在 C API 中的声明见 robot.h(const char *wb_robot_get_urdf(const char *prefix);)。
实操要点:
- 需要 R2021a 及以上版本才能在机器人右键菜单中直接导出
.urdf(R2020b 只能导出.wbo)。 - 社区用户 Simon Steinmann 曾开发 proto-splitter 脚本,可从 Webots 中提取
.obj/VRML 网格用于补全 URDF 的视觉部分,但当时缺乏平滑处理。
2.2 pyikfast:6 自由度机械臂的高性能 IK 方案
针对 PR2(7 自由度)等机械臂的 Python IK 需求,2021 年社区主推pyikfast(基于 IKFast 的 Python 模块):
- 生成求解器使用官方 Docker 镜像,命令形如:
docker run -v ${PWD}:/output cyberbotics/pyikfast torso_lift_link solid_363 _pr2其中三个参数依次对应base_link、effector与module_extension(模块名后缀)。
- PR2 的注意点:其手臂为 7 DOF,而 IKFast 默认只支持 6 DOF,需要将某一关节视为 inactive link;社区给出的参数示例为
base_link = "torso_lift_link"、effector = "r_wrist_flex_link"。 - Windows 用户需保证 Docker Desktop 已启动(包括 WSL2 后端)、在 PowerShell 中用引号包裹含空格路径(
cd "path")、且以管理员身份运行 shell。 - 常见编译失败信息
RuntimeError: maximum recursion depth exceeded意味着 solver 编译失败,通常与 URDF 本身(或 DOF 配置)有关。 - 求解器生成后
pip3 install .安装 Python 包,机器人需设为 supervisor 才能完成姿态读取/写入。 - 相比
ikpy(社区评价其"慢且难用"),pyikfast 性能更好;仓库示例使用 ABB IRB4600 机器人。若没有可用 solver,ROS + MoveIt 仍是功能最完整的路线。
2.3 在 Webots 内绘制轨迹的入门路线
对于"让 IRB 机械臂画字母/圆"这类入门需求,官方示例世界路径为:File > Open Sample World > inverse_kinematics.wbt(IRB 机器人画圆),可从中取逆向运动学实现灵感。
三、LiDAR 点云:启用、可视化与数据访问
LiDAR 是 2021 年讨论最密集的传感器话题之一,本仓库 C API 头文件 lidar.h 提供了全部相关函数,可与下文逐一对照。
3.1 启用与可视化
- 点云可视化入口:
View / Optional Rendering / Show Lidar Point Cloud与Show Lidar Rays Paths(详见 用户界面文档)。 - 必须先启用点云,方式二选一:在机器人窗口(双击机器人)中勾选,或从控制器调用
wb_lidar_enable_point_cloud()(C++ 为enablePointCloud(),见 Lidar.hpp)。 - 常见坑:
wb_lidar_get_layer_range_image()在设备未启用时调用会直接报错(called for a disabled device! Please use: wb_lidar_enable()),须先用wb_lidar_enable()启用设备。
3.2 2021 年已知 Bug 与规避
- 点云"闪烁/随机消失":社区报告点云显示数秒后中断再恢复,且
lidar.wbt示例可复现。开发组定位到与渲染相关的 PR,并确认"当某条射线无碰撞(超出 maxRange)时返回 infinity,而可视化未能处理无穷值",导致整片点云不被绘制。该问题随后在 nightly 构建中修复。 - Python 3.9 兼容问题:R2021b 在 Python 3.9 下有已知问题,已在 R2021b rev1 nightly 中修复;临时方案是改用 Python 3.8。
WbLidarPoint属性访问回归:Python 下访问point.x一度失败(报AttributeError: Object 'SwigPyObject' has no attribute 'getX'),属 SWIG 绑定回归,隔日 nightly 修复。
3.3 点云数据结构(源码级)
WbLidarPoint定义于 lidar_point.h,C/C++ 通用:
typedef struct { float x; // 点的 x 坐标(世界坐标系) float y; // 点的 y 坐标 float z; // 点的 z 坐标 int layer_id; // 所属层 float time; // 采样时间 } WbLidarPoint;取点云用wb_lidar_get_point_cloud()(或按层wb_lidar_get_layer_point_cloud()),点数用wb_lidar_get_number_of_points();C++ 侧对应getPointCloud()/getLayerPointCloud()(Lidar.hpp)。Python 下访问属性写作.x、.y、.z(修复后的 nightly 支持)。
3.4 用 LiDAR 做"点到物体"测距
当相机识别到物体但距离传感器指向不重合时,官方建议让 LiDAR 与相机拥有相同的 position、orientation、FOV 与分辨率,即可把"相机识别 + 深度"组合成类 3D 感知方案;更简单的单点测距则直接加DistanceSensor节点。
四、控制器开发:编译、IDE、外部控制器与常见报错
4.1 C++ 控制器与USE_C_API陷阱
用户报错'light_sensor' does not name a type,最终定位到Makefile 中误设USE_C_API。该变量告知 Webots 编译系统"本 C++ 控制器使用 C API",若你实际使用 C++ API(<webots/LightSensor.hpp>),应注释或删除USE_C_API行后重新编译。排查建议:将代码精简到只保留出错片段、检查设备名是否正确、确认返回值非 NULL。
4.2 手动链接 ROS 等第三方库
在控制器 Makefile 中集成 ROS(如/opt/ros/noetic)时,正确写法是追加而非覆盖:
INCLUDE = -I"/opt/ros/noetic/include" LIBRARIES += -L"/opt/ros/noetic/lib" -lroscpp -lroslib -lrosconsole -lrostime -lroscpp_serialization -ltf_conversions -ltf注意LIBRARIES +=(追加),否则会覆盖 Webots 自带的链接项;即便如此仍报ros/ros.h: No such file or directory,多半是INCLUDE路径未被Makefile.include引用到(其编译规则位于resources/Makefile.include,报错行号可作线索)。IDE 方面,VSCode、Visual Studio 均可用,VS 配置参考 using-your-ide.md。
4.3 外部控制器:多机器人场景的WEBOTS_ROBOT_NAME
在 Webots 中将控制器设为<extern>后从外部 Python 启动时,单机器人可以、双机器人不行的经典原因:每个外部控制器进程必须用WEBOTS_ROBOT_NAME环境变量指定目标机器人,且所有外部控制器都要各自运行。参考写法(注意sys.path需指向本机 Webots 的 Python 绑定目录):
#!/usr/bin/python3 import sys sys.path.append("/usr/local/webots/lib/controller") sys.path.append("/usr/local/webots/lib/controller/python38") from controller import Robot import os os.environ["WEBOTS_ROBOT_NAME"] = "Master" robot = Robot() while robot.step(32) != -1: print("Hello World!")更完整的规范见 running-extern-robot-controllers.md。
4.4 Python SDK 的生成机制
社区询问"Python SDK 如何生成、能否加类型提示":官方答复是SWIG 从 C++ 接口自动生成(src/controller/python/Makefile即构建入口);相关改进讨论可追溯至仓库 issue #2385,且本仓库 lib/controller/python 下的绑定文件即为产物。若希望给绑定补充类型信息,属于对 SDK 生成流程的增强,需要提交 PR 由上游评审。
4.5 控制台输出等小坑
- 控制器内
printf无输出:检查是否把\n误写成/n,或是否在wb_robot_step循环之后才调用。 - 旧 API 迁移:
DifferentialWheels已被Motor+PositionSensor取代,设置编码器归零可等价写为:
wb_motor_set_position(left_motor, INFINITY); wb_motor_set_position(right_motor, INFINITY); wb_motor_set_velocity(left_motor, 0.0); wb_motor_set_velocity(right_motor, 0.0);这是 Webots 官方转换默认世界时采用的速度控制写法;PositionSensor 只负责读取电机位置,若需"设置编码器"应通过 Motor API。
五、电机、坐标系统与 Supervisor 编程
5.1 电机限速与限位
- 电机最大速度由
Motor.maxVelocity字段决定(见 motor.md 的字段汇总),机器人"太慢"时应检查并调大该字段。 - 设置负值限位(如
minPosition=-180°、maxPosition=-45°)报Invalid 'maxPosition'时,正确顺序是:先改minPosition→ 再把当前关节位置改到新区间内 → 最后改maxPosition,否则 Webots 会拒绝设置不包含当前位置的范围。另外注意仅改 HingeJoint 的 position 不会改变末端位姿,需同步修改 HingeJointendPoint节点的 rotation。
5.2 NUE 坐标系与轴角(angle-axis)旋转
- Webots 默认使用NUE 坐标系(Y 轴向上)(见 worldinfo.md)。用 Supervisor 设旋转时若直接
[0,0,1,rad]而机器人初始 rotation 非零(如1,0,0,-1.57),实际效果是"初始旋转 + 期望旋转"的组合,而非单纯的绕 Z 轴旋转。 - 正确做法:把当前 rotation 转成旋转矩阵或四元数 → 左乘目标旋转(矩阵/四元数形式)→ 再转回轴角表示(前 3 个值为单位旋转轴,第 4 个值为弧度)。社区推荐 transforms3d 库完成转换。
- Webots 中四元数顺序为
(x, y, z, w);陀螺/IMU 数据跨工具链(如 PCL 仍用 NUE)时务必确认坐标系约定,否则会出现"方向对不上"的假 bug。
5.3 Supervisor:获取与修改节点位姿
- 获取任意物体的世界坐标,标准做法是 Supervisor API(见 supervisor-programming.md);调试时也可在场景树中把物体坐标临时设为
(0,0,0)来确认世界原点。 supervisor.getFromDef(...)返回None的常见原因是机器人节点的supervisor字段未设为 TRUE(R2021b 起行为更严格,此前可能是"侥幸能用"的 bug)。- 世界原点并非一定在地面节点中心,需通过上述方法自行确认。
- 向多个机器人下发任务参数,可用emitter/receiver通信,官方参考示例为
File > Open Sample World > samples > curriculum > advanced_genetic_algorithm。
5.4 传感器与识别
- 相机识别(Recognition):
getRecognitionObjects()返回对象数组指针;每个对象的position(3 值)为 XYZ 坐标、orientation(4 值)为轴角表示;对象 ID 的访问可参考 camera_recognition.c 示例。 - 基于颜色做"跟随指定颜色物体"时,可使用识别对象的颜色数组;社区建议为所有官方对象 PROTO 暴露
recognitionColors字段,该建议最终形成 PR(webots#3108)。 - Fog 与相机:相机看不到 Fog 效果时,先检查世界文件中 Fog 节点是否声明在相机节点之前。
- 喷雾/划线类效果:用Pen 节点实现(见 pen.md)。
- 直线轨迹绘制:可用地面贴图/几何建模(社区也提供了用 TinkerCAD 制作轨迹的第三方教程)。
六、图像流、远程控制库与真实机器人迁移
6.1 相机图像流:GPU → 共享内存与 JPEG 压缩
面向 RoboCup 人形联赛"8~16 路 640×480@30fps 相机同时推流"的诉求,官方解释了 Webots 的相机实现:图像直接从 GPU 显存读入共享内存段,本机控制器与 Webots 共享,避免不必要的图像拷贝。对 RoboCup 这类"本地控制器作中继、真机控制器在网络上另一台机器"的架构,官方建议在中继控制器中加入 JPEG 压缩再经网络发送——而这正是 ROS2 控制器发布相机图像时已经自动完成的(自动 JPEG 压缩且压缩比可调)。即压缩不内置在 Webots 仿真核心,而是约定在传输层实现。
6.2 远程控制库:注入传感器数据
社区问"能否从外部给传感器喂值"(例如把真机传感器数据反馈进仿真)。官方确认可以,入口是远程控制(remote control)库(见 controller-plugin.md 与 remote_control.h)。其原始用途正是让控制器在"仿真"与"遥控真机"之间切换,并把真机传感器值像仿真传感器一样显示出来。关键函数(本仓库头文件中均可查证):
- 传感器注入:
wbr_distance_sensor_set_value()、wbr_gps_set_values()、wbr_camera_set_image()、wbr_motor_set_position_feedback()等; - 执行器回调:
WbrInterface结构体(wbr_robot_step、wbr_motor_set_position等); - 2021 年社区曾提出扩展 LiDAR 端点,开发组建议在插件中自行分配内存并调用
wbr_camera_set_image()/相关wbr_*注入函数填充数据,并鼓励以 Draft PR 形式提交供评审。
6.3 把仿真控制器搬到真机
Webots 没有"一键移植到任意机器人"的机制,官方认可两条路:① 重写控制器中用到的 Webots API 函数使其对接硬件;② 若真机有 ROS API,则用 ROS 作为仿真与真机的统一中间件。以 Khepera IV 为例(无 ROS 接口、GNU C/C++ 原生应用),重写函数是最简方案,详细指导见 transfer-to-your-own-robot.md。
七、性能、调试与平台适配
7.1 RAM 占用与"无渲染/无网格"模式
针对 RL 训练场景,社区实测 UR5e 在空世界中的内存占用:初始约 850MB、关闭所有图形效果约 400MB、移除网格后约 177MB。据此提出增加 CLI 参数(如webots --disable-meshes)以禁用网格与纹理的建议(对应 issue webots#2777)。需要区分:--no-rendering只是不渲染主窗口,仍会为相机类设备渲染网格,因此不等于"省内存的纯物理模式"。做大量并行仿真时(如 8 核 16 线程跑 8 实例),需按"每实例 Webots 进程 + 控制器进程"规划内存预算。
7.2 调试与性能分析
- 崩溃定位:编译debug 模式可获更多信息;若 IDE 的 GDB 集成拿不到函数名,可尝试附加
-ggdb标志(当时尚未进入官方 Makefile,社区建议提小 PR)。 - 性能分析:在
WEBOTS_HOME/src/webots目录执行make profile,再用 gprof 分析运行结果。 - 版本确认:
webots --version;nightly 构建可从 releases 页面获取。
7.3 平台兼容性速记
- Apple M1:2021 年 Webots 经 Rosetta 翻译运行即可流畅工作(社区实测 M1 MacBook Air 运行无压力),原生 ARM 构建处于规划中。
- 旧系统:Ubuntu 16.04 上 R2021b 无官方二进制时,可从源码编译(参见 building-webots.md)。
- 仓库体积:克隆 Webots 仓库无需 Git LFS(仓库无超大文件),社区担心的"GitHub 2GB 仓库上限"并不存在。
八、面向教育与社区:翻译、示例与贡献
- GUI 翻译:Webots 支持多语言 GUI,翻译文件位于
resources/translations,官方欢迎以 PR 形式提交翻译;2021 年社区即启动了俄语翻译。注意:机器翻译质量不佳,需要母语者校对。 - 文档翻译:官方采用"官方英文 + 社区翻译链接"模式,
docs目录下的guide与reference是两个最大的文档目录。 - 示例世界:车辆相关可看
File > Open Sample World > vehicles(如city.wbt,另见 docs/automobile/index.md);巡线机器人、相机识别、遗传算法、IK 等均有现成示例世界。 - 社区项目:自研项目(如跳舞 NAO、RoboCup Junior Rescue 巡线世界)可提交到
community-projects仓库(robots或samples目录)。 - 功能请求:Webots 不支持的功能(如波士顿动力 Spot SDK 集成、VR 交互等)建议在官方 Discussions 的 Ideas 分类发起讨论;小修复(typo、编译标志)也欢迎直接提 PR——2021 年社区正是通过这种方式修复了
WbLidar.cpp中的文案错误并为所有对象 PROTO 暴露recognitionColors。
九、总结:2021 年经验对当前开发的启示
- ROS 集成:Webots 的 ROS1/ROS2 接口本体在仿真器内,示例仓库只提供参考;版本分支(master=正式版,develop=nightly)必须与 Webots 版本匹配。
- 传感器数据流:LiDAR 点云需先
enable_point_cloud;WbLidarPoint结构体(x/y/z/layer_id/time)是跨语言访问点云的标准入口;图像推流建议在传输层做 JPEG 压缩。 - API 迁移:
DifferentialWheels→Motor + PositionSensor、USE_C_API与 C++ API 二选一,是 2021 年控制器迁移的两个高频坑。 - 坐标与旋转:NUE(Y 向上)、轴角(axis + rad)、四元数(x,y,z,w)三者间的换算,是 Supervisor 姿态控制出错的首要来源。
- 远程控制库:
wbr_*注入函数 +WbrInterface回调,让"仿真/真机双模控制器"成为可能,也是把外部传感器数据接入仿真的官方途径。
以上所有结论均可在本仓库对应头文件与文档中复核:传感器 API 见 include/controller/c/webots 下各头文件;URDF 导出见 robot.h;远程控制见 remote_control.h;配套教程见 guide 与 reference 文档目录。
- 科研
- 自动驾驶
- 物理引擎
【免费下载链接】webots
Webots Robot Simulator
相关推荐
vphone-cli AI自动化:vphone.sock宿主控制套接字全解析
vphone cli AI自动化:vphone.sock宿主控制套接字全解析 📱 vphone cli 是一款在 Mac 上通过 Apple Virtuali
科研自动驾驶物理引擎Webots 官方文档频道问答精解:从传感器仿真、渲染技巧到 ROS 集成的实战手册
Webots 官方文档频道问答精解:从传感器仿真、渲染技巧到 ROS 集成的实战手册 本篇技术指南以 Webots 开源仓库中的 docs/discord/do
科研自动驾驶物理引擎Pinocchio与ROS深度集成:实战机器人控制系统开发
Pinocchio与ROS深度集成:实战机器人控制系统开发 Pinocchio作为一个快速灵活的刚体动力学算法实现库,与ROS(Robot Operating
机器人物理引擎
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考