gazebosim / gz-sim

Open source robotics simulator. The latest version of Gazebo.
https://gazebosim.org
Apache License 2.0
684 stars 262 forks source link

Use a long term reference for real time target for update to calculate sleeps #1742

Open tobyatcrown opened 2 years ago

tobyatcrown commented 2 years ago

Desired behavior

Realtime factor should remain as close as possible to 100%, currently the system will always end up below 100% as it will never target less than the desired update step. If a previous update step took longer than the ideal time we never catch up in future steps. This is most obvious in a fairly highly loaded system that occasionally has a long update.

Alternatives considered

Implementation suggestion

I propose recording realtime reference as the code enters the simualtion run loop, and then calculating the target sleep time based on ideal offset from this based on simulation steps executed.

see proposed change https://github.com/tobyatcrown/gz-sim/commit/bed535c785a6d5494416df4ffb26ad04711c50bb

This will attempt to regain 1:1 ratio of sim to real time. The will be less steady on a system that cannot keep up, but if you have intermittent changes in CPU load or larger sim update steps (say when adding an element) the system will run as fast as possible to catch up.

This is better in my use case, but there may be use cases I have not taken into account.

Additional context

tobyatcrown commented 2 years ago

If you like the proposed idea I can put this up as a PR.

azeey commented 1 year ago

Sorry for the long delay in responding to this.

I think the current behavior is what most users have become accustomed to and expect to see. For example, if you have a robot controller in ROS that needs 1ms to compute it's control signal, having the simulator suddenly go faster than real-time would break things. I think we can accept a PR with your desired changes, but it would have to be enabled by a flag--it wouldn't be the default behavior.

tobyatcrown commented 1 year ago

Thanks for the response. I take your point on current behaviour being expected.

I can have a look to see if I can sensibly make this a flag, perhaps with a threshold for max % above realtime it should use to try catch up.

In theory the only time it needs to go faster than realtime is when it has had a slow update (which may have already messed with a controller expecting real world timing). In the worst case where it is always missing its deadline the two approaches should converge as neither should sleep.