配置网格地图环境#

网格地图是用于碰撞检测和路径规划的二维占据栅格。通过 YAML 文件 world 部分的 obstacle_map 键进行配置。栅格由 地图生成器 构建;内置生成器有 image(来自 PNG 文件)和 perlin(程序化噪声)。也可添加自定义生成器(参见添加新地图生成器)。

概述#

  • obstacle_map 接受:null生成器配置字典(推荐)、字符串路径(图像的简写形式)或 ndarray(仅限程序化使用)。

  • 生成器配置 是一个字典,name 标识生成器,其余为生成器特定参数。栅格大小和语义取决于所用生成器。

  • mdownsample(world 部分):对生成的栅格进行降采样的因子,用于降低分辨率和计算量。

快速示例#

import irsim

env = irsim.make()

for i in range(1000):
    env.step()
    env.render(0.05)
    if env.done():
        break
env.end()
world:
  height: 50
  width: 50
  obstacle_map: 'cave.png'   # shorthand for image generator
  mdownsample: 2

robot:
  - kinematics: {name: 'acker'}
    shape: {name: 'rectangle', length: 4.6, width: 1.6, wheelbase: 3}
    state: [5, 5, 0, 0]
    goal: [40, 40, 0]
    vel_max: [4, 1]
    plot:
      show_trail: true
      show_trajectory: true
    sensors:
      - name: 'lidar2d'
        range_min: 0
        range_max: 20
        angle_range: 3.14
        number: 100
        alpha: 0.4

obstacle:
  - number: 10
    distribution: {name: 'manual'}
    shape:
      - {name: 'polygon', random_shape: true, center_range: [5, 10, 40, 30], avg_radius_range: [0.5, 2]}

障碍物地图类型#

标准形式:生成器配置字典

使用包含 name 和参数的字典。两个内置生成器:

  • name: image — 从图像文件加载栅格。仅需 path 参数。栅格大小来源于图像尺寸。

  • name: perlin — 程序化 Perlin 噪声栅格。需要 resolution(每格米数);栅格大小 = 世界 width / height ÷ resolution

其他可接受的值

  • 字符串(如 'cave.png'):视为 { name: image, path: 'cave.png' }(向后兼容)。

  • null:无障碍物地图(空白可通行空间)。

  • ndarray:仅限程序化使用(如在 Python 中构建世界时)。浮点数组 0–100;大于 50 的格为障碍物。不可从 YAML 使用。

内置生成器#

图像生成器(name: image#

加载图像文件(如 PNG)并将其转换为 0–100 占据栅格。黑色像素为障碍物(高值),白色像素为可通行空间(低值)。栅格大小为图像的像素尺寸。

YAML(显式):

world:
  width: 50
  height: 50
  obstacle_map:
    name: image
    path: 'cave.png'
  mdownsample: 2

YAML(简写): obstacle_map: 'cave.png' 等同于上述配置。

图像位置: 路径相对于脚本目录或包内 world/map 搜索路径解析。可使用绝对或相对路径。将 cave.png 放在脚本同目录下,或相应设置路径。

示例洞穴地图

小技巧

使用自定义 PNG 图像可创建不同环境。值的解释为:越暗 → 障碍物,越亮 → 可通行。支持绝对和相对路径。

Perlin 生成器(name: perlin#

由 Perlin 噪声生成的程序化栅格。栅格大小由世界尺寸和 resolution 决定:例如 20 m × 20 m 的世界配合 resolution: 0.1 可得 200×200 格。

YAML:

world:
  height: 20
  width: 20
  mdownsample: 1
  obstacle_map:
    name: perlin
    resolution: 0.1    # meters per cell → 200×200 grid
    complexity: 0.12
    fill: 0.32
    fractal: 1
    attenuation: 0.5
    seed: 48          # optional; omit for random map each run

参数(参见 irsim.world.map.PerlinGridGenerator):complexityfillfractalattenuationseed(可选)。resolution 为必需;widthheight(格数)由世界尺寸计算,不可在 YAML 中设置。

完整示例:usage/10grid_map/grid_map_perlin.yamlgrid_map_perlin.py

降采样(mdownsample#

mdownsample 是一个整数(默认 1),作用于生成的栅格:按此因子对栅格降采样(如 2 → 每 2×2 块合并为一格)。用于降低分辨率并加速碰撞检测。仅在存在障碍物地图时生效。

添加新地图生成器#

要添加自定义生成器(如迷宫或其他程序化地图),在 irsim/world/map/ 下实现一个类,并在 irsim/world/map/__init__.py 中导入以完成注册。

1. 实现生成器

  • 继承 GridMapGenerator(来自 irsim.world.map.grid_map_generator_base)。

  • 实现 _build_grid(self) -> np.ndarray:返回形状为 (width, height) 的占据栅格,值 0–100(> 50 为障碍物)。框架会将 widthheight(由世界尺寸和 resolution 计算)传递给 __init__

  • 设置类属性:

    • name(str):YAML 键名,如 name = "maze"

    • yaml_param_names(tuple):从 YAML 传递给 __init__ 的参数名(如 ("seed", "density"))。不要 包含 "name""resolution""width""height"resolution 在配置中为必需项;widthheight 由框架注入。

2. 注册

irsim/world/map/__init__.py 中导入新类。注册是自动的:GridMapGenerator 的子类在定义时,若 name 非空则自动添加到 GridMapGenerator.registry。可选择将其加入 __all__

3. 在 YAML 中使用

自定义生成器(如 perlin)通过 build_grid_from_generator 处理:配置中必须包含 nameresolution。栅格大小为(世界宽度 / resolution,世界高度 / resolution)。示例:

world:
  width: 20
  height: 20
  obstacle_map:
    name: maze
    resolution: 0.1
    seed: 42
    density: 0.3

框架示例:

# irsim/world/map/my_maze_generator.py
from .grid_map_generator_base import GridMapGenerator
import numpy as np

class MazeGridGenerator(GridMapGenerator):
    name = "maze"
    yaml_param_names = ("seed", "density")

    def __init__(self, width: int, height: int, seed: int = 0, density: float = 0.3, **kwargs):
        super().__init__(**kwargs)
        self.width = width
        self.height = height
        self.seed = seed
        self.density = density

    def _build_grid(self) -> np.ndarray:
        # Build (self.width, self.height) grid, values 0–100
        ...
        return grid.astype(np.float64)

注意: image 生成器较为特殊:它不使用 resolution 或世界尺寸(栅格来源于图像),由 resolve_obstacle_map 处理。所有其他生成器均使用 build_grid_from_generator 且需要 resolutionwidthheight 由框架计算并传入。