diff --git a/docs/tutorials/physics/mocap_control.md b/docs/tutorials/physics/mocap_control.md index 2b64469..d65b5a0 100644 --- a/docs/tutorials/physics/mocap_control.md +++ b/docs/tutorials/physics/mocap_control.md @@ -10,7 +10,7 @@ from textwrap import dedent from killport import kill_ports from vuer import Vuer, VuerSession from vuer.events import ClientEvent -from vuer.schemas import MuJoCo, Scene, Fog, Sphere, Hands, HandActuator +from vuer.schemas import MuJoCo, Scene, Fog, Sphere, Hands, HandActuator, MotionControllers, MotionControllerActuator ``` @@ -90,7 +90,8 @@ async def main(sess: VuerSession): # grid=False, bgChildren=[ Fog(color=0x2C3F57, near=10, far=20), - Hands(), + # Hands(), + MotionControllers(), Sphere( args=[50, 10, 10], materialType="basic", @@ -101,8 +102,8 @@ async def main(sess: VuerSession): await sleep(0.0005) sess.upsert @ MuJoCo( - HandActuator(key="pinch-on-squeeze"), - + # HandActuator(key="pinch-on-squeeze"), + MotionControllerActuator(high=0.15, low=0.01, ctrlId=-1), key="franka-gripper", src=asset_pref + "scene.xml", assets=[asset_pref + fn for fn in ASSETS_LIST], @@ -113,40 +114,3 @@ async def main(sess: VuerSession): await sleep(100.0) ``` - - -```{admonition} Note -:class: tip - -Note the `HandActuator` that is used to add control to the -gripper fingers. This is currently hand-specific. - - class HandActuator(SceneElement): - tag = "HandActuator" - - ctrlId = -1 - offset = 0.01 - low = 0.01 - high = 1.0 - cond = 'right-squeeze' - value = "right:thumb-tip,right:index-finger-tip" - scale = 1.0 -``` - -This correspond to the following actuator definition -in the MJCF file: - -```xml -... - - - - - -... - - - - -``` diff --git a/docs/tutorials/physics/mocap_control.py b/docs/tutorials/physics/mocap_control.py index 08315f9..e2c3e6f 100644 --- a/docs/tutorials/physics/mocap_control.py +++ b/docs/tutorials/physics/mocap_control.py @@ -3,7 +3,7 @@ from cmx import doc -MAKE_DOCS = os.getenv("MAKE_DOCS", True) +MAKE_DOCS = os.getenv("MAKE_DOCS", False) doc @ """ # MuJoCo VR Mocap Example @@ -17,7 +17,7 @@ from killport import kill_ports from vuer import Vuer, VuerSession from vuer.events import ClientEvent - from vuer.schemas import MuJoCo, Scene, Fog, Sphere, Hands, HandActuator + from vuer.schemas import MuJoCo, Scene, Fog, Sphere, Hands, HandActuator, MotionControllers, MotionControllerActuator doc @ """ @@ -97,7 +97,8 @@ async def main(sess: VuerSession): # grid=False, bgChildren=[ Fog(color=0x2C3F57, near=10, far=20), - Hands(), + # Hands(), + MotionControllers(), Sphere( args=[50, 10, 10], materialType="basic", @@ -108,8 +109,8 @@ async def main(sess: VuerSession): await sleep(0.0005) sess.upsert @ MuJoCo( - HandActuator(key="pinch-on-squeeze"), - + # HandActuator(key="pinch-on-squeeze"), + MotionControllerActuator(high=0.15, low=0.01, ctrlId=-1), key="franka-gripper", src=asset_pref + "scene.xml", assets=[asset_pref + fn for fn in ASSETS_LIST], diff --git a/vuer/schemas/physics_components.py b/vuer/schemas/physics_components.py index b5f2bda..00a17a8 100644 --- a/vuer/schemas/physics_components.py +++ b/vuer/schemas/physics_components.py @@ -49,3 +49,34 @@ class HandActuator(SceneElement): cond = 'right-squeeze' value = "right:thumb-tip,right:index-finger-tip" scale = 1.0 + +class MotionControllerActuator(SceneElement): + """ + MotionControllerActuator component for actuating the MuJoCo simulation based on motion controller inputs. + + :param ctrlId: The control ID in the MuJoCo simulation to actuate. + :type ctrlId: int + :param low: The minimum value for actuation. + :type low: float + :param high: The maximum value for actuation. + :type high: float + :param cond: The condition for actuation, e.g., 'right-trigger'. + :type cond: str + :param scale: The scaling factor applied to the input value for actuation. + :type scale: float + """ + tag = "MotionControllerActuator" + + ctrlId: int = -1 + low: float = 0.0 + high: float = 1.0 + cond: str = 'right-trigger' + scale: float = 1.0 + + def __init__(self, ctrlId=-1, low=0.0, high=1.0, cond='right-trigger', scale=1.0, **kwargs): + super().__init__(**kwargs) + self.ctrlId = ctrlId + self.low = low + self.high = high + self.cond = cond + self.scale = scale \ No newline at end of file diff --git a/vuer/schemas/scene_components.py b/vuer/schemas/scene_components.py index 8c5e688..f83fa15 100644 --- a/vuer/schemas/scene_components.py +++ b/vuer/schemas/scene_components.py @@ -628,6 +628,49 @@ def __init__( **kwargs, ) +class MotionControllers(SceneElement): + """ + MotionController for tracking XR controller poses and button states. + + :param key: Unique identifier for the controller. + :type key: str, optional + :param eventTypes: A tuple or list of events to track (e.g., "trigger", "squeeze"). + :type eventTypes: tuple or list, optional + :param stream: Whether to enable streaming of controller data. + :type stream: bool, optional + :param left: Boolean indicating if the left controller should be tracked. + :type left: bool, optional + :param right: Boolean indicating if the right controller should be tracked. + :type right: bool, optional + :param showLeft: Boolean indicating if the left controller visualization should be shown. + :type showLeft: bool, optional + :param showRight: Boolean indicating if the right controller visualization should be shown. + :type showRight: bool, optional + """ + + tag = "MotionControllers" + + def __init__( + self, + key="motionControllers", + eventTypes=("trigger", "squeeze"), + stream=True, + left=None, + right=None, + showLeft=True, + showRight=True, + **kwargs, + ): + super().__init__( + key=key, + eventTypes=eventTypes, + stream=stream, + left=left, + right=right, + showLeft=showLeft, + showRight=showRight, + **kwargs, + ) class Obj(SceneElement): tag = "Obj" @@ -771,6 +814,7 @@ def __init__( AmbientLight(key="ambient", intensity=0.25), PointLight(key="spot", intensity=1, position=[0, 1, 1]), Hands(fps=30, eventType=["squeeze"], stream=True), + MotionControllers(fps=30, eventType=["trigger", "squeeze"], stream=True), ] self.up = up