@@ -3,19 +3,20 @@ use bevy::prelude::*;
33
44/// Determines how the joint motor force/torque is computed.
55///
6- /// Different models offer trade-offs between ease of tuning, physical accuracy,
7- /// and timestep-independence. The default is a [`SpringDamper`](MotorModel::SpringDamper)
8- /// model that provides stable, predictable behavior regardless of the timestep .
6+ /// Different models offer trade-offs between ease of tuning and physical accuracy.
7+ /// The default is a [`SpringDamper`](MotorModel::SpringDamper) model that provides
8+ /// stable, predictable behavior across different configurations .
99#[ derive( Clone , Copy , Debug , PartialEq , Reflect ) ]
1010#[ cfg_attr( feature = "serialize" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
1111#[ cfg_attr( feature = "serialize" , reflect( Serialize , Deserialize ) ) ]
1212#[ reflect( Debug , PartialEq ) ]
1313pub enum MotorModel {
14- /// A spring-damper model using implicit Euler integration for timestep-independent behavior .
14+ /// A spring-damper model using implicit Euler integration.
1515 ///
16- /// While not truly timestep-independent, this model provides stable and predictable
17- /// spring-damper behavior regardless of the physics substep count or mass configuration.
18- /// This makes it easier to achieve the desired behavior without extensive tuning.
16+ /// Unlike the other models, this is unconditionally stable: the implicit formulation
17+ /// naturally limits the response as frequency increases, preventing overshoot and
18+ /// oscillation even with aggressive parameters. This makes it easier to tune than
19+ /// the other models, which can become unstable with high stiffness values.
1920 ///
2021 /// This is the recommended model for most use cases.
2122 ///
@@ -44,9 +45,8 @@ pub enum MotorModel {
4445 ///
4546 /// This produces physically accurate forces/torques, but requires careful tuning of the
4647 /// stiffness and damping parameters based on the masses of the connected bodies.
47- /// As a result, it can be more difficult to achieve the desired behavior compared to
48- /// the [`AccelerationBased`](MotorModel::AccelerationBased) model or the
49- /// [`SpringDamper`](MotorModel::SpringDamper) model.
48+ /// High stiffness values can cause instability (overshoot, oscillation, or divergence),
49+ /// so parameters must be chosen appropriately for your timestep and mass configuration.
5050 ///
5151 /// # Parameters
5252 ///
@@ -72,8 +72,8 @@ pub enum MotorModel {
7272 /// It is therefore easier to tune compared to the [`ForceBased`](MotorModel::ForceBased) model,
7373 /// which requires manual adjustment of stiffness and damping based on mass.
7474 ///
75- /// For more timestep-independent spring-damper behavior, consider using
76- /// the [`SpringDamper`](MotorModel::SpringDamper) model instead.
75+ /// Note that high stiffness values can still cause instability. For unconditionally
76+ /// stable behavior, use the [`SpringDamper`](MotorModel::SpringDamper) model instead.
7777 ///
7878 /// # Parameters
7979 ///
@@ -205,11 +205,11 @@ impl AngularMotor {
205205/// Motors are configured as part of a joint, applying force to drive
206206/// the joint towards a target velocity and/or position.
207207///
208- /// # Timestep-Independent Spring-Damper
208+ /// # Spring-Damper Model
209209///
210- /// For position control that behaves consistently regardless of substep count, use
211- /// [`MotorModel::SpringDamper`]. This uses an implicit Euler integration that provides
212- /// stable, predictable spring-damper behavior .
210+ /// For stable position control that behaves consistently across different configurations,
211+ /// use [`MotorModel::SpringDamper`]. This uses implicit Euler integration for
212+ /// unconditional stability .
213213///
214214/// ```ignore
215215/// PrismaticJoint::new(entity1, entity2)
0 commit comments