Pydrake:set_realtime_rate需AdvanceTo调用后生效,InitializeParams能否解决?
问题描述
环境配置
- drake 1.9.0
- python 3.7
- 系统:ubuntu 20.04
- 工具:pycharm、Meshcat viz
我将一台KUKA机械臂固定在世界坐标系中,通过Differential Inverse Kinematics控制器和Inverse Dynamics控制器处理笛卡尔轨迹指令,实现轨迹跟踪。
仿真刚启动时,机械臂运行速度达到实时速率的400%以上,直到首次调用AdvanceTo(t+0.1)对应的时间点,才会遵守我在Initialize()步骤前设置的set_realtime_rate(0.1%)。
我希望仿真全程都能遵守设定的实时速率,请问是否可以通过InitializeParams来实现?目前InitializeParams的相关文档内容较为匮乏。
代码片段
# Set up the simulation simulator = Simulator(diagram, context) simulator.set_target_realtime_rate(0.10) simulator.Initialize() # Add a button to start the simulation start_sim_button = 'Start Simulation' meshcat.AddButton(start_sim_button) # Wait until the start button is pressed before beginning the simulation print(f'Press the \'{start_sim_button}\' to start the simulation') while meshcat.GetButtonClicks(start_sim_button) < 1: time.sleep(1.0) # Replace the start button with a stop button meshcat.DeleteButton(start_sim_button) stop_sim_button = 'Stop Simulation' meshcat.AddButton(stop_sim_button) # Wait until the stop button is pressed before stopping the simulation print(f'Press the \'{stop_sim_button}\' to stop the simulation') # Add simulation monitors ... while meshcat.GetButtonClicks(stop_sim_button) < 1: # Advance the simulation t = simulator.get_context().get_time() simulator.AdvanceTo(t + 0.1)
解决方案
InitializeParams主要用于配置仿真初始化时的状态逻辑(如是否跳过离散更新、设置初始时间等),无法直接控制实时速率的生效时机。
问题根源
调用simulator.Initialize()后,仿真会执行一次初始状态更新(包括离散系统的初始化步),这一步属于初始化流程,不受实时速率限制约束。而你在初始化后等待按钮的这段时间,初始化阶段的状态更新已经让机械臂产生了超速运动。
可行解决方式
- 延迟Initialize()调用(推荐)
将simulator.Initialize()移到用户点击启动按钮之后执行,确保初始化阶段的状态更新也在实时速率限制下进行:
# Wait until the start button is pressed before beginning the simulation print(f'Press the \'{start_sim_button}\' to start the simulation') while meshcat.GetButtonClicks(start_sim_button) < 1: time.sleep(1.0) # 移到此处初始化仿真 simulator.Initialize() # Replace the start button with a stop button meshcat.DeleteButton(start_sim_button) stop_sim_button = 'Stop Simulation' meshcat.AddButton(stop_sim_button)
- 跳过初始化阶段的离散更新(慎用)
如果必须提前调用Initialize(),可通过InitializeParams的skip_discrete_update参数跳过初始化时的离散系统更新,但这可能导致系统初始状态不符合预期:
from drake.systems import InitializeParams params = InitializeParams(skip_discrete_update=True) simulator.Initialize(params)
注意:该方法仅能跳过离散更新,连续系统的初始化仍可能产生快速变化,因此第一种方法更可靠。
总结:要让仿真全程遵守实时速率,最稳妥的方式是将Initialize()延迟到用户触发启动动作之后执行。
内容的提问来源于stack exchange,提问作者L Wall
相关产品推荐
相关产品推荐

