@@ -571,6 +571,209 @@ quaternions in XYZW format:
571571- And all other quaternion utilities
572572
573573
574+ Warp Backend for Asset and Sensor Data
575+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
576+
577+ All ``.data.* `` properties on asset and sensor classes now return ``wp.array `` instead of
578+ ``torch.Tensor ``. This change applies to all asset classes (:class: `~isaaclab.assets.Articulation `,
579+ :class: `~isaaclab.assets.RigidObject `, :class: `~isaaclab.assets.RigidObjectCollection `,
580+ :class: `~isaaclab_physx.assets.DeformableObject `) and all sensor classes
581+ (:class: `~isaaclab_physx.sensors.ContactSensor `, :class: `~isaaclab_physx.sensors.Imu `,
582+ :class: `~isaaclab_physx.sensors.FrameTransformer `).
583+
584+ To convert back to ``torch.Tensor `` for use with PyTorch operations, wrap the property
585+ access with ``wp.to_torch() ``:
586+
587+ .. code-block :: python
588+
589+ import warp as wp
590+
591+ # Before (Isaac Lab 2.x)
592+ root_pos = robot.data.root_pos_w # torch.Tensor
593+ joint_pos = robot.data.joint_pos # torch.Tensor
594+ contact_forces = sensor.data.net_forces_w # torch.Tensor
595+
596+ # After (Isaac Lab 3.x)
597+ root_pos = robot.data.root_pos_w # wp.array
598+ joint_pos = robot.data.joint_pos # wp.array
599+ contact_forces = sensor.data.net_forces_w # wp.array
600+
601+ # To use with torch operations, wrap with wp.to_torch()
602+ root_pos_torch = wp.to_torch(robot.data.root_pos_w) # torch.Tensor
603+ joint_pos_torch = wp.to_torch(robot.data.joint_pos) # torch.Tensor
604+ contact_torch = wp.to_torch(sensor.data.net_forces_w) # torch.Tensor
605+
606+ Common patterns that need updating:
607+
608+ .. code-block :: python
609+
610+ # Cloning data
611+ # Before:
612+ pos = robot.data.root_pos_w.clone()
613+ # After:
614+ pos = wp.to_torch(robot.data.root_pos_w).clone()
615+
616+ # Creating zero tensors with matching shape
617+ # Before:
618+ zeros = torch.zeros_like(robot.data.root_pos_w)
619+ # After:
620+ zeros = torch.zeros_like(wp.to_torch(robot.data.root_pos_w))
621+
622+ # Assertions in tests
623+ # Before:
624+ torch.testing.assert_close(robot.data.root_pos_w, expected)
625+ # After:
626+ torch.testing.assert_close(wp.to_torch(robot.data.root_pos_w), expected)
627+
628+ .. list-table :: Affected classes
629+ :header-rows: 1
630+ :widths: 40 60
631+
632+ * - Class
633+ - Package
634+ * - :class: `~isaaclab.assets.Articulation `
635+ - ``isaaclab `` / ``isaaclab_physx ``
636+ * - :class: `~isaaclab.assets.RigidObject `
637+ - ``isaaclab `` / ``isaaclab_physx ``
638+ * - :class: `~isaaclab.assets.RigidObjectCollection `
639+ - ``isaaclab `` / ``isaaclab_physx ``
640+ * - :class: `~isaaclab_physx.assets.DeformableObject `
641+ - ``isaaclab_physx ``
642+ * - :class: `~isaaclab_physx.sensors.ContactSensor `
643+ - ``isaaclab_physx ``
644+ * - :class: `~isaaclab_physx.sensors.Imu `
645+ - ``isaaclab_physx ``
646+ * - :class: `~isaaclab_physx.sensors.FrameTransformer `
647+ - ``isaaclab_physx ``
648+
649+ .. note ::
650+
651+ An automated migration tool is provided at ``scripts/tools/wrap_warp_to_torch.py ``.
652+ It scans Python files for ``.data.<property> `` accesses and wraps them with
653+ ``wp.to_torch() ``. Usage:
654+
655+ .. code-block :: bash
656+
657+ # Dry run (preview changes)
658+ python scripts/tools/wrap_warp_to_torch.py path/to/your/code --dry-run
659+
660+ # Apply changes in-place
661+ python scripts/tools/wrap_warp_to_torch.py path/to/your/code
662+
663+ Always review the changes after running the tool, as some accesses (e.g., those
664+ already passed to warp-native functions) should not be wrapped.
665+
666+
667+ Write Method Index/Mask Split
668+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
669+
670+ All asset write methods have been split into two explicit variants:
671+
672+ - ``write_*_to_sim_index(data, env_ids) `` — accepts partial data for a sparse set of
673+ environment indices. The ``data `` tensor has shape ``(len(env_ids), ...) ``.
674+ - ``write_*_to_sim_mask(data, env_mask) `` — accepts full data for all environments with a
675+ boolean mask selecting which environments to update. The ``data `` tensor has shape
676+ ``(num_envs, ...) ``.
677+
678+ The previous ``write_*_to_sim(data, env_ids) `` methods have been removed.
679+
680+ .. code-block :: python
681+
682+ # Before (Isaac Lab 2.x)
683+ robot.write_root_pose_to_sim(pose_data, env_ids)
684+
685+ # After (Isaac Lab 3.x) — indexed variant (partial data)
686+ robot.write_root_pose_to_sim_index(pose_data, env_ids)
687+
688+ # After (Isaac Lab 3.x) — mask variant (full data, boolean mask)
689+ robot.write_root_pose_to_sim_mask(pose_data, env_mask)
690+
691+ .. list-table :: Affected write methods (RigidObject / Articulation)
692+ :header-rows: 1
693+ :widths: 50 50
694+
695+ * - Old method
696+ - New methods
697+ * - ``write_root_pose_to_sim ``
698+ - ``write_root_pose_to_sim_index `` / ``write_root_pose_to_sim_mask ``
699+ * - ``write_root_link_pose_to_sim ``
700+ - ``write_root_link_pose_to_sim_index `` / ``write_root_link_pose_to_sim_mask ``
701+ * - ``write_root_com_pose_to_sim ``
702+ - ``write_root_com_pose_to_sim_index `` / ``write_root_com_pose_to_sim_mask ``
703+ * - ``write_root_velocity_to_sim ``
704+ - ``write_root_velocity_to_sim_index `` / ``write_root_velocity_to_sim_mask ``
705+ * - ``write_root_com_velocity_to_sim ``
706+ - ``write_root_com_velocity_to_sim_index `` / ``write_root_com_velocity_to_sim_mask ``
707+ * - ``write_root_link_velocity_to_sim ``
708+ - ``write_root_link_velocity_to_sim_index `` / ``write_root_link_velocity_to_sim_mask ``
709+
710+ .. list-table :: Additional Articulation-specific write methods
711+ :header-rows: 1
712+ :widths: 50 50
713+
714+ * - Old method
715+ - New methods
716+ * - ``write_joint_position_to_sim ``
717+ - ``write_joint_position_to_sim_index `` / ``write_joint_position_to_sim_mask ``
718+ * - ``write_joint_velocity_to_sim ``
719+ - ``write_joint_velocity_to_sim_index `` / ``write_joint_velocity_to_sim_mask ``
720+ * - ``write_joint_stiffness_to_sim ``
721+ - ``write_joint_stiffness_to_sim_index `` / ``write_joint_stiffness_to_sim_mask ``
722+ * - ``write_joint_damping_to_sim ``
723+ - ``write_joint_damping_to_sim_index `` / ``write_joint_damping_to_sim_mask ``
724+ * - ``write_joint_position_limit_to_sim ``
725+ - ``write_joint_position_limit_to_sim_index `` / ``write_joint_position_limit_to_sim_mask ``
726+ * - ``write_joint_velocity_limit_to_sim ``
727+ - ``write_joint_velocity_limit_to_sim_index `` / ``write_joint_velocity_limit_to_sim_mask ``
728+ * - ``write_joint_effort_limit_to_sim ``
729+ - ``write_joint_effort_limit_to_sim_index `` / ``write_joint_effort_limit_to_sim_mask ``
730+ * - ``write_joint_armature_to_sim ``
731+ - ``write_joint_armature_to_sim_index `` / ``write_joint_armature_to_sim_mask ``
732+ * - ``write_joint_friction_coefficient_to_sim ``
733+ - ``write_joint_friction_coefficient_to_sim_index `` / ``write_joint_friction_coefficient_to_sim_mask ``
734+
735+ .. list-table :: RigidObjectCollection write methods
736+ :header-rows: 1
737+ :widths: 50 50
738+
739+ * - Old method
740+ - New methods
741+ * - ``write_body_pose_to_sim ``
742+ - ``write_body_pose_to_sim_index `` / ``write_body_pose_to_sim_mask ``
743+ * - ``write_body_link_pose_to_sim ``
744+ - ``write_body_link_pose_to_sim_index `` / ``write_body_link_pose_to_sim_mask ``
745+ * - ``write_body_com_pose_to_sim ``
746+ - ``write_body_com_pose_to_sim_index `` / ``write_body_com_pose_to_sim_mask ``
747+ * - ``write_body_velocity_to_sim ``
748+ - ``write_body_velocity_to_sim_index `` / ``write_body_velocity_to_sim_mask ``
749+ * - ``write_body_com_velocity_to_sim ``
750+ - ``write_body_com_velocity_to_sim_index `` / ``write_body_com_velocity_to_sim_mask ``
751+ * - ``write_body_link_velocity_to_sim ``
752+ - ``write_body_link_velocity_to_sim_index `` / ``write_body_link_velocity_to_sim_mask ``
753+
754+
755+ TimestampedBufferWarp
756+ ~~~~~~~~~~~~~~~~~~~~~
757+
758+ If you have custom asset or sensor data classes that subclass the Isaac Lab base data classes,
759+ note that internal buffers have changed from :class: `~isaaclab.utils.buffers.TimestampedBuffer `
760+ to :class: `~isaaclab.utils.buffers.TimestampedBufferWarp `. The new class takes ``(shape, device,
761+ wp_dtype) `` as constructor arguments instead of a ``torch.Tensor ``:
762+
763+ .. code-block :: python
764+
765+ import warp as wp
766+ from isaaclab.utils.buffers import TimestampedBufferWarp
767+
768+ # Before (Isaac Lab 2.x)
769+ self ._data.root_pos_w = TimestampedBuffer(torch.zeros(num_envs, 3 , device = device))
770+
771+ # After (Isaac Lab 3.x)
772+ self ._data.root_pos_w = TimestampedBufferWarp(
773+ shape = (num_envs,), device = device, wp_dtype = wp.vec3f
774+ )
775+
776+
574777 Need Help?
575778~~~~~~~~~~
576779
0 commit comments