Dear all,
I have been using Isaac Sim 2022.2.1 for a few weeks now and am currently working on achieving a pick-and-place simulation with a high frame rate, not necessarily in real-time. The setup appears to be functioning well so far, but I am encountering challenges in controlling the parameters physics_dt
, render_dt
, and time_codes_per_second
in combination with the omni.isaac.franka.controllers.PickplaceController
.
My goal is to achieve a frame rate of 300 with 600 physics steps and also 600 time codes per second to synchronize the simulation time with the frames per second. I am attempting to control these parameters as follows:
world = World(physics_dt=1.0 / 600.0, rendering_dt=1.0 / 300.0)
timeline.set_time_codes_per_second(600)
When I add callbacks for physics steps and render steps, I get the expected results with one rendering per two physics steps.
But if I check the timeline via timeline.get_current_time()
on every physics step and rendering step every rendering step and the next two physics steps share the same time before it gets updated in the next rendering step.
What I expected is a unique time for every step, no matter if physics or rendering.
However, the real issue arises when executing the pick-and-place task. With rendering_dt=60
, everything works fine. Still, when I increase the rendering_dt, the arm starts to move but attempts to grasp the object even before reaching it and continues initiating the placing action without holding the object.
It seems like the controller is executing a fixed number of steps without considering simulation time. Even then, I am puzzled as to why it reacts to rendering_dt and not physics_dt.
I would greatly appreciate any assistance in resolving this issue.
UPDATE: same behavior in Isaac Sim 2023.1.0-Hotfix.1
Here the code to reproduce:
from omni.isaac.kit import SimulationApp
sim_app_config = {
"headless": True,
"renderer": "RayTracedLighting"
}
simulation_app = SimulationApp(sim_app_config)
from omni.isaac.core import World
from omni.timeline import get_timeline_interface
from omni.isaac.franka.tasks import PickPlace
from omni.isaac.franka.controllers import PickPlaceController
def check_timeline(last_sec=0, fr_counter=0):
if int(_timeline.get_current_time()) > last_sec:
print(f"++++++++++ framerate of second {int(last_sec)} {fr_counter} ++++++++++")
last_sec = int(_timeline.get_current_time())
fr_counter = 1
else:
fr_counter += 1
return last_sec, fr_counter
def on_physics_step(event):
print('physics step', _timeline.get_current_time())
pass
def on_render_step(event):
print('render step', _timeline.get_current_time())
pass
_timeline = get_timeline_interface()
_world = World(physics_dt=1.0 / 600.0, rendering_dt=1.0 / 300.0)
_timeline.set_time_codes_per_second(600)
_world.add_physics_callback('physics callback', on_physics_step)
_world.add_render_callback('render callback', on_render_step)
_task = PickPlace(name="easy task")
_world.add_task(_task)
_world.reset()
_task_params = _world.get_task("easy task").get_params()
_franka = _world.scene.get_object(_task_params["robot_name"]["value"])
_cube_name = _task_params["cube_name"]["value"]
_controller = PickPlaceController(
name="pick_place_controller",
gripper=_franka.gripper,
robot_articulation=_franka,
)
last_sec = 0
fr_counter = 0
while simulation_app.is_running():
_world.step(render=True)
last_sec, fr_counter = check_timeline(last_sec, fr_counter)
current_observations = _world.get_observations()
actions = _controller.forward(
picking_position=current_observations[_cube_name]["position"],
placing_position=current_observations[_cube_name]["target_position"],
current_joint_positions=current_observations[_franka.name]["joint_positions"],
)
_franka.apply_action(actions)