拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

e-puck机器人场景搭建全攻略:物理实验与Webots仿真避坑指南

e-puck机器人场景搭建全攻略:物理实验与Webots仿真避坑指南

拿到 e-puck 的时候,我盯着那块巴掌大的圆板愣了很久。它看起来实在不像一台值得花整个学期去折腾的机器人:没有机械臂,没有激光雷达,连屏幕都没有。但等你发现一颗电池电压不足都会让它在实验台上画弧线,一组 ps0 到 ps7 的红外传感器就能写出“避障”却避不开桌子腿,你就明白为什么实验室里排着队借它的人从来没断过。

e-puck 是一台面向教学和科研的微型移动机器人,也是 Webots 仿真软件里出场率最高的机器人模型之一。这篇文章想聊的不是某个高级控制算法,而是所有算法开始前必须做的那件事:把 e-puck 的物理实验台和仿真场景都搭出来,让它先稳定地动起来、稳定地感知周围环境。无论你是刚拆箱的新手,还是想快速搭一组对比实验的研究生,这套流程应该能帮你少踩很多坑。

1. “e-puck场景搭建”到底要搭什么

1.1 e-puck是哪路机器人,为什么大家都拿它跑实验

e-puck 的定位很明确:教学不是为了造一台能送货的机器,而是为了在一个很小的、可控的平台上把“传感器—控制器—执行器”这条链路讲清楚。它采用两轮差速驱动,左右两个步进电机各带一个轮子,前后用万向球支撑,转弯半径可以做到极小。第一代产品用的是一颗 dsPIC 微控制器,后续 e-puck2 换上了主频更高的 ARM 平台,还加上了 WiFi、更多的传感器和更灵活的扩展接口。

真正让它成为“场景搭建常青树”的是传感器配置。整台机器密密麻麻装了 8 个红外距离传感器,环绕在底盘一圈,能做最简单的避障和沿墙导航;底盘底部还有 3 个地面传感器,适合做巡线、边缘检测;上方一个可旋转的小型摄像头,既能看前方也能转到朝下看地面。除此之外还有麦克风、加速度计、LED 灯珠,甚至能靠扩展板去做群体机器人实验。换句话说,e-puck 像是一个会跑的“传感器全家桶”,绝大多数移动机器人入门实验都能在它身上跑一遍。

这也是“场景搭建”这件事变得重要的原因。机器人的算法再漂亮,最终都要在具体场景里去验证。场景搭得对不对,直接影响传感器读值、里程计精度和整个实验的可重复性。很多人把时间花在调 PID 参数上,结果发现跑出来的问题其实是地面反光太强、围墙太低、仿真里的物理参数没对齐——这些都是场景问题,不是算法问题。

1.2 两条路线:物理场地与仿真环境别搞混

做 e-puck 场景,一般会走两条路线:一条是在现实中用木板、纸箱、电工胶带搭出物理场地;另一条是在 Webots 里用三维节点搭出仿真世界。两条路线解决的不是同一个问题,我建议从没接触过的人先搞清楚它们的区别。

对比项物理场地Webots 仿真环境
成本需要材料费、场地空间、备用电池免费开源,一台普通电脑即可
可重复性受光照、地面、电池影响大场景参数完全固定,适合重复实验
调试速度改一个障碍物位置要弯腰搬东西改坐标数值只要几秒
真实噪声传感器噪声、电机误差都在模型相对理想,噪声偏小
典型用途课程验收、实物验证、可靠性测试算法迭代、参数批量搜索、群体仿真

我的建议是固定一个组合:仿真里先把算法逻辑跑通、把参数范围试探出来,再花半天时间在物理场地上复现一遍。仿真不能替代实物,因为现实中那些红外地板的干扰、电机打滑、蓝牙断了又自动连上,都是实验的一部分。但完全没有仿真直接上物理场地调试,效率会非常低,尤其是做避障这种依赖传感器阈值的任务,一个阈值调不出来你可能一晚上都耗在同一个弯道。

2. 物理场景搭建:从拆箱到能跑的最小闭环

2.1 开箱检查与准备工作

拿到 e-puck 的第一件事不是急着开机,而是先做配件清点和结构检查。以 e-puck2 为例,箱子里通常包括机器人本体、锂电池、充电器、USB 线,有时还会有几块不同用途的扩展板。第一代 e-puck 可能还带一个蓝牙适配器,或者机器人腹部本来就有蓝牙模块。先把轮子用手拨一圈,确认没有被卡住,再把底盘上所有螺丝检查一遍,确认没有运输过程中松脱的地方。

电池这块最容易踩坑。e-puck 对电压非常敏感,新电池和用了两年、只剩 60% 容量的电池,跑出来的速度曲线完全是两台机器。充电时注意看充电器指示灯,很多版本的红灯表示正在充电、绿灯表示充满,具体以你手上那只的壳体标识为准。如果连续使用时发现电机声音发闷、LED 变暗,大概率是电池到了该换的时候。这个看起来是“小事”,但真的足以让一次完整实验白做。

硬件检查完之后,把机器人放在桌面或地面上,尽量让它水平。e-puck 的底部有三个支撑点,地面不平会导致万向球受力不均,影响转弯表现。我第一次就是放在一块有点倾斜的泡沫板上,结果机器人总是自己慢慢偏转,还以为是陀螺仪坏了。

2.2 通讯连接:蓝牙和串口那一堆事

实体 e-puck 要跟电脑通信,常用的有三种方式:蓝牙、USB、WiFi,具体取决于你的版本。

第一代 e-puck 用得最多的是蓝牙。操作起来并不复杂,但坑不少:打开电脑蓝牙搜索设备,配对时 PIN 码一般是 0000,配对成功后会在系统里生成一个串口设备。Windows 下通常是 COM3、COM4 这种编号,Linux 下往往是 /dev/rfcomm0 或者 /dev/ttyUSB0。很多人在这一步卡住,是因为 Linux 下当前用户没有串口访问权限,报错 Permission denied。解决方法是把自己的账号加进 dialout 用户组,然后重新登录系统。

e-puck2 的话就省心很多,直接用 USB 线连接,系统会把它识别成串口设备,同样要留意权限。WiFi 模式更适合做多机器人实验,但第一次配置时还是得先用 USB 连电脑,把 WiFi 的账号和密码写进去。如果你只是想跑跑基础例程,USB 是最稳的。

确认串口以后可以打开串口终端软件,设置波特率。e-puck 常见的是 115200,部分旧固件用 57600,建议看一下自己手上固件版本。连接成功后,在终端里输入 help 或 h,能看到固件支持的指令列表,这就说明通信链路已经通了。

2.3 通电自检:电机、传感器和摄像头是否在线

通信链路通了以后,下一步是跑一遍自检。e-puck 出厂固件里一般带有测试模式,可以通过串口指令控制 LED 灯逐个点亮、让电机正反转、读取传感器原始值。我第一次做自检时就发现一个轮子转得比另一个慢,排查半天才发现是轮轴里缠了一小截胶带。

具体操作可以这样:让机器人悬空,轮子不要接触地面,先用串口发给一个固定的 PWM 值,观察两个轮子是否同步转动。步进电机的特点是开环控制,发多少脉冲转多少角度,但这不代表它能“无脑用”——负载过大、电压偏低都会导致丢步。所以自检时除了看能否转动,还要听声音是否均匀,有没有咔咔的异响。

传感器自检同样重要。红外距离传感器在没有障碍物的情况下会输出一个基础值,当有物体靠近时数值会上升。你可以拿一只手在 e-puck 周边慢慢靠近,观察串口里对应传感器的数值是否平滑变化。如果某个传感器一开始就冲到最大值或者一直是一个恒定值,可能是红外发射管或接收管脏了,用干净棉签轻轻擦拭传感器开孔附近,经常能解决。

摄像头自检主要看画面是否清晰、曝光是否正常。e-puck 的摄像头是转台式设计,可以手动或通过固件调整朝前还是朝下,做巡线时就得让它朝下。仿真环境里没有这些问题,但实体机器人上这个细节特别容易被忽略。

2.4 动手布置一个能反复实验的物理场地

物理场地没有标准尺寸,关键是要满足你的实验需求。做避障实验,我一般会在 1.2 米乘 1.2 米的木板上完成,四周用 8 厘米高的围挡,防止机器人“越狱”。围挡材料用木板、亚克力板都行,甚至用厚纸板折起来也可以用,但表面要尽量平整,因为红外传感器对障碍物的颜色和材质敏感,黑色哑光墙面和白色反光墙面读出的数值完全不同。

地面处理是很多人容易忽略的点。红外距离传感器是发射红外光然后接收反射光的,地面太光滑或者反光太强,会导致近距离读数失真;地面是镜面瓷砖的话,机器人会像喝醉一样乱跑。所以实验场地最好铺哑光纸、哑光地板革或者纯色哑光涂料。做巡线实验时,用黑色电工胶带贴出路径,宽度在 2 到 3 厘米比较合适,太窄了传感器采样点容易偏出去,太宽了转弯时无法判断边界。

障碍物摆放也有讲究。不要直接放在场地正中央,最好留出足够的车辆通道,让实验者可以通过串口随时把机器人复位。每次跑完一组实验后,用卷尺把所有障碍物位置量一遍并记录,这样即使有人不小心碰了场地,也能快速恢复原样。严谨一点的实验室会在木板上打孔做定位销,障碍物直接插到孔里,位置可复现性会高很多。

3. 仿真场景搭建:在Webots里搭一个可复用的e-puck环境

3.1 为什么选Webots而不是其他仿真软件

做仿真场景,市面上能用的工具很多,Gazebo、CoppeliaSim、Webots 都有人用。我的选择是 Webots,原因很简单:它对 e-puck 的支持是“亲儿子”级别的。

Webots 是开源机器人仿真器,内置 ODE 物理引擎,支持 C、C++、Python、Java、MATLAB 等多种控制器语言。它自带 e-puck 的高精度模型,红外传感器、摄像头、地面传感器、电机全都建模好了,不需要你自己手工去搭一个机器人模型。Gazebo 当然也能用,但要先折腾 URDF、SDF,还得配置好传感器插件,对只想跑实验的人来说学习成本偏高。

还有个很实用的功能是 Supervisor,可以在仿真运行时读取机器人的位置、速度、传感器数据,甚至能在实验结束时自动判定机器人有没有到达目标点。做群体机器人实验时,Supervisor 可以批量控制多台 e-puck,并统一记录实验数据。这个能力在物理场地上实现起来相当费劲,但在 Webots 里只是几行代码的事。

3.2 从空白世界到第一台“你的e-puck”

安装 Webots 之后,先别急着新建世界,建议直接打开官方示例:File 菜单下选择 Open Sample World,找到 e-puck 相关示例。官方示例里已经有一台 e-puck 放在地面上,控制器的代码也能直接跑起来,这比从零开始建世界稳得多。

如果你想从空白世界开始,操作也不复杂:新建世界后,左侧是场景树,右侧是 3D 视图。在场景树里添加节点,选择 Proto 节点,找到 e-puck,然后确认。这时候 3D 视图里就会出现一台 e-puck。要让它落在“地面”上,需要先添加一个 Floor 节点,否则机器人会直接掉到世界底部。Floor 是什么?可以理解成一张无限大的水平面,给机器人一个落脚点。

添加完机器人后,我习惯把它的名字改一下。比如从默认的 e-puck 改成 e-puck_exp1,这样后面程序里引用设备时逻辑更清楚。改名字不会影响传感器,但能让你在多个机器人环境里不至于搞混。

这一步跑通以后,可以在场景树里双击每个节点查看属性。e-puck 节点展开后能看到 wheel1、wheel2 这些轮子关节,还有 ps0 到 ps7 这 8 个红外传感器设备。这也是我推荐新手自己点开看一眼的原因,你只有在场景树里见过这些名字,写控制器代码时才知道 device name 到底对应哪个设备。

3.3 用不同实体搭出一个迷宫或巡线赛道

仿真世界的“物料”就是各种节点。搭一个最简单的避障场地,我会用这么几样东西:地面用 Floor,围墙用 Box 实体,障碍物也用 Box,巡线用平面上的贴图或者改用地面传感器读数。

实操时从菜单里添加一个 Box 节点,它默认只是图形,没有碰撞属性。要让机器人真的撞到它而不是穿过去,需要把 Box 放在一个有碰撞检测的 Solid 节点里。Webots 里有个很常见的操作:先添加 Solid,在 Solid 的 children 里添加 Shape,然后再给 Shape 添加 Box 几何。很多第一次接触的人在这一步会漏掉 Solid,导致机器人直接“穿墙”。

具体参数给一组我自己常用的:场地地面用默认 Floor,四周围墙用 4 个 Solid+Box,每个 Wall 的 translation 设成长 2.4 米、宽 2 米,高度 0.12 米、厚度 0.05 米,围成一个矩形。障碍物用若干个小 Box,尺寸可以是 0.15 米乘 0.1 米乘 0.15 米,摆放时注意与机器人尺寸匹配,e-puck 直径只有 7 厘米左右,通道留 0.3 米以上会比较舒服。

摆放时直接在场景树里手动改 translation 和 rotation 数值,比拖拽精准得多。一个技巧:先把网格显示打开,用 3D 视图里的移动工具大概放个位置,再微调坐标数字。全部摆好之后,在场景树里选中这些固体节点,右键 Lock,防止误操作。这个习惯很重要,因为后来你会发现,一个不小心拖动的障碍物足以让整套仿真数据的轨迹完全不同。

3.4 第一个控制器:让机器人先动起来

控制器是整个场景的灵魂。Webots 里每个机器人节点可以绑定一个 controller,这个控制器就是一段独立程序,可以用 Python 写,也可以用 C/C++ 写。先给你看一个最基础的 Python 控制器,让 e-puck 直线前进:

from controller import Robot TIME_STEP = 64 robot = Robot() left_wheel = robot.getDevice("wheel1") right_wheel = robot.getDevice("wheel2") left_wheel.setPosition(float("inf")) right_wheel.setPosition(float("inf")) left_wheel.setVelocity(3.0) right_wheel.setVelocity(3.0) while robot.step(TIME_STEP) != -1: pass

这里有两个关键点。第一,setPosition(float("inf"))表示让电机切换到速度控制模式,而不是位置控制模式。如果你忘了写这句,电机默认可能期望一个目标角度,机器人要么不动要么猛转一圈。第二,robot.step(TIME_STEP)是让仿真推进一个步长,返回值是 -1 时说明仿真被停止,循环会退出。

速度单位是弧度每秒。3.0 大约对应机器人以半圈每秒的速度转轮子,这个速度在 Webots 里看起来不快不慢,适合刚开始测试。如果想让它转弯,把左右轮速度设成不一样的值就行。比如左轮 3.0、右轮 1.5,机器人会向右侧画弧。

如果你打开的是官方示例世界,可以直接在那个世界的 controller 字段里把控制器换成你自己新建的 Python 文件。Webots 对 Python 控制器的支持很成熟,但要注意,不同版本对 Python 环境的要求略有差异,较新版本会在安装目录下自带 controller 模块,直接用 import controller 就行。如果报错找不到模块,多半是 Python 环境变量没配对。

3.5 让传感器参与仿真:避障与巡线两个经典场景

机器人能动之后,就可以把传感器接进来了。先说最简单的避障场景。e-puck 的 8 个红外传感器在 Webots 里的设备名是 ps0 到 ps7,其中 ps0 和 ps7 大致朝前,ps3 和 ps4 大致朝后。传感器读出来的数值是一个整数,范围在 0 到 4095 之间,离障碍物越近数值越大。

一个经典避障逻辑可以这样写:持续读取 ps0 和 ps7,如果两个数值都小于某个阈值,说明前方安全,就全速前进;如果其中一个数值超过阈值,说明那一侧有墙,就往反方向转弯。我给阈值取 500 作为示例,因为我在默认模型里测过,无障碍时这个值一般在 250 以下,靠近墙时会快速上升到几千。但不同场景、不同光照下读数会有差异,所以实际用之前最好先让机器人静止在某个位置,读几组基础值,再设定阈值。

巡线场景要复杂一点。e-puck 有底部地面传感器,在 Webots 模型里通常对应 gs0、gs1、gs2 这类设备名。地面传感器的工作原理和红外距离传感器类似,黑线反射的红外光少、数值低,白色地面反射多、数值高。控制器可以让机器人只读取中间那个地面传感器的值,如果它检测到黑线,就继续直行;如果偏出黑线,就根据左右传感器的读数判断应该往哪个方向修正。这就是最经典的 PID 巡线雏形。

另一个做法是用摄像头。把 e-puck 的摄像头转到朝下,持续读取图像中心区域的灰度值,用阈值判断是否在黑线上。摄像头方案的优点是通用性强,缺点是要处理图像曝光和分辨率,实时性不如地面传感器。做入门实验我建议先用地面传感器,等理解了传感器数据如何驱动控制逻辑,再切换到摄像头去处理更复杂的视觉场景。

4. 场景搭建中的高频坑与排查思路

4.1 仿真里机器人不动或乱走,按什么顺序排查

仿真场景里最让人郁闷的问题就是:机器人明明加了,控制器也写了,但一按 Run,它就在原地发呆。我自己的排查顺序是固定的。

先看控制台有没有报错。Webots 底部有日志输出栏,如果控制器编译失败或者 Python 语法错误,会直接显示出来。C 控制器首次运行需要编译,如果本机缺编译工具或者 Makefile 不对,会出现 build 失败。Python 控制器很少遇到编译问题,但要注意 import 模块的路径是否被 Webots 正确识别。

再看机器人的 controller 字段有没有指向你的控制器文件。很多人新建了一个 Python 文件,名字写对了,但 controller 字段里填的却是另一个名字,结果跑的永远是旧代码。还有个常见问题是机器人节点被禁用了,场景树里节点名称旁如果有禁用图标,机器人就不会参与仿真。

最后看电机的 setPosition。不设置成无穷大,电机会进入位置控制模式,当目标位置是 0 时机器人会尝试回到“初始角度”,表现就是你推它一下它马上转回来,看起来像在抽搐。这个问题在论坛上被问的次数特别多。

如果机器人能跑但轨迹不对,比如一直绕圈,先检查左右轮速度符号有没有反。Webots 里电机速度正负对应的旋转方向,跟实际机器人有点差异,最简单的方法是把左右速度分别设成正相反数,看机器人是否以中心点原地旋转。如果它原地不动,说明两个轮子的方向定义和你预期不一致,改一下负号就行。

4.2 实体机器人连接不稳定与数据异常的几类原因

实体 e-puck 的问题,十次有七次出在电力和通信上。

电池电压是最容易忽略的元凶。e-puck 的电机是开环步进电机,电压稍微偏低,就会出现丢步、速度不均匀、甚至轮子完全不动的情况。很多时候你以为自己写错了算法,实际上只是电池老了。判断方法很简单:拔掉充电器,用万用表测电池空载电压,如果明显低于标称电压,就别指望机器人能规规矩矩跑实验。

蓝牙通信的坑集中在串口占用和权限上。Windows 下如果串口工具占用了 COM 口,自己的程序就连不上;Linux 下则是权限问题或者模块未被加载。一个稳妥的办法是,先把所有可能占用串口的程序关掉,在设备管理器或 dmesg 里确认串口编号,再重新连接一次。

传感器数据异常要分情况。如果某个红外传感器数值一直是 4095 或者 0,先检查传感器开孔附近有没有灰尘或胶带残胶。如果是所有传感器数值都比平常高,看看场地灯光是不是改成了强红外光源环境,比如阳光直射或某些射灯。e-puck 的红外传感器对环境光里的红外分量很敏感,实验场地尽量避开窗户直射区域,能显著提升数据稳定性。

4.3 问题排查速查表

我把经常遇到的现象、原因和处理方法整理成一张表,贴在实验室桌子边上挺管用的。

现象可能原因处理办法
仿真中机器人完全不运动控制器没编译成功查看日志,补装编译工具,重新 build
仿真中机器人原地抽搐电机处于位置控制模式对每个电机调用 setPosition(inf)
机器人总是走不直电池电压低 / 轮轴卡滞更换或充电电池,清理轮轴异物
红外传感器读数全部偏高环境红外干扰强 / 地面反光遮挡窗外光线,改用哑光地面材料
串口连接不上串口被占用 / 权限不足关闭占用程序,用户加入 dialout 组
巡线时机器人冲出赛道地面传感器阈值未标定静止测试黑白面读数,重新设置阈值
仿真视频画面全黑或过曝相机朝向不对 / 光照不足检查摄像头朝向,调整 DirectionalLight 强度
避障时机器人还是撞墙传感器阈值太高降低阈值,或先贴墙读实际距离值再换算

这张表不是一个万能清单,但覆盖了我个人遇到的八成问题。剩下的两成,大部分是版本差异或者某个节点属性被误改,通常把场景重置一下就能恢复。

5. 从“能搭出来”到“好做实验”的几点心得

5.1 场景设计不要一上来就追求复杂

我见过不少同学第一次搭场景就搞了一个八边形迷宫加斜坡加路障的综合赛道,结果机器人连门都出不去,光在那里反复撞墙。场景复杂不是本事,可控才是。实验的目的是验证某个控制逻辑,不是考验机器人能不能在复杂环境里“幸存”。

建议从最小场景开始:一个空旷地面,一台 e-puck,一个遥控或简单的直线运动。跑通了再加一堵墙,然后是两堵墙,再然后是一个弯道。每加一个元素,就重新记录一遍传感器数据和运动表现。这个过程可以让你清楚知道是哪一次修改导致了行为变化,在调参时能精准定位问题。

5.2 给传感器做“标定”,是场景搭建的一部分

这不是什么高深操作,就是在固定场景里测几组基准数据。让机器人静止在场地中央,读一遍所有传感器的值;再把它推到墙边,让传感器贴近障碍物,再读一遍。这两个值决定了你的控制阈值区间。没有这一步,你所有写在代码里的阈值都是拍脑袋。

摄像头相关的参数也一样。如果要做巡线,先把机器人放到线上和线外各拍一张图,把灰度值记下来,再决定用多少作为黑白分界。仿真里做这些操作很方便,因为场景不变化;实体环境里如果换了实验区域,一定要重新测一遍,因为不同地板的光学特性差异非常大。

5.3 版本、日志和备份:让实验经得起复查

最后想认真提一个不太“酷”、但特别重要的点:记录版本。Webots 本身更新很频繁,不同版本对传感器模型、物理参数的处理会有细微差别;e-puck 固件也有多个版本;你的控制器代码有 v1、v2、v3。这些版本号必须混在一起记录,否则三个月后回看实验数据,你完全不知道当时用的是哪个组合。

我会在每个实验目录下建一个 README,写上 Webots 版本号、e-puck 固件版本号、控制器文件 hash 或者最后修改时间、场景文件的位置,再顺手截一张 3D 视图的图。成本很低,但复查的时候能省下大量时间。仿真里有个额外的习惯就是定期备份世界文件。Webots 的 .wbt 文件是文本格式,你可以用版本管理软件管理,改乱了就回退到上一个能跑的版本,这比手动撤销稳妥得多。

这阵子搭过好几个 e-puck 场景之后,我最大的感受是:场景搭建不是准备工作,它本身就是实验的一部分。你在物理场地贴的那条黑胶带,你在 Webots 里给某面墙加的摩擦参数,都会真实影响机器人的行为。把这些因素纳入实验考虑,比盲目堆算法更能提升实验质量的稳定性。希望这篇记录能让你搭场景的过程顺利一点,少走那些我走过的弯路。

返回列表