generated from tpl/purs
Compare commits
13 Commits
eaaeb071a2
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96e85ca24d | ||
|
|
f8a18fe3fc | ||
|
|
24d375993a | ||
|
|
26bf20cff9 | ||
|
|
39229ca2c4 | ||
|
|
b536f7fc4a | ||
|
|
1f7086f85e | ||
|
|
88fcf9b4a3 | ||
|
|
3029ea0e68 | ||
|
|
b1a1264be1 | ||
|
|
442351f47d | ||
|
|
8b7ad814fd | ||
|
|
6ca132788f |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -11,3 +11,4 @@
|
||||
.log
|
||||
.purs-repl
|
||||
.env
|
||||
.spec-results
|
||||
|
||||
1912
doc/Modeling.rst
Normal file
1912
doc/Modeling.rst
Normal file
File diff suppressed because it is too large
Load Diff
9882
doc/XMLReference.rst
Normal file
9882
doc/XMLReference.rst
Normal file
File diff suppressed because it is too large
Load Diff
@@ -9,11 +9,16 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"bun-types": "1.0.11",
|
||||
"mujoco_wasm": "^3.2.2",
|
||||
"purs-tidy": "^0.10.0",
|
||||
"spago": "^1.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"dependencies": {}
|
||||
"dependencies": {
|
||||
"react": "17",
|
||||
"react-dom": "17",
|
||||
"server": "react-dom/server"
|
||||
}
|
||||
}
|
||||
|
||||
32
spago.lock
32
spago.lock
@@ -6,11 +6,16 @@
|
||||
"core": {
|
||||
"dependencies": [
|
||||
"arrays",
|
||||
"either",
|
||||
"elmish",
|
||||
"elmish-html",
|
||||
"foldable-traversable",
|
||||
"integers",
|
||||
"maybe",
|
||||
"numbers",
|
||||
"ordered-collections",
|
||||
"prelude",
|
||||
"strings",
|
||||
"tuples",
|
||||
"typelevel-prelude",
|
||||
"unsafe-coerce"
|
||||
@@ -18,6 +23,8 @@
|
||||
},
|
||||
"test": {
|
||||
"dependencies": [
|
||||
"aff-promise",
|
||||
"assert",
|
||||
"spec",
|
||||
"spec-node"
|
||||
]
|
||||
@@ -640,6 +647,21 @@
|
||||
"unsafe-coerce"
|
||||
]
|
||||
},
|
||||
"aff-promise": {
|
||||
"type": "registry",
|
||||
"version": "4.0.0",
|
||||
"integrity": "sha256-Jgp3y+NWuuAmwz2V3LlWoX+AvxqfVglY77N5zTw8xnI=",
|
||||
"dependencies": [
|
||||
"aff",
|
||||
"control",
|
||||
"effect",
|
||||
"either",
|
||||
"exceptions",
|
||||
"foreign",
|
||||
"prelude",
|
||||
"transformers"
|
||||
]
|
||||
},
|
||||
"ansi": {
|
||||
"type": "registry",
|
||||
"version": "7.0.0",
|
||||
@@ -718,6 +740,16 @@
|
||||
"unsafe-coerce"
|
||||
]
|
||||
},
|
||||
"assert": {
|
||||
"type": "registry",
|
||||
"version": "6.0.0",
|
||||
"integrity": "sha256-hCZ1J8/71nQiRwsSV2j7iicppScOegBFZrLI6sPf9F8=",
|
||||
"dependencies": [
|
||||
"console",
|
||||
"effect",
|
||||
"prelude"
|
||||
]
|
||||
},
|
||||
"avar": {
|
||||
"type": "registry",
|
||||
"version": "5.0.1",
|
||||
|
||||
@@ -15,15 +15,22 @@ package:
|
||||
test:
|
||||
main: Test.Main
|
||||
dependencies:
|
||||
- aff-promise
|
||||
- assert
|
||||
- spec
|
||||
- spec-node
|
||||
dependencies:
|
||||
- arrays
|
||||
- either
|
||||
- elmish
|
||||
- elmish-html
|
||||
- foldable-traversable
|
||||
- integers
|
||||
- maybe
|
||||
- numbers
|
||||
- ordered-collections
|
||||
- prelude
|
||||
- strings
|
||||
- tuples
|
||||
- typelevel-prelude
|
||||
- unsafe-coerce
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
module Mujoco where
|
||||
167
src/Mujoco/MJCF.purs
Normal file
167
src/Mujoco/MJCF.purs
Normal file
@@ -0,0 +1,167 @@
|
||||
module Mujoco.MJCF
|
||||
( Angle
|
||||
, Cone
|
||||
, Coordinate
|
||||
, EnableDisable
|
||||
, InertiaFromGeom
|
||||
, Jacobian
|
||||
, Props_compiler
|
||||
, Props_flag
|
||||
, Props_option
|
||||
, Props_size
|
||||
, Props_mujoco
|
||||
, Props_statistic
|
||||
, Props_plugin
|
||||
, Solver
|
||||
, plugin
|
||||
, compiler
|
||||
, flag
|
||||
, mujoco
|
||||
, option
|
||||
, size
|
||||
, statistic
|
||||
, module X
|
||||
) where
|
||||
|
||||
import Mujoco.MJCF.Prelude
|
||||
|
||||
import Mujoco.MJCF.Keyword as Kw
|
||||
import Mujoco.MJCF.Keyframe (Props_key, key, keyframe) as X
|
||||
import Mujoco.MJCF.Keyword (Acc(..), Affine(..), Allowed(..), Auto(..), Axis(..), Ball(..), Body(..), Box(..), CG(..), Camera(..), Capsule(..), Checker(..), Convex(..), Cross(..), Cube(..), Cubic(..), Cylinder(..), Degree(..), Dense(..), Depth(..), Dir(..), Directional(..), Disable(..), Dist(..), Distance(..), Edge(..), Ellipsoid(..), Elliptic(..), Emissive(..), Enable(..), Euler(..), Exact(..), Filter(..), FilterExact(..), Fixed(..), Flat(..), Force(..), Found(..), Free(..), Geom(..), Global(..), Gradient(..), Hfield(..), Hinge(..), Image(..), Implicit(..), ImplicitFast(..), Init(..), Integrator(..), Legacy(..), Linear(..), Local(..), MaxForce(..), Mesh(..), Metallic(..), MinDist(..), Muscle(..), NetForce(..), Never(..), Newton(..), None(..), Normal(..), Occlusion(..), Opacity(..), Origin(..), Orm(..), Orthographic(..), PGS(..), Perspective(..), Plane(..), Point(..), Pos(..), Positive(..), Pyramidal(..), Quaternion(..), RK4(..), Radian(..), Random(..), Real(..), Rgb(..), Rgba(..), Roughness(..), SRGB(..), Sdf(..), Segmentation(..), Shell(..), Site(..), Skybox(..), Slide(..), Sparse(..), Sphere(..), Spot(..), Tangent(..), Targetbody(..), Targetbodycom(..), Torque(..), Track(..), Trackcom(..), TwoD(..), User(..), Vel(..), Xbody(..), Zoh(..), false_, kw, true_) as X
|
||||
import Mujoco.MJCF.Asset (LayerRole, MeshInertia, Props_hfield, Props_layer, Props_material, Props_mesh, Props_model, Props_texture, TextureBuiltin, TextureColorspace, TextureMark, TextureType, asset, hfield, layer, material, mesh, model, texture) as X
|
||||
import Mujoco.MJCF.Body (CameraMode, CameraOutput, JointType, LightType, Projection, Props_attach, Props_body, Props_camera, Props_frame, Props_freejoint, Props_geom, Props_inertial, Props_joint, Props_light, Props_site, SiteType, SleepPolicy, attach, body, camera, frame, freejoint, geom, inertial, joint, light, site, worldbody) as X
|
||||
import Mujoco.MJCF.Contact (Props_exclude, Props_pair, contact, exclude, pair) as X
|
||||
import Mujoco.MJCF.Sensor (sensor) as X
|
||||
import Mujoco.MJCF.Actuator (actuator) as X
|
||||
import Mujoco.MJCF.Tendon (tendon) as X
|
||||
import Mujoco.MJCF.XML (empty, text, fragment) as X
|
||||
|
||||
type Props_mujoco = (model :: String)
|
||||
mujoco = tag @Props_mujoco "mujoco" :: Tag Props_mujoco
|
||||
|
||||
type Cone = Kw.Pyramidal \/ Kw.Elliptic
|
||||
type Jacobian = Kw.Dense \/ Kw.Sparse
|
||||
type Solver = Kw.PGS \/ Kw.CG \/ Kw.Newton
|
||||
type EnableDisable = Kw.Enable \/ Kw.Disable
|
||||
type Coordinate = Kw.Local \/ Kw.Global
|
||||
type Angle = Kw.Radian \/ Kw.Degree
|
||||
type InertiaFromGeom = Kw.Auto \/ Boolean
|
||||
|
||||
type Props_option =
|
||||
( timestep :: Real
|
||||
, impratio :: Real
|
||||
, gravity :: Vec Real
|
||||
, wind :: Vec Real
|
||||
, magnetic :: Vec Real
|
||||
, density :: Real
|
||||
, viscosity :: Real
|
||||
, o_margin :: Real
|
||||
, o_solref :: Real /\ Real
|
||||
, o_solimp :: Vec5 Real
|
||||
, integrator :: Kw.Euler \/ Kw.RK4 \/ Kw.Implicit \/ Kw.ImplicitFast
|
||||
, cone :: Cone
|
||||
, jacobian :: Jacobian
|
||||
, iterations :: Int
|
||||
, tolerance :: Real
|
||||
, ls_iterations :: Int
|
||||
, ls_tolerance :: Real
|
||||
, noslip_tolerance :: Real
|
||||
, ccd_iterations :: Int
|
||||
, ccd_tolerance :: Real
|
||||
, sleep_tolerance :: Real
|
||||
, sdf_iterations :: Int
|
||||
, sdf_initpoints :: Int
|
||||
, actuatorgroupdisable :: Array Int
|
||||
, solver :: Solver
|
||||
)
|
||||
|
||||
option = tag @Props_option "mjcf:option" :: Tag Props_option
|
||||
|
||||
type Props_flag =
|
||||
( constraint :: EnableDisable
|
||||
, equality :: EnableDisable
|
||||
, frictionloss :: EnableDisable
|
||||
, limit :: EnableDisable
|
||||
, contact :: EnableDisable
|
||||
, spring :: EnableDisable
|
||||
, damper :: EnableDisable
|
||||
, gravity :: EnableDisable
|
||||
, clampctrl :: EnableDisable
|
||||
, warmstart :: EnableDisable
|
||||
, filterparent :: EnableDisable
|
||||
, actuation :: EnableDisable
|
||||
, refsafe :: EnableDisable
|
||||
, sensor :: EnableDisable
|
||||
, midphase :: EnableDisable
|
||||
, nativeccd :: EnableDisable
|
||||
, island :: EnableDisable
|
||||
, eulerdamp :: EnableDisable
|
||||
, autoreset :: EnableDisable
|
||||
, override :: EnableDisable
|
||||
, energy :: EnableDisable
|
||||
, fwdinv :: EnableDisable
|
||||
, invdiscrete :: EnableDisable
|
||||
, multiccd :: EnableDisable
|
||||
, sleep :: EnableDisable
|
||||
)
|
||||
|
||||
flag = tagNoContent @Props_flag "flag" :: TagNoContent Props_flag
|
||||
|
||||
type Props_compiler =
|
||||
( autolimits :: Boolean
|
||||
, boundmass :: Real
|
||||
, boundinertia :: Real
|
||||
, settotalmass :: Real
|
||||
, balanceinertia :: Boolean
|
||||
, strippath :: Boolean
|
||||
, coordinate :: Coordinate
|
||||
, angle :: Angle
|
||||
, fitaabb :: Boolean
|
||||
, eulerseq :: String
|
||||
, meshdir :: String
|
||||
, texturedir :: String
|
||||
, assetdir :: String
|
||||
, discardvisual :: Boolean
|
||||
, usethread :: Boolean
|
||||
, fusestatic :: Boolean
|
||||
, inertiafromgeom :: InertiaFromGeom
|
||||
, alignfree :: Boolean
|
||||
, inertiagrouprange :: Int /\ Int
|
||||
, saveinertial :: Boolean
|
||||
)
|
||||
|
||||
compiler = tagNoContent @Props_compiler "compiler" :: TagNoContent Props_compiler
|
||||
|
||||
type Props_size =
|
||||
( memory :: String
|
||||
, njmax :: Int
|
||||
, nconmax :: Int
|
||||
, nstack :: Int
|
||||
, nuserdata :: Int
|
||||
, nkey :: Int
|
||||
, nuser_body :: Int
|
||||
, nuser_jnt :: Int
|
||||
, nuser_geom :: Int
|
||||
, nuser_site :: Int
|
||||
, nuser_cam :: Int
|
||||
, nuser_tendon :: Int
|
||||
, nuser_actuator :: Int
|
||||
, nuser_sensor :: Int
|
||||
)
|
||||
|
||||
size = tagNoContent @Props_size "size" :: TagNoContent Props_size
|
||||
|
||||
type Props_statistic =
|
||||
( meanmass :: Real
|
||||
, meaninertia :: Real
|
||||
, meansize :: Real
|
||||
, extent :: Real
|
||||
, center :: Vec Real
|
||||
)
|
||||
|
||||
statistic = tagNoContent @Props_statistic "statistic" :: TagNoContent Props_statistic
|
||||
|
||||
type Props_plugin = (plugin :: String, instance :: String)
|
||||
|
||||
-- | `body/plugin`, `asset/mesh/plugin`
|
||||
plugin = tag @Props_plugin "plugin" :: Tag Props_plugin
|
||||
143
src/Mujoco/MJCF/Actuator.purs
Normal file
143
src/Mujoco/MJCF/Actuator.purs
Normal file
@@ -0,0 +1,143 @@
|
||||
module Mujoco.MJCF.Actuator where
|
||||
|
||||
import Mujoco.MJCF.Prelude
|
||||
import Mujoco.MJCF.Keyword as Kw
|
||||
|
||||
actuator = tag @() "actuator" :: Tag ()
|
||||
|
||||
type Interp = Kw.Zoh \/ Kw.Linear \/ Kw.Cubic
|
||||
type DynType = Kw.None \/ Kw.Integrator \/ Kw.Filter \/ Kw.FilterExact \/ Kw.Muscle \/ Kw.User
|
||||
type GainType = Kw.Fixed \/ Kw.Affine \/ Kw.Muscle \/ Kw.User
|
||||
type BiasType = Kw.None \/ Kw.Affine \/ Kw.Muscle \/ Kw.User
|
||||
|
||||
type CommonMin r =
|
||||
( class :: String
|
||||
, group :: Int
|
||||
, delay :: Real
|
||||
, forcelimited :: Kw.Auto \/ Boolean
|
||||
, ctrlrange :: Real /\ Real
|
||||
, forcerange :: Real /\ Real
|
||||
, user :: Array Real
|
||||
, interp :: Interp
|
||||
, nsample :: Int
|
||||
| Named r
|
||||
)
|
||||
|
||||
type Common r =
|
||||
( ctrllimited :: Kw.Auto \/ Boolean
|
||||
, lengthrange :: Real /\ Real
|
||||
, gear :: Array Real
|
||||
, cranklength :: Real
|
||||
, joint :: String
|
||||
, jointinparent :: String
|
||||
, tendon :: String
|
||||
, cranksite :: String
|
||||
, slidersite :: String
|
||||
, site :: String
|
||||
, refsite :: String
|
||||
| CommonMin r
|
||||
)
|
||||
|
||||
type Props_general =
|
||||
( actlimited :: Kw.Auto \/ Boolean
|
||||
, actrange :: Real /\ Real
|
||||
, actdim :: Int
|
||||
, dyntype :: DynType
|
||||
, gaintype :: GainType
|
||||
, biastype :: BiasType
|
||||
, dynprm :: Array Real
|
||||
, gainprm :: Array Real
|
||||
, biasprm :: Array Real
|
||||
, actearly :: Boolean
|
||||
, body :: String
|
||||
| Common ()
|
||||
)
|
||||
|
||||
general = tagNoContent @Props_general "general" :: TagNoContent Props_general
|
||||
|
||||
type Props_adhesion =
|
||||
( body :: String
|
||||
, gain :: Real
|
||||
| CommonMin ()
|
||||
)
|
||||
|
||||
adhesion = tagNoContent @Props_adhesion "adhesion" :: TagNoContent Props_adhesion
|
||||
|
||||
type Props_plugin =
|
||||
( actlimited :: Kw.Auto \/ Boolean
|
||||
, actdim :: Int
|
||||
, dynprm :: Array Real
|
||||
, actearly :: Boolean
|
||||
, actrange :: Real /\ Real
|
||||
, dyntype :: DynType
|
||||
, instance :: String
|
||||
, plugin :: String
|
||||
| Common ()
|
||||
)
|
||||
|
||||
plugin = tagNoContent @Props_plugin "plugin" :: TagNoContent Props_plugin
|
||||
|
||||
type Props_motor = Common ()
|
||||
motor = tagNoContent @Props_motor "motor" :: TagNoContent Props_motor
|
||||
|
||||
type Props_position =
|
||||
( kp :: Real
|
||||
, kv :: Real
|
||||
, dampratio :: Real
|
||||
, timeconst :: Real
|
||||
, inheritrange :: Real
|
||||
| Common ()
|
||||
)
|
||||
|
||||
position = tagNoContent @Props_position "position" :: TagNoContent Props_position
|
||||
|
||||
type Props_velocity =
|
||||
( kv :: Real
|
||||
| Common ()
|
||||
)
|
||||
|
||||
velocity = tagNoContent @Props_velocity "velocity" :: TagNoContent Props_velocity
|
||||
|
||||
type Props_intvelocity =
|
||||
( kp :: Real
|
||||
, kv :: Real
|
||||
, dampratio :: Real
|
||||
, inheritrange :: Real
|
||||
, actrange :: Real /\ Real
|
||||
| Common ()
|
||||
)
|
||||
|
||||
intvelocity = tagNoContent @Props_intvelocity "intvelocity" :: TagNoContent Props_intvelocity
|
||||
|
||||
type Props_damper =
|
||||
( kv :: Real
|
||||
| Common ()
|
||||
)
|
||||
|
||||
damper = tagNoContent @Props_damper "damper" :: TagNoContent Props_damper
|
||||
|
||||
type Props_cylinder =
|
||||
( timeconst :: Real
|
||||
, area :: Real
|
||||
, diameter :: Real
|
||||
, bias :: Vec Real
|
||||
| Common ()
|
||||
)
|
||||
|
||||
cylinder = tagNoContent @Props_cylinder "cylinder" :: TagNoContent Props_cylinder
|
||||
|
||||
type Props_muscle =
|
||||
( timeconst :: Real /\ Real
|
||||
, tausmooth :: Real
|
||||
, range :: Real /\ Real
|
||||
, force :: Real
|
||||
, scale :: Real
|
||||
, lmin :: Real
|
||||
, lmax :: Real
|
||||
, vmax :: Real
|
||||
, fpmax :: Real
|
||||
, fvmax :: Real
|
||||
| Common ()
|
||||
)
|
||||
|
||||
muscle = tagNoContent @Props_muscle "muscle" :: TagNoContent Props_muscle
|
||||
111
src/Mujoco/MJCF/Asset.purs
Normal file
111
src/Mujoco/MJCF/Asset.purs
Normal file
@@ -0,0 +1,111 @@
|
||||
module Mujoco.MJCF.Asset where
|
||||
|
||||
import Mujoco.MJCF.Prelude
|
||||
|
||||
import Mujoco.MJCF.Keyword as Kw
|
||||
|
||||
asset = tag @() "asset" :: Tag ()
|
||||
|
||||
type MeshInertia = Kw.Convex \/ Kw.Exact \/ Kw.Legacy \/ Kw.Shell
|
||||
|
||||
type Props_mesh =
|
||||
( name :: String
|
||||
, class :: String
|
||||
, content_type :: String
|
||||
, file :: String
|
||||
, scale :: Vec Real
|
||||
, inertia :: MeshInertia
|
||||
, smoothnormal :: Boolean
|
||||
, maxhullvert :: Int
|
||||
, vertex :: Array Real
|
||||
, normal :: Array Real
|
||||
, texcoord :: Array Real
|
||||
, face :: Array Int
|
||||
, refpos :: Vec Real
|
||||
, refquat :: Vec4 Real
|
||||
, builtin :: String
|
||||
, params :: Array Real
|
||||
, material :: String
|
||||
)
|
||||
|
||||
mesh = tag @Props_mesh "mesh" :: Tag Props_mesh
|
||||
|
||||
type Props_hfield =
|
||||
( name :: String
|
||||
, content_type :: String
|
||||
, file :: String
|
||||
, nrow :: Int
|
||||
, ncol :: Int
|
||||
, elevation :: Array Real
|
||||
, size :: Vec4 Real
|
||||
)
|
||||
|
||||
hfield = tagNoContent @Props_hfield "hfield" :: TagNoContent Props_hfield
|
||||
|
||||
type TextureType = Kw.TwoD \/ Kw.Cube \/ Kw.Skybox
|
||||
type TextureColorspace = Kw.Auto \/ Kw.Linear \/ Kw.SRGB
|
||||
type TextureBuiltin = Kw.None \/ Kw.Gradient \/ Kw.Checker \/ Kw.Flat
|
||||
type TextureMark = Kw.None \/ Kw.Edge \/ Kw.Cross \/ Kw.Random
|
||||
|
||||
type Props_texture =
|
||||
( name :: String
|
||||
, type :: TextureType
|
||||
, colorspace :: TextureColorspace
|
||||
, content_type :: String
|
||||
, file :: String
|
||||
, gridsize :: Int /\ Int
|
||||
, gridlayout :: String
|
||||
, fileright :: String
|
||||
, fileleft :: String
|
||||
, fileup :: String
|
||||
, filedown :: String
|
||||
, filefront :: String
|
||||
, fileback :: String
|
||||
, builtin :: TextureBuiltin
|
||||
, rgb1 :: Vec Real
|
||||
, rgb2 :: Vec Real
|
||||
, mark :: TextureMark
|
||||
, markrgb :: Vec Real
|
||||
, random :: Real
|
||||
, width :: Int
|
||||
, height :: Int
|
||||
, hflip :: Boolean
|
||||
, vflip :: Boolean
|
||||
, nchannel :: Int
|
||||
)
|
||||
|
||||
texture = tagNoContent @Props_texture "texture" :: TagNoContent Props_texture
|
||||
|
||||
type Props_material =
|
||||
( name :: String
|
||||
, class :: String
|
||||
, texture :: String
|
||||
, texrepeat :: Real /\ Real
|
||||
, texuniform :: Boolean
|
||||
, emission :: Real
|
||||
, specular :: Real
|
||||
, shininess :: Real
|
||||
, reflectance :: Real
|
||||
, metallic :: Real
|
||||
, roughness :: Real
|
||||
, rgba :: Vec4 Real
|
||||
)
|
||||
|
||||
material = tag @Props_material "material" :: Tag Props_material
|
||||
|
||||
type LayerRole = Kw.Rgb \/ Kw.Normal \/ Kw.Occlusion \/ Kw.Roughness \/ Kw.Metallic \/ Kw.Opacity \/ Kw.Emissive \/ Kw.Orm \/ Kw.Rgba
|
||||
|
||||
type Props_layer =
|
||||
( texture :: String
|
||||
, role :: LayerRole
|
||||
)
|
||||
|
||||
layer = tagNoContent @Props_layer "layer" :: TagNoContent Props_layer
|
||||
|
||||
type Props_model =
|
||||
( name :: String
|
||||
, file :: String
|
||||
, content_type :: String
|
||||
)
|
||||
|
||||
model = tagNoContent @Props_model "model" :: TagNoContent Props_model
|
||||
209
src/Mujoco/MJCF/Body.purs
Normal file
209
src/Mujoco/MJCF/Body.purs
Normal file
@@ -0,0 +1,209 @@
|
||||
module Mujoco.MJCF.Body
|
||||
( CameraMode
|
||||
, CameraOutput
|
||||
, JointType
|
||||
, LightType
|
||||
, Projection
|
||||
, Props_attach
|
||||
, Props_body
|
||||
, Props_camera
|
||||
, Props_frame
|
||||
, Props_freejoint
|
||||
, Props_inertial
|
||||
, Props_joint
|
||||
, Props_light
|
||||
, Props_site
|
||||
, SiteType
|
||||
, SleepPolicy
|
||||
, attach
|
||||
, body
|
||||
, camera
|
||||
, frame
|
||||
, freejoint
|
||||
, inertial
|
||||
, joint
|
||||
, light
|
||||
, site
|
||||
, worldbody
|
||||
, module X
|
||||
) where
|
||||
|
||||
import Mujoco.MJCF.Prelude
|
||||
|
||||
import Mujoco.MJCF.Geom (Props_geom, geom) as X
|
||||
import Mujoco.MJCF.Keyword as Kw
|
||||
|
||||
type SleepPolicy = Kw.Auto \/ Kw.Never \/ Kw.Allowed \/ Kw.Init
|
||||
|
||||
type Props_body =
|
||||
( name :: String
|
||||
, childclass :: String
|
||||
, mocap :: Boolean
|
||||
, pos :: Vec Real
|
||||
, quat :: Vec4 Real
|
||||
, axisangle :: Vec4 Real
|
||||
, xyaxes :: Array Real
|
||||
, zaxis :: Vec Real
|
||||
, euler :: Vec Real
|
||||
, gravcomp :: Real
|
||||
, sleep :: SleepPolicy
|
||||
, user :: Array Real
|
||||
)
|
||||
|
||||
body = tag @Props_body "body" :: Tag Props_body
|
||||
worldbody = tag @Props_body "worldbody" :: Tag Props_body
|
||||
|
||||
type Props_inertial =
|
||||
( pos :: Vec Real
|
||||
, quat :: Vec4 Real
|
||||
, axisangle :: Vec4 Real
|
||||
, xyaxes :: Array Real
|
||||
, zaxis :: Vec Real
|
||||
, euler :: Vec Real
|
||||
, mass :: Real
|
||||
, diaginertia :: Vec Real
|
||||
, fullinertia :: Array Real
|
||||
)
|
||||
|
||||
inertial = tagNoContent @Props_inertial "inertial" :: TagNoContent Props_inertial
|
||||
|
||||
type JointType = Kw.Free \/ Kw.Ball \/ Kw.Slide \/ Kw.Hinge
|
||||
|
||||
type Props_joint =
|
||||
( name :: String
|
||||
, class :: String
|
||||
, type :: JointType
|
||||
, group :: Int
|
||||
, pos :: Vec Real
|
||||
, axis :: Vec Real
|
||||
, springdamper :: Real /\ Real
|
||||
, solreflimit :: Real /\ Real
|
||||
, solimplimit :: Vec5 Real
|
||||
, solreffriction :: Real /\ Real
|
||||
, solimpfriction :: Vec5 Real
|
||||
, stiffness :: Real
|
||||
, range :: Real /\ Real
|
||||
, limited :: Kw.Auto \/ Boolean
|
||||
, actuatorfrcrange :: Real /\ Real
|
||||
, actuatorfrclimited :: Kw.Auto \/ Boolean
|
||||
, actuatorgravcomp :: Boolean
|
||||
, margin :: Real
|
||||
, ref :: Real
|
||||
, springref :: Real
|
||||
, armature :: Real
|
||||
, damping :: Real
|
||||
, frictionloss :: Real
|
||||
, user :: Array Real
|
||||
)
|
||||
|
||||
joint = tagNoContent @Props_joint "joint" :: TagNoContent Props_joint
|
||||
|
||||
type Props_freejoint =
|
||||
( name :: String
|
||||
, group :: Int
|
||||
, align :: Kw.Auto \/ Boolean
|
||||
)
|
||||
|
||||
freejoint = tagNoContent @Props_freejoint "freejoint" :: TagNoContent Props_freejoint
|
||||
|
||||
type SiteType = Kw.Sphere \/ Kw.Capsule \/ Kw.Ellipsoid \/ Kw.Cylinder \/ Kw.Box
|
||||
|
||||
type Props_site =
|
||||
( name :: String
|
||||
, class :: String
|
||||
, type :: SiteType
|
||||
, group :: Int
|
||||
, material :: String
|
||||
, rgba :: Vec4 Real
|
||||
, size :: Vec Real
|
||||
, fromto :: Array Real
|
||||
, pos :: Vec Real
|
||||
, quat :: Vec4 Real
|
||||
, axisangle :: Vec4 Real
|
||||
, xyaxes :: Array Real
|
||||
, zaxis :: Vec Real
|
||||
, euler :: Vec Real
|
||||
, user :: Array Real
|
||||
)
|
||||
|
||||
site = tagNoContent @Props_site "site" :: TagNoContent Props_site
|
||||
|
||||
type CameraMode = Kw.Fixed \/ Kw.Track \/ Kw.Trackcom \/ Kw.Targetbody \/ Kw.Targetbodycom
|
||||
type Projection = Kw.Perspective \/ Kw.Orthographic
|
||||
type CameraOutput = Kw.Rgb \/ Kw.Depth \/ Kw.Distance \/ Kw.Normal \/ Kw.Segmentation
|
||||
|
||||
type Props_camera =
|
||||
( name :: String
|
||||
, class :: String
|
||||
, mode :: CameraMode
|
||||
, target :: String
|
||||
, projection :: Projection
|
||||
, fovy :: Real
|
||||
, resolution :: Int /\ Int
|
||||
, output :: CameraOutput
|
||||
, sensorsize :: Real /\ Real
|
||||
, focal :: Real /\ Real
|
||||
, focalpixel :: Real /\ Real
|
||||
, principal :: Real /\ Real
|
||||
, principalpixel :: Real /\ Real
|
||||
, ipd :: Real
|
||||
, pos :: Vec Real
|
||||
, quat :: Vec4 Real
|
||||
, axisangle :: Vec4 Real
|
||||
, xyaxes :: Array Real
|
||||
, zaxis :: Vec Real
|
||||
, euler :: Vec Real
|
||||
, user :: Array Real
|
||||
)
|
||||
|
||||
camera = tagNoContent @Props_camera "camera" :: TagNoContent Props_camera
|
||||
|
||||
type LightType = Kw.Spot \/ Kw.Directional \/ Kw.Point \/ Kw.Image
|
||||
|
||||
type Props_light =
|
||||
( name :: String
|
||||
, class :: String
|
||||
, mode :: CameraMode
|
||||
, target :: String
|
||||
, type :: LightType
|
||||
, directional :: Boolean
|
||||
, castshadow :: Boolean
|
||||
, active :: Boolean
|
||||
, pos :: Vec Real
|
||||
, dir :: Vec Real
|
||||
, diffuse :: Vec Real
|
||||
, texture :: String
|
||||
, intensity :: Real
|
||||
, ambient :: Vec Real
|
||||
, specular :: Vec Real
|
||||
, range :: Real
|
||||
, bulbradius :: Real
|
||||
, attenuation :: Vec Real
|
||||
, cutoff :: Real
|
||||
, exponent :: Real
|
||||
)
|
||||
|
||||
light = tagNoContent @Props_light "light" :: TagNoContent Props_light
|
||||
|
||||
-- TODO: body/composite reuses row types of joint, geom, site, skin, plugin
|
||||
|
||||
type Props_attach =
|
||||
( model :: String
|
||||
, body :: String
|
||||
, prefix :: String
|
||||
)
|
||||
|
||||
attach = tagNoContent @Props_attach "attach" :: TagNoContent Props_attach
|
||||
|
||||
type Props_frame =
|
||||
( name :: String
|
||||
, childclass :: String
|
||||
, pos :: Vec Real
|
||||
, quat :: Vec4 Real
|
||||
, axisangle :: Vec4 Real
|
||||
, xyaxes :: Array Real
|
||||
, zaxis :: Vec Real
|
||||
, euler :: Vec Real
|
||||
)
|
||||
|
||||
frame = tagNoContent @Props_frame "frame" :: TagNoContent Props_frame
|
||||
27
src/Mujoco/MJCF/Common.purs
Normal file
27
src/Mujoco/MJCF/Common.purs
Normal file
@@ -0,0 +1,27 @@
|
||||
module Mujoco.MJCF.Common
|
||||
( Named
|
||||
, Oriented
|
||||
, Positioned
|
||||
, Real
|
||||
, Vec
|
||||
, Vec4
|
||||
, Vec5
|
||||
) where
|
||||
|
||||
import Data.Tuple.Nested (type (/\))
|
||||
|
||||
type Named r = (name :: String | r)
|
||||
type Positioned r = (pos :: Vec Real | r)
|
||||
type Oriented r =
|
||||
( quat :: Vec4 Real
|
||||
, axisangle :: Vec4 Real
|
||||
, xyaxes :: Array Real
|
||||
, zaxis :: Vec Real
|
||||
, euler :: Vec Real
|
||||
| r
|
||||
)
|
||||
|
||||
type Real = Number
|
||||
type Vec a = a /\ a /\ a
|
||||
type Vec4 a = a /\ a /\ a /\ a
|
||||
type Vec5 a = a /\ a /\ a /\ a /\ a
|
||||
29
src/Mujoco/MJCF/Contact.purs
Normal file
29
src/Mujoco/MJCF/Contact.purs
Normal file
@@ -0,0 +1,29 @@
|
||||
module Mujoco.MJCF.Contact where
|
||||
|
||||
import Mujoco.MJCF.Prelude
|
||||
|
||||
contact = tag @() "contact" :: Tag ()
|
||||
|
||||
type Props_pair =
|
||||
( name :: String
|
||||
, class :: String
|
||||
, geom1 :: String
|
||||
, geom2 :: String
|
||||
, condim :: Int
|
||||
, friction :: Vec5 Real
|
||||
, solref :: Real /\ Real
|
||||
, solimp :: Vec5 Real
|
||||
, solreffriction :: Real /\ Real
|
||||
, margin :: Real
|
||||
, gap :: Real
|
||||
)
|
||||
|
||||
pair = tagNoContent @Props_pair "pair" :: TagNoContent Props_pair
|
||||
|
||||
type Props_exclude =
|
||||
( name :: String
|
||||
, body1 :: String
|
||||
, body2 :: String
|
||||
)
|
||||
|
||||
exclude = tagNoContent @Props_exclude "exclude" :: TagNoContent Props_exclude
|
||||
31
src/Mujoco/MJCF/Custom.purs
Normal file
31
src/Mujoco/MJCF/Custom.purs
Normal file
@@ -0,0 +1,31 @@
|
||||
module Mujoco.MJCF.Custom where
|
||||
|
||||
import Mujoco.MJCF.Prelude
|
||||
|
||||
custom = tag @() "custom" :: Tag ()
|
||||
|
||||
type Props_numeric =
|
||||
( name :: String
|
||||
, size :: Int
|
||||
, data :: Array Real
|
||||
)
|
||||
|
||||
numeric = tagNoContent @Props_numeric "numeric" :: TagNoContent Props_numeric
|
||||
|
||||
type Props_text =
|
||||
( name :: String
|
||||
, data :: String
|
||||
)
|
||||
|
||||
text = tagNoContent @Props_text "text" :: TagNoContent Props_text
|
||||
|
||||
type Props_tuple = (name :: String)
|
||||
tuple = tag @Props_tuple "tuple" :: Tag Props_tuple
|
||||
|
||||
type Props_element =
|
||||
( objtype :: String
|
||||
, objname :: String
|
||||
, prm :: Real
|
||||
)
|
||||
|
||||
element = tagNoContent @Props_element "element" :: TagNoContent Props_element
|
||||
34
src/Mujoco/MJCF/Default.purs
Normal file
34
src/Mujoco/MJCF/Default.purs
Normal file
@@ -0,0 +1,34 @@
|
||||
module Mujoco.MJCF.Default where
|
||||
|
||||
import Mujoco.MJCF.Prelude
|
||||
|
||||
import Mujoco.MJCF.Actuator as Actuator
|
||||
import Mujoco.MJCF.Asset as Asset
|
||||
import Mujoco.MJCF.Body as Body
|
||||
import Mujoco.MJCF.Contact as Contact
|
||||
import Mujoco.MJCF.Equality as Equality
|
||||
import Mujoco.MJCF.Geom as Geom
|
||||
import Mujoco.MJCF.Tendon as Tendon
|
||||
|
||||
type Props_default = (class :: String)
|
||||
default = tag @Props_default "default" :: Tag Props_default
|
||||
|
||||
mesh = tagNoContent @Asset.Props_mesh "mesh" :: TagNoContent Asset.Props_mesh
|
||||
material = tagNoContent @Asset.Props_material "material" :: TagNoContent Asset.Props_material
|
||||
joint = tagNoContent @Body.Props_joint "joint" :: TagNoContent Body.Props_joint
|
||||
geom = tagNoContent @Geom.Props_geom "geom" :: TagNoContent Geom.Props_geom
|
||||
site = tagNoContent @Body.Props_site "site" :: TagNoContent Body.Props_site
|
||||
camera = tagNoContent @Body.Props_camera "camera" :: TagNoContent Body.Props_camera
|
||||
light = tagNoContent @Body.Props_light "light" :: TagNoContent Body.Props_light
|
||||
pair = tagNoContent @Contact.Props_pair "pair" :: TagNoContent Contact.Props_pair
|
||||
equality = tagNoContent @(Equality.Common ()) "equality" :: TagNoContent (Equality.Common ())
|
||||
tendon = tagNoContent @(Tendon.Common ()) "tendon" :: TagNoContent (Tendon.Common ())
|
||||
general = tagNoContent @Actuator.Props_general "general" :: TagNoContent Actuator.Props_general
|
||||
motor = tagNoContent @Actuator.Props_motor "motor" :: TagNoContent Actuator.Props_motor
|
||||
position = tagNoContent @Actuator.Props_position "position" :: TagNoContent Actuator.Props_position
|
||||
velocity = tagNoContent @Actuator.Props_velocity "velocity" :: TagNoContent Actuator.Props_velocity
|
||||
intvelocity = tagNoContent @Actuator.Props_intvelocity "intvelocity" :: TagNoContent Actuator.Props_intvelocity
|
||||
damper = tagNoContent @Actuator.Props_damper "damper" :: TagNoContent Actuator.Props_damper
|
||||
cylinder = tagNoContent @Actuator.Props_cylinder "cylinder" :: TagNoContent Actuator.Props_cylinder
|
||||
muscle = tagNoContent @Actuator.Props_muscle "muscle" :: TagNoContent Actuator.Props_muscle
|
||||
adhesion = tagNoContent @Actuator.Props_adhesion "adhesion" :: TagNoContent Actuator.Props_adhesion
|
||||
71
src/Mujoco/MJCF/Deformable.Flex.purs
Normal file
71
src/Mujoco/MJCF/Deformable.Flex.purs
Normal file
@@ -0,0 +1,71 @@
|
||||
module Mujoco.MJCF.Deformable.Flex where
|
||||
|
||||
import Mujoco.MJCF.Prelude
|
||||
import Mujoco.MJCF.Geom as Geom
|
||||
|
||||
type Props_flex =
|
||||
( name :: String
|
||||
, dim :: Int
|
||||
, radius :: Real
|
||||
, body :: Array String
|
||||
, vertex :: Array Real
|
||||
, texcoord :: Array Real
|
||||
, elemtexcoord :: Array Int
|
||||
, element :: Array Int
|
||||
, flatskin :: Boolean
|
||||
, material :: String
|
||||
, rgba :: Vec4 Real
|
||||
, group :: Int
|
||||
, node :: Array String
|
||||
)
|
||||
|
||||
flex = tag @Props_flex "flex" :: Tag Props_flex
|
||||
|
||||
type Props_edge =
|
||||
( stiffness :: Real
|
||||
, damping :: Real
|
||||
)
|
||||
|
||||
edge = tagNoContent @Props_edge "edge" :: TagNoContent Props_edge
|
||||
|
||||
data Elastic2d = Elastic2dNone | Elastic2dBend | Elastic2dStretch | Elastic2dBoth
|
||||
|
||||
instance Serialize Elastic2d where
|
||||
serialize Elastic2dNone = "none"
|
||||
serialize Elastic2dBend = "bend"
|
||||
serialize Elastic2dStretch = "stretch"
|
||||
serialize Elastic2dBoth = "both"
|
||||
|
||||
type Props_elasticity =
|
||||
( young :: Real
|
||||
, poisson :: Real
|
||||
, damping :: Real
|
||||
, thickness :: Real
|
||||
, elastic2d :: Elastic2d
|
||||
)
|
||||
|
||||
elasticity = tagNoContent @Props_elasticity "elasticity" :: TagNoContent Props_elasticity
|
||||
|
||||
data SelfCollide = SelfCollideNone | SelfCollideNarrow | SelfCollideBvh | SelfCollideSap | SelfCollideAuto
|
||||
|
||||
instance Serialize SelfCollide where
|
||||
serialize SelfCollideNone = "none"
|
||||
serialize SelfCollideNarrow = "narrow"
|
||||
serialize SelfCollideBvh = "bvh"
|
||||
serialize SelfCollideSap = "sap"
|
||||
serialize SelfCollideAuto = "auto"
|
||||
|
||||
type Props_contact =
|
||||
( internal :: Boolean
|
||||
, selfcollide :: SelfCollide
|
||||
, vertcollide :: Boolean
|
||||
, activelayers :: Int
|
||||
, priority :: Int
|
||||
, friction :: Vec Real
|
||||
, passive :: Boolean
|
||||
| Geom.Solver
|
||||
+ Geom.Contact
|
||||
+ Geom.ContactSpacing ()
|
||||
)
|
||||
|
||||
contact = tagNoContent @Props_contact "contact" :: TagNoContent Props_contact
|
||||
27
src/Mujoco/MJCF/Deformable.Skin.purs
Normal file
27
src/Mujoco/MJCF/Deformable.Skin.purs
Normal file
@@ -0,0 +1,27 @@
|
||||
module Mujoco.MJCF.Deformable.Skin where
|
||||
|
||||
import Mujoco.MJCF.Prelude
|
||||
|
||||
type Props_skin =
|
||||
( name :: String
|
||||
, file :: String
|
||||
, vertex :: Array Real
|
||||
, texcoord :: Array Real
|
||||
, face :: Array Int
|
||||
, inflate :: Real
|
||||
, material :: String
|
||||
, rgba :: Vec4 Real
|
||||
, group :: Int
|
||||
)
|
||||
|
||||
skin = tag @Props_skin "skin" :: Tag Props_skin
|
||||
|
||||
type Props_bone =
|
||||
( body :: String
|
||||
, bindpos :: Vec Real
|
||||
, bindquat :: Vec4 Real
|
||||
, vertid :: Array Int
|
||||
, vertweight :: Array Real
|
||||
)
|
||||
|
||||
bone = tagNoContent @Props_bone "bone" :: TagNoContent Props_bone
|
||||
5
src/Mujoco/MJCF/Deformable.purs
Normal file
5
src/Mujoco/MJCF/Deformable.purs
Normal file
@@ -0,0 +1,5 @@
|
||||
module Mujoco.MJCF.Deformable where
|
||||
|
||||
import Mujoco.MJCF.Prelude
|
||||
|
||||
deformable = tag @() "deformable" :: Tag ()
|
||||
69
src/Mujoco/MJCF/Equality.purs
Normal file
69
src/Mujoco/MJCF/Equality.purs
Normal file
@@ -0,0 +1,69 @@
|
||||
module Mujoco.MJCF.Equality where
|
||||
|
||||
import Mujoco.MJCF.Prelude
|
||||
|
||||
type Common r =
|
||||
( class :: String
|
||||
, active :: Boolean
|
||||
, solref :: Real /\ Real
|
||||
, solimp :: Vec5 Real
|
||||
| Named r
|
||||
)
|
||||
|
||||
equality = tag @() "equality" :: Tag ()
|
||||
|
||||
type Props_connect =
|
||||
( body1 :: String
|
||||
, body2 :: String
|
||||
, anchor :: Vec Real
|
||||
, site1 :: String
|
||||
, site2 :: String
|
||||
| Common ()
|
||||
)
|
||||
|
||||
connect = tag @Props_connect "connect" :: Tag Props_connect
|
||||
|
||||
type Props_weld =
|
||||
( body1 :: String
|
||||
, body2 :: String
|
||||
, relpose :: Array Real
|
||||
, anchor :: Vec Real
|
||||
, site1 :: String
|
||||
, site2 :: String
|
||||
, torquescale :: Real
|
||||
| Common ()
|
||||
)
|
||||
|
||||
weld = tagNoContent @Props_weld "weld" :: TagNoContent Props_weld
|
||||
|
||||
type Props_joint =
|
||||
( joint1 :: String
|
||||
, joint2 :: String
|
||||
, polycoef :: Vec5 Real
|
||||
| Common ()
|
||||
)
|
||||
|
||||
joint = tagNoContent @Props_joint "joint" :: TagNoContent Props_joint
|
||||
|
||||
type Props_tendon =
|
||||
( tendon1 :: String
|
||||
, tendon2 :: String
|
||||
, polycoef :: Vec5 Real
|
||||
| Common ()
|
||||
)
|
||||
|
||||
tendon = tagNoContent @Props_tendon "tendon" :: TagNoContent Props_tendon
|
||||
|
||||
type Props_flex =
|
||||
( flex :: String
|
||||
| Common ()
|
||||
)
|
||||
|
||||
flex = tagNoContent @Props_flex "flex" :: TagNoContent Props_flex
|
||||
|
||||
type Props_flexvert =
|
||||
( flex :: String
|
||||
| Common ()
|
||||
)
|
||||
|
||||
flexvert = tagNoContent @Props_flexvert "flexvert" :: TagNoContent Props_flexvert
|
||||
14
src/Mujoco/MJCF/Extension.purs
Normal file
14
src/Mujoco/MJCF/Extension.purs
Normal file
@@ -0,0 +1,14 @@
|
||||
module Mujoco.MJCF.Extension where
|
||||
|
||||
import Mujoco.MJCF.Prelude
|
||||
|
||||
extension = tag @() "extension" :: Tag ()
|
||||
|
||||
type Props_plugin = (plugin :: String)
|
||||
plugin = tag @Props_plugin "plugin" :: Tag Props_plugin
|
||||
|
||||
type Props_instance = (name :: String)
|
||||
instance_ = tag @Props_instance "instance" :: Tag Props_instance
|
||||
|
||||
type Props_config = (key :: String, value :: String)
|
||||
config = tagNoContent @Props_config "config" :: TagNoContent Props_config
|
||||
53
src/Mujoco/MJCF/Geom.purs
Normal file
53
src/Mujoco/MJCF/Geom.purs
Normal file
@@ -0,0 +1,53 @@
|
||||
module Mujoco.MJCF.Geom where
|
||||
|
||||
import Mujoco.MJCF.Prelude
|
||||
import Mujoco.MJCF.Keyword as Kw
|
||||
|
||||
type Contact r =
|
||||
( contype :: Int
|
||||
, conaffinity :: Int
|
||||
, condim :: Int
|
||||
, priority :: Int
|
||||
| r
|
||||
)
|
||||
|
||||
type ContactSpacing r =
|
||||
( margin :: Real
|
||||
, gap :: Real
|
||||
| r
|
||||
)
|
||||
|
||||
type Solver r =
|
||||
( solmix :: Real
|
||||
, solref :: Real /\ Real
|
||||
, solimp :: Vec5 Real
|
||||
| r
|
||||
)
|
||||
|
||||
type Props_geom =
|
||||
( class :: String
|
||||
, type :: Kw.Plane \/ Kw.Hfield \/ Kw.Sphere \/ Kw.Capsule \/ Kw.Ellipsoid \/ Kw.Cylinder \/ Kw.Box \/ Kw.Mesh \/ Kw.Sdf
|
||||
, group :: Int
|
||||
, size :: Array Real
|
||||
, material :: String
|
||||
, rgba :: Vec4 Real
|
||||
, friction :: Vec Real
|
||||
, mass :: Real
|
||||
, density :: Real
|
||||
, shellinertia :: Boolean
|
||||
, fromto :: Array Real
|
||||
, hfield :: String
|
||||
, mesh :: String
|
||||
, fitscale :: Real
|
||||
, fluidshape :: Kw.None \/ Kw.Ellipsoid
|
||||
, fluidcoef :: Vec5 Real
|
||||
, user :: Array Real
|
||||
| Named
|
||||
+ Contact
|
||||
+ ContactSpacing
|
||||
+ Solver
|
||||
+ Positioned
|
||||
+ Oriented ()
|
||||
)
|
||||
|
||||
geom = tag @Props_geom "geom" :: Tag Props_geom
|
||||
18
src/Mujoco/MJCF/Keyframe.purs
Normal file
18
src/Mujoco/MJCF/Keyframe.purs
Normal file
@@ -0,0 +1,18 @@
|
||||
module Mujoco.MJCF.Keyframe where
|
||||
|
||||
import Mujoco.MJCF.Prelude
|
||||
|
||||
keyframe = tag @() "keyframe" :: Tag ()
|
||||
|
||||
type Props_key =
|
||||
( time :: Real
|
||||
, qpos :: Array Real
|
||||
, qvel :: Array Real
|
||||
, act :: Array Real
|
||||
, ctrl :: Array Real
|
||||
, mpos :: Array Real
|
||||
, mquat :: Array Real
|
||||
| Named ()
|
||||
)
|
||||
|
||||
key = tagNoContent @Props_key "key" :: TagNoContent Props_key
|
||||
528
src/Mujoco/MJCF/Keyword.purs
Normal file
528
src/Mujoco/MJCF/Keyword.purs
Normal file
@@ -0,0 +1,528 @@
|
||||
module Mujoco.MJCF.Keyword where
|
||||
|
||||
import Data.Either.Inject (class Inject, inj)
|
||||
import Mujoco.MJCF.XML.Prop (class Serialize)
|
||||
|
||||
kw :: forall kw sum. Inject kw sum => kw -> sum
|
||||
kw = inj
|
||||
|
||||
true_ :: forall sum. Inject Boolean sum => sum
|
||||
true_ = inj true
|
||||
|
||||
false_ :: forall sum. Inject Boolean sum => sum
|
||||
false_ = inj false
|
||||
|
||||
data None = None
|
||||
|
||||
instance Serialize None where
|
||||
serialize None = "none"
|
||||
|
||||
data Integrator = Integrator
|
||||
|
||||
instance Serialize Integrator where
|
||||
serialize Integrator = "integrator"
|
||||
|
||||
data Filter = Filter
|
||||
|
||||
instance Serialize Filter where
|
||||
serialize Filter = "filter"
|
||||
|
||||
data FilterExact = FilterExact
|
||||
|
||||
instance Serialize FilterExact where
|
||||
serialize FilterExact = "filterexact"
|
||||
|
||||
data Muscle = Muscle
|
||||
|
||||
instance Serialize Muscle where
|
||||
serialize Muscle = "muscle"
|
||||
|
||||
data User = User
|
||||
|
||||
instance Serialize User where
|
||||
serialize User = "user"
|
||||
|
||||
data Fixed = Fixed
|
||||
|
||||
instance Serialize Fixed where
|
||||
serialize Fixed = "fixed"
|
||||
|
||||
data Affine = Affine
|
||||
|
||||
instance Serialize Affine where
|
||||
serialize Affine = "affine"
|
||||
|
||||
data Zoh = Zoh
|
||||
|
||||
instance Serialize Zoh where
|
||||
serialize Zoh = "zoh"
|
||||
|
||||
data Linear = Linear
|
||||
|
||||
instance Serialize Linear where
|
||||
serialize Linear = "linear"
|
||||
|
||||
data Cubic = Cubic
|
||||
|
||||
instance Serialize Cubic where
|
||||
serialize Cubic = "cubic"
|
||||
|
||||
data Convex = Convex
|
||||
|
||||
instance Serialize Convex where
|
||||
serialize Convex = "convex"
|
||||
|
||||
data Exact = Exact
|
||||
|
||||
instance Serialize Exact where
|
||||
serialize Exact = "exact"
|
||||
|
||||
data Legacy = Legacy
|
||||
|
||||
instance Serialize Legacy where
|
||||
serialize Legacy = "legacy"
|
||||
|
||||
data Shell = Shell
|
||||
|
||||
instance Serialize Shell where
|
||||
serialize Shell = "shell"
|
||||
|
||||
data TwoD = TwoD
|
||||
|
||||
instance Serialize TwoD where
|
||||
serialize TwoD = "2d"
|
||||
|
||||
data Cube = Cube
|
||||
|
||||
instance Serialize Cube where
|
||||
serialize Cube = "cube"
|
||||
|
||||
data Skybox = Skybox
|
||||
|
||||
instance Serialize Skybox where
|
||||
serialize Skybox = "skybox"
|
||||
|
||||
data SRGB = SRGB
|
||||
|
||||
instance Serialize SRGB where
|
||||
serialize SRGB = "sRGB"
|
||||
|
||||
data Gradient = Gradient
|
||||
|
||||
instance Serialize Gradient where
|
||||
serialize Gradient = "gradient"
|
||||
|
||||
data Checker = Checker
|
||||
|
||||
instance Serialize Checker where
|
||||
serialize Checker = "checker"
|
||||
|
||||
data Flat = Flat
|
||||
|
||||
instance Serialize Flat where
|
||||
serialize Flat = "flat"
|
||||
|
||||
data Edge = Edge
|
||||
|
||||
instance Serialize Edge where
|
||||
serialize Edge = "edge"
|
||||
|
||||
data Cross = Cross
|
||||
|
||||
instance Serialize Cross where
|
||||
serialize Cross = "cross"
|
||||
|
||||
data Random = Random
|
||||
|
||||
instance Serialize Random where
|
||||
serialize Random = "random"
|
||||
|
||||
data Rgb = Rgb
|
||||
|
||||
instance Serialize Rgb where
|
||||
serialize Rgb = "rgb"
|
||||
|
||||
data Normal = Normal
|
||||
|
||||
instance Serialize Normal where
|
||||
serialize Normal = "normal"
|
||||
|
||||
data Occlusion = Occlusion
|
||||
|
||||
instance Serialize Occlusion where
|
||||
serialize Occlusion = "occlusion"
|
||||
|
||||
data Roughness = Roughness
|
||||
|
||||
instance Serialize Roughness where
|
||||
serialize Roughness = "roughness"
|
||||
|
||||
data Metallic = Metallic
|
||||
|
||||
instance Serialize Metallic where
|
||||
serialize Metallic = "metallic"
|
||||
|
||||
data Opacity = Opacity
|
||||
|
||||
instance Serialize Opacity where
|
||||
serialize Opacity = "opacity"
|
||||
|
||||
data Emissive = Emissive
|
||||
|
||||
instance Serialize Emissive where
|
||||
serialize Emissive = "emissive"
|
||||
|
||||
data Orm = Orm
|
||||
|
||||
instance Serialize Orm where
|
||||
serialize Orm = "orm"
|
||||
|
||||
data Rgba = Rgba
|
||||
|
||||
instance Serialize Rgba where
|
||||
serialize Rgba = "rgba"
|
||||
|
||||
data Auto = Auto
|
||||
|
||||
instance Serialize Auto where
|
||||
serialize Auto = "auto"
|
||||
|
||||
data Never = Never
|
||||
|
||||
instance Serialize Never where
|
||||
serialize Never = "never"
|
||||
|
||||
data Allowed = Allowed
|
||||
|
||||
instance Serialize Allowed where
|
||||
serialize Allowed = "allowed"
|
||||
|
||||
data Init = Init
|
||||
|
||||
instance Serialize Init where
|
||||
serialize Init = "init"
|
||||
|
||||
data Free = Free
|
||||
|
||||
instance Serialize Free where
|
||||
serialize Free = "free"
|
||||
|
||||
data Ball = Ball
|
||||
|
||||
instance Serialize Ball where
|
||||
serialize Ball = "ball"
|
||||
|
||||
data Slide = Slide
|
||||
|
||||
instance Serialize Slide where
|
||||
serialize Slide = "slide"
|
||||
|
||||
data Hinge = Hinge
|
||||
|
||||
instance Serialize Hinge where
|
||||
serialize Hinge = "hinge"
|
||||
|
||||
data Sphere = Sphere
|
||||
|
||||
instance Serialize Sphere where
|
||||
serialize Sphere = "sphere"
|
||||
|
||||
data Capsule = Capsule
|
||||
|
||||
instance Serialize Capsule where
|
||||
serialize Capsule = "capsule"
|
||||
|
||||
data Ellipsoid = Ellipsoid
|
||||
|
||||
instance Serialize Ellipsoid where
|
||||
serialize Ellipsoid = "ellipsoid"
|
||||
|
||||
data Cylinder = Cylinder
|
||||
|
||||
instance Serialize Cylinder where
|
||||
serialize Cylinder = "cylinder"
|
||||
|
||||
data Box = Box
|
||||
|
||||
instance Serialize Box where
|
||||
serialize Box = "box"
|
||||
|
||||
data Track = Track
|
||||
|
||||
instance Serialize Track where
|
||||
serialize Track = "track"
|
||||
|
||||
data Trackcom = Trackcom
|
||||
|
||||
instance Serialize Trackcom where
|
||||
serialize Trackcom = "trackcom"
|
||||
|
||||
data Targetbody = Targetbody
|
||||
|
||||
instance Serialize Targetbody where
|
||||
serialize Targetbody = "targetbody"
|
||||
|
||||
data Targetbodycom = Targetbodycom
|
||||
|
||||
instance Serialize Targetbodycom where
|
||||
serialize Targetbodycom = "targetbodycom"
|
||||
|
||||
data Perspective = Perspective
|
||||
|
||||
instance Serialize Perspective where
|
||||
serialize Perspective = "perspective"
|
||||
|
||||
data Orthographic = Orthographic
|
||||
|
||||
instance Serialize Orthographic where
|
||||
serialize Orthographic = "orthographic"
|
||||
|
||||
data Depth = Depth
|
||||
|
||||
instance Serialize Depth where
|
||||
serialize Depth = "depth"
|
||||
|
||||
data Distance = Distance
|
||||
|
||||
instance Serialize Distance where
|
||||
serialize Distance = "distance"
|
||||
|
||||
data Segmentation = Segmentation
|
||||
|
||||
instance Serialize Segmentation where
|
||||
serialize Segmentation = "segmentation"
|
||||
|
||||
data Spot = Spot
|
||||
|
||||
instance Serialize Spot where
|
||||
serialize Spot = "spot"
|
||||
|
||||
data Directional = Directional
|
||||
|
||||
instance Serialize Directional where
|
||||
serialize Directional = "directional"
|
||||
|
||||
data Point = Point
|
||||
|
||||
instance Serialize Point where
|
||||
serialize Point = "point"
|
||||
|
||||
data Image = Image
|
||||
|
||||
instance Serialize Image where
|
||||
serialize Image = "image"
|
||||
|
||||
data Plane = Plane
|
||||
|
||||
instance Serialize Plane where
|
||||
serialize Plane = "plane"
|
||||
|
||||
data Hfield = Hfield
|
||||
|
||||
instance Serialize Hfield where
|
||||
serialize Hfield = "hfield"
|
||||
|
||||
data Mesh = Mesh
|
||||
|
||||
instance Serialize Mesh where
|
||||
serialize Mesh = "mesh"
|
||||
|
||||
data Sdf = Sdf
|
||||
|
||||
instance Serialize Sdf where
|
||||
serialize Sdf = "sdf"
|
||||
|
||||
data Euler = Euler
|
||||
|
||||
instance Serialize Euler where
|
||||
serialize Euler = "Euler"
|
||||
|
||||
data RK4 = RK4
|
||||
|
||||
instance Serialize RK4 where
|
||||
serialize RK4 = "RK4"
|
||||
|
||||
data Implicit = Implicit
|
||||
|
||||
instance Serialize Implicit where
|
||||
serialize Implicit = "implicit"
|
||||
|
||||
data ImplicitFast = ImplicitFast
|
||||
|
||||
instance Serialize ImplicitFast where
|
||||
serialize ImplicitFast = "implicitfast"
|
||||
|
||||
data Pyramidal = Pyramidal
|
||||
|
||||
instance Serialize Pyramidal where
|
||||
serialize Pyramidal = "pyramidal"
|
||||
|
||||
data Elliptic = Elliptic
|
||||
|
||||
instance Serialize Elliptic where
|
||||
serialize Elliptic = "elliptic"
|
||||
|
||||
data Dense = Dense
|
||||
|
||||
instance Serialize Dense where
|
||||
serialize Dense = "dense"
|
||||
|
||||
data Sparse = Sparse
|
||||
|
||||
instance Serialize Sparse where
|
||||
serialize Sparse = "sparse"
|
||||
|
||||
data PGS = PGS
|
||||
|
||||
instance Serialize PGS where
|
||||
serialize PGS = "PGS"
|
||||
|
||||
data CG = CG
|
||||
|
||||
instance Serialize CG where
|
||||
serialize CG = "CG"
|
||||
|
||||
data Newton = Newton
|
||||
|
||||
instance Serialize Newton where
|
||||
serialize Newton = "Newton"
|
||||
|
||||
data Enable = Enable
|
||||
|
||||
instance Serialize Enable where
|
||||
serialize Enable = "enable"
|
||||
|
||||
data Disable = Disable
|
||||
|
||||
instance Serialize Disable where
|
||||
serialize Disable = "disable"
|
||||
|
||||
data Local = Local
|
||||
|
||||
instance Serialize Local where
|
||||
serialize Local = "local"
|
||||
|
||||
data Global = Global
|
||||
|
||||
instance Serialize Global where
|
||||
serialize Global = "global"
|
||||
|
||||
data Radian = Radian
|
||||
|
||||
instance Serialize Radian where
|
||||
serialize Radian = "radian"
|
||||
|
||||
data Degree = Degree
|
||||
|
||||
instance Serialize Degree where
|
||||
serialize Degree = "degree"
|
||||
|
||||
data Dist = Dist
|
||||
|
||||
instance Serialize Dist where
|
||||
serialize Dist = "dist"
|
||||
|
||||
data Dir = Dir
|
||||
|
||||
instance Serialize Dir where
|
||||
serialize Dir = "dir"
|
||||
|
||||
data Origin = Origin
|
||||
|
||||
instance Serialize Origin where
|
||||
serialize Origin = "origin"
|
||||
|
||||
data Body = Body
|
||||
|
||||
instance Serialize Body where
|
||||
serialize Body = "body"
|
||||
|
||||
data Xbody = Xbody
|
||||
|
||||
instance Serialize Xbody where
|
||||
serialize Xbody = "xbody"
|
||||
|
||||
data Geom = Geom
|
||||
|
||||
instance Serialize Geom where
|
||||
serialize Geom = "geom"
|
||||
|
||||
data Site = Site
|
||||
|
||||
instance Serialize Site where
|
||||
serialize Site = "site"
|
||||
|
||||
data Camera = Camera
|
||||
|
||||
instance Serialize Camera where
|
||||
serialize Camera = "camera"
|
||||
|
||||
data Found = Found
|
||||
|
||||
instance Serialize Found where
|
||||
serialize Found = "found"
|
||||
|
||||
data Force = Force
|
||||
|
||||
instance Serialize Force where
|
||||
serialize Force = "force"
|
||||
|
||||
data Torque = Torque
|
||||
|
||||
instance Serialize Torque where
|
||||
serialize Torque = "torque"
|
||||
|
||||
data Pos = Pos
|
||||
|
||||
instance Serialize Pos where
|
||||
serialize Pos = "pos"
|
||||
|
||||
data Vel = Vel
|
||||
|
||||
instance Serialize Vel where
|
||||
serialize Vel = "vel"
|
||||
|
||||
data Acc = Acc
|
||||
|
||||
instance Serialize Acc where
|
||||
serialize Acc = "acc"
|
||||
|
||||
data Tangent = Tangent
|
||||
|
||||
instance Serialize Tangent where
|
||||
serialize Tangent = "tangent"
|
||||
|
||||
data MinDist = MinDist
|
||||
|
||||
instance Serialize MinDist where
|
||||
serialize MinDist = "mindist"
|
||||
|
||||
data MaxForce = MaxForce
|
||||
|
||||
instance Serialize MaxForce where
|
||||
serialize MaxForce = "maxforce"
|
||||
|
||||
data NetForce = NetForce
|
||||
|
||||
instance Serialize NetForce where
|
||||
serialize NetForce = "netforce"
|
||||
|
||||
data Real = Real
|
||||
|
||||
instance Serialize Real where
|
||||
serialize Real = "real"
|
||||
|
||||
data Positive = Positive
|
||||
|
||||
instance Serialize Positive where
|
||||
serialize Positive = "positive"
|
||||
|
||||
data Axis = Axis
|
||||
|
||||
instance Serialize Axis where
|
||||
serialize Axis = "axis"
|
||||
|
||||
data Quaternion = Quaternion
|
||||
|
||||
instance Serialize Quaternion where
|
||||
serialize Quaternion = "quaternion"
|
||||
14
src/Mujoco/MJCF/Meta.purs
Normal file
14
src/Mujoco/MJCF/Meta.purs
Normal file
@@ -0,0 +1,14 @@
|
||||
module Mujoco.MJCF.Meta where
|
||||
|
||||
import Mujoco.MJCF.Prelude
|
||||
|
||||
type Props_frame :: Row Type
|
||||
type Props_frame = ()
|
||||
|
||||
frame = tag @Props_frame "frame" :: Tag Props_frame
|
||||
|
||||
type Props_replicate = (count :: Int, sep :: String, offset :: Vec Number, euler :: Vec Number)
|
||||
replicate = tag @Props_replicate "replicate" :: Tag Props_replicate
|
||||
|
||||
type Props_include = (file :: String)
|
||||
include = tag @Props_include "include" :: Tag Props_include
|
||||
18
src/Mujoco/MJCF/Prelude.purs
Normal file
18
src/Mujoco/MJCF/Prelude.purs
Normal file
@@ -0,0 +1,18 @@
|
||||
module Mujoco.MJCF.Prelude (module X) where
|
||||
|
||||
import Type.Row (type (+)) as X
|
||||
import Prelude (class Applicative, class Apply, class Bind, class BooleanAlgebra, class Bounded, class Category, class CommutativeRing, class Discard, class DivisionRing, class Eq, class EuclideanRing, class Field, class Functor, class HeytingAlgebra, class Monad, class Monoid, class Ord, class Ring, class Semigroup, class Semigroupoid, class Semiring, class Show, type (~>), Ordering(..), Unit, Void, absurd, add, ap, append, apply, between, bind, bottom, clamp, compare, comparing, compose, conj, const, degree, discard, disj, div, eq, flap, flip, gcd, identity, ifM, join, lcm, liftA1, liftM1, map, max, mempty, min, mod, mul, negate, not, notEq, one, otherwise, pure, recip, show, sub, top, unit, unless, unlessM, void, when, whenM, zero, (#), ($), ($>), (&&), (*), (*>), (+), (-), (/), (/=), (<), (<#>), (<$), (<$>), (<*), (<*>), (<<<), (<=), (<=<), (<>), (<@>), (=<<), (==), (>), (>=), (>=>), (>>=), (>>>), (||)) as X
|
||||
import Data.Either.Nested ((\/), type (\/)) as X
|
||||
import Mujoco.MJCF.Common (Named, Oriented, Positioned, Real, Vec, Vec4, Vec5) as X
|
||||
import Mujoco.MJCF.XML
|
||||
( tag
|
||||
, tagNoContent
|
||||
, Tag
|
||||
, TagNoContent
|
||||
) as X
|
||||
|
||||
import Mujoco.MJCF.XML.Prop (class Serialize, serialize) as X
|
||||
|
||||
import Data.Tuple (Tuple(..)) as X
|
||||
import Data.Tuple.Nested (type (/\), (/\)) as X
|
||||
import Data.Maybe (Maybe(..), maybe, fromMaybe) as X
|
||||
241
src/Mujoco/MJCF/Sensor.purs
Normal file
241
src/Mujoco/MJCF/Sensor.purs
Normal file
@@ -0,0 +1,241 @@
|
||||
module Mujoco.MJCF.Sensor where
|
||||
|
||||
import Mujoco.MJCF.Prelude
|
||||
|
||||
import Mujoco.MJCF.Keyword as Kw
|
||||
|
||||
sensor = tag @() "sensor" :: Tag ()
|
||||
|
||||
type ObjType = Kw.Body \/ Kw.Xbody \/ Kw.Geom \/ Kw.Site \/ Kw.Camera
|
||||
|
||||
type Common' r =
|
||||
( noise :: Real
|
||||
, cutoff :: Real
|
||||
, user :: Array Real
|
||||
| Named r
|
||||
)
|
||||
|
||||
type Common r =
|
||||
( nsample :: Int
|
||||
, interval :: Real /\ Real
|
||||
, delay :: Real
|
||||
, interp :: Kw.Zoh \/ Kw.Linear \/ Kw.Cubic
|
||||
| Common' r
|
||||
)
|
||||
|
||||
type Props_touch = Common (site :: String)
|
||||
touch = tagNoContent @Props_touch "touch" :: TagNoContent Props_touch
|
||||
|
||||
type Props_accelerometer = Common (site :: String)
|
||||
accelerometer = tagNoContent @Props_accelerometer "accelerometer" :: TagNoContent Props_accelerometer
|
||||
|
||||
type Props_velocimeter = Common (site :: String)
|
||||
velocimeter = tagNoContent @Props_velocimeter "velocimeter" :: TagNoContent Props_velocimeter
|
||||
|
||||
type Props_gyro = Common (site :: String)
|
||||
gyro = tagNoContent @Props_gyro "gyro" :: TagNoContent Props_gyro
|
||||
|
||||
type Props_force = Common (site :: String)
|
||||
force = tagNoContent @Props_force "force" :: TagNoContent Props_force
|
||||
|
||||
type Props_torque = Common (site :: String)
|
||||
torque = tagNoContent @Props_torque "torque" :: TagNoContent Props_torque
|
||||
|
||||
type Props_magnetometer = Common (site :: String)
|
||||
magnetometer = tagNoContent @Props_magnetometer "magnetometer" :: TagNoContent Props_magnetometer
|
||||
|
||||
type Props_rangefinder =
|
||||
( site :: String
|
||||
, camera :: String
|
||||
, data :: Array (Kw.Dist \/ Kw.Dir \/ Kw.Origin \/ Kw.Point \/ Kw.Normal \/ Kw.Depth)
|
||||
| Common ()
|
||||
)
|
||||
|
||||
rangefinder = tagNoContent @Props_rangefinder "rangefinder" :: TagNoContent Props_rangefinder
|
||||
|
||||
type Props_camprojection = Common (site :: String, camera :: String)
|
||||
camprojection = tagNoContent @Props_camprojection "camprojection" :: TagNoContent Props_camprojection
|
||||
|
||||
type Props_jointpos = Common (joint :: String)
|
||||
jointpos = tagNoContent @Props_jointpos "jointpos" :: TagNoContent Props_jointpos
|
||||
|
||||
type Props_jointvel = Common (joint :: String)
|
||||
jointvel = tagNoContent @Props_jointvel "jointvel" :: TagNoContent Props_jointvel
|
||||
|
||||
type Props_jointactuatorfrc = Common (joint :: String)
|
||||
jointactuatorfrc = tagNoContent @Props_jointactuatorfrc "jointactuatorfrc" :: TagNoContent Props_jointactuatorfrc
|
||||
|
||||
type Props_ballquat = Common (joint :: String)
|
||||
ballquat = tagNoContent @Props_ballquat "ballquat" :: TagNoContent Props_ballquat
|
||||
|
||||
type Props_ballangvel = Common (joint :: String)
|
||||
ballangvel = tagNoContent @Props_ballangvel "ballangvel" :: TagNoContent Props_ballangvel
|
||||
|
||||
type Props_jointlimitpos = Common (joint :: String)
|
||||
jointlimitpos = tagNoContent @Props_jointlimitpos "jointlimitpos" :: TagNoContent Props_jointlimitpos
|
||||
|
||||
type Props_jointlimitvel = Common (joint :: String)
|
||||
jointlimitvel = tagNoContent @Props_jointlimitvel "jointlimitvel" :: TagNoContent Props_jointlimitvel
|
||||
|
||||
type Props_jointlimitfrc = Common (joint :: String)
|
||||
jointlimitfrc = tagNoContent @Props_jointlimitfrc "jointlimitfrc" :: TagNoContent Props_jointlimitfrc
|
||||
|
||||
type Props_tendonpos = Common (tendon :: String)
|
||||
tendonpos = tagNoContent @Props_tendonpos "tendonpos" :: TagNoContent Props_tendonpos
|
||||
|
||||
type Props_tendonvel = Common (tendon :: String)
|
||||
tendonvel = tagNoContent @Props_tendonvel "tendonvel" :: TagNoContent Props_tendonvel
|
||||
|
||||
type Props_tendonactuatorfrc = Common (tendon :: String)
|
||||
tendonactuatorfrc = tagNoContent @Props_tendonactuatorfrc "tendonactuatorfrc" :: TagNoContent Props_tendonactuatorfrc
|
||||
|
||||
type Props_tendonlimitpos = Common (tendon :: String)
|
||||
tendonlimitpos = tagNoContent @Props_tendonlimitpos "tendonlimitpos" :: TagNoContent Props_tendonlimitpos
|
||||
|
||||
type Props_tendonlimitvel = Common (tendon :: String)
|
||||
tendonlimitvel = tagNoContent @Props_tendonlimitvel "tendonlimitvel" :: TagNoContent Props_tendonlimitvel
|
||||
|
||||
type Props_tendonlimitfrc = Common (tendon :: String)
|
||||
tendonlimitfrc = tagNoContent @Props_tendonlimitfrc "tendonlimitfrc" :: TagNoContent Props_tendonlimitfrc
|
||||
|
||||
type Props_actuatorpos = Common (actuator :: String)
|
||||
actuatorpos = tagNoContent @Props_actuatorpos "actuatorpos" :: TagNoContent Props_actuatorpos
|
||||
|
||||
type Props_actuatorvel = Common (actuator :: String)
|
||||
actuatorvel = tagNoContent @Props_actuatorvel "actuatorvel" :: TagNoContent Props_actuatorvel
|
||||
|
||||
type Props_actuatorfrc = Common (actuator :: String)
|
||||
actuatorfrc = tagNoContent @Props_actuatorfrc "actuatorfrc" :: TagNoContent Props_actuatorfrc
|
||||
|
||||
type Frame r =
|
||||
( objtype :: ObjType
|
||||
, objname :: String
|
||||
, reftype :: ObjType
|
||||
, refname :: String
|
||||
| Common r
|
||||
)
|
||||
|
||||
type Props_framepos = Frame ()
|
||||
framepos = tagNoContent @Props_framepos "framepos" :: TagNoContent Props_framepos
|
||||
|
||||
type Props_framequat = Frame ()
|
||||
framequat = tagNoContent @Props_framequat "framequat" :: TagNoContent Props_framequat
|
||||
|
||||
type Props_framexaxis = Frame ()
|
||||
framexaxis = tagNoContent @Props_framexaxis "framexaxis" :: TagNoContent Props_framexaxis
|
||||
|
||||
type Props_frameyaxis = Frame ()
|
||||
frameyaxis = tagNoContent @Props_frameyaxis "frameyaxis" :: TagNoContent Props_frameyaxis
|
||||
|
||||
type Props_framezaxis = Frame ()
|
||||
framezaxis = tagNoContent @Props_framezaxis "framezaxis" :: TagNoContent Props_framezaxis
|
||||
|
||||
type Props_framelinvel = Frame ()
|
||||
framelinvel = tagNoContent @Props_framelinvel "framelinvel" :: TagNoContent Props_framelinvel
|
||||
|
||||
type Props_frameangvel = Frame ()
|
||||
frameangvel = tagNoContent @Props_frameangvel "frameangvel" :: TagNoContent Props_frameangvel
|
||||
|
||||
type Props_framelinacc =
|
||||
( objtype :: ObjType
|
||||
, objname :: String
|
||||
| Common ()
|
||||
)
|
||||
|
||||
framelinacc = tagNoContent @Props_framelinacc "framelinacc" :: TagNoContent Props_framelinacc
|
||||
|
||||
type Props_frameangacc =
|
||||
( objtype :: ObjType
|
||||
, objname :: String
|
||||
| Common ()
|
||||
)
|
||||
|
||||
frameangacc = tagNoContent @Props_frameangacc "frameangacc" :: TagNoContent Props_frameangacc
|
||||
|
||||
type Props_subtreecom = Common (body :: String)
|
||||
subtreecom = tagNoContent @Props_subtreecom "subtreecom" :: TagNoContent Props_subtreecom
|
||||
|
||||
type Props_subtreelinvel = Common (body :: String)
|
||||
subtreelinvel = tagNoContent @Props_subtreelinvel "subtreelinvel" :: TagNoContent Props_subtreelinvel
|
||||
|
||||
type Props_subtreeangmom = Common (body :: String)
|
||||
subtreeangmom = tagNoContent @Props_subtreeangmom "subtreeangmom" :: TagNoContent Props_subtreeangmom
|
||||
|
||||
type Props_insidesite =
|
||||
( objtype :: ObjType
|
||||
, objname :: String
|
||||
, site :: String
|
||||
| Common ()
|
||||
)
|
||||
|
||||
insidesite = tagNoContent @Props_insidesite "insidesite" :: TagNoContent Props_insidesite
|
||||
|
||||
type Collision r = (geom1 :: String, geom2 :: String, body1 :: String, body2 :: String | Common r)
|
||||
|
||||
type Props_distance = Collision ()
|
||||
distance = tagNoContent @Props_distance "distance" :: TagNoContent Props_distance
|
||||
|
||||
type Props_normal = Collision ()
|
||||
normal = tagNoContent @Props_normal "normal" :: TagNoContent Props_normal
|
||||
|
||||
type Props_fromto = Collision ()
|
||||
fromto = tagNoContent @Props_fromto "fromto" :: TagNoContent Props_fromto
|
||||
|
||||
type Props_contact =
|
||||
( subtree1 :: String
|
||||
, subtree2 :: String
|
||||
, site :: String
|
||||
, num :: Int
|
||||
, data :: Array (Kw.Found \/ Kw.Force \/ Kw.Torque \/ Kw.Dist \/ Kw.Pos \/ Kw.Normal \/ Kw.Tangent)
|
||||
, reduce :: Kw.None \/ Kw.MinDist \/ Kw.MaxForce \/ Kw.NetForce
|
||||
| Collision ()
|
||||
)
|
||||
|
||||
contact = tagNoContent @Props_contact "contact" :: TagNoContent Props_contact
|
||||
|
||||
type Props_tactile =
|
||||
( geom :: String
|
||||
, mesh :: String
|
||||
, nsample :: Int
|
||||
, interp :: Kw.Zoh \/ Kw.Linear \/ Kw.Cubic
|
||||
, interval :: Real /\ Real
|
||||
, delay :: Real
|
||||
, user :: Array Real
|
||||
| Named ()
|
||||
)
|
||||
|
||||
tactile = tagNoContent @Props_tactile "tactile" :: TagNoContent Props_tactile
|
||||
|
||||
type Props_e_potential = Common ()
|
||||
e_potential = tagNoContent @Props_e_potential "e_potential" :: TagNoContent Props_e_potential
|
||||
|
||||
type Props_e_kinetic = Common ()
|
||||
e_kinetic = tagNoContent @Props_e_kinetic "e_kinetic" :: TagNoContent Props_e_kinetic
|
||||
|
||||
type Props_clock = Common ()
|
||||
clock = tagNoContent @Props_clock "clock" :: TagNoContent Props_clock
|
||||
|
||||
type Props_user =
|
||||
( objtype :: String
|
||||
, objname :: String
|
||||
, datatype :: Kw.Real \/ Kw.Positive \/ Kw.Axis \/ Kw.Quaternion
|
||||
, needstage :: Kw.Pos \/ Kw.Vel \/ Kw.Acc
|
||||
, dim :: Int
|
||||
| Common' ()
|
||||
)
|
||||
|
||||
user = tagNoContent @Props_user "user" :: TagNoContent Props_user
|
||||
|
||||
type Props_plugin =
|
||||
( plugin :: String
|
||||
, instance :: String
|
||||
, cutoff :: Real
|
||||
, objtype :: ObjType
|
||||
, objname :: String
|
||||
, reftype :: ObjType
|
||||
, refname :: String
|
||||
, user :: Array Real
|
||||
| Named ()
|
||||
)
|
||||
|
||||
plugin = tag @Props_plugin "plugin" :: Tag Props_plugin
|
||||
52
src/Mujoco/MJCF/Tendon.purs
Normal file
52
src/Mujoco/MJCF/Tendon.purs
Normal file
@@ -0,0 +1,52 @@
|
||||
module Mujoco.MJCF.Tendon where
|
||||
|
||||
import Mujoco.MJCF.Prelude
|
||||
|
||||
import Mujoco.MJCF.Keyword as Kw
|
||||
|
||||
tendon = tag @() "tendon" :: Tag ()
|
||||
|
||||
type Common r =
|
||||
( class :: String
|
||||
, group :: Int
|
||||
, limited :: Kw.Auto \/ Boolean
|
||||
, range :: Real /\ Real
|
||||
, solimplimit :: Vec5 Real
|
||||
, solimpfriction :: Vec5 Real
|
||||
, solreflimit :: Real /\ Real
|
||||
, solreffriction :: Real /\ Real
|
||||
, margin :: Real
|
||||
, frictionloss :: Real
|
||||
, springlength :: Real /\ Real
|
||||
, stiffness :: Real
|
||||
, damping :: Real
|
||||
, user :: Array Real
|
||||
| Named r
|
||||
)
|
||||
|
||||
type Props_spatial =
|
||||
( actuatorfrcrange :: Real /\ Real
|
||||
, actuatorfrclimited :: Kw.Auto \/ Boolean
|
||||
, width :: Real
|
||||
, material :: String
|
||||
, rgba :: Vec4 Real
|
||||
, armature :: Real
|
||||
| Common ()
|
||||
)
|
||||
|
||||
spatial = tag @Props_spatial "spatial" :: Tag Props_spatial
|
||||
|
||||
type Props_site = (site :: String)
|
||||
site = tagNoContent @Props_site "site" :: TagNoContent Props_site
|
||||
|
||||
type Props_pulley = (divisor :: Real)
|
||||
pulley = tagNoContent @Props_pulley "pulley" :: TagNoContent Props_pulley
|
||||
|
||||
type Props_geom = (geom :: String, sidesite :: String)
|
||||
geom = tagNoContent @Props_geom "geom" :: TagNoContent Props_geom
|
||||
|
||||
type Props_fixed = Common ()
|
||||
fixed = tag @Props_fixed "fixed" :: Tag Props_fixed
|
||||
|
||||
type Props_joint = (joint :: String, coef :: Real)
|
||||
joint = tagNoContent @Props_joint "joint" :: TagNoContent Props_joint
|
||||
112
src/Mujoco/MJCF/Visual.purs
Normal file
112
src/Mujoco/MJCF/Visual.purs
Normal file
@@ -0,0 +1,112 @@
|
||||
module Mujoco.MJCF.Visual where
|
||||
|
||||
import Mujoco.MJCF.Prelude
|
||||
|
||||
visual = tag @() "visual" :: Tag ()
|
||||
|
||||
type Props_global =
|
||||
( cameraid :: Int
|
||||
, orthographic :: Boolean
|
||||
, fovy :: Real
|
||||
, ipd :: Real
|
||||
, azimuth :: Real
|
||||
, elevation :: Real
|
||||
, linewidth :: Real
|
||||
, glow :: Real
|
||||
, realtime :: Real
|
||||
, offwidth :: Int
|
||||
, offheight :: Int
|
||||
, ellipsoidinertia :: Boolean
|
||||
, bvactive :: Boolean
|
||||
)
|
||||
|
||||
global = tagNoContent @Props_global "global" :: TagNoContent Props_global
|
||||
|
||||
type Props_quality =
|
||||
( shadowsize :: Int
|
||||
, offsamples :: Int
|
||||
, numslices :: Int
|
||||
, numstacks :: Int
|
||||
, numquads :: Int
|
||||
)
|
||||
|
||||
quality = tagNoContent @Props_quality "quality" :: TagNoContent Props_quality
|
||||
|
||||
type Props_headlight =
|
||||
( ambient :: Vec Real
|
||||
, diffuse :: Vec Real
|
||||
, specular :: Vec Real
|
||||
, active :: Int
|
||||
)
|
||||
|
||||
headlight = tagNoContent @Props_headlight "headlight" :: TagNoContent Props_headlight
|
||||
|
||||
type Props_map =
|
||||
( stiffness :: Real
|
||||
, stiffnessrot :: Real
|
||||
, force :: Real
|
||||
, torque :: Real
|
||||
, alpha :: Real
|
||||
, fogstart :: Real
|
||||
, fogend :: Real
|
||||
, znear :: Real
|
||||
, zfar :: Real
|
||||
, haze :: Real
|
||||
, shadowclip :: Real
|
||||
, shadowscale :: Real
|
||||
, actuatortendon :: Real
|
||||
)
|
||||
|
||||
map = tagNoContent @Props_map "map" :: TagNoContent Props_map
|
||||
|
||||
type Props_scale =
|
||||
( forcewidth :: Real
|
||||
, contactwidth :: Real
|
||||
, contactheight :: Real
|
||||
, connect :: Real
|
||||
, com :: Real
|
||||
, camera :: Real
|
||||
, light :: Real
|
||||
, selectpoint :: Real
|
||||
, jointlength :: Real
|
||||
, jointwidth :: Real
|
||||
, actuatorlength :: Real
|
||||
, actuatorwidth :: Real
|
||||
, framelength :: Real
|
||||
, framewidth :: Real
|
||||
, constraint :: Real
|
||||
, slidercrank :: Real
|
||||
, frustum :: Real
|
||||
)
|
||||
|
||||
scale = tagNoContent @Props_scale "scale" :: TagNoContent Props_scale
|
||||
|
||||
type Props_rgba =
|
||||
( fog :: Vec4 Real
|
||||
, haze :: Vec4 Real
|
||||
, force :: Vec4 Real
|
||||
, inertia :: Vec4 Real
|
||||
, joint :: Vec4 Real
|
||||
, actuator :: Vec4 Real
|
||||
, actuatornegative :: Vec4 Real
|
||||
, actuatorpositive :: Vec4 Real
|
||||
, com :: Vec4 Real
|
||||
, camera :: Vec4 Real
|
||||
, light :: Vec4 Real
|
||||
, selectpoint :: Vec4 Real
|
||||
, connect :: Vec4 Real
|
||||
, contactpoint :: Vec4 Real
|
||||
, contactforce :: Vec4 Real
|
||||
, contactfriction :: Vec4 Real
|
||||
, contacttorque :: Vec4 Real
|
||||
, contactgap :: Vec4 Real
|
||||
, rangefinder :: Vec4 Real
|
||||
, constraint :: Vec4 Real
|
||||
, slidercrank :: Vec4 Real
|
||||
, crankbroken :: Vec4 Real
|
||||
, frustum :: Vec4 Real
|
||||
, bv :: Vec4 Real
|
||||
, bvactive :: Vec4 Real
|
||||
)
|
||||
|
||||
rgba = tagNoContent @Props_rgba "rgba" :: TagNoContent Props_rgba
|
||||
@@ -1,20 +1,28 @@
|
||||
module Mujoco.XML.Node.Prop (class Serialize, serialize, serializeProps, class SerializeProps', serializeProps') where
|
||||
module Mujoco.MJCF.XML.Prop (class Serialize, serialize, serializeProps, class SerializeProps', serializeProps', renames) where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Array as Array
|
||||
import Data.Either (Either, either)
|
||||
import Data.Int as Int
|
||||
import Data.Number.Format (toString) as Number
|
||||
import Data.Map (Map)
|
||||
import Data.Map as Map
|
||||
import Data.Maybe (fromMaybe)
|
||||
import Data.Number.Format (precision)
|
||||
import Data.Number.Format (toString, toStringWith) as Number
|
||||
import Data.Symbol (class IsSymbol, reflectSymbol)
|
||||
import Data.Tuple (Tuple)
|
||||
import Data.Tuple.Nested ((/\))
|
||||
import Prim.Row (class Cons, class Union)
|
||||
import Prim.RowList (class RowToList, RowList)
|
||||
import Prim.RowList as RL
|
||||
import Record.Unsafe (unsafeSet, unsafeHas, unsafeGet) as Record
|
||||
import Record.Unsafe (unsafeDelete, unsafeGet, unsafeHas, unsafeSet) as Record
|
||||
import Type.Prelude (Proxy(..))
|
||||
import Unsafe.Coerce (unsafeCoerce)
|
||||
|
||||
renames :: Map String String
|
||||
renames = Map.fromFoldable [ "size" /\ "mjcf:size", "class" /\ "mjcf:class" ]
|
||||
|
||||
class Serialize a where
|
||||
serialize :: a -> String
|
||||
|
||||
@@ -23,19 +31,21 @@ instance Serialize String where
|
||||
else instance Serialize Int where
|
||||
serialize = Int.toStringAs Int.decimal
|
||||
else instance Serialize Number where
|
||||
serialize = Number.toString
|
||||
serialize = Number.toStringWith (precision 5)
|
||||
else instance Serialize Boolean where
|
||||
serialize = show
|
||||
else instance (Serialize a, Serialize b) => Serialize (Either a b) where
|
||||
serialize = either serialize serialize
|
||||
else instance Serialize a => Serialize (Array a) where
|
||||
serialize = Array.intercalate " " <<< map serialize
|
||||
else instance (Serialize a, Serialize b) => Serialize (Tuple a b) where
|
||||
serialize (a /\ b) = serialize [serialize a, serialize b]
|
||||
serialize (a /\ b) = serialize [ serialize a, serialize b ]
|
||||
|
||||
serializeProps :: forall @props part missing propsrl. RowToList props propsrl => SerializeProps' props propsrl => Union part missing props => Record part -> {}
|
||||
serializeProps =
|
||||
(unsafeCoerce :: Record props -> {})
|
||||
<<< serializeProps' @props @propsrl
|
||||
<<< (unsafeCoerce :: Record part -> Record props)
|
||||
<<< serializeProps' @props @propsrl
|
||||
<<< (unsafeCoerce :: Record part -> Record props)
|
||||
|
||||
class SerializeProps' :: Row Type -> RowList Type -> Constraint
|
||||
class SerializeProps' p prl | prl -> p where
|
||||
@@ -48,23 +58,32 @@ instance
|
||||
, Cons k v p' p
|
||||
, SerializeProps' p' prl'
|
||||
, Serialize v
|
||||
) => SerializeProps' p (RL.Cons k v prl') where
|
||||
) =>
|
||||
SerializeProps' p (RL.Cons k v prl') where
|
||||
serializeProps' =
|
||||
patchUnsafe @k serialize
|
||||
<<< remember @k
|
||||
<<< serializeProps' @p' @prl'
|
||||
<<< forget @k
|
||||
<<< remember @k
|
||||
<<< serializeProps' @p' @prl'
|
||||
<<< forget @k
|
||||
|
||||
instance SerializeProps' () RL.Nil where
|
||||
serializeProps' = identity
|
||||
|
||||
patchUnsafe :: forall (@k :: Symbol) a b @r @lacksK. IsSymbol k => Cons k a lacksK r => (a -> b) -> Record r -> Record r
|
||||
patchUnsafe f r =
|
||||
let
|
||||
k = reflectSymbol $ Proxy @k
|
||||
k' = reflectSymbol $ Proxy @k
|
||||
k = fromMaybe k' $ Map.lookup k' renames
|
||||
btoa = unsafeCoerce :: b -> a
|
||||
newValue _ = btoa $ f $ Record.unsafeGet k' r
|
||||
maybeWasRenamed
|
||||
| k' /= k = Record.unsafeDelete k'
|
||||
| otherwise = identity
|
||||
in
|
||||
if Record.unsafeHas k r then
|
||||
Record.unsafeSet k (btoa $ f $ Record.unsafeGet k r) r
|
||||
if Record.unsafeHas k' r then
|
||||
maybeWasRenamed
|
||||
$ Record.unsafeSet k (newValue unit)
|
||||
$ r
|
||||
else
|
||||
r
|
||||
|
||||
4
src/Mujoco/MJCF/XML.js
Normal file
4
src/Mujoco/MJCF/XML.js
Normal file
@@ -0,0 +1,4 @@
|
||||
import ReactDOM from 'react-dom/server.js'
|
||||
|
||||
/** @type {(node: import('react').ReactElement) => String} */
|
||||
export const renderToString = el => ReactDOM.renderToStaticMarkup(el)
|
||||
@@ -1,4 +1,4 @@
|
||||
module Mujoco.XML.Node
|
||||
module Mujoco.MJCF.XML
|
||||
( Node
|
||||
, render
|
||||
, tag
|
||||
@@ -8,34 +8,50 @@ module Mujoco.XML.Node
|
||||
, fragment
|
||||
, empty
|
||||
, text
|
||||
, Tag
|
||||
, TagNoContent
|
||||
) where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.FoldableWithIndex (foldlWithIndex)
|
||||
import Data.Map (Map)
|
||||
import Data.Map as Map
|
||||
import Data.String as String
|
||||
import Data.Tuple as Tuple
|
||||
import Data.Tuple.Nested ((/\))
|
||||
import Elmish.HTML (empty, fragment, text) as HTML
|
||||
import Elmish.HTML.Internal (tag, tagNoContent) as HTML
|
||||
import Elmish.React (ReactElement)
|
||||
import Elmish.React as React
|
||||
import Mujoco.XML.Node.Prop (class SerializeProps', serializeProps)
|
||||
import Mujoco.MJCF.XML.Prop (class SerializeProps', serializeProps)
|
||||
import Mujoco.MJCF.XML.Prop as Prop
|
||||
import Prim.Row (class Union)
|
||||
import Prim.RowList (class RowToList)
|
||||
import Unsafe.Coerce (unsafeCoerce)
|
||||
|
||||
type Tag props
|
||||
= forall r missing a propsrl
|
||||
unrenames :: Map String String
|
||||
unrenames =
|
||||
let
|
||||
props = Map.fromFoldable $ map Tuple.swap $ (Map.toUnfoldable Prop.renames :: Array _)
|
||||
tags = Map.fromFoldable [ "mjcf:option" /\ "option" ]
|
||||
in
|
||||
Map.union props tags
|
||||
|
||||
foreign import renderToString :: ReactElement -> String
|
||||
|
||||
type Tag props =
|
||||
forall r missing a propsrl
|
||||
. Children a
|
||||
=> Union r missing props
|
||||
=> React.ValidReactProps (Record r)
|
||||
=> RowToList props propsrl
|
||||
=> SerializeProps' props propsrl
|
||||
=> Record r
|
||||
-> a
|
||||
-> Node
|
||||
|
||||
type TagNoContent props
|
||||
= forall r missing propsrl
|
||||
type TagNoContent props =
|
||||
forall r missing propsrl
|
||||
. Union r missing props
|
||||
=> React.ValidReactProps (Record r)
|
||||
=> RowToList props propsrl
|
||||
=> SerializeProps' props propsrl
|
||||
=> Record r
|
||||
@@ -44,7 +60,15 @@ type TagNoContent props
|
||||
foreign import data Node :: Type
|
||||
|
||||
render :: Node -> String
|
||||
render = React.renderToString <<< toReact
|
||||
render =
|
||||
let
|
||||
unrename str =
|
||||
foldlWithIndex unrename' str unrenames
|
||||
|
||||
unrename' from str to =
|
||||
String.replaceAll (String.Pattern from) (String.Replacement to) str
|
||||
in
|
||||
unrename <<< renderToString <<< toReact
|
||||
|
||||
fromReact :: ReactElement -> Node
|
||||
fromReact = unsafeCoerce
|
||||
@@ -57,13 +81,12 @@ tag
|
||||
. RowToList props propsrl
|
||||
=> SerializeProps' props propsrl
|
||||
=> String
|
||||
-> ( forall r missing a.
|
||||
Union r missing props
|
||||
=> Children a
|
||||
=> React.ValidReactProps (Record r)
|
||||
=> Record r
|
||||
-> a
|
||||
-> Node
|
||||
-> ( forall r missing a
|
||||
. Union r missing props
|
||||
=> Children a
|
||||
=> Record r
|
||||
-> a
|
||||
-> Node
|
||||
)
|
||||
tag el p a = fromReact $ HTML.tag el (serializeProps @props p) $ toReact <$> asChildren a
|
||||
|
||||
@@ -72,11 +95,10 @@ tagNoContent
|
||||
. RowToList props propsrl
|
||||
=> SerializeProps' props propsrl
|
||||
=> String
|
||||
-> ( forall r missing.
|
||||
Union r missing props
|
||||
=> React.ValidReactProps (Record r)
|
||||
=> Record r
|
||||
-> Node
|
||||
-> ( forall r missing
|
||||
. Union r missing props
|
||||
=> Record r
|
||||
-> Node
|
||||
)
|
||||
tagNoContent el p = fromReact $ HTML.tagNoContent el (serializeProps @props p)
|
||||
|
||||
@@ -92,7 +114,14 @@ text = fromReact <<< HTML.text
|
||||
class Children a where
|
||||
asChildren :: a -> Array Node
|
||||
|
||||
instance Children (Array Node) where asChildren = identity
|
||||
instance Children String where asChildren s = [ unsafeCoerce s ]
|
||||
instance Children Node where asChildren e = [ e ]
|
||||
instance Children Unit where asChildren _ = []
|
||||
instance Children (Array Node) where
|
||||
asChildren = identity
|
||||
|
||||
instance Children String where
|
||||
asChildren s = [ unsafeCoerce s ]
|
||||
|
||||
instance Children Node where
|
||||
asChildren e = [ e ]
|
||||
|
||||
instance Children Unit where
|
||||
asChildren _ = []
|
||||
@@ -3,11 +3,41 @@ module Test.Main where
|
||||
import Prelude
|
||||
|
||||
import Effect (Effect)
|
||||
import Test.Mujoco.XML.Node.Prop as Test.Mujoco.XML.Node.Prop
|
||||
import Effect.Aff (launchAff_)
|
||||
import Effect.Class (liftEffect)
|
||||
import Mujoco.Wasm as Wasm
|
||||
import Test.Mujoco.MJCF as Test.Mujoco.MJCF
|
||||
import Test.Mujoco.MJCF.Actuator as Test.Mujoco.MJCF.Actuator
|
||||
import Test.Mujoco.MJCF.Contact as Test.Mujoco.MJCF.Contact
|
||||
import Test.Mujoco.MJCF.Custom as Test.Mujoco.MJCF.Custom
|
||||
import Test.Mujoco.MJCF.Default as Test.Mujoco.MJCF.Default
|
||||
import Test.Mujoco.MJCF.Deformable as Test.Mujoco.MJCF.Deformable
|
||||
import Test.Mujoco.MJCF.Equality as Test.Mujoco.MJCF.Equality
|
||||
import Test.Mujoco.MJCF.Keyframe as Test.Mujoco.MJCF.Keyframe
|
||||
import Test.Mujoco.MJCF.Sensor as Test.Mujoco.MJCF.Sensor
|
||||
import Test.Mujoco.MJCF.Tendon as Test.Mujoco.MJCF.Tendon
|
||||
import Test.Mujoco.MJCF.Util (mjcf)
|
||||
import Test.Mujoco.MJCF.Visual as Test.Mujoco.MJCF.Visual
|
||||
import Test.Mujoco.MJCF.XML.Prop as Test.Mujoco.MJCF.XML.Prop
|
||||
import Test.Spec.Reporter.Console (consoleReporter)
|
||||
import Test.Spec.Runner.Node (runSpecAndExitProcess)
|
||||
|
||||
main :: Effect Unit
|
||||
main =
|
||||
runSpecAndExitProcess [consoleReporter] do
|
||||
Test.Mujoco.XML.Node.Prop.spec
|
||||
launchAff_ do
|
||||
mj <- Wasm.loadMujoco
|
||||
liftEffect
|
||||
$ runSpecAndExitProcess [consoleReporter]
|
||||
$ mjcf mj do
|
||||
Test.Mujoco.MJCF.spec
|
||||
Test.Mujoco.MJCF.XML.Prop.spec
|
||||
Test.Mujoco.MJCF.Actuator.spec
|
||||
Test.Mujoco.MJCF.Contact.spec
|
||||
Test.Mujoco.MJCF.Custom.spec
|
||||
Test.Mujoco.MJCF.Deformable.spec
|
||||
Test.Mujoco.MJCF.Default.spec
|
||||
Test.Mujoco.MJCF.Equality.spec
|
||||
Test.Mujoco.MJCF.Keyframe.spec
|
||||
Test.Mujoco.MJCF.Sensor.spec
|
||||
Test.Mujoco.MJCF.Tendon.spec
|
||||
Test.Mujoco.MJCF.Visual.spec
|
||||
|
||||
102
test/Mujoco.MJCF.Actuator.purs
Normal file
102
test/Mujoco.MJCF.Actuator.purs
Normal file
@@ -0,0 +1,102 @@
|
||||
module Test.Mujoco.MJCF.Actuator where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Tuple.Nested ((/\))
|
||||
import Mujoco.MJCF as X
|
||||
import Mujoco.MJCF.Actuator as Act
|
||||
import Mujoco.MJCF.XML (Node)
|
||||
import Test.Mujoco.MJCF.Util (MjcfSpec, parseOk)
|
||||
import Test.Spec (describe, it)
|
||||
|
||||
-- | Model with a body + hinge joint for actuator tests
|
||||
m :: Node -> Node
|
||||
m a = X.mujoco {}
|
||||
[ X.compiler { inertiafromgeom: X.true_ }
|
||||
, X.worldbody {}
|
||||
[ X.body { name: "b1", pos: 0.0 /\ 0.0 /\ 0.5 }
|
||||
[ X.joint { name: "j1", type: X.kw X.Hinge, axis: 1.0 /\ 0.0 /\ 0.0 }
|
||||
, X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit
|
||||
]
|
||||
]
|
||||
, a
|
||||
]
|
||||
|
||||
spec :: MjcfSpec Unit
|
||||
spec =
|
||||
describe "actuator" do
|
||||
describe "general" do
|
||||
it "basic" $ parseOk $ m $
|
||||
Act.actuator {} [ Act.general { name: "a_gen", joint: "j1" } ]
|
||||
|
||||
it "dyntype + gaintype + biastype" $ parseOk $ m $
|
||||
Act.actuator {}
|
||||
[ Act.general { name: "a_gen2", joint: "j1", dyntype: X.kw X.Filter, gaintype: X.kw X.Fixed, biastype: X.kw X.Affine } ]
|
||||
|
||||
it "ctrlrange + forcerange" $ parseOk $ m $
|
||||
Act.actuator {}
|
||||
[ Act.general { name: "a_gen3", joint: "j1", ctrllimited: X.true_, ctrlrange: (-1.0) /\ 1.0, forcelimited: X.true_, forcerange: (-100.0) /\ 100.0 } ]
|
||||
|
||||
describe "motor" do
|
||||
it "basic" $ parseOk $ m $
|
||||
Act.actuator {} [ Act.motor { name: "a_motor", joint: "j1" } ]
|
||||
|
||||
it "ctrlrange + gear" $ parseOk $ m $
|
||||
Act.actuator {}
|
||||
[ Act.motor { name: "a_motor2", joint: "j1", ctrllimited: X.true_, ctrlrange: (-1.0) /\ 1.0, gear: [ 100.0, 0.0, 0.0, 0.0, 0.0, 0.0 ] } ]
|
||||
|
||||
describe "position" do
|
||||
it "basic" $ parseOk $ m $
|
||||
Act.actuator {} [ Act.position { name: "a_pos", joint: "j1" } ]
|
||||
|
||||
it "kp + kv" $ parseOk $ m $
|
||||
Act.actuator {}
|
||||
[ Act.position { name: "a_pos2", joint: "j1", kp: 100.0, kv: 10.0 } ]
|
||||
|
||||
describe "velocity" do
|
||||
it "basic" $ parseOk $ m $
|
||||
Act.actuator {} [ Act.velocity { name: "a_vel", joint: "j1" } ]
|
||||
|
||||
it "kv" $ parseOk $ m $
|
||||
Act.actuator {}
|
||||
[ Act.velocity { name: "a_vel2", joint: "j1", kv: 10.0 } ]
|
||||
|
||||
describe "intvelocity" do
|
||||
it "basic" $ parseOk $ m $
|
||||
Act.actuator {} [ Act.intvelocity { name: "a_iv", joint: "j1" } ]
|
||||
|
||||
it "kp + actrange" $ parseOk $ m $
|
||||
Act.actuator {}
|
||||
[ Act.intvelocity { name: "a_iv2", joint: "j1", kp: 100.0, actrange: (-1.0) /\ 1.0 } ]
|
||||
|
||||
describe "damper" do
|
||||
it "basic" $ parseOk $ m $
|
||||
Act.actuator {} [ Act.damper { name: "a_damp", joint: "j1" } ]
|
||||
|
||||
it "kv" $ parseOk $ m $
|
||||
Act.actuator {}
|
||||
[ Act.damper { name: "a_damp2", joint: "j1", kv: 10.0 } ]
|
||||
|
||||
describe "cylinder" do
|
||||
it "basic" $ parseOk $ m $
|
||||
Act.actuator {} [ Act.cylinder { name: "a_cyl", joint: "j1" } ]
|
||||
|
||||
it "timeconst + area" $ parseOk $ m $
|
||||
Act.actuator {}
|
||||
[ Act.cylinder { name: "a_cyl2", joint: "j1", timeconst: 0.1, area: 0.01 } ]
|
||||
|
||||
describe "muscle" do
|
||||
it "basic" $ parseOk $ m $
|
||||
Act.actuator {} [ Act.muscle { name: "a_musc", joint: "j1" } ]
|
||||
|
||||
it "force + range + timeconst" $ parseOk $ m $
|
||||
Act.actuator {}
|
||||
[ Act.muscle { name: "a_musc2", joint: "j1", force: 100.0, range: 0.75 /\ 1.05, timeconst: 0.01 /\ 0.04 } ]
|
||||
|
||||
describe "adhesion" do
|
||||
it "basic" $ parseOk $ m $
|
||||
Act.actuator {} [ Act.adhesion { name: "a_adh", body: "b1" } ]
|
||||
|
||||
it "gain" $ parseOk $ m $
|
||||
Act.actuator {}
|
||||
[ Act.adhesion { name: "a_adh2", body: "b1", gain: 1.0 } ]
|
||||
47
test/Mujoco.MJCF.Contact.purs
Normal file
47
test/Mujoco.MJCF.Contact.purs
Normal file
@@ -0,0 +1,47 @@
|
||||
module Test.Mujoco.MJCF.Contact where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Tuple.Nested ((/\))
|
||||
import Mujoco.MJCF as X
|
||||
import Test.Mujoco.MJCF.Util (MjcfSpec, parseOk)
|
||||
import Test.Spec (describe, it)
|
||||
|
||||
spec :: MjcfSpec Unit
|
||||
spec =
|
||||
describe "contact" do
|
||||
describe "pair" do
|
||||
it "geom1 + geom2" $ parseOk $ X.mujoco {}
|
||||
[ X.worldbody {}
|
||||
[ X.geom { name: "g1", type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit
|
||||
, X.geom { name: "g2", type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ], pos: 1.0 /\ 0.0 /\ 0.0 } unit
|
||||
]
|
||||
, X.contact {} [ X.pair { geom1: "g1", geom2: "g2" } ]
|
||||
]
|
||||
|
||||
it "condim + friction" $ parseOk $ X.mujoco {}
|
||||
[ X.worldbody {}
|
||||
[ X.geom { name: "g1", type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit
|
||||
, X.geom { name: "g2", type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ], pos: 1.0 /\ 0.0 /\ 0.0 } unit
|
||||
]
|
||||
, X.contact {} [ X.pair { geom1: "g1", geom2: "g2", condim: 3, friction: 1.0 /\ 0.005 /\ 0.0001 /\ 0.005 /\ 0.0001 } ]
|
||||
]
|
||||
|
||||
it "solref + solimp + margin + gap" $ parseOk $ X.mujoco {}
|
||||
[ X.worldbody {}
|
||||
[ X.geom { name: "g1", type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit
|
||||
, X.geom { name: "g2", type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ], pos: 1.0 /\ 0.0 /\ 0.0 } unit
|
||||
]
|
||||
, X.contact {} [ X.pair { geom1: "g1", geom2: "g2", solref: 0.02 /\ 1.0, solimp: 0.9 /\ 0.95 /\ 0.001 /\ 0.5 /\ 2.0, margin: 0.01, gap: 0.0 } ]
|
||||
]
|
||||
|
||||
describe "exclude" do
|
||||
it "body1 + body2" $ parseOk $ X.mujoco {}
|
||||
[ X.worldbody {}
|
||||
[ X.body { name: "b1", pos: 0.0 /\ 0.0 /\ 0.0 }
|
||||
[ X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit ]
|
||||
, X.body { name: "b2", pos: 1.0 /\ 0.0 /\ 0.0 }
|
||||
[ X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit ]
|
||||
]
|
||||
, X.contact {} [ X.exclude { body1: "b1", body2: "b2" } ]
|
||||
]
|
||||
50
test/Mujoco.MJCF.Custom.purs
Normal file
50
test/Mujoco.MJCF.Custom.purs
Normal file
@@ -0,0 +1,50 @@
|
||||
module Test.Mujoco.MJCF.Custom where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Mujoco.MJCF as X
|
||||
import Mujoco.MJCF.Custom as Custom
|
||||
import Test.Mujoco.MJCF.Util (MjcfSpec, parseOk)
|
||||
import Test.Spec (describe, it)
|
||||
|
||||
spec :: MjcfSpec Unit
|
||||
spec =
|
||||
describe "custom" do
|
||||
describe "numeric" do
|
||||
it "name + data" $ parseOk $ X.mujoco {}
|
||||
[ Custom.custom {}
|
||||
[ Custom.numeric { name: "params", data: [ 1.0, 2.0, 3.0 ] } ]
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
it "name + size" $ parseOk $ X.mujoco {}
|
||||
[ Custom.custom {}
|
||||
[ Custom.numeric { name: "zeros", size: 5 } ]
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
describe "text" do
|
||||
it "name + data" $ parseOk $ X.mujoco {}
|
||||
[ Custom.custom {}
|
||||
[ Custom.text { name: "info", data: "hello world" } ]
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
describe "tuple" do
|
||||
it "with elements" $ parseOk $ X.mujoco {}
|
||||
[ Custom.custom {}
|
||||
[ Custom.tuple { name: "body_list" }
|
||||
[ Custom.element { objtype: "body", objname: "world", prm: 1.0 } ]
|
||||
]
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
describe "mixed" do
|
||||
it "numeric + text + tuple" $ parseOk $ X.mujoco {}
|
||||
[ Custom.custom {}
|
||||
[ Custom.numeric { name: "n1", data: [ 0.0 ] }
|
||||
, Custom.text { name: "t1", data: "value" }
|
||||
, Custom.tuple { name: "tup1" } unit
|
||||
]
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
87
test/Mujoco.MJCF.Default.purs
Normal file
87
test/Mujoco.MJCF.Default.purs
Normal file
@@ -0,0 +1,87 @@
|
||||
module Test.Mujoco.MJCF.Default where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Tuple.Nested ((/\))
|
||||
import Mujoco.MJCF as X
|
||||
import Mujoco.MJCF.Default as Def
|
||||
import Test.Mujoco.MJCF.Util (MjcfSpec, parseOk)
|
||||
import Test.Spec (describe, it)
|
||||
|
||||
spec :: MjcfSpec Unit
|
||||
spec =
|
||||
describe "default" do
|
||||
it "empty" $ parseOk $ X.mujoco {}
|
||||
[ Def.default {} unit
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
it "with class" $ parseOk $ X.mujoco {}
|
||||
[ Def.default { class: "main" } unit
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
it "geom defaults" $ parseOk $ X.mujoco {}
|
||||
[ Def.default {}
|
||||
[ Def.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ], rgba: 1.0 /\ 0.0 /\ 0.0 /\ 1.0 } ]
|
||||
, X.worldbody {}
|
||||
[ X.geom {} unit ]
|
||||
]
|
||||
|
||||
it "joint defaults" $ parseOk $ X.mujoco {}
|
||||
[ X.compiler { inertiafromgeom: X.true_ }
|
||||
, Def.default {}
|
||||
[ Def.joint { type: X.kw X.Hinge, damping: 1.0, stiffness: 10.0 }
|
||||
, Def.geom { type: X.kw X.Capsule, size: [ 0.05, 0.2 ] }
|
||||
]
|
||||
, X.worldbody {}
|
||||
[ X.body { pos: 0.0 /\ 0.0 /\ 0.5 }
|
||||
[ X.joint { axis: 1.0 /\ 0.0 /\ 0.0 }
|
||||
, X.geom {} unit
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
it "nested defaults" $ parseOk $ X.mujoco {}
|
||||
[ X.compiler { inertiafromgeom: X.true_ }
|
||||
, Def.default {}
|
||||
[ Def.geom { rgba: 1.0 /\ 1.0 /\ 1.0 /\ 1.0 }
|
||||
, Def.default { class: "red" }
|
||||
[ Def.geom { rgba: 1.0 /\ 0.0 /\ 0.0 /\ 1.0 } ]
|
||||
]
|
||||
, X.worldbody {}
|
||||
[ X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit ]
|
||||
]
|
||||
|
||||
it "site defaults" $ parseOk $ X.mujoco {}
|
||||
[ Def.default {}
|
||||
[ Def.site { type: X.kw X.Sphere, size: 0.02 /\ 0.02 /\ 0.02, rgba: 0.0 /\ 1.0 /\ 0.0 /\ 1.0 } ]
|
||||
, X.worldbody {}
|
||||
[ X.site { name: "s1", pos: 0.0 /\ 0.0 /\ 0.0 } ]
|
||||
]
|
||||
|
||||
it "light defaults" $ parseOk $ X.mujoco {}
|
||||
[ Def.default {}
|
||||
[ Def.light { diffuse: 0.8 /\ 0.8 /\ 0.8, castshadow: true } ]
|
||||
, X.worldbody {}
|
||||
[ X.light { name: "l1", pos: 0.0 /\ 0.0 /\ 3.0 } ]
|
||||
]
|
||||
|
||||
it "camera defaults" $ parseOk $ X.mujoco {}
|
||||
[ Def.default {}
|
||||
[ Def.camera { fovy: 60.0 } ]
|
||||
, X.worldbody {}
|
||||
[ X.camera { name: "c1", pos: 0.0 /\ (-2.0) /\ 1.0 } ]
|
||||
]
|
||||
|
||||
it "motor defaults" $ parseOk $ X.mujoco {}
|
||||
[ X.compiler { inertiafromgeom: X.true_ }
|
||||
, Def.default {}
|
||||
[ Def.motor { ctrllimited: X.true_, ctrlrange: (-1.0) /\ 1.0 } ]
|
||||
, X.worldbody {}
|
||||
[ X.body { pos: 0.0 /\ 0.0 /\ 0.5 }
|
||||
[ X.joint { name: "j1", type: X.kw X.Hinge, axis: 1.0 /\ 0.0 /\ 0.0 }
|
||||
, X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit
|
||||
]
|
||||
]
|
||||
]
|
||||
92
test/Mujoco.MJCF.Deformable.purs
Normal file
92
test/Mujoco.MJCF.Deformable.purs
Normal file
@@ -0,0 +1,92 @@
|
||||
module Test.Mujoco.MJCF.Deformable where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Tuple.Nested ((/\))
|
||||
import Mujoco.MJCF as X
|
||||
import Mujoco.MJCF.Deformable as Deformable
|
||||
import Mujoco.MJCF.Deformable.Flex as Flex
|
||||
import Mujoco.MJCF.Deformable.Skin as Skin
|
||||
import Test.Mujoco.MJCF.Util (MjcfSpec, parseOk)
|
||||
import Test.Spec (describe, it)
|
||||
|
||||
spec :: MjcfSpec Unit
|
||||
spec =
|
||||
describe "deformable" do
|
||||
describe "flex" do
|
||||
it "basic" $ parseOk $ X.mujoco {}
|
||||
[ X.compiler { inertiafromgeom: X.true_ }
|
||||
, Deformable.deformable {}
|
||||
[ Flex.flex { name: "f1", dim: 3, body: [ "world", "world", "world", "world" ], vertex: [ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 ], element: [ 0, 1, 2, 3 ] }
|
||||
unit
|
||||
]
|
||||
, X.worldbody {}
|
||||
[ X.body { pos: 0.0 /\ 0.0 /\ 0.0 }
|
||||
[ X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit ]
|
||||
]
|
||||
]
|
||||
|
||||
it "with edge" $ parseOk $ X.mujoco {}
|
||||
[ X.compiler { inertiafromgeom: X.true_ }
|
||||
, Deformable.deformable {}
|
||||
[ Flex.flex { name: "f2", dim: 3, body: [ "world", "world", "world", "world" ], vertex: [ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 ], element: [ 0, 1, 2, 3 ] }
|
||||
[ Flex.edge { stiffness: 100.0, damping: 1.0 } ]
|
||||
]
|
||||
, X.worldbody {}
|
||||
[ X.body { pos: 0.0 /\ 0.0 /\ 0.0 }
|
||||
[ X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit ]
|
||||
]
|
||||
]
|
||||
|
||||
it "with elasticity" $ parseOk $ X.mujoco {}
|
||||
[ X.compiler { inertiafromgeom: X.true_ }
|
||||
, Deformable.deformable {}
|
||||
[ Flex.flex { name: "f3", dim: 3, body: [ "world", "world", "world", "world" ], vertex: [ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 ], element: [ 0, 1, 2, 3 ] }
|
||||
[ Flex.elasticity { young: 1000.0, poisson: 0.3, damping: 0.01 } ]
|
||||
]
|
||||
, X.worldbody {}
|
||||
[ X.body { pos: 0.0 /\ 0.0 /\ 0.0 }
|
||||
[ X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit ]
|
||||
]
|
||||
]
|
||||
|
||||
it "with contact" $ parseOk $ X.mujoco {}
|
||||
[ X.compiler { inertiafromgeom: X.true_ }
|
||||
, Deformable.deformable {}
|
||||
[ Flex.flex { name: "f4", dim: 3, body: [ "world", "world", "world", "world" ], vertex: [ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 ], element: [ 0, 1, 2, 3 ] }
|
||||
[ Flex.contact { internal: true } ]
|
||||
]
|
||||
, X.worldbody {}
|
||||
[ X.body { pos: 0.0 /\ 0.0 /\ 0.0 }
|
||||
[ X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit ]
|
||||
]
|
||||
]
|
||||
|
||||
it "rgba + group" $ parseOk $ X.mujoco {}
|
||||
[ X.compiler { inertiafromgeom: X.true_ }
|
||||
, Deformable.deformable {}
|
||||
[ Flex.flex { name: "f5", dim: 3, body: [ "world", "world", "world", "world" ], vertex: [ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 ], element: [ 0, 1, 2, 3 ], rgba: 1.0 /\ 0.0 /\ 0.0 /\ 1.0, group: 0 }
|
||||
unit
|
||||
]
|
||||
, X.worldbody {}
|
||||
[ X.body { pos: 0.0 /\ 0.0 /\ 0.0 }
|
||||
[ X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit ]
|
||||
]
|
||||
]
|
||||
|
||||
describe "skin" do
|
||||
it "basic" $ parseOk $ X.mujoco {}
|
||||
[ Deformable.deformable {}
|
||||
[ Skin.skin { name: "sk1", vertex: [ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0 ], face: [ 0, 1, 2 ] }
|
||||
[ Skin.bone { body: "world", bindpos: 0.0 /\ 0.0 /\ 0.0, bindquat: 1.0 /\ 0.0 /\ 0.0 /\ 0.0, vertid: [ 0, 1, 2 ], vertweight: [ 1.0, 1.0, 1.0 ] } ]
|
||||
]
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
it "inflate + rgba" $ parseOk $ X.mujoco {}
|
||||
[ Deformable.deformable {}
|
||||
[ Skin.skin { name: "sk2", vertex: [ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0 ], face: [ 0, 1, 2 ], inflate: 0.01, rgba: 0.5 /\ 0.5 /\ 1.0 /\ 0.8 }
|
||||
[ Skin.bone { body: "world", bindpos: 0.0 /\ 0.0 /\ 0.0, bindquat: 1.0 /\ 0.0 /\ 0.0 /\ 0.0, vertid: [ 0, 1, 2 ], vertweight: [ 1.0, 1.0, 1.0 ] } ]
|
||||
]
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
73
test/Mujoco.MJCF.Equality.purs
Normal file
73
test/Mujoco.MJCF.Equality.purs
Normal file
@@ -0,0 +1,73 @@
|
||||
module Test.Mujoco.MJCF.Equality where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Tuple.Nested ((/\))
|
||||
import Mujoco.MJCF as X
|
||||
import Mujoco.MJCF.Equality as Eq
|
||||
import Mujoco.MJCF.Tendon as Tendon
|
||||
import Mujoco.MJCF.XML (Node)
|
||||
import Test.Mujoco.MJCF.Util (MjcfSpec, parseOk)
|
||||
import Test.Spec (describe, it)
|
||||
|
||||
-- | Model with two bodies, joints, and sites for equality constraint tests
|
||||
m :: Node -> Node
|
||||
m e = X.mujoco {}
|
||||
[ X.compiler { inertiafromgeom: X.true_ }
|
||||
, X.worldbody {}
|
||||
[ X.body { name: "b1", pos: 0.0 /\ 0.0 /\ 0.5 }
|
||||
[ X.joint { name: "j1", type: X.kw X.Hinge, axis: 1.0 /\ 0.0 /\ 0.0 }
|
||||
, X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit
|
||||
, X.site { name: "s1", pos: 0.0 /\ 0.0 /\ 0.1, size: 0.01 /\ 0.01 /\ 0.01 }
|
||||
]
|
||||
, X.body { name: "b2", pos: 1.0 /\ 0.0 /\ 0.5 }
|
||||
[ X.joint { name: "j2", type: X.kw X.Hinge, axis: 1.0 /\ 0.0 /\ 0.0 }
|
||||
, X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit
|
||||
, X.site { name: "s2", pos: 0.0 /\ 0.0 /\ 0.1, size: 0.01 /\ 0.01 /\ 0.01 }
|
||||
]
|
||||
]
|
||||
, e
|
||||
]
|
||||
|
||||
spec :: MjcfSpec Unit
|
||||
spec =
|
||||
describe "equality" do
|
||||
describe "connect" do
|
||||
it "body1 + body2 + anchor" $ parseOk $ m $
|
||||
Eq.equality {} [ Eq.connect { body1: "b1", body2: "b2", anchor: 0.5 /\ 0.0 /\ 0.5 } unit ]
|
||||
|
||||
it "site1 + site2" $ parseOk $ m $
|
||||
Eq.equality {} [ Eq.connect { site1: "s1", site2: "s2" } unit ]
|
||||
|
||||
it "solref + solimp" $ parseOk $ m $
|
||||
Eq.equality {} [ Eq.connect { body1: "b1", body2: "b2", anchor: 0.5 /\ 0.0 /\ 0.5, solref: 0.02 /\ 1.0, solimp: 0.9 /\ 0.95 /\ 0.001 /\ 0.5 /\ 2.0 } unit ]
|
||||
|
||||
describe "weld" do
|
||||
it "body1 + body2" $ parseOk $ m $
|
||||
Eq.equality {} [ Eq.weld { body1: "b1", body2: "b2" } ]
|
||||
|
||||
it "site1 + site2" $ parseOk $ m $
|
||||
Eq.equality {} [ Eq.weld { site1: "s1", site2: "s2" } ]
|
||||
|
||||
it "torquescale" $ parseOk $ m $
|
||||
Eq.equality {} [ Eq.weld { body1: "b1", body2: "b2", torquescale: 1.0 } ]
|
||||
|
||||
describe "joint" do
|
||||
it "joint1 + joint2" $ parseOk $ m $
|
||||
Eq.equality {} [ Eq.joint { joint1: "j1", joint2: "j2" } ]
|
||||
|
||||
it "polycoef" $ parseOk $ m $
|
||||
Eq.equality {} [ Eq.joint { joint1: "j1", joint2: "j2", polycoef: 0.0 /\ 1.0 /\ 0.0 /\ 0.0 /\ 0.0 } ]
|
||||
|
||||
describe "tendon" do
|
||||
it "tendon1" $ parseOk $ X.mujoco {}
|
||||
[ X.compiler { inertiafromgeom: X.true_ }
|
||||
, X.worldbody {}
|
||||
[ X.body { name: "b1", pos: 0.0 /\ 0.0 /\ 0.5 }
|
||||
[ X.joint { name: "j1", type: X.kw X.Hinge, axis: 1.0 /\ 0.0 /\ 0.0 }
|
||||
, X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit
|
||||
]
|
||||
]
|
||||
, Tendon.tendon {} $ Tendon.fixed { name: "t1" } [ Tendon.joint { joint: "j1", coef: 1.0 } ]
|
||||
, Eq.equality {} [ Eq.tendon { tendon1: "t1" } ]
|
||||
]
|
||||
54
test/Mujoco.MJCF.Keyframe.purs
Normal file
54
test/Mujoco.MJCF.Keyframe.purs
Normal file
@@ -0,0 +1,54 @@
|
||||
module Test.Mujoco.MJCF.Keyframe where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Tuple.Nested ((/\))
|
||||
import Mujoco.MJCF as X
|
||||
import Test.Mujoco.MJCF.Util (MjcfSpec, parseOk)
|
||||
import Test.Spec (describe, it)
|
||||
|
||||
spec :: MjcfSpec Unit
|
||||
spec =
|
||||
describe "keyframe" do
|
||||
it "empty" $ parseOk $ X.mujoco {}
|
||||
[ X.worldbody {} unit
|
||||
, X.keyframe {} unit
|
||||
]
|
||||
|
||||
it "key with time" $ parseOk $ X.mujoco {}
|
||||
[ X.worldbody {} unit
|
||||
, X.keyframe {}
|
||||
[ X.key { name: "home", time: 0.0 } ]
|
||||
]
|
||||
|
||||
it "key with qpos + qvel" $ parseOk $ X.mujoco {}
|
||||
[ X.compiler { inertiafromgeom: X.true_ }
|
||||
, X.worldbody {}
|
||||
[ X.body { pos: 0.0 /\ 0.0 /\ 0.5 }
|
||||
[ X.joint { name: "j1", type: X.kw X.Hinge, axis: 1.0 /\ 0.0 /\ 0.0 }
|
||||
, X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit
|
||||
]
|
||||
]
|
||||
, X.keyframe {}
|
||||
[ X.key { name: "init", time: 0.0, qpos: [ 0.5 ], qvel: [ 0.0 ] } ]
|
||||
]
|
||||
|
||||
it "key with ctrl" $ parseOk $ X.mujoco {}
|
||||
[ X.compiler { inertiafromgeom: X.true_ }
|
||||
, X.worldbody {}
|
||||
[ X.body { pos: 0.0 /\ 0.0 /\ 0.5 }
|
||||
[ X.joint { name: "j1", type: X.kw X.Hinge, axis: 1.0 /\ 0.0 /\ 0.0 }
|
||||
, X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit
|
||||
]
|
||||
]
|
||||
, X.keyframe {}
|
||||
[ X.key { name: "start", ctrl: [ 0.0 ] } ]
|
||||
]
|
||||
|
||||
it "multiple keys" $ parseOk $ X.mujoco {}
|
||||
[ X.worldbody {} unit
|
||||
, X.keyframe {}
|
||||
[ X.key { name: "k1", time: 0.0 }
|
||||
, X.key { name: "k2", time: 1.0 }
|
||||
]
|
||||
]
|
||||
166
test/Mujoco.MJCF.Sensor.purs
Normal file
166
test/Mujoco.MJCF.Sensor.purs
Normal file
@@ -0,0 +1,166 @@
|
||||
module Test.Mujoco.MJCF.Sensor where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Tuple.Nested ((/\))
|
||||
import Mujoco.MJCF as X
|
||||
import Mujoco.MJCF.Actuator as Act
|
||||
import Mujoco.MJCF.Sensor as Sens
|
||||
import Mujoco.MJCF.XML (Node)
|
||||
import Test.Mujoco.MJCF.Util (MjcfSpec, parseOk)
|
||||
import Test.Spec (describe, it)
|
||||
|
||||
-- | Model with body, site, joint, tendon, and actuator for sensor tests
|
||||
m :: Node -> Node
|
||||
m s = X.mujoco {}
|
||||
[ X.compiler { inertiafromgeom: X.true_ }
|
||||
, X.worldbody {}
|
||||
[ X.body { name: "b1", pos: 0.0 /\ 0.0 /\ 0.5 }
|
||||
[ X.joint { name: "j1", type: X.kw X.Hinge, axis: 1.0 /\ 0.0 /\ 0.0 }
|
||||
, X.geom { name: "g1", type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit
|
||||
, X.site { name: "s1", pos: 0.0 /\ 0.0 /\ 0.1, size: 0.01 /\ 0.01 /\ 0.01 }
|
||||
, X.camera { name: "cam1", pos: 0.0 /\ (-1.0) /\ 0.5, fovy: 60.0 }
|
||||
]
|
||||
, X.body { name: "b2", pos: 1.0 /\ 0.0 /\ 0.5 }
|
||||
[ X.joint { name: "j2", type: X.kw X.Hinge, axis: 1.0 /\ 0.0 /\ 0.0 }
|
||||
, X.geom { name: "g2", type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit
|
||||
, X.site { name: "s2", pos: 0.0 /\ 0.0 /\ 0.1, size: 0.01 /\ 0.01 /\ 0.01 }
|
||||
]
|
||||
]
|
||||
, Act.actuator {} [ Act.motor { name: "a1", joint: "j1" } ]
|
||||
, s
|
||||
]
|
||||
|
||||
spec :: MjcfSpec Unit
|
||||
spec =
|
||||
describe "sensor" do
|
||||
describe "site-based" do
|
||||
it "touch" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.touch { name: "se_touch", site: "s1" } ]
|
||||
|
||||
it "accelerometer" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.accelerometer { name: "se_accel", site: "s1" } ]
|
||||
|
||||
it "velocimeter" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.velocimeter { name: "se_velo", site: "s1" } ]
|
||||
|
||||
it "gyro" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.gyro { name: "se_gyro", site: "s1" } ]
|
||||
|
||||
it "force" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.force { name: "se_force", site: "s1" } ]
|
||||
|
||||
it "torque" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.torque { name: "se_torque", site: "s1" } ]
|
||||
|
||||
it "magnetometer" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.magnetometer { name: "se_mag", site: "s1" } ]
|
||||
|
||||
it "rangefinder" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.rangefinder { name: "se_range", site: "s1" } ]
|
||||
|
||||
it "camprojection" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.camprojection { name: "se_camp", site: "s1", camera: "cam1" } ]
|
||||
|
||||
describe "joint-based" do
|
||||
it "jointpos" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.jointpos { name: "se_jpos", joint: "j1" } ]
|
||||
|
||||
it "jointvel" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.jointvel { name: "se_jvel", joint: "j1" } ]
|
||||
|
||||
it "jointactuatorfrc" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.jointactuatorfrc { name: "se_jafrc", joint: "j1" } ]
|
||||
|
||||
it "jointlimitpos" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.jointlimitpos { name: "se_jlpos", joint: "j1" } ]
|
||||
|
||||
it "jointlimitvel" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.jointlimitvel { name: "se_jlvel", joint: "j1" } ]
|
||||
|
||||
it "jointlimitfrc" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.jointlimitfrc { name: "se_jlfrc", joint: "j1" } ]
|
||||
|
||||
describe "actuator-based" do
|
||||
it "actuatorpos" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.actuatorpos { name: "se_apos", actuator: "a1" } ]
|
||||
|
||||
it "actuatorvel" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.actuatorvel { name: "se_avel", actuator: "a1" } ]
|
||||
|
||||
it "actuatorfrc" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.actuatorfrc { name: "se_afrc", actuator: "a1" } ]
|
||||
|
||||
describe "frame-based" do
|
||||
it "framepos" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.framepos { name: "se_fpos", objtype: X.kw X.Body, objname: "b1" } ]
|
||||
|
||||
it "framequat" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.framequat { name: "se_fquat", objtype: X.kw X.Body, objname: "b1" } ]
|
||||
|
||||
it "framexaxis" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.framexaxis { name: "se_fxax", objtype: X.kw X.Body, objname: "b1" } ]
|
||||
|
||||
it "frameyaxis" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.frameyaxis { name: "se_fyax", objtype: X.kw X.Body, objname: "b1" } ]
|
||||
|
||||
it "framezaxis" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.framezaxis { name: "se_fzax", objtype: X.kw X.Body, objname: "b1" } ]
|
||||
|
||||
it "framelinvel" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.framelinvel { name: "se_flv", objtype: X.kw X.Body, objname: "b1" } ]
|
||||
|
||||
it "frameangvel" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.frameangvel { name: "se_fav", objtype: X.kw X.Body, objname: "b1" } ]
|
||||
|
||||
it "framelinvel with ref" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.framelinvel { name: "se_flvr", objtype: X.kw X.Body, objname: "b1", reftype: X.kw X.Body, refname: "b2" } ]
|
||||
|
||||
it "framelinacc" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.framelinacc { name: "se_fla", objtype: X.kw X.Body, objname: "b1" } ]
|
||||
|
||||
it "frameangacc" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.frameangacc { name: "se_faa", objtype: X.kw X.Body, objname: "b1" } ]
|
||||
|
||||
describe "subtree" do
|
||||
it "subtreecom" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.subtreecom { name: "se_stcom", body: "b1" } ]
|
||||
|
||||
it "subtreelinvel" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.subtreelinvel { name: "se_stlv", body: "b1" } ]
|
||||
|
||||
it "subtreeangmom" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.subtreeangmom { name: "se_stam", body: "b1" } ]
|
||||
|
||||
describe "collision" do
|
||||
it "distance" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.distance { name: "se_dist", geom1: "g1", geom2: "g2" } ]
|
||||
|
||||
it "normal" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.normal { name: "se_norm", geom1: "g1", geom2: "g2" } ]
|
||||
|
||||
it "fromto" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.fromto { name: "se_ft", geom1: "g1", geom2: "g2" } ]
|
||||
|
||||
it "contact" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.contact { name: "se_cont", body1: "b1", body2: "b2" } ]
|
||||
|
||||
describe "other" do
|
||||
it "insidesite" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.insidesite { name: "se_inside", objtype: X.kw X.Geom, objname: "g1", site: "s1" } ]
|
||||
|
||||
it "e_potential" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.e_potential { name: "se_ep" } ]
|
||||
|
||||
it "e_kinetic" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.e_kinetic { name: "se_ek" } ]
|
||||
|
||||
it "clock" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.clock { name: "se_clock" } ]
|
||||
|
||||
it "user" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.user { name: "se_user", objtype: "body", objname: "b1", datatype: X.kw X.Real, needstage: X.kw X.Vel, dim: 1 } ]
|
||||
|
||||
describe "common props" do
|
||||
it "noise + cutoff" $ parseOk $ m $
|
||||
X.sensor {} [ Sens.touch { name: "se_noisy", site: "s1", noise: 0.01, cutoff: 100.0 } ]
|
||||
64
test/Mujoco.MJCF.Tendon.purs
Normal file
64
test/Mujoco.MJCF.Tendon.purs
Normal file
@@ -0,0 +1,64 @@
|
||||
module Test.Mujoco.MJCF.Tendon where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Tuple.Nested ((/\))
|
||||
import Mujoco.MJCF as X
|
||||
import Mujoco.MJCF.Tendon as Tendon
|
||||
import Mujoco.MJCF.XML (Node)
|
||||
import Test.Mujoco.MJCF.Util (MjcfSpec, parseOk)
|
||||
import Test.Spec (describe, it)
|
||||
|
||||
-- | Model with two bodies, two hinge joints, and two sites for tendon routing
|
||||
m :: Node -> Node
|
||||
m t = X.mujoco {}
|
||||
[ X.compiler { inertiafromgeom: X.true_ }
|
||||
, X.worldbody {}
|
||||
[ X.body { name: "b1", pos: 0.0 /\ 0.0 /\ 0.5 }
|
||||
[ X.joint { name: "j1", type: X.kw X.Hinge, axis: 1.0 /\ 0.0 /\ 0.0 }
|
||||
, X.geom { type: X.kw X.Capsule, size: [ 0.05, 0.2 ] } unit
|
||||
, X.site { name: "s1", pos: 0.0 /\ 0.0 /\ 0.2, size: 0.01 /\ 0.01 /\ 0.01 }
|
||||
, X.body { name: "b2", pos: 0.0 /\ 0.0 /\ 0.5 }
|
||||
[ X.joint { name: "j2", type: X.kw X.Hinge, axis: 1.0 /\ 0.0 /\ 0.0 }
|
||||
, X.geom { type: X.kw X.Capsule, size: [ 0.05, 0.2 ] } unit
|
||||
, X.site { name: "s2", pos: 0.0 /\ 0.0 /\ 0.2, size: 0.01 /\ 0.01 /\ 0.01 }
|
||||
]
|
||||
]
|
||||
]
|
||||
, t
|
||||
]
|
||||
|
||||
spec :: MjcfSpec Unit
|
||||
spec =
|
||||
describe "tendon" do
|
||||
describe "spatial" do
|
||||
it "basic site routing" $ parseOk $ m $ Tendon.tendon {} $
|
||||
Tendon.spatial { name: "t_spatial" }
|
||||
[ Tendon.site { site: "s1" }
|
||||
, Tendon.site { site: "s2" }
|
||||
]
|
||||
|
||||
it "with pulley" $ parseOk $ m $ Tendon.tendon {} $
|
||||
Tendon.spatial { name: "t_pulley" }
|
||||
[ Tendon.site { site: "s1" }
|
||||
, Tendon.pulley { divisor: 2.0 }
|
||||
, Tendon.site { site: "s2" }
|
||||
]
|
||||
|
||||
it "limited + range + stiffness + damping" $ parseOk $ m $ Tendon.tendon {} $
|
||||
Tendon.spatial { name: "t_props", limited: X.true_, range: (-1.0) /\ 1.0, stiffness: 100.0, damping: 10.0 }
|
||||
[ Tendon.site { site: "s1" }
|
||||
, Tendon.site { site: "s2" }
|
||||
]
|
||||
|
||||
describe "fixed" do
|
||||
it "basic joint" $ parseOk $ m $ Tendon.tendon {} $
|
||||
Tendon.fixed { name: "t_fixed" }
|
||||
[ Tendon.joint { joint: "j1", coef: 1.0 }
|
||||
, Tendon.joint { joint: "j2", coef: -1.0 }
|
||||
]
|
||||
|
||||
it "stiffness + damping" $ parseOk $ m $ Tendon.tendon {} $
|
||||
Tendon.fixed { name: "t_fixed2", stiffness: 50.0, damping: 5.0 }
|
||||
[ Tendon.joint { joint: "j1", coef: 1.0 }
|
||||
]
|
||||
82
test/Mujoco.MJCF.Visual.purs
Normal file
82
test/Mujoco.MJCF.Visual.purs
Normal file
@@ -0,0 +1,82 @@
|
||||
module Test.Mujoco.MJCF.Visual where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Tuple.Nested ((/\))
|
||||
import Mujoco.MJCF as X
|
||||
import Mujoco.MJCF.Visual as Vis
|
||||
import Mujoco.MJCF.XML (Node)
|
||||
import Test.Mujoco.MJCF.Util (MjcfSpec, parseOk)
|
||||
import Test.Spec (describe, it)
|
||||
|
||||
v :: Node -> Node
|
||||
v c = X.mujoco {}
|
||||
[ Vis.visual {} [ c ]
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
spec :: MjcfSpec Unit
|
||||
spec =
|
||||
describe "visual" do
|
||||
describe "global" do
|
||||
it "fovy + linewidth" $ parseOk $ v $
|
||||
Vis.global { fovy: 45.0, linewidth: 2.0 }
|
||||
|
||||
it "offwidth + offheight" $ parseOk $ v $
|
||||
Vis.global { offwidth: 1920, offheight: 1080 }
|
||||
|
||||
it "orthographic + ellipsoidinertia" $ parseOk $ v $
|
||||
Vis.global { orthographic: true, ellipsoidinertia: true }
|
||||
|
||||
describe "quality" do
|
||||
it "shadowsize + offsamples" $ parseOk $ v $
|
||||
Vis.quality { shadowsize: 4096, offsamples: 8 }
|
||||
|
||||
it "numslices + numstacks + numquads" $ parseOk $ v $
|
||||
Vis.quality { numslices: 32, numstacks: 32, numquads: 4 }
|
||||
|
||||
describe "headlight" do
|
||||
it "ambient + diffuse + specular" $ parseOk $ v $
|
||||
Vis.headlight { ambient: 0.3 /\ 0.3 /\ 0.3, diffuse: 0.6 /\ 0.6 /\ 0.6, specular: 0.2 /\ 0.2 /\ 0.2 }
|
||||
|
||||
it "active" $ parseOk $ v $
|
||||
Vis.headlight { active: 0 }
|
||||
|
||||
describe "map" do
|
||||
it "stiffness + force + torque" $ parseOk $ v $
|
||||
Vis.map { stiffness: 100.0, force: 0.05, torque: 0.1 }
|
||||
|
||||
it "fogstart + fogend" $ parseOk $ v $
|
||||
Vis.map { fogstart: 2.0, fogend: 10.0 }
|
||||
|
||||
it "znear + zfar" $ parseOk $ v $
|
||||
Vis.map { znear: 0.01, zfar: 50.0 }
|
||||
|
||||
it "shadowclip + shadowscale" $ parseOk $ v $
|
||||
Vis.map { shadowclip: 0.5, shadowscale: 0.5 }
|
||||
|
||||
describe "scale" do
|
||||
it "forcewidth + contactwidth + contactheight" $ parseOk $ v $
|
||||
Vis.scale { forcewidth: 0.1, contactwidth: 0.3, contactheight: 0.1 }
|
||||
|
||||
it "jointlength + jointwidth" $ parseOk $ v $
|
||||
Vis.scale { jointlength: 0.5, jointwidth: 0.1 }
|
||||
|
||||
it "framelength + framewidth" $ parseOk $ v $
|
||||
Vis.scale { framelength: 1.0, framewidth: 0.05 }
|
||||
|
||||
it "actuatorlength + actuatorwidth" $ parseOk $ v $
|
||||
Vis.scale { actuatorlength: 0.7, actuatorwidth: 0.1 }
|
||||
|
||||
describe "rgba" do
|
||||
it "fog + haze" $ parseOk $ v $
|
||||
Vis.rgba { fog: 0.0 /\ 0.0 /\ 0.0 /\ 1.0, haze: 1.0 /\ 1.0 /\ 1.0 /\ 1.0 }
|
||||
|
||||
it "force + inertia + joint" $ parseOk $ v $
|
||||
Vis.rgba { force: 1.0 /\ 0.5 /\ 0.5 /\ 1.0, inertia: 0.8 /\ 0.2 /\ 0.2 /\ 0.6, joint: 0.2 /\ 0.6 /\ 0.8 /\ 1.0 }
|
||||
|
||||
it "com + camera + light" $ parseOk $ v $
|
||||
Vis.rgba { com: 0.0 /\ 1.0 /\ 0.0 /\ 1.0, camera: 0.6 /\ 0.9 /\ 0.6 /\ 1.0, light: 0.9 /\ 0.9 /\ 0.3 /\ 1.0 }
|
||||
|
||||
it "contact colors" $ parseOk $ v $
|
||||
Vis.rgba { contactpoint: 0.9 /\ 0.2 /\ 0.2 /\ 1.0, contactforce: 0.2 /\ 0.9 /\ 0.2 /\ 1.0, contactfriction: 0.2 /\ 0.2 /\ 0.9 /\ 1.0, contacttorque: 0.9 /\ 0.9 /\ 0.2 /\ 1.0 }
|
||||
@@ -1,12 +1,13 @@
|
||||
module Test.Mujoco.XML.Node.Prop where
|
||||
module Test.Mujoco.MJCF.XML.Prop where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Tuple.Nested (type (/\), (/\))
|
||||
import Mujoco.XML.Node.Prop (class SerializeProps', serialize, serializeProps)
|
||||
import Mujoco.MJCF.XML.Prop (class SerializeProps', serialize, serializeProps)
|
||||
import Prim.Row (class Union)
|
||||
import Prim.RowList (class RowToList)
|
||||
import Test.Spec (Spec, describe, it)
|
||||
import Test.Mujoco.MJCF.Util (MjcfSpec)
|
||||
import Test.Spec (describe, it)
|
||||
import Test.Spec.Assertions (shouldEqual)
|
||||
import Unsafe.Coerce (unsafeCoerce)
|
||||
|
||||
@@ -20,19 +21,20 @@ type Props =
|
||||
, bool :: Boolean
|
||||
)
|
||||
|
||||
spec :: Spec Unit
|
||||
spec :: MjcfSpec Unit
|
||||
spec =
|
||||
describe "Mujoco.XML.Node.Prop" do
|
||||
describe "Mujoco.MJCF.XML.Prop" do
|
||||
describe "Serialize" do
|
||||
it "serializes boolean" $ serialize true `shouldEqual` "true"
|
||||
it "serializes string" $ serialize "a" `shouldEqual` "a"
|
||||
it "serializes array" $ serialize ["a", "b"] `shouldEqual` "a b"
|
||||
it "serializes nested array" $ serialize [["a", "b"], ["c"]] `shouldEqual` "a b c"
|
||||
it "serializes array" $ serialize [ "a", "b" ] `shouldEqual` "a b"
|
||||
it "serializes nested array" $ serialize [ [ "a", "b" ], [ "c" ] ] `shouldEqual` "a b c"
|
||||
it "serializes int" $ serialize 1 `shouldEqual` "1"
|
||||
it "serializes int array" $ serialize [1, 2] `shouldEqual` "1 2"
|
||||
it "serializes number array" $ serialize [1.0, 2.0] `shouldEqual` "1 2"
|
||||
it "serializes int array" $ serialize [ 1, 2 ] `shouldEqual` "1 2"
|
||||
it "serializes number array" $ serialize [ 1.0, 2.0 ] `shouldEqual` "1 2"
|
||||
it "serializes tuple" $ serialize (1 /\ 2) `shouldEqual` "1 2"
|
||||
it "serializes nested tuple" $ serialize (1 /\ 2 /\ 3) `shouldEqual` "1 2 3"
|
||||
it "serializes real(4)" $ serialize (1.0 /\ 1.0 /\ 0.5 /\ 0.1) `shouldEqual` "1 1 0.5 0.1"
|
||||
|
||||
describe "SerializeProps" do
|
||||
let
|
||||
@@ -48,4 +50,4 @@ spec =
|
||||
it "handles empty" $ serializeProps' {} `shouldEqual` {}
|
||||
it "handles int" $ serializeProps' { int: 1 } `shouldEqual` { int: "1" }
|
||||
it "handles string" $ serializeProps' { string: "a" } `shouldEqual` { string: "a" }
|
||||
it "handles array2" $ serializeProps' { array2: [[1, 2, 3], [4, 5]] } `shouldEqual` { array2: "1 2 3 4 5" }
|
||||
it "handles array2" $ serializeProps' { array2: [ [ 1, 2, 3 ], [ 4, 5 ] ] } `shouldEqual` { array2: "1 2 3 4 5" }
|
||||
235
test/Mujoco.MJCF.purs
Normal file
235
test/Mujoco.MJCF.purs
Normal file
@@ -0,0 +1,235 @@
|
||||
module Test.Mujoco.MJCF where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Tuple.Nested ((/\))
|
||||
import Mujoco.MJCF as X
|
||||
import Test.Mujoco.MJCF.Util (MjcfSpec, parseFail, parseOk, w)
|
||||
import Test.Spec (describe, it)
|
||||
|
||||
spec :: MjcfSpec Unit
|
||||
spec =
|
||||
describe "MJCF" do
|
||||
it "</>" $ parseFail $ X.empty
|
||||
it "<mujoco>" $ parseOk $ X.mujoco {} unit
|
||||
it "<worldbody>" $ parseOk $ X.mujoco {} $ X.worldbody {} unit
|
||||
|
||||
describe "compiler" do
|
||||
it "empty" $ parseOk $ X.mujoco {}
|
||||
[ X.compiler {}
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
it "angle=radian" $ parseOk $ X.mujoco {}
|
||||
[ X.compiler { angle: X.kw X.Radian }
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
it "autolimits + coordinate" $ parseOk $ X.mujoco {}
|
||||
[ X.compiler { autolimits: true, coordinate: X.kw X.Local }
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
it "inertiafromgeom=auto" $ parseOk $ X.mujoco {}
|
||||
[ X.compiler { inertiafromgeom: X.kw X.Auto }
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
it "boundmass + boundinertia" $ parseOk $ X.mujoco {}
|
||||
[ X.compiler { boundmass: 0.01, boundinertia: 0.001 }
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
describe "size" do
|
||||
it "empty" $ parseOk $ X.mujoco {}
|
||||
[ X.size {}
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
it "memory" $ parseOk $ X.mujoco {}
|
||||
[ X.size { memory: "16M" }
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
it "nuser fields" $ parseOk $ X.mujoco {}
|
||||
[ X.size { nuser_body: 2, nuser_jnt: 1, nuser_geom: 3 }
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
describe "option" do
|
||||
it "timestep + integrator" $ parseOk $ X.mujoco {}
|
||||
[ X.option { timestep: 0.001, integrator: X.kw X.RK4 } unit
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
it "gravity + solver" $ parseOk $ X.mujoco {}
|
||||
[ X.option { gravity: 0.0 /\ 0.0 /\ (-9.81), solver: X.kw X.Newton } unit
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
describe "statistic" do
|
||||
it "extent + center" $ parseOk $ X.mujoco {}
|
||||
[ X.statistic { extent: 2.0, center: 0.0 /\ 0.0 /\ 1.0 }
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
describe "asset" do
|
||||
describe "mesh" do
|
||||
it "inline vertex" $ parseOk $ X.mujoco {}
|
||||
[ X.asset {}
|
||||
[ X.mesh { name: "tetra", vertex: [ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 ] } unit ]
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
describe "hfield" do
|
||||
it "nrow + ncol + size" $ parseOk $ X.mujoco {}
|
||||
[ X.asset {}
|
||||
[ X.hfield { name: "terrain", nrow: 10, ncol: 10, size: 1.0 /\ 1.0 /\ 0.5 /\ 0.1 } ]
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
describe "texture" do
|
||||
it "procedural checker" $ parseOk $ X.mujoco {}
|
||||
[ X.asset {}
|
||||
[ X.texture
|
||||
{ name: "grid"
|
||||
, type: X.kw X.TwoD
|
||||
, builtin: X.kw X.Checker
|
||||
, width: 512
|
||||
, height: 512
|
||||
, rgb1: 0.9 /\ 0.9 /\ 0.9
|
||||
, rgb2: 0.1 /\ 0.1 /\ 0.1
|
||||
}
|
||||
]
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
describe "material" do
|
||||
it "rgba + specular" $ parseOk $ X.mujoco {}
|
||||
[ X.asset {}
|
||||
[ X.material { name: "mat1", rgba: 0.8 /\ 0.2 /\ 0.2 /\ 1.0, specular: 0.8 } unit ]
|
||||
, X.worldbody {} unit
|
||||
]
|
||||
|
||||
describe "body" do
|
||||
describe "joint" do
|
||||
it "hinge" $ parseOk $ w $
|
||||
X.body { name: "b1", pos: 0.0 /\ 0.0 /\ 0.5 }
|
||||
[ X.joint { type: X.kw X.Hinge, axis: 1.0 /\ 0.0 /\ 0.0 }
|
||||
, X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit
|
||||
]
|
||||
|
||||
it "slide with range" $ parseOk $ w $
|
||||
X.body { name: "slider", pos: 0.0 /\ 0.0 /\ 1.0 }
|
||||
[ X.joint { type: X.kw X.Slide, axis: 0.0 /\ 0.0 /\ 1.0, range: (-1.0) /\ 1.0, limited: X.true_ }
|
||||
, X.geom { type: X.kw X.Box, size: [ 0.1, 0.1, 0.1 ] } unit
|
||||
]
|
||||
|
||||
it "stiffness + damping" $ parseOk $ w $
|
||||
X.body { pos: 0.0 /\ 0.0 /\ 0.0 }
|
||||
[ X.joint { type: X.kw X.Hinge, stiffness: 100.0, damping: 10.0, armature: 0.1 }
|
||||
, X.geom { type: X.kw X.Sphere, size: [ 0.05, 0.0, 0.0 ] } unit
|
||||
]
|
||||
|
||||
describe "freejoint" do
|
||||
it "basic" $ parseOk $ w $
|
||||
X.body { name: "free_body", pos: 0.0 /\ 0.0 /\ 1.0 }
|
||||
[ X.freejoint { name: "fj" }
|
||||
, X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit
|
||||
]
|
||||
|
||||
describe "geom" do
|
||||
it "sphere" $ parseOk $ w $
|
||||
X.geom { type: X.kw X.Sphere, size: [ 1.0, 0.0, 0.0 ] } unit
|
||||
|
||||
it "capsule fromto" $ parseOk $ w $
|
||||
X.geom { type: X.kw X.Capsule, fromto: [ 0.0, 0.0, 0.0, 0.0, 0.0, 1.0 ], size: [ 0.05, 0.0, 0.0 ] } unit
|
||||
|
||||
it "box with material" $ parseOk $ X.mujoco {}
|
||||
[ X.asset {}
|
||||
[ X.material { name: "red", rgba: 1.0 /\ 0.0 /\ 0.0 /\ 1.0 } unit ]
|
||||
, X.worldbody {} $
|
||||
X.geom { type: X.kw X.Box, size: [ 0.5, 0.5, 0.5 ], material: "red" } unit
|
||||
]
|
||||
|
||||
it "plane" $ parseOk $ w $
|
||||
X.geom { type: X.kw X.Plane, size: [ 5.0, 5.0, 0.1 ] } unit
|
||||
|
||||
it "friction + density" $ parseOk $ w $
|
||||
X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ], friction: 0.5 /\ 0.005 /\ 0.0001, density: 500.0 } unit
|
||||
|
||||
describe "site" do
|
||||
it "basic" $ parseOk $ w $
|
||||
X.body { pos: 0.0 /\ 0.0 /\ 0.0 }
|
||||
[ X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit
|
||||
, X.site { name: "s1", pos: 0.0 /\ 0.0 /\ 0.1, size: 0.01 /\ 0.01 /\ 0.01 }
|
||||
]
|
||||
|
||||
describe "camera" do
|
||||
it "fixed" $ parseOk $ w $
|
||||
X.camera { name: "cam1", pos: 0.0 /\ (-2.0) /\ 1.0, fovy: 60.0 }
|
||||
|
||||
it "tracking" $ parseOk $ w $
|
||||
X.body { name: "target_body", pos: 0.0 /\ 0.0 /\ 0.5 }
|
||||
[ X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit
|
||||
, X.camera { name: "tracker", mode: X.kw X.Targetbody, target: "target_body", pos: 1.0 /\ 0.0 /\ 0.5 }
|
||||
]
|
||||
|
||||
describe "light" do
|
||||
it "spotlight" $ parseOk $ w $
|
||||
X.light { name: "spot1", pos: 0.0 /\ 0.0 /\ 3.0, dir: 0.0 /\ 0.0 /\ (-1.0), diffuse: 1.0 /\ 1.0 /\ 1.0 }
|
||||
|
||||
it "directional" $ parseOk $ w $
|
||||
X.light { name: "sun", type: X.kw X.Directional, dir: 0.0 /\ (-1.0) /\ (-1.0), castshadow: true }
|
||||
|
||||
describe "inertial" do
|
||||
it "explicit mass + diaginertia" $ parseOk $ w $
|
||||
X.body { pos: 0.0 /\ 0.0 /\ 0.0 }
|
||||
[ X.inertial { pos: 0.0 /\ 0.0 /\ 0.0, mass: 1.0, diaginertia: 0.01 /\ 0.01 /\ 0.01 }
|
||||
, X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ] } unit
|
||||
]
|
||||
|
||||
describe "composite" do
|
||||
it "full model"
|
||||
$ parseOk
|
||||
$ X.mujoco { model: "test" }
|
||||
[ X.compiler { angle: X.kw X.Radian, inertiafromgeom: X.true_ }
|
||||
, X.option { timestep: 0.002, gravity: 0.0 /\ 0.0 /\ (-9.81) }
|
||||
[ X.flag { contact: X.kw X.Enable } ]
|
||||
, X.asset {}
|
||||
[ X.texture { name: "grid", type: X.kw X.TwoD, builtin: X.kw X.Checker, width: 256, height: 256, rgb1: 0.9 /\ 0.9 /\ 0.9, rgb2: 0.1 /\ 0.1 /\ 0.1 }
|
||||
, X.material { name: "floor_mat", texture: "grid", texrepeat: 5.0 /\ 5.0 } unit
|
||||
]
|
||||
, X.worldbody {}
|
||||
[ X.geom { type: X.kw X.Plane, size: [ 5.0, 5.0, 0.1 ], material: "floor_mat" } unit
|
||||
, X.light { name: "top", pos: 0.0 /\ 0.0 /\ 3.0, dir: 0.0 /\ 0.0 /\ (-1.0) }
|
||||
, X.body { name: "ball", pos: 0.0 /\ 0.0 /\ 1.0 }
|
||||
[ X.freejoint {}
|
||||
, X.geom { type: X.kw X.Sphere, size: [ 0.1, 0.0, 0.0 ], rgba: 1.0 /\ 0.0 /\ 0.0 /\ 1.0 } unit
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
it "bodies with joints" $ parseOk $ w
|
||||
[ X.light { name: "top", pos: 0.0 /\ 0.0 /\ 1.0 }
|
||||
, X.body {}
|
||||
[ X.joint { name: "v0_rx", damping: 1.0, stiffness: 10.0, axis: 1.0 /\ 0.0 /\ 0.0, pos: 0.0 /\ 0.0 /\ (-0.5) }
|
||||
, X.joint { name: "v0_ry", damping: 1.0, stiffness: 10.0, axis: 0.0 /\ 1.0 /\ 0.0, pos: 0.0 /\ 0.0 /\ (-0.5) }
|
||||
, X.geom { type: X.kw X.Cylinder, size: [ 1.0, 0.05 ] } unit
|
||||
, X.body { pos: zero /\ zero /\ 0.51 }
|
||||
[ X.joint { name: "b0a_rx", damping: 1.0, stiffness: 10.0, axis: 1.0 /\ 0.0 /\ 0.0, pos: 0.0 /\ 0.0 /\ (-0.5) }
|
||||
, X.joint { name: "b0a_ry", damping: 1.0, stiffness: 10.0, axis: 0.0 /\ 1.0 /\ 0.0, pos: 0.0 /\ 0.0 /\ (-0.5) }
|
||||
, X.geom { type: X.kw X.Cylinder, size: [ 0.05, 0.5 ] } unit
|
||||
, X.body { pos: zero /\ zero /\ one }
|
||||
[ X.joint { name: "b0b_rx", damping: 1.0, stiffness: 10.0, axis: 1.0 /\ 0.0 /\ 0.0, pos: 0.0 /\ 0.0 /\ (-0.5) }
|
||||
, X.joint { name: "b0b_ry", damping: 1.0, stiffness: 10.0, axis: 0.0 /\ 1.0 /\ 0.0, pos: 0.0 /\ 0.0 /\ (-0.5) }
|
||||
, X.geom { type: X.kw X.Cylinder, size: [ 0.05, 0.5 ] } unit
|
||||
, X.body { pos: zero /\ zero /\ 0.5 }
|
||||
[ X.joint { name: "v1_rx", damping: 1.0, stiffness: 10.0, axis: 1.0 /\ 0.0 /\ 0.0, pos: 0.0 /\ 0.0 /\ (-0.5) }
|
||||
, X.joint { name: "v1_ry", damping: 1.0, stiffness: 10.0, axis: 0.0 /\ 1.0 /\ 0.0, pos: 0.0 /\ 0.0 /\ (-0.5) }
|
||||
, X.geom { type: X.kw X.Cylinder, size: [ 1.0, 0.05 ] } unit
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
10
test/Mujoco.Wasm.js
Normal file
10
test/Mujoco.Wasm.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import load_mujoco from 'mujoco_wasm/mujoco_wasm.js'
|
||||
|
||||
/** @typedef {import('mujoco_wasm').MainModule} Mujoco */
|
||||
/** @typedef {import('mujoco_wasm').MjSpec} Spec */
|
||||
|
||||
/** @type {() => Promise<Mujoco>} */
|
||||
export const loadMujoco_ = () => load_mujoco()
|
||||
|
||||
/** @type {(mj: Mujoco) => (xml: String) => () => Spec} */
|
||||
export const parseXMLString = m => xml => () => m.parseXMLString(xml)
|
||||
15
test/Mujoco.Wasm.purs
Normal file
15
test/Mujoco.Wasm.purs
Normal file
@@ -0,0 +1,15 @@
|
||||
module Mujoco.Wasm where
|
||||
|
||||
import Control.Promise (Promise)
|
||||
import Control.Promise as Promise
|
||||
import Effect (Effect)
|
||||
import Effect.Aff (Aff)
|
||||
|
||||
foreign import data Mujoco :: Type
|
||||
foreign import data Spec :: Type
|
||||
|
||||
foreign import loadMujoco_ :: Effect (Promise Mujoco)
|
||||
foreign import parseXMLString :: Mujoco -> String -> Effect Spec
|
||||
|
||||
loadMujoco :: Aff Mujoco
|
||||
loadMujoco = Promise.toAffE loadMujoco_
|
||||
70
test/Mujuco.MJCF.Util.purs
Normal file
70
test/Mujuco.MJCF.Util.purs
Normal file
@@ -0,0 +1,70 @@
|
||||
module Test.Mujoco.MJCF.Util where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Control.Monad.Error.Class (class MonadError, class MonadThrow, try)
|
||||
import Control.Monad.Reader (class MonadAsk, class MonadReader, ReaderT, ask, local, runReaderT)
|
||||
import Data.Either (isLeft)
|
||||
import Data.Identity (Identity)
|
||||
import Data.Newtype (class Newtype, unwrap)
|
||||
import Effect.Aff (Aff)
|
||||
import Effect.Aff.Class (class MonadAff)
|
||||
import Effect.Class (class MonadEffect, liftEffect)
|
||||
import Effect.Console as Console
|
||||
import Effect.Exception (Error)
|
||||
import Mujoco.MJCF as X
|
||||
import Mujoco.MJCF.XML (Node)
|
||||
import Mujoco.MJCF.XML as XML
|
||||
import Mujoco.Wasm (Mujoco)
|
||||
import Mujoco.Wasm as Mj
|
||||
import Test.Assert (assertTrue)
|
||||
import Test.Spec (SpecT, Spec, hoistSpec)
|
||||
|
||||
type T' = { mj :: Mujoco, dbg :: Boolean }
|
||||
newtype T a = T (ReaderT T' Aff a)
|
||||
|
||||
derive instance Newtype (T a) _
|
||||
derive newtype instance Functor T
|
||||
derive newtype instance Applicative T
|
||||
derive newtype instance Apply T
|
||||
derive newtype instance Bind T
|
||||
derive newtype instance Monad T
|
||||
derive newtype instance MonadReader T' T
|
||||
derive newtype instance MonadAsk T' T
|
||||
derive newtype instance MonadEffect T
|
||||
derive newtype instance MonadAff T
|
||||
derive newtype instance MonadThrow Error T
|
||||
derive newtype instance MonadError Error T
|
||||
|
||||
type MjcfSpec a = SpecT T Unit Identity a
|
||||
|
||||
mjcf :: forall a. Mujoco -> MjcfSpec a -> Spec a
|
||||
mjcf mj = hoistSpec identity (\_ -> runT mj)
|
||||
|
||||
runT :: forall a. Mujoco -> T a -> Aff a
|
||||
runT mj m = runReaderT (unwrap m) { mj, dbg: false }
|
||||
|
||||
dbg :: forall a. T a -> T a
|
||||
dbg = local (_ { dbg = true })
|
||||
|
||||
renderSpec :: XML.Node -> T Mj.Spec
|
||||
renderSpec node = do
|
||||
{ mj, dbg: dbg' } <- ask
|
||||
let
|
||||
xml = XML.render node
|
||||
|
||||
when dbg'
|
||||
$ liftEffect
|
||||
$ Console.log
|
||||
$ xml
|
||||
|
||||
liftEffect $ Mj.parseXMLString mj xml
|
||||
|
||||
parseOk :: XML.Node -> T Unit
|
||||
parseOk = void <<< renderSpec
|
||||
|
||||
parseFail :: XML.Node -> T Unit
|
||||
parseFail = (liftEffect <<< assertTrue <<< isLeft) <=< (try <<< renderSpec)
|
||||
|
||||
w :: forall a. XML.Children a => a -> Node
|
||||
w = X.mujoco {} <<< X.worldbody {}
|
||||
Reference in New Issue
Block a user