gazebosim / gz-rendering

C++ library designed to provide an abstraction for different rendering engines. It offers unified APIs for creating 3D graphics applications.
https://gazebosim.org
Apache License 2.0
56 stars 51 forks source link

Potential non-deterministic behavior in particle emitter (ogre2) #556

Open iche033 opened 2 years ago

iche033 commented 2 years ago

Environment

Description

The particle emitter in ogre2 uses the Particle FX plugin. The plugin likely animates the particles using real time so the effect could be non-deterministic.

Steps to reproduce

  1. Easier to reproduce using ign gazebo. Change <real_time_factor> in particle_emitter2.sdf file to 0 so simulation runs as fast as possible.
  2. Launch ign gazebo with the modified particle_emitter2.sdf world
  3. See the particles flow upwards in regular speed when it should be flowing as fast as possible.
darksylinc commented 2 years ago

I haven't looked much into this, for what is worth ParticleSystemUpdateValue register itself to update the particle, which gets called in ControllerManager::updateAllControllers and gets updated when we (ignition) directly or indirectly call updateSceneGraph (normally Ogre does that call but I think it was in Edifice that I changed it so that we call it explicitly).

I've been thinking there's two possible solutions:

  1. Somehow figure out how to manually update the controlled ourselves so we use simulation time.
  2. Modify Ogre so that Root::populateFrameEvent can alternatively be fed user-specified time (i.e. simulation time) instead of real time.

The 2nd option is highly desirable because it will also fix other stuff I just realized we were overlooking: For example any time-based postprocessing FX (if there's any, I think the gaussian noise is using it) should be using simulation time, not real time.

darksylinc commented 2 years ago

We should either reopen this ticket or create a new one because there is still one source of non-determinism to fix:

// Ideal:
const float timeToSimulate = 10 seconds;
const int numTicks = floor( timeToSimulate / tickRate );
for( int i = 0; i < numTicks; ++i )
    updateParticles( tickRate );

// What is happening when you relaunch the GUI with a simulation of 10 seconds
const float timeToSimulate = 10 seconds;
updateParticles( timeToSimulate ); // Just one tick with 10.0 as tick rate
iche033 commented 2 years ago

github auto-closed the issue with the merge of #584. Reopening.

darksylinc commented 2 years ago

I've pushed https://github.com/OGRECave/ogre-next/commit/d3bd8b423d53b08276d7d5b4501f36160a0a25c5 to branches:

AFAICT it won't break ABI nor API.

By calling ParticleSystemManager::getSingleton().setSimulationTickRate( positive_non_zero_value ) as soon as possible during initialization and then setting the tick rate to the desired one at any time will do the trick.

Now the thing is getting this patch into Ignition's fork.

iche033 commented 2 years ago

thanks, we'll likely just have this fix in Garden with ogre 2.3. So I'll keep in mind to test this as part of the review of your existing PR, https://github.com/ignitionrobotics/ign-rendering/pull/553.