创建环境#
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或 Pythonrandom,需改用 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:定义仿真环境属性的主段height与width:以米为单位指定世界尺寸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_time 与 step_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():当满足结束条件时返回Trueenv.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 - 仿真状态与设置:
属性 |
类型 |
默认值 |
描述 |
|---|---|---|---|
|
|
|
当前仿真时间 |
|
|
|
控制模式( |
|
|
|
碰撞处理模式 |
|
|
|
时间步长(秒) |
|
|
|
仿真步数计数器 |
env_param - 环境对象与工具:
属性 |
类型 |
描述 |
|---|---|---|
|
|
环境中所有对象的列表 |
|
|
此环境的日志器实例 |
|
|
用于碰撞检测的空间索引 |
|
|
操作系统名称 |
path_param - 文件路径管理:
属性 |
类型 |
描述 |
|---|---|---|
|
|
irsim 包目录路径 |
|
|
动画帧缓冲路径 |
|
|
保存动画的路径 |
|
|
保存图像的路径 |
每个环境中的对象引用各自环境的参数:
备注
使用 display=True 创建多个环境时,每个环境会打开各自的可视化窗口。对于训练或批量仿真,建议使用 display=False 禁用渲染以提高性能。