机器人【免费下载链接】gz-simOpen source robotics simulator. The latest version of Gazebo.项目地址https://gitcode.com/gh_mirrors/gz/gz-sim点击查看免费下载本篇技术指南基于 gz-simGazebo Sim仓库中的设计文档 doc/architecture_design.md系统讲解其面向大规模场景的分布式仿真设计世界按 Level 切分、动态实体标记为 Performer、仿真器按 primary/secondary runner 分工以及基于缓冲区的实体按需加载与卸载。读完本文后你将理解该架构的核心概念与 SDF 配置方式并能结合 src/LevelManager.cc 源码掌握其判定与加载算法可用于在大型仿真环境中降低实体数量、提升性能。1. 设计目标懒加载的 Serverdoc/architecture_design.md 在 High level behavior 一节给出了整体行为约定Server加载一个 SDF 文件文件中可以包含多个 world而每个 world 又可被划分为多个 level理想情况下server 只应加载文件中的高层信息worlds、levels、performers而不立即实例化所有实体仅根据仿真的分布方式和哪些 level 被激活来决定加载哪些实体。文档同时标注了一个性能 TODO如果 SDFormat 库能提供增量加载 world 的方式至少不要一次性为所有对象创建内存对象性能会更好。这一点也解释了当前实现的折中SDF 文件会被完整解析进内存但实体entity的创建/销毁是按需进行的。1.1 多个 world 的设计取向设计文档中的 Multiple worlds 一节仍标记为 TODO是否以及如何支持多个world标签尚未定案。其设想是并行运行多个不同 world同一进程或不同进程时每个 world 由一个 runner 独立仿真负责该 world 的全部系统与实体这种模式下不存在 primary/secondary 的概念各 world 以 lock-step 方式运行数据可被统一收集。由于当前仓库中该部分尚无实现以上应视为设计方向的描述而非已有能力。2. 多 Performer、多 Server 的分解方式这是设计文档的核心章节。当 world 中存在多个 performer 时仿真会被分解为2 个或更多 secondary simulation runner每个仿真 1 个或多个 level1 个 primary simulation runner负责让所有 secondary 保持同步。runner 的总数、以及 level 与 performer 对各 runner 的亲和性affinity都通过 SDF 预先定义。根据某个时刻 world 的布局部分 runner 可能处于 stand-by 状态例如所有 performer 都在互相物理接触时。文档给出了一个 3 个 performer 的示例场景见下图存在 3 个 performerR1~R3R1和R2都在 levelL1R3在L2server 按 SDF 的声明启动 3 个 runner1 个 primary1 个装载了L1连同R1、R2的 secondarySR11 个装载了L2连同R3的 secondarySR2注意M6被两个 secondary 同时加载因为它是全局实体global entity。在仿真运行中primary 持续跟踪 performer 是否进入任何 level 的缓冲区buffer zone。以R1从L1移动到L3为例由于没有 stand-by 的 secondarySR1会同时仿真L1和L3而SR2继续只仿真L2反之如果启动时存在一个 stand-by 的SR3则它将被分配去负责L3。当R1向L2移动时文档描述了完整的交接流程R1进入L2的缓冲区primary 检测到后将R1的当前状态转发给SR2。此时SR1与SR2都持有R1R3的传感器可以检测到R1但只有SR1对R1施加物理仿真R1进入L2后SR2接管其物理仿真但SR1仍跟踪其状态直到R1离开L1的缓冲区SR1才卸载其相关实体。与 runner 同步相关的实现事实可以在仓库中得到印证secondary 的 performer 归属用 PerformerAffinity 组件表示holds the address of the distributed secondary that this performer is associated with分布式通信层由 src/network/NetworkManager.cc、NetworkManagerPrimary.cc、NetworkManagerSecondary.cc 实现。tutorials/distributed_simulation.md 也印证了文档中的分工描述同一 level 的 performers 始终在同一 secondary 实例中primary 保持所有 performer 加载但不做物理仿真secondary 根据收到的 affinity 变化加载/卸载 performer。3. SDF 配置level与performer标签Level 与 performer 的概念是 Gazebo 特有的直接挂在world下会降低 SDF 的通用性文档提到extension标签曾被提议但尚未实现因此这两个标签被放在一个固定名称的插件标签内plugin namegz::sim filenamedummy performer ... /performer level ... /level /plugingz::sim这个插件名是约定的仿真 runner 见到它就知道需要读取其中的 level/performer 配置。源码中这一约定在 src/LevelManager.cc 的ReadLevelPerformerInfo中实现遍历sdf::World的 plugins匹配名称为gz::sim的插件若找不到则打印 Levels and distributed simulation will not work。3.1level标签level描述 level 占据的体积以及其中的实体level namelevel1 pose0 0 5 0 0 0/pose geometry box size10 10 10/size /box /geometry buffer2/buffer refmodel1/ref refmodel2/ref /level各字段的含义与当前实现的约束poselevel 体积在世界坐标系中的位置。朝向部分会被忽略——从源码看box 会被内部转换为 axis-aligned box轴对齐盒体以加速相交计算见 src/LevelManager.ccgeometry目前仅支持box。ReadLevels中明确校验geometry.BoxShape()非 box 会报错 geometry is not a box, level wont be createdsrc/LevelManager.ccbuffer缓冲区大小默认0不允许为负——负值会告警并被强制设为 0src/LevelManager.ccreflevel 包含的实体名称可多个。是否属于某 level 完全由ref决定即使实体位置在 level 体积之外也会被算作该 level 的一部分用户需自行保证ref实体确实位于体积内。每个level最终会被创建为一个 ECS 实体并附带 Level、LevelBuffer、LevelEntityNames 等组件见 src/LevelManager.cc。所有 level 初始状态都是未激活、未加载的。3.2performer标签performer nameperf1 refrobot1/ref geometry box size1 1 1/size /box /geometry /performerref指向 performer 实体通常是 model的名称必填且唯一多个performer不能指向同一实体源码在 src/LevelManager.cc 中对重复 ref 打印错误geometry描述 performer 占用的体积目前仅支持box。文档注明未来版本可能会自动生成该体积每个 performer 会被创建为一个独立实体携带 Performer、PerformerRef、PerformerLevels、Name、Geometry 组件见 src/LevelManager.cc。文档中还给了一个完整的示例 world对应上文的 L1/L2/L3 场景三个 level 的 box 体积均为10 10 10、buffer为 2实体M1~M6中M1属于L1、M2属于L2、M4/M5属于L3、M3同属多个 level、M6不属于任何 level全局实体R1~R3分别被perf1~perf3引用。这里可以总结出两类实体的加载规则属于某个 level 的实体随 level 加载/卸载而创建/销毁同一实体属于多个 level 时只要其中任一 level 处于加载状态它就保持加载M3的情形全局实体始终加载应尽量避免使用除非确有需求例如无限大地面。3.3 运行时添加 performerperformer 也可以通过 Gazebo Transport 服务在运行时指定用于启动时空 world、之后再 spawn 模型这类场景服务名/world/world_name/level/set_performerworld_name替换为实际 world 名请求为gz.msgs.StringMsgdata 为模型名响应为gz.msgs.Boolean成功添加时响应为 true。实现位于 src/LevelManager.cc构造函数中通过transport::Node广告该服务与 OnSetPerformer。源码中可以看到一个值得注意的工程细节由于EntityComponentManager的查询不是线程安全的当前实现只是把请求存入待处理队列performersToAdd加互斥锁保护在下一个更新周期由UpdateLevelsState统一处理因此无法在响应中给出真实的成功信息——代码注释中也坦承这是为了线程安全的妥协。另外运行时创建的 performer 目前使用一个硬编码的2x2x2box 作为其几何体源码标注 TODO改用 bounding box。tutorials/levels.md 给出了实际调用示例world 名为levels时gz service -s /world/levels/level/set_performer --reqtype gz.msgs.StringMsg \ --reptype gz.msgs.Boolean --timeout 2000 --req data: vehicle_blue4. 加载算法缓冲区判定与 LevelManager单 server 场景下的加载/卸载由 src/LevelManager.cc 实现其类注释src/LevelManager.hh描述了实体层级结构world - default level - level - light - model - performer - link - nested model即 level 实体是 world 的直接子节点performer 实体是其对应 model 的直接子节点。注释同时给出了该特性的两条假设/限制属于某个 level 的实体不应在仿真期间被修改——任何组件变更或新增在 level 重新加载时会被忽略也不应被删除仿真运行期间 spawn 出来的实体归入default level。4.1--levels开关与调用链启用该功能需要 SDF 中配置相应标签并且以--levels命令行参数启动gz sim levels.sdf --levels调用链在源码中清晰可循--levels标志定义于 src/cmd/sim_main.ccsrc/cmd/gz.cc 中将其转换为ServerConfig::SetUseLevels(true)值得注意的是设置--network-role时也会强制打开levels分布式仿真必须依赖 level 系统src/SimulationRunner.cc 在启动时按serverConfig.UseLevels()创建LevelManager每个仿真步中由 runner 调用LevelManager::UpdateLevelsState()计算相交并决定加载/卸载src/LevelManager.hh 注释明确要求在每步更新周期调用。4.2 缓冲区相交判定UpdateLevelsState核心逻辑位于 src/LevelManager.cc其流程可概括为对每个 performer读取其父 model 的Pose与自身Geometrybox构造出 performer 的轴对齐包围盒performerVolume遍历所有Level实体构造两个盒体regionlevel 本体体积outerRegion本体向外膨胀buffer后的体积判定规则若region与performerVolume相交→ 该 level 需要加载performer 被记入该 level否则若 level 当前处于激活状态且outerRegion仍相交 → 维持激活performer 还在缓冲区里否则 → 将该 level 标记为待卸载对加载/卸载列表去重后把待加载 level 的LevelEntityNames汇总剔除已激活的实体名剩下未加载的交给LoadActiveEntities卸载时通过UnloadLevel剔除仍被其他待加载 level 标记的实体名再调用UnloadInactiveEntities移除实体。这与设计文档和 tutorials/levels.md 的文字描述一一对应performer 进入缓冲区时加载 level离开缓冲区时卸载 level两个方向都依赖 buffer 做迟滞hysteresis避免在边界附近反复加载/卸载。LoadActiveEntitiessrc/LevelManager.cc按名称从 SDF world 中重新创建 models、actors、lights、joints 实体并挂到 world 下UnloadInactiveEntitiessrc/LevelManager.cc则对四类实体调用SdfEntityCreator::RequestRemoveEntity移除。对上层系统的含义持有内部状态的 system 必须能正确处理实体的加入与移除如 test/integration/level_manager.cc 中的测试用例所验证的那样。4.3 默认 level 与全局实体ConfigureDefaultLevelsrc/LevelManager.cc创建一个名为default的 level 实体携带LevelDefaultLevel组件凡未被任何level的ref引用的 models、actors、lights、jointsperformer 除外都归入默认 level 的实体名集合从而保证全局实体始终加载。未启用 levels 时该逻辑退化为把所有实体放入 default level。5. 动手验证示例 world 与测试仓库自带可直接运行的 level 演示examples/worlds/levels.sdf。该 world 定义了vehicle_red/vehicle_blue两个 performer 和level0~level19共 20 个 level每个 level 通过ref关联一块tile_N地砖见文件末尾 L4195-L4409。按 tutorials/levels.md 的步骤运行# 1. 启动带 levels 的示例 world gz sim levels.sdf --levels # 2. 在另一个终端发布速度指令让车辆前进 gz topic -t /model/vehicle_blue/cmd_vel -m gz.msgs.Twist -p linear: {x: 4.0} gz topic -t /model/vehicle_red/cmd_vel -m gz.msgs.Twist -p linear: {x: 2.0}按播放键后可以看到地砖tunnels/tiles随车辆前进逐步被加载。分布式场景的完整脚本含 primary/secondary 启动方式与 SDF 变体位于 examples/scripts/distributed/ 与 examples/scripts/distributed_levels/。测试层面test/integration/level_manager.cc 使用 test/worlds/levels.sdf 验证默认 level 加载、performer 移动触发的加载/卸载行为test/integration/level_manager_runtime_performers.cc 验证运行时set_performer服务路径test/integration/performer_detector.cc 与 src/systems/performer_detector/ 系统则演示了基于 performer 的自定义系统写法。6. 设计文档中尚未落地的部分忠实呈现 doc/architecture_design.md 的状态以下条目在设计文档中仍为 TODO本文不将其当作已实现功能Component serialization组件如何在 runner 之间序列化以同步状态文档尚未描述Standalone programs设想在 SDF 中声明独立程序如不需要 world API、不必跑在物理线程里的 JoyPlugin以便与仿真同时加载多 world 支持是否支持多个world标签未定案跨 level 交互的 performer一个 performer 同时与两个不同 level 中的实体交互时如何处理尚无结论加载策略决策performer 移动到某 level 时是把 performer 迁移过去还是把 level 加载到当前 secondary例如目标 secondary 已仿真过多 level 时文档将其留作待决问题Primary 的同步机制细节文档对 primary 如何利用高层 ECM 跟踪 performer 所在 level 的具体做法标注为待补充。7. 小结gz-sim 的这套设计可以用三层概括概念层world → levelbox 体积 ref实体集合 buffer 缓冲区→ performer可移动的标注实体全局实体常驻配置层plugin namegz::sim下的level/performer标签 --levels或--network-role开关 /world/world/level/set_performer运行时服务实现层LevelManager每步执行 buffer 迟滞判定并驱动SdfEntityCreator创建/移除实体分布式场景下由 primary/secondaryNetworkManager与PerformerAffinity组件协同完成 performer 在 runner 之间的状态交接与物理所有权转移。理解了这一套机制后再结合仓库内的 tutorials/levels.md、tutorials/distributed_simulation.md 与 test/integration/level_manager.cc即可从配置到测试完整地搭建一个按需加载的大型仿真场景。赞分享机器人【免费下载链接】gz-simOpen source robotics simulator. The latest version of Gazebo.项目地址https://gitcode.com/gh_mirrors/gz/gz-sim点击查看免费下载相关推荐Gazebo Sim分布式仿真平台架构深度解构与工程实践Gazebo Sim分布式仿真平台架构深度解构与工程实践 在机器人技术快速发展的当下传统仿真工具在面对大规模分布式仿真需求时往往力不从心。Gazebo Si机器人Gazebo Sim 机器人仿真平台深度解析Gazebo Sim 机器人仿真平台深度解析 平台架构全景 Gazebo Sim 作为一个开源的机器人仿真平台其代码仓库采用精心设计的模块化架构为开发者提供机器人Gazebo Sim 深度指南机器人仿真核心架构与实战应用Gazebo Sim 深度指南机器人仿真核心架构与实战应用 Gazebo Sim作为开源机器人仿真平台集成了高精度物理引擎、传感器建模和可视化渲染等关键技术机器人创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考