From 7bfdbad80be9a3cc4d2bd3b782b6923814d7fff8 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Wed, 13 May 2026 02:33:50 -0700 Subject: [PATCH] Make PGS solver constraint visitation order time-independent. PiperOrigin-RevId: 914741347 Change-Id: I7889a42543e9a9f3ff883e25ee9eafaceedc29e1 --- doc/changelog.rst | 6 ++++++ src/engine/engine_solver.c | 7 +------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/doc/changelog.rst b/doc/changelog.rst index 437cdac0..5261a0b3 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -5,6 +5,12 @@ Changelog Upcoming version (not yet released) ----------------------------------- +General +^^^^^^^ +- The pseudo-random constraint visitation order in the :ref:`PGS solver`, introduced in the previous + release, now uses a fixed seed. The previous implementation seeded with ``mjData.time``, which introduced subtle yet + undesirable time dependence. + .. admonition:: Breaking API changes :class: attention diff --git a/src/engine/engine_solver.c b/src/engine/engine_solver.c index cd44350d..dd18ae55 100644 --- a/src/engine/engine_solver.c +++ b/src/engine/engine_solver.c @@ -444,15 +444,10 @@ static void solPGS(const mjModel* m, mjData* d, int island, } } - // seed PCG32 RNG from simulation time + // seed PCG32 RNG with a fixed seed pcg32_state rng; - uint64_t seed = 0; - memcpy(&seed, &d->time, sizeof(d->time)); rng.state = 0; rng.inc = 1; - rng.state = seed; - pcg32_next(&rng); - rng.state += seed; pcg32_next(&rng); // main iteration