diff options
| author | Sébastien Crozet <developer@crozet.re> | 2024-01-24 22:19:08 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-24 22:19:08 +0100 |
| commit | 51f5bd6cb466fa65ee755c1905e46ff405217143 (patch) | |
| tree | 67e2a9666504c87fe993ee59b76df3fb1b70760d /src/dynamics/integration_parameters.rs | |
| parent | aef85ec2554476485dbf3de5f01257ced22bfe2f (diff) | |
| parent | d1fc90c150ff7ddd077f5770d4ac30108b5e6de5 (diff) | |
| download | rapier-51f5bd6cb466fa65ee755c1905e46ff405217143.tar.gz rapier-51f5bd6cb466fa65ee755c1905e46ff405217143.tar.bz2 rapier-51f5bd6cb466fa65ee755c1905e46ff405217143.zip | |
Merge pull request #581 from dimforge/solver-pick
feat: rework solver parameters to make it easy to recover the old behaviors
Diffstat (limited to 'src/dynamics/integration_parameters.rs')
| -rw-r--r-- | src/dynamics/integration_parameters.rs | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/src/dynamics/integration_parameters.rs b/src/dynamics/integration_parameters.rs index d07527f..bcb823b 100644 --- a/src/dynamics/integration_parameters.rs +++ b/src/dynamics/integration_parameters.rs @@ -44,10 +44,12 @@ pub struct IntegrationParameters { pub max_penetration_correction: Real, /// The maximal distance separating two objects that will generate predictive contacts (default: `0.002`). pub prediction_distance: Real, - /// Number of iterations performed to solve friction constraints at solver iteration (default: `2`). - pub num_friction_iteration_per_solver_iteration: usize, /// The number of solver iterations run by the constraints solver for calculating forces (default: `4`). pub num_solver_iterations: NonZeroUsize, + /// Number of addition friction resolution iteration run during the last solver sub-step (default: `4`). + pub num_additional_friction_iterations: usize, + /// Number of internal Project Gauss Seidel (PGS) iterations run at each solver iteration (default: `1`). + pub num_internal_pgs_iterations: usize, /// Minimum number of dynamic bodies in each active island (default: `128`). pub min_island_size: usize, /// Maximum number of substeps performed by the solver (default: `1`). @@ -55,6 +57,52 @@ pub struct IntegrationParameters { } impl IntegrationParameters { + /// Configures the integration parameters to match the old PGS solver + /// from Rapier version <= 0.17. + /// + /// This solver was slightly faster than the new one but resulted + /// in less stable joints and worse convergence rates. + /// + /// This should only be used for comparison purpose or if you are + /// experiencing problems with the new solver. + /// + /// NOTE: this does not affect any [`RigidBody::additional_solver_iterations`] that will + /// still create solver iterations based on the new "small-steps" PGS solver. + /// NOTE: this resets [`Self::erp`], [`Self::damping_ratio`], [`Self::joint_erp`], + /// [`Self::joint_damping_ratio`] to their former default values. + pub fn switch_to_standard_pgs_solver(&mut self) { + self.num_internal_pgs_iterations = + self.num_solver_iterations.get() * self.num_internal_pgs_iterations; + self.num_solver_iterations = NonZeroUsize::new(1).unwrap(); + self.erp = 0.8; + self.damping_ratio = 0.25; + self.joint_erp = 1.0; + self.joint_damping_ratio = 1.0; + } + + /// Configures the integration parameters to match the new "small-steps" PGS solver + /// from Rapier version >= 0.18. + /// + /// The "small-steps" PGS solver is the default one given by [`Self::default()`] so + /// calling this function is generally not needed unless + /// [`Self::switch_to_standard_pgs_solver()`] was called. + /// + /// This solver results in more stable joints and significantly better convergence + /// rates but is slightly slower in its default settings. + /// + /// NOTE: this resets [`Self::erp`], [`Self::damping_ratio`], [`Self::joint_erp`], + /// [`Self::joint_damping_ratio`] to their default values. + pub fn switch_to_small_steps_pgs_solver(&mut self) { + self.num_solver_iterations = NonZeroUsize::new(self.num_internal_pgs_iterations).unwrap(); + self.num_internal_pgs_iterations = 1; + + let default = Self::default(); + self.erp = default.erp; + self.damping_ratio = default.damping_ratio; + self.joint_erp = default.joint_erp; + self.joint_damping_ratio = default.joint_damping_ratio; + } + /// The inverse of the time-stepping length, i.e. the steps per seconds (Hz). /// /// This is zero if `self.dt` is zero. @@ -154,7 +202,8 @@ impl Default for IntegrationParameters { allowed_linear_error: 0.001, max_penetration_correction: Real::MAX, prediction_distance: 0.002, - num_friction_iteration_per_solver_iteration: 2, + num_internal_pgs_iterations: 1, + num_additional_friction_iterations: 4, num_solver_iterations: NonZeroUsize::new(4).unwrap(), // TODO: what is the optimal value for min_island_size? // It should not be too big so that we don't end up with |
