创建环境#

IR-SIM 仿真通过 irsim.make() 从 YAML 场景文件创建,并由一个简短的 Python 循环驱动(env.step()env.render()env.done())。本页介绍如何构建环境、核心循环、状态控制、动态对象管理,以及运行多个环境。

Python 脚本与 YAML 配置文件#

要开始仿真,需要先创建一个环境。环境是仿真中所有对象的容器,并负责在每个时间步更新仿真状态。

可以使用简单的 Python 脚本创建环境:

import irsim

env = irsim.make('empty_world.yaml')

make 函数会根据配置文件创建环境,支持的参数包括:

  • world_name(str,可选):世界 YAML 配置文件路径

  • projection(str,可选):投影类型(“3d” 表示 3D 环境,None 表示 2D)

  • display(bool):是否显示环境可视化(默认 True)

  • save_ani(bool):是否将仿真保存为动图(默认 False)

  • log_level(str):环境日志级别(默认 "INFO")

  • seed(int,可选):IR-SIM 随机数引擎的种子。提供后,IR-SIM 生成的随机内容即可复现;若省略或为 None,则使用未设种子的生成器(不可复现)。若自定义扩展仍使用 np.random 或 Python random,需改用 IR-SIM RNG 或另行设定种子。

更多信息见 EnvBase 类文档。

在 YAML 文件(如 empty_world.yaml)中定义世界属性:

world:
  height: 10  # the height of the world (meters)
  width: 10   # the width of the world (meters)
  step_time: 0.1  # simulation time step (seconds) - 10Hz
  sample_time: 0.1  # rendering frequency (seconds) - 10Hz
  offset: [0, 0] # the offset of the world origin [x, y]
  control_mode: 'auto' # control mode: 'auto', 'keyboard'
  collision_mode: 'stop' # collision behavior: 'stop', 'unobstructed', 'unobstructed_obstacles'
  obstacle_map: null # path to obstacle map file (optional)

配置文件采用 YAML 格式,用于描述环境属性。empty_world.yaml 是一个简单示例,用于创建空环境。

重要参数说明#

世界配置#

  • world:定义仿真环境属性的主段

  • heightwidth:以米为单位指定世界尺寸

  • step_time:控制仿真精度与速度(越小越精确但更慢)

  • sample_time:控制渲染频率(越大仿真越快,可视化越不平滑)

  • offset:以米为单位偏移世界坐标系原点 [x, y]

  • control_mode:决定仿真控制方式

    • 'auto':自动执行仿真

    • 'keyboard':手动键盘控制

  • collision_mode:定义碰撞检测行为

    • 'stop':发生碰撞时停止仿真(默认)

    • 'unobstructed':忽略所有碰撞

    • 'unobstructed_obstacles':仅忽略障碍物碰撞

  • obstacle_map:可选。障碍物地图图像的路径,或生成器配置(例如 { name: perlin, ... })。参见 配置栅格地图

性能考量#

  • 更小的 step_time:物理更精确但仿真更慢

  • 更大的 sample_time:仿真更快但可视化不够流畅

  • 世界尺寸:更大的世界需要更多算力

小技巧

可以通过 sample_time 控制渲染频率、提升仿真速度。默认情况下 sample_timestep_time 相同。

更详细的参数说明参见 YAML 配置

小技巧

自动配置检测:默认 YAML 配置文件与 Python 脚本同名。例如脚本为 test.py,IR-SIM 会在同目录自动寻找 test.yaml

import irsim

# Automatically uses 'test.yaml' if this file is 'test.py'
env = irsim.make()

该特性避免手动指定配置文件,简化了开发流程。

基础仿真循环#

创建环境后,通常会运行如下仿真循环:

import irsim

env = irsim.make('config.yaml')

# Main simulation loop
for i in range(1000):
    env.step()        # Update simulation state
    env.render(0.05)  # Render with 0.05 second interval (20Hz)
    
    if env.done():    # Check if simulation should end
        break

env.end()  # Clean up resources

核心方法说明#

  • env.step():让仿真前进一步

  • env.render(interval):按设定的帧间隔刷新可视化

  • env.done():当满足结束条件时返回 True

  • env.reset(random=False):将对象恢复为初始状态。传入 random=True 时,会基于缓存的 YAML 解析结果重建世界,从而让随机元素(如 distribution: random、随机形状生成器)按当前 RNG 状态重新采样 —— 可配合 irsim.util.random.set_seed(seed) 获得可复现的全新场景。此操作不会重新读取磁盘上的 YAML 文件;如需加载磁盘上的修改,请改用 env.reload()

  • env.refresh():在不推进仿真的前提下,刷新由状态派生的属性(几何、传感器读数、碰撞树以及状态)。当你直接修改对象状态(例如 robot.set_state(...))后,若希望在下一次 env.step() 之前让传感器和碰撞信息同步到最新状态,使用此方法。

  • env.reload(world_name=None):重新解析 YAML 文件(可选指定其他文件)并重建世界/对象。

  • env.end():正确关闭环境并释放资源

  • env.close()env.end() 的别名,提供 Gym 风格的 API 兼容性

小技巧

更新顺序

环境会先推进所有对象,再更新全部传感器。这种两阶段更新保证传感器读取到的都是最新世界状态。若手动推进对象,请在 ObjectBase.step(...) 传入 sensor_step=True,或在更新对象状态后调用 obj.sensor_step()

环境控制与状态#

状态管理#

import irsim

env = irsim.make('config.yaml')

# Check current status
print(f"Current status: {env.status}")
print(f"Current time: {env.time}")

# Control simulation state
env.pause()    # Pause the simulation
env.resume()   # Resume the simulation

# Simulation loop with status checking
for i in range(50):
    env.step()
    env.render(0.05)

    if i < 10:
        env.pause()
    elif i > 20 and i < 30:
        env.resume()
    
    if env.status == "Pause":
        print("Environment is paused")
    
    if env.done():
        print("Simulation completed successfully")

env.end()

可用状态值#

  • "Running":环境在自动控制模式运行

  • "Running (keyboard)":环境在键盘控制模式运行

  • "Pause":仿真已暂停

  • "Done":仿真已完成

  • "Arrived":所有机器人都到达目标

  • "Collision":检测到碰撞

  • "Pause (Debugging)":调试模式(按下 F5 时)

  • "Reset":环境已复位

  • "Reload":环境已重新加载

  • "Save Figure":已保存图像

  • "Quit":环境已退出

配置环境标题#

默认情况下,环境标题会显示仿真时间与状态。可通过设置 show_title 并调用 env.set_title() 来自定义该行为。

import irsim

env = irsim.make('config.yaml')

# Set custom title
env.set_title("Multi-Robot Navigation Simulation")

# Update title dynamically
for i in range(100):
    env.step()
    
    # Update title every 10 steps
    if i % 10 == 0:
        env.set_title(f"Simulation Step: {i}")
    
    env.render(0.05)

env.end()
world:
  height: 20
  width: 20
  control_mode: 'auto'
  plot:
    show_title: true    # Show title with time and status
    show_axis: true     # Optional: show axis labels

动态对象管理#

除了在 YAML 配置文件中定义对象外,还可以在运行时通过代码动态创建和添加对象。这适用于在仿真过程中动态生成对象,例如随机生成障碍物或动态添加机器人。

通过代码创建对象#

使用 env.create_robot()env.create_obstacle() 通过关键字参数创建对象:

import irsim

env = irsim.make('empty_world.yaml')

# Create a differential-drive robot
robot = env.create_robot(
    kinematics={"name": "diff"},
    shape={"name": "circle", "radius": 0.2},
    state=[1, 1, 0],
    goal=[8, 8, 0],
    name="robot_0",
)

# Create a static circular obstacle
obstacle = env.create_obstacle(
    shape={"name": "circle", "radius": 0.5},
    state=[5, 5, 0],
    name="obs_0",
)

常用关键字参数包括:

  • kinematics(dict):运动学模型,如 {"name": "diff"}{"name": "omni"}{"name": "acker"}。省略或使用 {"name": "static"} 表示静态对象。

  • shape(dict):形状定义,如 {"name": "circle", "radius": 0.5}{"name": "polygon", "vertices": [[0,0],[1,0],[0,1]]}

  • state(list):初始状态 [x, y, theta, ...]

  • goal(list):目标状态 [x, y, theta, ...]

  • color(str):对象颜色(默认值因运动学类型而异)。

  • name(str):唯一对象名称,不能与已有对象重名。

  • goal_threshold(float):到达检测的距离阈值(默认 0.1)。

完整参数列表参见 ObjectBase 类文档。

向环境添加对象#

创建对象后,使用 env.add_object()env.add_objects() 将其添加到环境中:

# Add a single object
env.add_object(robot)

# Add multiple objects at once
env.add_objects([obstacle])

每个对象必须有唯一名称。添加重名对象会引发 ValueError

多环境#

IR-SIM 支持同时创建和运行多个环境。每个环境维护各自独立的状态,包括世界参数、对象和仿真时间。适用场景包括:

  • 并行仿真:同时运行多个场景

  • 对比研究:比较不同算法或配置

  • 训练:为强化学习运行多个实例

创建多个环境#

import irsim

# Create two separate environments
env1 = irsim.make('scenario_a.yaml')
env2 = irsim.make('scenario_b.yaml')

# Each environment has its own state
print(f"Env1 robots: {env1.robot_number}")
print(f"Env2 robots: {env2.robot_number}")

参数隔离#

每个环境拥有完全独立的参数实例:

import irsim

env1 = irsim.make('world1.yaml')
env2 = irsim.make('world2.yaml')

# World parameters are isolated
env1.world_param.control_mode = 'keyboard'
print(f"Env1 control mode: {env1.world_param.control_mode}")  # keyboard
print(f"Env2 control mode: {env2.world_param.control_mode}")  # auto (unchanged)

# Simulation time is independent
for _ in range(10):
    env1.step()

for _ in range(5):
    env2.step()

print(f"Env1 time: {env1.time}")  # 1.0 (10 steps * 0.1)
print(f"Env2 time: {env2.time}")  # 0.5 (5 steps * 0.1)

运行多个环境#

import irsim

env1 = irsim.make('scenario_a.yaml', display=True)
env2 = irsim.make('scenario_b.yaml', display=True)

# Run both environments in the same loop
for i in range(500):
    # Step both environments
    env1.step()
    env2.step()

    # Render both (creates two windows)
    env1.render(0.01)
    env2.render(0.01)

    # Check completion independently
    if env1.done() and env2.done():
        break

env1.end()
env2.end()
import irsim

# Create multiple headless environments for training
num_envs = 4
envs = [
    irsim.make(f'training_world.yaml', display=False, seed=i)
    for i in range(num_envs)
]

# Run training loop
for episode in range(100):
    # Reset all environments
    for env in envs:
        env.reset()

    # Collect experiences from all environments
    for step in range(1000):
        actions = [get_action(env) for env in envs]  # Your policy

        for env, action in zip(envs, actions):
            env.step(action)

        # Check if any environment is done
        if all(env.done() for env in envs):
            break

# Clean up
for env in envs:
    env.end()

参数隔离详情#

每个环境实例创建并绑定各自的参数对象:

world_param - 仿真状态与设置:

属性

类型

默认值

描述

time

float

0.0

当前仿真时间

control_mode

str

"auto"

控制模式("auto""keyboard"

collision_mode

str

"stop"

碰撞处理模式

step_time

float

0.1

时间步长(秒)

count

int

0

仿真步数计数器

env_param - 环境对象与工具:

属性

类型

描述

objects

list[ObjectBase]

环境中所有对象的列表

logger

EnvLogger

此环境的日志器实例

GeometryTree

STRtree

用于碰撞检测的空间索引

platform_name

str

操作系统名称

path_param - 文件路径管理:

属性

类型

描述

root_path

str

irsim 包目录路径

ani_buffer_path

str

动画帧缓冲路径

ani_path

str

保存动画的路径

fig_path

str

保存图像的路径

每个环境中的对象引用各自环境的参数:

备注

使用 display=True 创建多个环境时,每个环境会打开各自的可视化窗口。对于训练或批量仿真,建议使用 display=False 禁用渲染以提高性能。