diff --git a/unity/Runtime/Components/Shapes/MjGeomSettings.cs b/unity/Runtime/Components/Shapes/MjGeomSettings.cs index c06d3981..5c887f1b 100644 --- a/unity/Runtime/Components/Shapes/MjGeomSettings.cs +++ b/unity/Runtime/Components/Shapes/MjGeomSettings.cs @@ -22,6 +22,10 @@ namespace Mujoco { [Serializable] public struct MjGeomSettings { + public enum FluidShapeTypes { + None, + Ellipsoid, + } [Tooltip("Priority")] public int Priority; @@ -35,11 +39,20 @@ public struct MjGeomSettings { [Tooltip("Contact friction parameters for dynamically generated contact pairs.")] public GeomFriction Friction; + [Tooltip("Shape used for fluid simulation.")] + public FluidShapeTypes FluidShapeType; + + [Tooltip("Dimensionless coefficients of fluid interaction model.")] + public GeomFluidCoefficients FluidCoefficients; + + // Default geom settings. public static MjGeomSettings Default = new MjGeomSettings() { Solver = GeomSolver.Default, Filtering = CollisionFiltering.Default, - Friction = GeomFriction.Default + Friction = GeomFriction.Default, + FluidShapeType = FluidShapeTypes.None, + FluidCoefficients = GeomFluidCoefficients.Default }; public void FromMjcf(XmlElement mjcf) { @@ -76,6 +89,20 @@ public struct MjGeomSettings { Friction.Sliding = friction[0]; Friction.Torsional = friction[1]; Friction.Rolling = friction[2]; + + // Fluid settings. + FluidShapeType = mjcf.GetEnumAttribute( + "fluidshape", FluidShapeTypes.None, ignoreCase: true); + var fluidcoef = mjcf.GetFloatArrayAttribute("fluidcoef", new float[] { + GeomFluidCoefficients.Default.BluntDrag, GeomFluidCoefficients.Default.SlenderDrag, + GeomFluidCoefficients.Default.AngularDrag, GeomFluidCoefficients.Default.KuttaLift, + GeomFluidCoefficients.Default.MagnusLift + }); + FluidCoefficients.BluntDrag = fluidcoef[0]; + FluidCoefficients.SlenderDrag = fluidcoef[1]; + FluidCoefficients.AngularDrag = fluidcoef[2]; + FluidCoefficients.KuttaLift = fluidcoef[3]; + FluidCoefficients.MagnusLift = fluidcoef[4]; } public void ToMjcf(XmlElement mjcf) { @@ -97,6 +124,11 @@ public struct MjGeomSettings { // Inertia and friction settings. mjcf.SetAttribute("friction", MjEngineTool.MakeLocaleInvariant($"{Friction.Sliding} {Friction.Torsional} {Friction.Rolling}")); + + // Fluid settings. + mjcf.SetAttribute("fluidshape", FluidShapeType.ToString().ToLower()); + mjcf.SetAttribute("fluidcoef", MjEngineTool.MakeLocaleInvariant( + $"{FluidCoefficients.BluntDrag} {FluidCoefficients.SlenderDrag} {FluidCoefficients.AngularDrag} {FluidCoefficients.KuttaLift} {FluidCoefficients.MagnusLift}")); } } @@ -155,4 +187,17 @@ public struct GeomSolver { Margin = 0.0f, Gap = 0.0f }; } + +[Serializable] +public struct GeomFluidCoefficients { + public float BluntDrag; + public float SlenderDrag; + public float AngularDrag; + public float KuttaLift; + public float MagnusLift; + + public static GeomFluidCoefficients Default = new GeomFluidCoefficients() { + BluntDrag = 5f, SlenderDrag = .25f, AngularDrag = 1.5f, KuttaLift = 1f, MagnusLift = 1f + }; +} } diff --git a/unity/Tests/Editor/Components/MjGeomSettingsTests.cs b/unity/Tests/Editor/Components/MjGeomSettingsTests.cs index 56471eab..27e41b10 100644 --- a/unity/Tests/Editor/Components/MjGeomSettingsTests.cs +++ b/unity/Tests/Editor/Components/MjGeomSettingsTests.cs @@ -109,6 +109,24 @@ public class MjGeomSettingsGenerationTests { _settings.ToMjcf(_mjcf); Assert.That(_doc.OuterXml, Does.Contain(@"friction=""5 6 7""")); } + + [Test] + public void FluidShapeTypeMjcf() { + _settings.FluidShapeType = MjGeomSettings.FluidShapeTypes.Ellipsoid; + _settings.ToMjcf(_mjcf); + Assert.That(_doc.OuterXml, Does.Contain(@"fluidshape=""ellipsoid""")); + } + + [Test] + public void FluidCoefficientsMjcf() { + _settings.FluidCoefficients.BluntDrag = 2f; + _settings.FluidCoefficients.SlenderDrag = 3f; + _settings.FluidCoefficients.AngularDrag = 4f; + _settings.FluidCoefficients.KuttaLift = 5f; + _settings.FluidCoefficients.MagnusLift = 6f; + _settings.ToMjcf(_mjcf); + Assert.That(_doc.OuterXml, Does.Contain(@"fluidcoef=""2 3 4 5 6""")); + } } [TestFixture] @@ -199,5 +217,25 @@ public class MjGeomSettingsParsingTests { Assert.That(_settings.Friction.Torsional, Is.EqualTo(6)); Assert.That(_settings.Friction.Rolling, Is.EqualTo(7)); } + + [Test] + public void FluidShapeTypeMjcf() { + _mjcf.SetAttribute("fluidshape", "ellipsoid"); + _settings.FromMjcf(_mjcf); + Assert.That(_settings.FluidShapeType, Is.EqualTo( + MjGeomSettings.FluidShapeTypes.Ellipsoid + )); + } + + [Test] + public void FluidCoefficientsMjcf() { + _mjcf.SetAttribute("fluidcoef", "2 3 4 5 6"); + _settings.FromMjcf(_mjcf); + Assert.That(_settings.FluidCoefficients.BluntDrag, Is.EqualTo(2)); + Assert.That(_settings.FluidCoefficients.SlenderDrag, Is.EqualTo(3)); + Assert.That(_settings.FluidCoefficients.AngularDrag, Is.EqualTo(4)); + Assert.That(_settings.FluidCoefficients.KuttaLift, Is.EqualTo(5)); + Assert.That(_settings.FluidCoefficients.MagnusLift, Is.EqualTo(6)); + } } }