简介:面向RoboCup3D人形仿真初学者的入门指南,系统讲解仿真环境搭建、SEU-SPARK源码编译与比赛启动全流程。包内为单个PDF文档,大小276KB,便于随时查阅,已有295人学习浏览。内容以Ubuntu 10.04为基准,从安装编译环境和依赖库开始,逐步完成server安装,并详解MESA、WXWIDGET等基础库的配置,随后通过cmake与make命令编译SEU-SPARK源码,生成可执行agent。针对比赛实操,还覆盖单人动作、双队对抗的启动方式,以及修改simspark.rb开启比赛LOG记录、使用seu-3d-toolkit回放等内容。对准备参加校内赛或首次接触RoboCup3D的开发者,这份指南能显著缩短环境配置和上手时间,是一份可直接照做的参考手册。
1. RoboCup3D 人形仿真的第一道门槛:server 装不起来,代码编不过
很多人入坑 RoboCup3D 人形仿真,第一周不是耗在决策算法上,而是耗在 server 安装和 agent 代码编译上。这里的 server 指 rcssserver3d,它配合 SimSpark 物理引擎模拟 22 个双足机器人,agent 则是独立进程,通过 UDP 与 server 对话。架构上东西不多,但依赖链长、协议细节多,装错一步全线卡住。
下文按「架构 → 安装 → 编译 → 联调」的顺序走,server 从依赖到跑通、agent 从源码到连线的完整路径都给出可执行命令,每步配验证方法和报错对照。
适合第一次碰 RoboCup3D 的人形组新人,也适合要给队友写环境搭建文档的队长。
2. RoboCup3D server 安装:先拆架构,再装依赖,最后验证端口
2.1 架构先立住:server、monitor、agent 三个进程怎么分工
RoboCup3D 仿真不是一个大程序,整个系统跑起来之后,通常是三类进程同时存在:
- rcssserver3d:承载 SimSpark 物理计算,维护球场和两队共 22 个机器人,默认在 UDP 3100 端口与 agent 通信,同时开一个 TCP 端口(默认 3200)供可视化工具连接。
- rcssmonitor3d 或 RoboViz:可视化客户端,连到 3200 端口展示赛场画面,不参与仿真逻辑,关掉它比赛照常跑。
- agent:你自己写的策略进程。每个 agent 控制一个机器人,通过 UDP 上报动作意图,server 用 ODE 物理引擎算完再把结果广播回去。
这个分工直接决定了安装顺序:先把 server 跑起来,再用任何能发 UDP 包的工具验证,最后才轮到编译 agent。很多新手把装 server 和编 agent 搅在一起,报错时根本分不清是物理引擎崩了还是自己的代码编不过。排查 RoboCup3D 环境问题时的第一件事,永远是看 server 进程在不在、端口在不在,再看 agent 侧日志。
另外一个容易忽略的点:server 本身也依赖物理引擎和一堆图形库,所以装 server 有发行版软件包和源码编译两条路。发行版有现成的包就直接装,装完能用即可;没有的情况下,才走 2.2 的依赖清单和 2.3 的源码编译流程。
2.2 在 Ubuntu 上装齐依赖:ODE、Boost、Qt5 一个都不能少
在 Ubuntu 上搭 RoboCup3D 环境,我一般先一次性装齐构建链,下面的命令覆盖了 server 和 monitor 两侧的绝大多数依赖:
sudo apt update sudo apt install build-essential cmake \ libboost-all-dev libode-dev \ libqt5opengl5-dev libqt5svg5-dev \ libsdl2-dev libgl1-mesa-devlibode-dev 提供 Open Dynamics Engine,SimSpark 用它做刚体动力学和碰撞检测,缺失时 CMake 在 find_package(ODE) 阶段直接失败,报错信息很短,基本只有一句 "could not find ODE"。libboost-all-dev 是 Boost 全量头文件和库,agent 代码里常用的 program_options、thread、system 都包含在内,装全量包省得逐个排查。libqt5opengl5-dev 负责 rcssmonitor3d 的渲染,libsdl2-dev 是部分老版本模块的窗口依赖,只跑 headless server 可以省,但源码整体编译时还是带着最省事。
提示:老教程里常见 libqt4-dev,Ubuntu 20.04 之后的官方仓库已经去掉这个包。看到 "Unable to locate package libqt4-dev" 别去找老源硬装,换 Qt5 系,源码通常同时兼容两个版本。
依赖层面的报错大多有固定特征,按下面这张表定位最快:
| 缺失的包 | 构建时报错特征 | 处理命令 | | libode-dev | CMake 阶段 "could not find ODE" | sudo apt install libode-dev | | libboost-dev | fatal error: boost/xxx.hpp | sudo apt install libboost-all-dev | | libqt5opengl5-dev | OpenGL/QtOpenGL 头文件找不到 | sudo apt install libqt5opengl5-dev | | libsdl2-dev | fatal error: SDL.h | sudo apt install libsdl2-dev |
装完依赖先确认 cmake 版本别太旧。rcssserver3d 的 CMakeLists 在 3.16 以下容易在生成阶段报语法错误,Ubuntu 22.04 自带的 cmake 已满足要求,更老的系统就加装 kitware 官方源再升级。
2.3 源码编译 rcssserver3d 与验证监听:两条 ss 命令闭环
拿到 SimSpark 和 rcssserver3d 的源码包后,解压、进目录,先编译 SimSpark 再编译 server,两者的构建流程一致:
cd simspark mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release make -j$(nproc) sudo make install cd ../../rcssserver3d # 按实际目录结构调整 mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release make -j$(nproc) sudo make install-DCMAKE_BUILD_TYPE=Release 去掉调试符号和断言,ODE 碰撞计算会快不少,Debug 版跑一场比赛经常比 Release 慢一倍以上,调试完策略记得切回 Release。-j$(nproc) 指定并行编译任务数,内存较小的机器全核并行容易 OOM,改成 make -j4 速度损失有限。sudo make install 会把可执行文件和共享库装到 /usr/local,之后运行 server 若报 error while loading shared libraries,先 sudo ldconfig 刷新动态库缓存,再确认 rcssserver3d 和 libsimspark 的安装路径是否在 ldconfig 可见目录里。
编译完成后验证 server 是否活着:
rcssserver3d & sleep 2 ss -ulnp | grep 3100 ss -tlnp | grep 3200两条 ss 命令分别确认 UDP 3100 和 TCP 3200 上有 rcssserver3d 进程在监听。ss 比 netstat 快,且不需要 root 就能看进程名。看到有监听条目,server 安装这步就闭环了;如果 3100 被别的进程占着,用 --agent-port 和 --monitor-port 换端口,注意 agent 启动参数里的端口要和这里保持一致。
3. RoboCup3D agent 代码编译:CMake 清单、Boost 链接与报错速查
3.1 拿到源码先读这三个文件:CMakeLists、README、主入口
Agent 代码常见的形态是 C++ 工程加 CMake 构建。拿到一份 RoboCup3D 人形仿真的 agent 源码,第一件事不是 mkdir build 直接编,而是先读三个文件,压缩排错时间。
CMakeLists.txt 决定三件事:C++ 标准、依赖哪些 Boost 子库、可执行文件名。人形 agent 的 CMakeLists 里通常会出现 find_package(Boost REQUIRED COMPONENTS program_options system thread) 这类写法,说明主程序用 program_options 解析 -host、-port、-team 参数,用 thread 跑感知循环。README 则记录了编译命令和启动示例,比如 ./agent -host localhost -port 3100 -team myteam。主程序入口一般做三件事:解析命令行参数、初始化关节模型、进入感知-决策-执行的循环,读懂入口即可定位大部分启动类问题。
有一个快速识别点:人形 agent 和 2D agent 的工程结构差异很大。人形代码里高频出现 JointID、Perception、SoccerCommand 这些类名,而且大概率带 .rsg 后缀的机器人身体描述文件。.rsg 是 RoboCup3D 特有的机器人实体描述格式,server 靠它创建带关节约束的刚体模型。看到工程的 data 目录里有一堆 .rsg 文件,基本可以确定这是标准 RoboCup3D 工程,而不是 2D 代码穿了个 3D 的马甲。
3.2 编译命令与必调参数:标准、Boost 路径和链接项
cd agent_source mkdir -p build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=17 make -j4 ls -l agent-DCMAKE_CXX_STANDARD=17 显式指定语言标准。老代码按 C++11 写的不少,新版 Boost 头文件在旧标准下会冒出一堆 "no template named" 之类的错误,直接指定 17 能把这类报错压到最低。系统里装了多个 Boost 版本时,CMake 可能找到旧的那个,用 -DBOOST_ROOT=/usr/local/boost_1_82_0 强制指过去,比改系统默认头文件干净。make 失败时看第一个 error,不要看屏幕最后一行:链接错误(undefined reference)查 target_link_libraries 漏项,编译错误(fatal error)查头文件路径。
Windows 下想用 VS2010 编译这个时代的 C++ 代码,很容易撞上 error MSB6006: "cmd.exe" exited with code 3。这个错误基本不是源码问题,而是 CMake 生成的工程在内嵌命令里调用的工具链找不到,或者工程路径带空格把命令行截断。我的建议是不要在 Windows 原生环境耗这个时间,直接切 WSL2 或 Ubuntu 虚拟机。RoboCup3D 的官方生态和多数开源 agent 都以 Linux 为第一目标平台,Windows 上省下的五分钟会在头文件路径和动态库问题上成倍还回去。
3.3 高频编译错误对照表:按报错特征反查原因
| 报错特征 | 原因 | 处理方式 | | fatal error: boost/shared_ptr.hpp 头文件缺失 | 没装 Boost 或版本过老 | sudo apt install libboost-all-dev | | undefined reference to boost::program_options::... | 漏写链接库 | CMake 中补 Boost::program_options | | Qt 相关文件编译失败 | Qt/GL 头文件缺失 | 补 libqt5opengl5-dev libgl1-mesa-dev | | make: *** No rule to make target | build 目录配置残留 | 删掉 build 重新 cmake | | agent: error while loading shared libraries | 运行期动态库路径缺失 | sudo ldconfig,或用 LD_LIBRARY_PATH 临时指定 |
对照表的使用方式是先抄报错的第一行,再按特征反查。有一点要注意:同一份源码在不同发行版上编译,头文件缺失的位置会变,比如 Boost 1.7x 把部分头文件挪过目录,老代码 include 的老路径就失效了。遇到这种问题别去改系统目录,优先在 C++ 标准或 include 路径上适配。
编译通过只证明语法和链接没问题,不证明能和 server 协议对上,真正的联调问题在下一章。
4. 把编译好的 agent 连上 RoboCup3D server:启动顺序、最小握手与日志定位
4.1 为什么必须先启 server 再启 agent
Agent 进程起来后会立刻向服务端发握手包,server 没监听时 agent 会反复重试,控制台错误信息通常是 Connection refused 或无响应,且伴有超时重连日志刷屏。所以标准启动顺序是:rcssserver3d 起来 → ss 确认端口 → rcssmonitor3d 起来 → agent 逐个启动。比赛模式下还要让 server 进入等待开球的状态再放 agent 入场,否则 22 个 agent 在错误的时间点注册,裁判逻辑可能判定该方缺员或产生位置冲突。
monitor 的启动顺序也有讲究:先启 monitor 再启 agent,能看到机器人被放置在初始位置的完整过程,方便确认 beam 坐标和身体朝向;反过来连也能显示,但画面会先空一阵直到收到 agent 状态。这个顺序对仿真正确性没有影响,但对确认"机器人到底站在哪"很有用,调试期建议固定为先 monitor 后 agent。
4.2 用 netcat 做一次最小握手:确认协议栈通不通
还没编任何代码时,可以用 nc 以 UDP 方式模拟一次握手,验证 server 协议栈是通的:
echo '(init (team Test) (version 12.0))' | nc -u -w 2 localhost 3100-u 指定 UDP,-w 2 表示最多等两秒后退出,避免 nc 挂着不返回。server 正常响应时,会返回一坨 S 表达式文本,开头通常是 (scene,里面带当前仿真时间 time 字段。能看到 (scene 就说明 server 在推进物理时钟,握手链路完全通畅。(version 参数必须与 server 编译时支持的协议版本一致,版本不匹配时 server 不回复或直接丢包。协议版本由 server 源码决定,agent 侧一般通过配置项指定,不要随意填数字,先看 server 打印的版本信息。
注意 echo 接管道这种方式只适合验证握手。真正的 agent 必须常驻,因为感知数据是 server 持续推送的,一次性 nc 收到第一批 (scene 就退出,无法维持连接。这个验证的全部意义在于把"server 是否活着"和"agent 代码是否有问题"两个变量分开,避免两边同时出问题时互相甩锅。
4.3 运行期日志怎么读:server.log 关键字与三类高频故障
server 日志默认打 stdout,推荐用 tee 同时落一份到文件,排错时配合 grep 回溯:
rcssserver3d 2>&1 | tee server.log grep -i "agent" server.log | tail -20tee 的好处是终端和文件双写,agent 异常时不用重新复现整场比赛,直接翻日志。日志关键字对应关系如下:
| 日志关键字 | 含义 | | Register agent | agent 握手成功并登记入队 | | Unable to bind socket | 端口被占,改用 --agent-port 换端口 | | Kick off / play | 比赛阶段推进到开球,agent 可以行动 |
运行期三大高频问题按概率排列:第一,monitor 里看不到刚启动的 agent,绝大多数是 .rsg 身体文件加载失败,server 日志里有 rsg 或 texture 相关报错,去检查 agent 启动时指定的 body 文件路径是否真实存在。第二,agent 显示在场上一路摔倒,这不是 server 问题,是关节初始角度或物理参数没归零,去 agent 的初始化代码里查头顶朝下或腿关节限位错误。第三,agent 能站起来但完全不动,先确认比赛状态,BeforeKickOff 阶段多数 agent 会压制踢球指令,需要 monitor 或裁判控制台下发开球指令后才能行动。
5. RoboCup3D 调试期最省时间的三个 server 技巧
5.1 headless 模式跑批量回归
调策略时不需要 monitor 画面,独立验证逻辑用rcssserver3d --headless。headless 模式下 CPU 占用和内存都低不少,适合把边路进攻、定位球这类固定场景反复跑几十遍做回归。配合 shell 循环,每局日志按编号归档,对比胜率时不用人工盯比赛:
for i in $(seq 1 10); do rcssserver3d --headless --game-duration 180 2>&1 > run_$i.log & sleep 60 kill %1 done循环里的 sleep 60 按实际比赛时长来定,机器性能差就把游戏时长调短,确保下一局启动前上一局已经释放端口。跑完用 grep 从 run_*.log 里批量提取比分关键字,就是一份最简单的回归报告。
5.2 三个必调 server 参数速查
| 参数 | 作用 | 调试期建议 | | --agent-port | agent 通信的 UDP 端口 | 本机多开实验时逐一错开 | | --game-duration | 半场时长(秒) | 验证整场策略时从 300 缩到 180 | | --agent-connect-timeout | agent 握手超时(秒) | 模拟高延迟网络时调大,本地默认值够用 |
这三个参数里最容易出问题的是端口:agent 启动参数里的 -port 要和 server 的 --agent-port 一致,赛前检查清单里一定要有这一条。时长参数影响的是裁判状态机,改短了利于快速验证胜负统计,但不要短到 agent 还没完成第一次 beam 就对局结束。
5.3 用日志往返时间戳区分策略问题和环境问题
遇到 agent 行为异常,先看 server.log 里有没有物理报错关键字,再看 agent 收到的 (scene 数据流是否连续。两边时间戳对不上,先怀疑网络延迟或丢包,而不是策略逻辑;磁盘 IO 异常也会导致 server 掉步,常见于把比赛日志写到机械硬盘同时开多个实例的场景。用 iostat 确认磁盘等待后再碰代码,往往能省下半天无意义的策略调参。
本文还有配套的精品资源,点击获取