diff --git a/AGXUnity/Cable.cs b/AGXUnity/Cable.cs index 85fec175..c92ba0f4 100644 --- a/AGXUnity/Cable.cs +++ b/AGXUnity/Cable.cs @@ -1,4 +1,5 @@ -using AGXUnity.Utils; +using agxCable; +using AGXUnity.Utils; using System; using System.Collections.Generic; using UnityEngine; @@ -516,7 +517,7 @@ private void OnPropertyValueUpdate( CableProperties.Direction dir ) { if ( Native != null ) { Native.getCableProperties().setYoungsModulus( Convert.ToDouble( Properties[ dir ].YoungsModulus ), CableProperties.ToNative( dir ) ); - Native.getCableProperties().setDamping( Convert.ToDouble( Properties[ dir ].Damping ), CableProperties.ToNative( dir ) ); + Native.getCableProperties().setAttenuation( Convert.ToDouble( Properties[ dir ].Attenuation ), CableProperties.ToNative( dir ) ); Native.getCableProperties().setPoissonsRatio( Convert.ToDouble( Properties[ dir ].PoissonsRatio ), CableProperties.ToNative( dir ) ); var plasticityComponent = Native.getCablePlasticity(); @@ -566,5 +567,14 @@ public PointCurve.SegmentationResult SynchronizeRoutePointCurve() return new PointCurve.SegmentationResult() { Error = float.PositiveInfinity, Successful = false }; } + protected override bool PerformMigration() + { + if ( m_serializationVersion < 3 ) { + foreach ( CableProperties.Direction dir in Enum.GetValues( typeof( CableProperties.Direction ) ) ) + Properties[ dir ].Attenuation *= Time.fixedDeltaTime; + return true; + } + return false; + } } } diff --git a/AGXUnity/CableProperties.cs b/AGXUnity/CableProperties.cs index 48e01fc1..2e8a3d28 100644 --- a/AGXUnity/CableProperties.cs +++ b/AGXUnity/CableProperties.cs @@ -1,5 +1,6 @@ using System; using UnityEngine; +using UnityEngine.Serialization; namespace AGXUnity { @@ -79,16 +80,17 @@ public float YieldPoint } [SerializeField] - private float m_damping = 2.0f / 50; + [FormerlySerializedAs( "m_damping" )] + private float m_attenuation = 2.0f; [ClampAboveZeroInInspector( true )] - [Tooltip( "The damping of the constraint" )] - public float Damping + [Tooltip( "The attenuation of the constraint" )] + public float Attenuation { - get { return m_damping; } + get { return m_attenuation; } set { - m_damping = value; + m_attenuation = value; OnValueCanged( Direction ); } @@ -130,7 +132,7 @@ public CableProperties RestoreLocalDataFrom( agxCable.CableProperties native, ag foreach ( Direction dir in Directions ) { this[ dir ].YoungsModulus = Convert.ToSingle( native.getYoungsModulus( ToNative( dir ) ) ); - this[ dir ].Damping = Convert.ToSingle( native.getDamping( ToNative( dir ) ) ); + this[ dir ].Attenuation = Convert.ToSingle( native.getAttenuation( ToNative( dir ) ) ); this[ dir ].PoissonsRatio = Convert.ToSingle( native.getPoissonsRatio( ToNative( dir ) ) ); this[ dir ].YieldPoint = plasticity != null ? Convert.ToSingle( plasticity.getYieldPoint( ToNative( dir ) ) ) : diff --git a/AGXUnity/Constraints/Constraint.cs b/AGXUnity/Constraints/Constraint.cs index ffa90bf1..b4c799f4 100644 --- a/AGXUnity/Constraints/Constraint.cs +++ b/AGXUnity/Constraints/Constraint.cs @@ -39,9 +39,9 @@ public void TraverseRowData( Action callback, T public void SetCompliance( float compliance ); public void SetCompliance( float compliance, TranslationalDof dof ); public void SetCompliance( float compliance, RotationalDof dof ); - public void SetDamping( float damping ); - public void SetDamping( float damping, TranslationalDof dof ); - public void SetDamping( float damping, RotationalDof dof ); + public void SetAttenuation( float attenuation ); + public void SetAttenuation( float attenuation, TranslationalDof dof ); + public void SetAttenuation( float attenuation, RotationalDof dof ); public void SetForceRange( RangeReal forceRange ); public void SetForceRange( RangeReal forceRange, TranslationalDof dof ); public void SetForceRange( RangeReal forceRange, RotationalDof dof ); @@ -480,36 +480,36 @@ public void SetCompliance( float compliance, RotationalDof dof ) } /// - /// Set damping to all ordinary degrees of freedom (not including controllers) + /// Set attenuation to all ordinary degrees of freedom (not including controllers) /// of this constraint. /// - /// New damping. - public void SetDamping( float damping ) + /// New attenuation. + public void SetAttenuation( float attenuation ) { - TraverseRowData( data => data.Damping = damping, TranslationalDof.All ); - TraverseRowData( data => data.Damping = damping, RotationalDof.All ); + TraverseRowData( data => data.Attenuation = attenuation, TranslationalDof.All ); + TraverseRowData( data => data.Attenuation = attenuation, RotationalDof.All ); } /// - /// Set damping to one or all translational ordinary degrees of freedom + /// Set attenuation to one or all translational ordinary degrees of freedom /// (not including controllers) of this constraint. /// - /// New damping. + /// New attenuation. /// Specific translational degree of freedom or all. - public void SetDamping( float damping, TranslationalDof dof ) + public void SetAttenuation( float attenuation, TranslationalDof dof ) { - TraverseRowData( data => data.Damping = damping, dof ); + TraverseRowData( data => data.Attenuation = attenuation, dof ); } /// - /// Set damping to one or all rotational ordinary degrees of freedom + /// Set attenuation to one or all rotational ordinary degrees of freedom /// (not including controllers) of this constraint. /// - /// New damping. + /// New attenuation. /// Specific rotational degree of freedom or all. - public void SetDamping( float damping, RotationalDof dof ) + public void SetAttenuation( float attenuation, RotationalDof dof ) { - TraverseRowData( data => data.Damping = damping, dof ); + TraverseRowData( data => data.Attenuation = attenuation, dof ); } /// @@ -1028,5 +1028,16 @@ private void OnDrawGizmosSelected() DrawGizmos( Color.green, AttachmentPair, true ); } + + protected override bool PerformMigration() + { + if ( m_serializationVersion < 3 ) { + // Migrate from damping to attenuation + TraverseRowData( data => data.Attenuation *= Time.fixedDeltaTime, TranslationalDof.All ); + TraverseRowData( data => data.Attenuation *= Time.fixedDeltaTime, RotationalDof.All ); + return true; + } + return false; + } } } diff --git a/AGXUnity/Constraints/ElementaryConstraint.cs b/AGXUnity/Constraints/ElementaryConstraint.cs index 11ac4b46..48a76ae9 100644 --- a/AGXUnity/Constraints/ElementaryConstraint.cs +++ b/AGXUnity/Constraints/ElementaryConstraint.cs @@ -118,7 +118,7 @@ public bool Enable public int NumRows => RowData.Length; /// - /// Data (compliance, damping etc.) for each row in this elementary constraint. + /// Data (compliance, attenuation etc.) for each row in this elementary constraint. /// [field: SerializeField] public ElementaryConstraintRowData[] RowData { get; private set; } @@ -174,7 +174,7 @@ public void MigrateInternalData( AGXUnity.Deprecated.ElementaryConstraint ec ) newRDs.Add( newRowData ); } newRowData.Compliance = row.Compliance; - newRowData.Damping = row.Damping; + newRowData.Attenuation = row.Attenuation; newRowData.ForceRange = row.ForceRange; } if ( newRDs.Count > 0 ) diff --git a/AGXUnity/Constraints/ElementaryConstraintController.cs b/AGXUnity/Constraints/ElementaryConstraintController.cs index 1438fef2..6f304f53 100644 --- a/AGXUnity/Constraints/ElementaryConstraintController.cs +++ b/AGXUnity/Constraints/ElementaryConstraintController.cs @@ -21,13 +21,13 @@ public float Compliance } /// - /// Get/set the damping of this controller (ignored for nonholonomic controllers). + /// Get/set the attenuation of this controller (ignored for nonholonomic controllers). /// [HideInInspector] - public float Damping + public float Attenuation { - get { return RowData[ 0 ].Damping; } - set { RowData[ 0 ].Damping = value; } + get { return RowData[ 0 ].Attenuation; } + set { RowData[ 0 ].Attenuation = value; } } /// diff --git a/AGXUnity/Constraints/ElementaryConstraintRowData.cs b/AGXUnity/Constraints/ElementaryConstraintRowData.cs index 87e69e4f..e902bdf4 100644 --- a/AGXUnity/Constraints/ElementaryConstraintRowData.cs +++ b/AGXUnity/Constraints/ElementaryConstraintRowData.cs @@ -1,5 +1,6 @@ using System; using UnityEngine; +using UnityEngine.Serialization; namespace AGXUnity { @@ -63,23 +64,24 @@ public float Compliance } /// - /// Damping of this row in the elementary constraint. Paired with property Damping. + /// Attenuation of this row in the elementary constraint. Paired with property Attenuation. /// [SerializeField] - private float m_damping = 2.0f / 50.0f; + [FormerlySerializedAs("m_damping")] + private float m_attenuation = 2.0f; /// - /// Damping of this row in the elementary constraint. + /// Attenuation of this row in the elementary constraint. /// [ClampAboveZeroInInspector( true )] - public float Damping + public float Attenuation { - get { return m_damping; } + get { return m_attenuation; } set { - m_damping = value; + m_attenuation = value; if ( ElementaryConstraint?.Native != null ) - ElementaryConstraint.Native.setDamping( m_damping, Row ); + ElementaryConstraint.Native.setAttenuation( m_attenuation, Row ); } } @@ -116,10 +118,7 @@ public ElementaryConstraintRowData( ElementaryConstraint elementaryConstraint, i m_row = row; if ( tmpEc != null ) { m_compliance = Convert.ToSingle( tmpEc.getCompliance( RowUInt ) ); - // AGX Dynamics damping is optimized for 60 Hz simulations. Assuming - // a fixed update of 50 Hz in Unity we scale the damping by 60 / 50 = 1.2 - // to transform the damping to 50 Hz. - m_damping = 1.2f * Convert.ToSingle( tmpEc.getDamping( RowUInt ) ); + m_attenuation = Convert.ToSingle( tmpEc.getAttenuation( RowUInt ) ); m_forceRange = new RangeReal( tmpEc.getForceRange( RowUInt ) ); } } @@ -139,7 +138,7 @@ public ElementaryConstraintRowData( ElementaryConstraint elementaryConstraint, E public void CopyFrom( ElementaryConstraintRowData source ) { m_compliance = source.m_compliance; - m_damping = source.m_damping; + m_attenuation = source.m_attenuation; m_forceRange = new RangeReal( source.m_forceRange ); } } diff --git a/AGXUnity/Constraints/Generic1DOFControlledConstraint.cs b/AGXUnity/Constraints/Generic1DOFControlledConstraint.cs index fa427600..bbea7686 100644 --- a/AGXUnity/Constraints/Generic1DOFControlledConstraint.cs +++ b/AGXUnity/Constraints/Generic1DOFControlledConstraint.cs @@ -55,7 +55,7 @@ private void RecreateElementary() if ( old != null ) { ConstraintController.Enable = old.Enable; ConstraintController.Compliance = old.Compliance; - ConstraintController.Damping = old.Damping; + ConstraintController.Attenuation = old.Attenuation; ConstraintController.ForceRange = old.ForceRange; } diff --git a/AGXUnity/ContactMaterial.cs b/AGXUnity/ContactMaterial.cs index bdd701d2..0f239545 100644 --- a/AGXUnity/ContactMaterial.cs +++ b/AGXUnity/ContactMaterial.cs @@ -1,5 +1,6 @@ using System; using UnityEngine; +using UnityEngine.Serialization; namespace AGXUnity { @@ -211,24 +212,25 @@ public float Restitution } /// - /// Damping of the contact constraint, paired with property Damping. + /// Attenuation of the contact constraint, paired with property Attenuation. /// [SerializeField] - private float m_damping = 4.5f / 60.0f; + [FormerlySerializedAs( "m_damping" )] + private float m_attenuation = 4.5f; /// - /// Damping of the contact constraint. Default: 4.5 / 60 = 0.075. + /// Attenuation of the contact constraint. Default: 2. /// [ClampAboveZeroInInspector( true )] - [Tooltip( "This defines the time it should take for the solver to restore an overlap. A higher value will lead to higher restoration forces as overlaps should be minimized faster" )] - public float Damping + [Tooltip( "This defines the number of integration steps the solver is given to satisfy the constraint. A higher value will lead to higher restoration forces as overlaps should be minimized faster" )] + public float Attenuation { - get { return m_damping; } + get { return m_attenuation; } set { - m_damping = value; + m_attenuation = value; if ( Native != null ) - Native.setDamping( m_damping ); + Native.setAttenuation( m_attenuation ); } } @@ -266,7 +268,7 @@ public float AdhesiveForce /// at higher overlap, the (usual) contact force. /// [ClampAboveZeroInInspector( true )] - [Tooltip( "allowed overlap from surface for resting contact. At this overlap, no force is applied. At lower overlap, the adhesion force will work, at higher overlap, the (usual) contact force" )] + [Tooltip( "Allowed overlap from surface for resting contact. At this overlap, no force is applied. At lower overlap, the adhesion force will work, at higher overlap, the (usual) contact force" )] public float AdhesiveOverlap { get { return m_adhesiveOverlap; } @@ -385,7 +387,7 @@ public ContactMaterial RestoreLocalDataFrom( agx.ContactMaterial contactMaterial FrictionCoefficients = new Vector2( Convert.ToSingle( contactMaterial.getFrictionCoefficient( agx.ContactMaterial.FrictionDirection.PRIMARY_DIRECTION ) ), Convert.ToSingle( contactMaterial.getFrictionCoefficient( agx.ContactMaterial.FrictionDirection.SECONDARY_DIRECTION ) ) ); Restitution = Convert.ToSingle( contactMaterial.getRestitution() ); - Damping = Convert.ToSingle( contactMaterial.getDamping() ); + Attenuation = Convert.ToSingle( contactMaterial.getAttenuation() ); AdhesiveForce = Convert.ToSingle( contactMaterial.getAdhesion() ); AdhesiveOverlap = Convert.ToSingle( contactMaterial.getAdhesiveOverlap() ); UseContactArea = contactMaterial.getUseContactAreaApproach(); @@ -508,5 +510,14 @@ private void OnFrictionModelNativeInstanceChanged( agx.FrictionModel frictionMod if ( Native != null ) Native.setFrictionModel( frictionModel ); } + + protected override bool PerformMigration() + { + if ( m_serializationVersion < 3 ) { + m_attenuation *= Time.fixedDeltaTime; + return true; + } + return false; + } } } diff --git a/AGXUnity/Deprecated/ElementaryConstraint.cs b/AGXUnity/Deprecated/ElementaryConstraint.cs index ba0deda8..672b0747 100644 --- a/AGXUnity/Deprecated/ElementaryConstraint.cs +++ b/AGXUnity/Deprecated/ElementaryConstraint.cs @@ -111,14 +111,14 @@ public bool Enable public int NumRows { get { return m_rowData.Length; } } /// - /// Data (compliance, damping etc.) for each row in this elementary constraint. + /// Data (compliance, attenuation etc.) for each row in this elementary constraint. /// Paired with property RowData. /// [SerializeField] private ElementaryConstraintRowData[] m_rowData = null; /// - /// Data (compliance, damping etc.) for each row in this elementary constraint. + /// Data (compliance, attenuation etc.) for each row in this elementary constraint. /// public ElementaryConstraintRowData[] RowData { get { return m_rowData; } } diff --git a/AGXUnity/Deprecated/ElementaryConstraintController.cs b/AGXUnity/Deprecated/ElementaryConstraintController.cs index ebab3da1..bdb656c4 100644 --- a/AGXUnity/Deprecated/ElementaryConstraintController.cs +++ b/AGXUnity/Deprecated/ElementaryConstraintController.cs @@ -24,13 +24,13 @@ public float Compliance } /// - /// Get/set the damping of this controller (ignored for nonholonomic controllers). + /// Get/set the attenuation of this controller (ignored for nonholonomic controllers). /// [HideInInspector] - public float Damping + public float Attenuation { - get { return RowData[ 0 ].Damping; } - set { RowData[ 0 ].Damping = value; } + get { return RowData[ 0 ].Attenuation; } + set { RowData[ 0 ].Attenuation = value; } } /// diff --git a/AGXUnity/Deprecated/ElementaryConstraintRowData.cs b/AGXUnity/Deprecated/ElementaryConstraintRowData.cs index 7fa475dc..74be1933 100644 --- a/AGXUnity/Deprecated/ElementaryConstraintRowData.cs +++ b/AGXUnity/Deprecated/ElementaryConstraintRowData.cs @@ -1,5 +1,6 @@ using System; using UnityEngine; +using UnityEngine.Serialization; namespace AGXUnity.Deprecated { @@ -70,23 +71,24 @@ public float Compliance } /// - /// Damping of this row in the elementary constraint. Paired with property Damping. + /// Attenuation of this row in the elementary constraint. Paired with property Damping. /// [SerializeField] - private float m_damping = 2.0f / 50.0f; + [FormerlySerializedAs( "m_damping" )] + private float m_attenuation = 2.0f; /// - /// Damping of this row in the elementary constraint. + /// Attenuation of this row in the elementary constraint. /// [ClampAboveZeroInInspector( true )] - public float Damping + public float Attenuation { - get { return m_damping; } + get { return m_attenuation; } set { - m_damping = value; + m_attenuation = value; if ( ElementaryConstraint.Native != null ) - ElementaryConstraint.Native.setDamping( m_damping, Row ); + ElementaryConstraint.Native.setAttenuation( m_attenuation, Row ); } } @@ -123,10 +125,7 @@ public ElementaryConstraintRowData( ElementaryConstraint elementaryConstraint, i m_row = row; if ( tmpEc != null ) { m_compliance = Convert.ToSingle( tmpEc.getCompliance( RowUInt ) ); - // AGX Dynamics damping is optimized for 60 Hz simulations. Assuming - // a fixed update of 50 Hz in Unity we scale the damping by 60 / 50 = 1.2 - // to transform the damping to 50 Hz. - m_damping = 1.2f * Convert.ToSingle( tmpEc.getDamping( RowUInt ) ); + m_attenuation = Convert.ToSingle( tmpEc.getAttenuation( RowUInt ) ); m_forceRange = new RangeReal( tmpEc.getForceRange( RowUInt ) ); } } @@ -146,7 +145,7 @@ public ElementaryConstraintRowData( ElementaryConstraint elementaryConstraint, E public void CopyFrom( ElementaryConstraintRowData source ) { m_compliance = source.m_compliance; - m_damping = source.m_damping; + m_attenuation = source.m_attenuation; m_forceRange = new RangeReal( source.m_forceRange ); } } diff --git a/AGXUnity/IO/OpenPLX/InteractionMapper.cs b/AGXUnity/IO/OpenPLX/InteractionMapper.cs index a9124f1e..978c6e10 100644 --- a/AGXUnity/IO/OpenPLX/InteractionMapper.cs +++ b/AGXUnity/IO/OpenPLX/InteractionMapper.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using UnityEngine; using Connector = openplx.Physics.Interactions.Connector; using InteractionKey = std.PhysicsInteractionsConnectorVector; @@ -182,20 +183,21 @@ Constraint CreateConstraint( IFrame f1, IFrame f2, ConstraintType type ) public static float? MapDissipation( openplx.Physics.Interactions.Dissipation.DefaultDissipation dissipation, openplx.Physics.Interactions.Flexibility.DefaultFlexibility deformation ) { + float? relaxation_time = null; if ( dissipation is openplx.Physics.Interactions.Dissipation.ConstraintRelaxationTimeDamping crtd ) - return (float)crtd.relaxation_time(); + relaxation_time = (float)crtd.relaxation_time(); - else if ( dissipation is openplx.Physics.Interactions.Dissipation.MechanicalDamping mechanical ) { - if ( deformation is openplx.Physics.Interactions.Flexibility.LinearElastic elastic && elastic.stiffness() != 0.0 ) - return (float)( mechanical.damping_constant() / elastic.stiffness() ); - return null; + else if ( dissipation is openplx.Physics.Interactions.Dissipation.MechanicalDamping mechanical && deformation is openplx.Physics.Interactions.Flexibility.LinearElastic elastic && elastic.stiffness() != 0.0 ) { + relaxation_time = (float)( mechanical.damping_constant() / elastic.stiffness() ); + } + else { + var agx_relaxation_time_annotations = dissipation.findAnnotations("agx_relaxation_time"); + if ( agx_relaxation_time_annotations.Count == 1 && agx_relaxation_time_annotations[ 0 ].isNumber() ) + relaxation_time =(float)agx_relaxation_time_annotations[ 0 ].asReal(); } - var agx_relaxation_time_annotations = dissipation.findAnnotations("agx_relaxation_time"); - if ( agx_relaxation_time_annotations.Count == 1 && agx_relaxation_time_annotations[ 0 ].isNumber() ) - return (float)agx_relaxation_time_annotations[ 0 ].asReal(); - - return null; + // We assume that the simulation will run at 50Hz to calculate the attenuation at "import time" + return relaxation_time / 50.0f; } Constraint.RotationalDof MapRotationalDOF( string axisName ) @@ -220,17 +222,17 @@ Constraint.TranslationalDof MapTranslationalDOF( string axisName ) }; } - void MapMateDissipation( Interactions.Dissipation.DefaultMateDissipation damping, Interactions.Flexibility.DefaultMateFlexibility deformation, Constraint target ) + void MapMateDissipation( Interactions.Dissipation.DefaultMateDissipation attenuation, Interactions.Flexibility.DefaultMateFlexibility deformation, Constraint target ) { - foreach ( var (key, damp) in damping.getEntries() ) { + foreach ( var (key, damp) in attenuation.getEntries() ) { var def = deformation.getDynamic( key ).asObject() as openplx.Physics.Interactions.Flexibility.DefaultFlexibility; float? mapped = MapDissipation(damp, def); if ( mapped == null ) continue; if ( key.StartsWith( "along_" ) ) - target.SetDamping( mapped.Value, MapRotationalDOF( key.Substring( key.LastIndexOf( '_' ) + 1 ) ) ); + target.SetAttenuation( mapped.Value, MapRotationalDOF( key.Substring( key.LastIndexOf( '_' ) + 1 ) ) ); else if ( key.StartsWith( "around_" ) ) - target.SetDamping( mapped.Value, MapTranslationalDOF( key.Substring( key.LastIndexOf( '_' ) + 1 ) ) ); + target.SetAttenuation( mapped.Value, MapTranslationalDOF( key.Substring( key.LastIndexOf( '_' ) + 1 ) ) ); } } @@ -247,12 +249,12 @@ void MapMateFlexibility( Interactions.Flexibility.DefaultMateFlexibility deforma } } - void MapControllerDissipation( openplx.Physics.Interactions.Dissipation.DefaultDissipation damping, openplx.Physics.Interactions.Flexibility.DefaultFlexibility deformation, ElementaryConstraintController target ) + void MapControllerDissipation( openplx.Physics.Interactions.Dissipation.DefaultDissipation attenuation, openplx.Physics.Interactions.Flexibility.DefaultFlexibility deformation, ElementaryConstraintController target ) { - float? mapped = MapDissipation(damping, deformation); + float? mapped = MapDissipation(attenuation, deformation); if ( mapped == null ) return; - target.Damping = mapped.Value; + target.Attenuation = mapped.Value; } void MapControllerFlexibility( openplx.Physics.Interactions.Flexibility.DefaultFlexibility deformation, ElementaryConstraintController target ) @@ -588,16 +590,15 @@ public void MapContactModel( openplx.Physics.Interactions.SurfaceContact.Model c if ( contactModel.normal_flexibility() is openplx.Physics.Interactions.Flexibility.Rigid rigid ) { // Set the contact as stiff as agx handle cm.YoungsModulus = 1e16f; - // Set the damping to two times the time step, which is the recommended minimum. - // Will override any other damping defined - // TODO: We dont know the timestep at import time so this needs to be revised - cm.Damping = ( 1.0f/60.0f ) * 2.0f; + // Set attenuation to 2 which is the recommended minumum for 60hz (assumed here) + // Will override any other attenuation defined + cm.Attenuation = 2.0f; } else if ( contactModel.normal_flexibility() is openplx.Physics.Interactions.Flexibility.LinearElastic elastic ) { cm.YoungsModulus = (float)elastic.stiffness(); var time = MapDissipation(contactModel.dissipation(), contactModel.normal_flexibility()); if ( time.HasValue ) - cm.Damping = time.Value; + cm.Attenuation = time.Value; if ( elastic is openplx.Physics.Interactions.SurfaceContact.PatchElasticity ) cm.UseContactArea = true; } diff --git a/AGXUnity/IO/OpenPLX/OpenPLXRoot.cs b/AGXUnity/IO/OpenPLX/OpenPLXRoot.cs index 351c2c04..26eb52ed 100644 --- a/AGXUnity/IO/OpenPLX/OpenPLXRoot.cs +++ b/AGXUnity/IO/OpenPLX/OpenPLXRoot.cs @@ -117,7 +117,7 @@ protected override bool Initialize() RuntimeMapped = new Dictionary(); - agxPowerLine.PowerLineRef powerline = mapper.mapDriveTrainIntoPowerLine( Native as openplx.Physics.System); + agxPowerLine.PowerLineRef powerline = mapper.mapDriveTrainIntoPowerLine( Native as openplx.Physics.System, Time.fixedDeltaTime); // TODO: Fix null return from this method if ( powerline != null && powerline.get() != null ) { Simulation.Instance.Native.add( powerline.get() ); diff --git a/AGXUnity/IO/OpenPLX/VehicleMapper.cs b/AGXUnity/IO/OpenPLX/VehicleMapper.cs index 47923127..89a24381 100644 --- a/AGXUnity/IO/OpenPLX/VehicleMapper.cs +++ b/AGXUnity/IO/OpenPLX/VehicleMapper.cs @@ -269,8 +269,8 @@ private void MapInternalMergeProperties( TrackSystem.Base track_system, Track tr merge_props.LockToReachMergeConditionEnabled = lockToReachMergeConditionEnabled; if ( track_system.TryGetRealAnnotation( "agx_set_lock_to_reach_merge_condition_compliance", out float LockToReachMergeConditionCompliance ) ) merge_props.LockToReachMergeConditionCompliance = LockToReachMergeConditionCompliance; - if ( track_system.TryGetRealAnnotation( "agx_set_lock_to_reach_merge_condition_relaxation_time", out float LockToReachMergeConditionDamping ) ) - merge_props.LockToReachMergeConditionDamping = LockToReachMergeConditionDamping; + if ( track_system.TryGetRealAnnotation( "agx_set_lock_to_reach_merge_condition_attenuation", out float LockToReachMergeConditionAttenuation ) ) + merge_props.LockToReachMergeConditionAttenuation = LockToReachMergeConditionAttenuation; if ( track_system.TryGetRealAnnotation( "agx_set_num_nodes_per_merge_segment", out float NumNodesPerMergeSegment ) ) merge_props.NumNodesPerMergeSegment = (int)NumNodesPerMergeSegment; if ( track_system.TryGetRealAnnotation( "agx_set_max_angle_merge_condition", out float MaxAngleMergeCondition ) ) @@ -531,9 +531,9 @@ private bool MapSingleMateSuspensionOnto( Suspensions.SingleMate.Base suspension wheelJoint.GetController( WheelJoint.WheelDimension.Steering ).Enable = true; if ( suspension is Suspensions.SingleMate.LinearSpringDamper lsd ) { - var damping = InteractionMapper.MapDissipation(lsd.mate().spring_damping(), lsd.mate().spring_constant()); - if ( damping.HasValue ) - wheelJoint.GetController( WheelJoint.WheelDimension.Suspension ).Damping = damping.Value; + var attenuation = InteractionMapper.MapDissipation(lsd.mate().spring_damping(), lsd.mate().spring_constant()); + if ( attenuation.HasValue ) + wheelJoint.GetController( WheelJoint.WheelDimension.Suspension ).Attenuation = attenuation.Value; var compliance = InteractionMapper.MapFlexibility(lsd.mate().spring_constant()); if ( compliance.HasValue ) wheelJoint.GetController( WheelJoint.WheelDimension.Suspension ).Compliance = compliance.Value; @@ -548,7 +548,7 @@ private bool MapSingleMateSuspensionOnto( Suspensions.SingleMate.Base suspension range.Compliance = rangeCompliance.Value; var rangeDamping = InteractionMapper.MapDissipation(suspension.range().dissipation(), suspension.range().flexibility()); if ( rangeDamping.HasValue ) - range.Damping = rangeDamping.Value; + range.Attenuation = rangeDamping.Value; range.Range = new RangeReal( (float)suspension.range().start(), (float)suspension.range().end() ); range.ForceRange = new RangeReal( (float)suspension.range().min_effort(), (float)suspension.range().max_effort() ); diff --git a/AGXUnity/IO/URDF/UJoint.cs b/AGXUnity/IO/URDF/UJoint.cs index 532a086d..7bcb9a9c 100644 --- a/AGXUnity/IO/URDF/UJoint.cs +++ b/AGXUnity/IO/URDF/UJoint.cs @@ -1,6 +1,7 @@ using System; using System.Xml.Linq; using UnityEngine; +using UnityEngine.Serialization; namespace AGXUnity.IO.URDF { @@ -116,7 +117,7 @@ public static CalibrationData ReadOptional( XElement parent ) public struct DynamicsData { /// - /// Read "dynamics" given parent. Defaults to Damping = 0.0 and Friction = 0.0 + /// Read "dynamics" given parent. Defaults to Attenuation = 0.0 and Friction = 0.0 /// if "dynamics" is null. /// /// Parent element. @@ -137,7 +138,7 @@ public static DynamicsData ReadOptional( XElement parent ) /// /// Damping of the joint. - /// + /// public float Damping; /// diff --git a/AGXUnity/Model/TrackInternalMergeProperties.cs b/AGXUnity/Model/TrackInternalMergeProperties.cs index 89076596..cefee296 100644 --- a/AGXUnity/Model/TrackInternalMergeProperties.cs +++ b/AGXUnity/Model/TrackInternalMergeProperties.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using UnityEngine; +using UnityEngine.Serialization; namespace AGXUnity.Model { @@ -119,21 +120,22 @@ public float LockToReachMergeConditionCompliance } [SerializeField] - private float m_lockToReachMergeConditionDamping = 0.06f; + [FormerlySerializedAs( "m_lockToReachMergeConditionDamping" )] + private float m_lockToReachMergeConditionAttenuation = 3.0f; /// /// Damping of the hinge lock used to reach merge condition. - /// Default: 0.06 + /// Default: 3 /// [ClampAboveZeroInInspector( true )] - [Tooltip( "Damping of the hinge lock used to reach merge condition." )] - public float LockToReachMergeConditionDamping + [Tooltip( "Attenuation of the hinge lock used to reach merge condition." )] + public float LockToReachMergeConditionAttenuation { - get { return m_lockToReachMergeConditionDamping; } + get { return m_lockToReachMergeConditionAttenuation; } set { - m_lockToReachMergeConditionDamping = value; - Propagate( properties => properties.setLockToReachMergeConditionDamping( m_lockToReachMergeConditionDamping ) ); + m_lockToReachMergeConditionAttenuation = value; + Propagate( properties => properties.setLockToReachMergeConditionAttenuation( m_lockToReachMergeConditionAttenuation ) ); } } @@ -229,5 +231,14 @@ private void Propagate( Action action ) [NonSerialized] private Track m_singleSynchronizeInstance = null; + + protected override bool PerformMigration() + { + if ( m_serializationVersion < 3 ) { + m_lockToReachMergeConditionAttenuation *= Time.fixedDeltaTime; + return true; + } + return true; + } } } diff --git a/AGXUnity/Model/WheelJoint.cs b/AGXUnity/Model/WheelJoint.cs index c98a5b54..d3ea8096 100644 --- a/AGXUnity/Model/WheelJoint.cs +++ b/AGXUnity/Model/WheelJoint.cs @@ -320,36 +320,36 @@ public void SetCompliance( float compliance, Constraint.RotationalDof dof ) } /// - /// Set damping to all ordinary degrees of freedom (not including controllers) + /// Set attenuation to all ordinary degrees of freedom (not including controllers) /// of this constraint. /// - /// New damping. - public void SetDamping( float damping ) + /// New attenuation. + public void SetAttenuation( float attenuation ) { - TraverseRowData( data => data.Damping = damping, Constraint.TranslationalDof.All ); - TraverseRowData( data => data.Damping = damping, Constraint.RotationalDof.All ); + TraverseRowData( data => data.Attenuation = attenuation, Constraint.TranslationalDof.All ); + TraverseRowData( data => data.Attenuation = attenuation, Constraint.RotationalDof.All ); } /// - /// Set damping to one or all translational ordinary degrees of freedom + /// Set attenuation to one or all translational ordinary degrees of freedom /// (not including controllers) of this constraint. /// - /// New damping. + /// New attenuation. /// Specific translational degree of freedom or all. - public void SetDamping( float damping, Constraint.TranslationalDof dof ) + public void SetAttenuation( float attenuation, Constraint.TranslationalDof dof ) { - TraverseRowData( data => data.Damping = damping, dof ); + TraverseRowData( data => data.Attenuation = attenuation, dof ); } /// - /// Set damping to one or all rotational ordinary degrees of freedom + /// Set attenuation to one or all rotational ordinary degrees of freedom /// (not including controllers) of this constraint. /// - /// New damping. + /// New attenuation. /// Specific rotational degree of freedom or all. - public void SetDamping( float damping, Constraint.RotationalDof dof ) + public void SetAttenuation( float attenuation, Constraint.RotationalDof dof ) { - TraverseRowData( data => data.Damping = damping, dof ); + TraverseRowData( data => data.Attenuation = attenuation, dof ); } /// diff --git a/AGXUnity/PickHandler.cs b/AGXUnity/PickHandler.cs index a2ff1a8e..905af29c 100644 --- a/AGXUnity/PickHandler.cs +++ b/AGXUnity/PickHandler.cs @@ -23,7 +23,7 @@ public static float FindDistanceFromCamera( Camera camera, Vector3 worldPoint ) return camera.WorldToViewportPoint( worldPoint ).z; } - public static void SetComplianceDamping( Constraint constraint ) + public static void SetComplianceAttenuation( Constraint constraint ) { if ( constraint == null ) return; @@ -38,7 +38,8 @@ public static void SetComplianceDamping( Constraint constraint ) float translationalCompliance = 1.0E-3f / ( distVal * Mathf.Max( mass, 1.0f ) ); float rotationalCompliance = 1.0E-10f / ( Mathf.Max( mass, 1.0f ) ); - float damping = 10.0f / 60.0f; + //TODO: Address timestep scaling since new attenuation scales + float attenuation = 2.0f; var rowParser = ConstraintUtils.ConstraintRowParser.Create( constraint.GetOrdinaryElementaryConstraints() ); if ( rowParser == null ) @@ -49,7 +50,7 @@ public static void SetComplianceDamping( Constraint constraint ) continue; translationalRow.RowData.Compliance = translationalCompliance; - translationalRow.RowData.Damping = damping; + translationalRow.RowData.Attenuation = attenuation; } foreach ( var rotationalRow in rowParser.RotationalRows ) { @@ -57,7 +58,7 @@ public static void SetComplianceDamping( Constraint constraint ) continue; rotationalRow.RowData.Compliance = rotationalCompliance; - rotationalRow.RowData.Damping = damping; + rotationalRow.RowData.Attenuation = attenuation; } } @@ -300,7 +301,7 @@ private void OnPreStepForwardCallback() Input.mousePosition.y, m_distanceFromCamera ) ); - SetComplianceDamping( Constraint ); + SetComplianceAttenuation( Constraint ); ConstraintGameObject.GetComponent().ThisMethodIsntAllowedToBeNamedUpdateByUnity( Constraint, m_camera ); } diff --git a/AGXUnity/ScriptComponent.cs b/AGXUnity/ScriptComponent.cs index e78906b5..7227e92e 100644 --- a/AGXUnity/ScriptComponent.cs +++ b/AGXUnity/ScriptComponent.cs @@ -41,7 +41,8 @@ protected ScriptComponent() // 2 - Migrate Range, Beam Divergence, and Beam Exit Radius into the LiDAR model // - Migrate old tracks into FullDoF tracks // - Add automatic positioning mode - private const int CurrentSerializationVersion = 2; + // 3 - Migrate damping into attenuation + private const int CurrentSerializationVersion = 3; [SerializeField] [HideInInspector] diff --git a/AGXUnity/ShapeMaterial.cs b/AGXUnity/ShapeMaterial.cs index e3dfd238..e6a40154 100644 --- a/AGXUnity/ShapeMaterial.cs +++ b/AGXUnity/ShapeMaterial.cs @@ -1,5 +1,7 @@ -using System; +using openplx.Vehicles.TrackSystem.Interactions.Dissipation; +using System; using UnityEngine; +using UnityEngine.Serialization; namespace AGXUnity { @@ -93,50 +95,52 @@ public float YoungsWireBend } /// - /// damping for wire stretching modulus stretch for wires. - /// Default value: 0.06 + /// attenuation for wire stretching modulus stretch for wires. + /// Default value: 3 /// [SerializeField] - private float m_dampingStretch = 0.06f; + [FormerlySerializedAs( "m_dampingStretch" )] + private float m_attenuationStretch = 3.0f; /// - /// Get or set stretch damping for wires. - /// Default value: 0.06 + /// Get or set stretch attenuation for wires. + /// Default value: 3 /// [ClampAboveZeroInInspector] - [Tooltip( "The damping of the stretch contstraint when this material is used as a wire" )] - public float DampingStretch + [Tooltip( "The attenuation of the stretch contstraint when this material is used as a wire" )] + public float AttenuationStretch { - get { return m_dampingStretch; } + get { return m_attenuationStretch; } set { - m_dampingStretch = value; + m_attenuationStretch = value; if ( Native != null ) - Native.getWireMaterial().setDampingStretch( m_dampingStretch ); + Native.getWireMaterial().setAttenuationStretch( m_attenuationStretch ); } } /// - /// Bend damping of this material. - /// Default value: 0.12 + /// Bend attenuation of this material. + /// Default value: 6 /// [SerializeField] - private float m_dampingBend = 0.12f; + [FormerlySerializedAs( "m_dampingBend" )] + private float m_attenuationBend = 6.0f; /// - /// Get or set bend damping of this material. - /// Default value: 0.12 + /// Get or set bend attenuation of this material. + /// Default value: 6 /// [ClampAboveZeroInInspector] - [Tooltip( "The damping of the bend contstraint when this material is used as a wire" )] - public float DampingBend + [Tooltip( "The attenuation of the bend contstraint when this material is used as a wire" )] + public float AttenuationBend { - get { return m_dampingBend; } + get { return m_attenuationBend; } set { - m_dampingBend = value; + m_attenuationBend = value; if ( Native != null ) - Native.getWireMaterial().setDampingBend( m_dampingBend ); + Native.getWireMaterial().setAttenuationBend( m_attenuationBend ); } } @@ -163,8 +167,8 @@ public ShapeMaterial RestoreLocalDataFrom( agx.Material native ) Density = Convert.ToSingle( native.getBulkMaterial().getDensity() ); YoungsWireStretch = Convert.ToSingle( native.getWireMaterial().getYoungsModulusStretch() ); YoungsWireBend = Convert.ToSingle( native.getWireMaterial().getYoungsModulusBend() ); - DampingStretch = Convert.ToSingle( native.getWireMaterial().getDampingStretch() ); - DampingBend = Convert.ToSingle( native.getWireMaterial().getDampingBend() ); + AttenuationStretch = Convert.ToSingle( native.getWireMaterial().getAttenuationStretch() ); + AttenuationBend = Convert.ToSingle( native.getWireMaterial().getAttenuationBend() ); return this; } @@ -205,5 +209,15 @@ public static ShapeMaterial Default return m_defaultMaterial; } } + + protected override bool PerformMigration() + { + if ( m_serializationVersion < 3 ) { + m_attenuationBend *= Time.fixedDeltaTime; + m_attenuationStretch *= Time.fixedDeltaTime; + return true; + } + return false; + } } } diff --git a/Editor/AGXUnityEditor/IO/InputAGXFile.cs b/Editor/AGXUnityEditor/IO/InputAGXFile.cs index 67284a31..9e824871 100644 --- a/Editor/AGXUnityEditor/IO/InputAGXFile.cs +++ b/Editor/AGXUnityEditor/IO/InputAGXFile.cs @@ -670,26 +670,19 @@ private bool CreateConstraint( Node node ) return false; } - // Scaling damping to our (sigh) hard coded time step. - float fixedStepTime = Time.fixedDeltaTime; - float readTimeStep = Convert.ToSingle( Simulation.getTimeStep() ); - float timeStepRatio = fixedStepTime / readTimeStep; - if ( !AGXUnity.Utils.Math.Approximately( timeStepRatio, 1.0f ) ) { - foreach ( var ec in constraint.ElementaryConstraints ) { - foreach ( var rowData in ec.RowData ) { - if ( rowData.Compliance < -float.Epsilon ) { - Debug.LogWarning( "Constraint: " + constraint.name + - " (ec name: " + rowData.ElementaryConstraint.NativeName + ")," + - " has too low compliance: " + rowData.Compliance + ". Setting to zero." ); - rowData.Compliance = 0.0f; - } - else if ( rowData.Compliance > float.MaxValue ) { - Debug.LogWarning( "Constraint: " + constraint.name + - " (ec name: " + rowData.ElementaryConstraint.NativeName + ")," + - " has too high compliance: " + rowData.Compliance + ". Setting to a large value." ); - rowData.Compliance = 0.5f * float.MaxValue; - } - rowData.Damping *= timeStepRatio; + foreach ( var ec in constraint.ElementaryConstraints ) { + foreach ( var rowData in ec.RowData ) { + if ( rowData.Compliance < -float.Epsilon ) { + Debug.LogWarning( "Constraint: " + constraint.name + + " (ec name: " + rowData.ElementaryConstraint.NativeName + ")," + + " has too low compliance: " + rowData.Compliance + ". Setting to zero." ); + rowData.Compliance = 0.0f; + } + else if ( rowData.Compliance > float.MaxValue ) { + Debug.LogWarning( "Constraint: " + constraint.name + + " (ec name: " + rowData.ElementaryConstraint.NativeName + ")," + + " has too high compliance: " + rowData.Compliance + ". Setting to a large value." ); + rowData.Compliance = 0.5f * float.MaxValue; } } } diff --git a/Editor/AGXUnityEditor/Tools/PickHandlerTool.cs b/Editor/AGXUnityEditor/Tools/PickHandlerTool.cs index f12af3ae..16a48e2b 100644 --- a/Editor/AGXUnityEditor/Tools/PickHandlerTool.cs +++ b/Editor/AGXUnityEditor/Tools/PickHandlerTool.cs @@ -49,7 +49,7 @@ public override void OnSceneViewGUI( SceneView sceneView ) constraint.AttachmentPair.ConnectedFrame.Position = HandleUtility.GUIPointToWorldRay( Event.current.mousePosition ).GetPoint( m_distanceFromCamera ); - PickHandler.SetComplianceDamping( constraint ); + PickHandler.SetComplianceAttenuation( constraint ); } private float m_distanceFromCamera = -1f; @@ -83,7 +83,7 @@ private void Initialize() VisualSphereConnected.Pickable = false; VisualCylinder.Pickable = false; - PickHandler.SetComplianceDamping( Constraint ); + PickHandler.SetComplianceAttenuation( Constraint ); } private void UpdateVisual( Constraint constraint )